di 0.1.0
Loading...
Searching...
No Matches
variant_impl.h
Go to the documentation of this file.
1#pragma once
2
3#include "di/meta/constexpr.h"
4#include "di/meta/util.h"
5#include "di/types/prelude.h"
6#include "di/util/forward.h"
8
9namespace di::vocab::detail {
10template<typename... Types>
11requires(sizeof...(Types) > 0)
12class VariantImpl;
13
14template<typename T, typename... Rest>
15class VariantImpl<T, Rest...> {
16public:
17 constexpr VariantImpl() {}
18 constexpr VariantImpl(VariantImpl const&) = default;
19 constexpr VariantImpl(VariantImpl&&) = default;
20
21 constexpr auto operator=(VariantImpl const&) -> VariantImpl& = default;
22 constexpr auto operator=(VariantImpl&&) -> VariantImpl& = default;
23
24 ~VariantImpl() = default;
25
26 constexpr ~VariantImpl()
27 requires(!concepts::TriviallyDestructible<T> || (!concepts::TriviallyDestructible<Rest> || ...))
28 {}
29
30 template<concepts::RemoveCVRefSameAs<VariantImpl> Self>
31 constexpr static auto static_get(Constexpr<0ZU>, Self&& self) -> meta::Like<Self, T>&& {
32 return util::forward<Self>(self).m_value.value();
33 }
34
35 template<concepts::RemoveCVRefSameAs<VariantImpl> Self, size_t index>
36 requires(index != 0)
37 constexpr static auto static_get(Constexpr<index>, Self&& self) -> decltype(auto) {
38 return VariantImpl<Rest...>::static_get(c_<index - 1>, util::forward<Self>(self).m_rest);
39 }
40
41 constexpr void destroy_impl(Constexpr<0ZU>) { util::destroy_at(util::addressof(m_value)); }
42
43 template<size_t index>
44 constexpr void destroy_impl(Constexpr<index>) {
45 return m_rest.destroy_impl(c_<index - 1>);
46 }
47
48 template<typename... Args>
49 constexpr auto emplace_impl(Constexpr<0ZU>, Args&&... args) -> T& {
50 util::construct_at(util::addressof(m_value), in_place, util::forward<Args>(args)...);
51 return m_value.value();
52 }
53
54 template<size_t index, typename... Args>
55 requires(index != 0)
56 constexpr auto emplace_impl(Constexpr<index>, Args&&... args) -> decltype(auto) {
57 util::construct_at(util::addressof(m_rest));
58 return m_rest.emplace_impl(c_<index - 1>, util::forward<Args>(args)...);
59 }
60
61private:
62 union {
64 VariantImpl<Rest...> m_rest;
65 };
66};
67
68template<typename T>
69class VariantImpl<T> {
70public:
71 constexpr VariantImpl() {}
72 constexpr VariantImpl(VariantImpl const&) = default;
73 constexpr VariantImpl(VariantImpl&&) = default;
74
75 constexpr auto operator=(VariantImpl const&) -> VariantImpl& = default;
76 constexpr auto operator=(VariantImpl&&) -> VariantImpl& = default;
77
78 ~VariantImpl() = default;
79
80 constexpr ~VariantImpl()
81 requires(!concepts::TriviallyDestructible<T>)
82 {}
83
84 template<concepts::RemoveCVRefSameAs<VariantImpl> Self>
85 constexpr static auto static_get(Constexpr<0ZU>, Self&& self) -> meta::Like<Self, T>&& {
86 return util::forward<Self>(self).m_value.value();
87 }
88
89 constexpr void destroy_impl(Constexpr<0ZU>) { util::destroy_at(util::addressof(m_value)); }
90
91 template<typename... Args>
92 constexpr auto emplace_impl(Constexpr<0ZU>, Args&&... args) -> T& {
93 util::construct_at(util::addressof(m_value), in_place, util::forward<Args>(args)...);
94 return m_value.value();
95 }
96
97private:
98 union {
100 };
101};
102}
Type< detail::LikeHelper< T, U > > Like
Definition language.h:468
RebindableBox(T &&) -> RebindableBox< meta::UnwrapRefDecay< T > >
constexpr auto destroy_at
Definition destroy_at.h:24
constexpr auto construct_at
Definition construct_at.h:27
constexpr auto c_
A value of type Constexpr<val>.
Definition constexpr.h:252
constexpr auto in_place
Definition in_place.h:8