Iros
 
Loading...
Searching...
No Matches
common.h
Go to the documentation of this file.
1#pragma once
2
4#include "di/meta/core.h"
5#include "di/meta/language.h"
7#include "di/meta/util.h"
8#include "di/types/prelude.h"
9#include "di/util/declval.h"
10
11namespace di::meta {
12template<typename T, typename U>
14
15namespace detail {
16 template<typename T, typename U>
18
19 template<typename T, typename U>
20 concept HasCustomCommonType = requires { typename CustomCommonType<T, U>::Type; };
21
22 template<typename T, typename U>
23 concept ValueCommonType = requires { false ? util::declval<T>() : util::declval<U>(); };
24
25 template<typename T, typename U>
29
30 template<typename... Types>
32
33 template<typename T>
34 struct CommonTypeHelper<T> : CommonTypeHelper<T, T> {};
35
36 template<typename T, typename U>
37 requires(NeedsDecay<T, U>)
39
40 template<typename T, typename U>
41 requires(!NeedsDecay<T, U> && HasCustomCommonType<T, U>)
42 struct CommonTypeHelper<T, U> : TypeConstant<typename CustomCommonType<T, U>::Type> {};
43
44 template<typename T, typename U>
45 requires(!NeedsDecay<T, U> && !HasCustomCommonType<T, U> && ValueCommonType<T, U>)
46 struct CommonTypeHelper<T, U>
47 : TypeConstant<meta::Decay<decltype(false ? util::declval<T>() : util::declval<U>())>> {};
48
49 template<typename T, typename U>
50 requires(!NeedsDecay<T, U> && !HasCustomCommonType<T, U> && !ValueCommonType<T, U> && ReferenceCommonType<T, U>)
51 struct CommonTypeHelper<T, U>
52 : TypeConstant<meta::Decay<decltype(false ? util::declval<meta::RemoveReference<T> const&>()
53 : util::declval<meta::RemoveReference<U> const&>())>> {};
54
55 template<typename T, typename U, typename W, typename... Rest>
56 requires(requires { typename CommonTypeHelper<T, U>::Type; })
57 struct CommonTypeHelper<T, U, W, Rest...> : CommonTypeHelper<typename CommonTypeHelper<T, U>::Type, W, Rest...> {};
58}
59
60template<typename... Types>
61requires(requires { typename detail::CommonTypeHelper<Types...>::Type; })
63
64template<typename T, typename U, template<typename> typename TQual, template<typename> typename UQual>
66
67namespace detail {
68 template<typename T>
69 auto __get_value() -> T;
70
71 template<typename T>
73 template<typename U>
75 };
76
77 template<typename T, typename U, typename R>
78 struct UnionCV : TypeConstant<R> {};
79
80 template<typename T, typename U, typename R>
81 struct UnionCV<T const, U, R> : TypeConstant<R const> {};
82
83 template<typename T, typename U, typename R>
84 struct UnionCV<T const, U const, R> : TypeConstant<R const> {};
85
86 template<typename T, typename U, typename R>
87 struct UnionCV<T const, U volatile, R> : TypeConstant<R const volatile> {};
88
89 template<typename T, typename U, typename R>
90 struct UnionCV<T const, U const volatile, R> : TypeConstant<R const volatile> {};
91
92 template<typename T, typename U, typename R>
93 struct UnionCV<T volatile, U, R> : TypeConstant<R volatile> {};
94
95 template<typename T, typename U, typename R>
96 struct UnionCV<T volatile, U const, R> : TypeConstant<R const volatile> {};
97
98 template<typename T, typename U, typename R>
99 struct UnionCV<T volatile, U volatile, R> : TypeConstant<R volatile> {};
100
101 template<typename T, typename U, typename R>
102 struct UnionCV<T volatile, U const volatile, R> : TypeConstant<R const volatile> {};
103
104 template<typename T, typename U, typename R>
105 struct UnionCV<T const volatile, U, R> : TypeConstant<R const volatile> {};
106
107 template<typename T, typename U, typename R>
108 struct UnionCV<T const volatile, U const, R> : TypeConstant<R const volatile> {};
109
110 template<typename T, typename U, typename R>
111 struct UnionCV<T const volatile, U volatile, R> : TypeConstant<R const volatile> {};
112
113 template<typename T, typename U, typename R>
114 struct UnionCV<T const volatile, U const volatile, R> : TypeConstant<R const volatile> {};
115
116 template<typename T, typename U>
118
119 template<concepts::LValueReference T, concepts::LValueReference U>
120 requires(requires {
124 meta::RemoveReference<U>>::Type&>();
125 })
126 struct SimpleCommonReference<T, U>
127 : TypeConstant<decltype(false
128 ? util::declval<typename UnionCV<meta::RemoveReference<T>, meta::RemoveReference<U>,
129 meta::RemoveReference<T>>::Type&>()
130 : util::declval<typename UnionCV<meta::RemoveReference<T>, meta::RemoveReference<U>,
131 meta::RemoveReference<U>>::Type&>())> {};
132
133 template<concepts::RValueReference T, concepts::RValueReference U>
134 requires(requires { typename SimpleCommonReference<T&, U&>::Type; } &&
135 concepts::ImplicitlyConvertibleTo<T, typename SimpleCommonReference<T&, U&>::Type> &&
136 concepts::ImplicitlyConvertibleTo<U, typename SimpleCommonReference<T&, U&>::Type>)
137 struct SimpleCommonReference<T, U> : TypeConstant<typename SimpleCommonReference<T&, U&>::Type> {};
138
139 template<concepts::LValueReference T, concepts::RValueReference U>
140 requires(requires {
142 } && concepts::ImplicitlyConvertibleTo<U &&,
144 struct SimpleCommonReference<T, U>
145 : TypeConstant<typename SimpleCommonReference<T, meta::RemoveReference<U> const&>::Type> {};
146
147 template<concepts::RValueReference T, concepts::LValueReference U>
149
150 template<typename T, typename U>
152
153 template<typename T, typename U>
158
159 template<typename T, typename U>
160 concept HasValueCommonReference = requires { false ? __get_value<T>() : __get_value<U>(); };
161
162 template<typename T, typename U>
163 concept HasCommonTypeCommonReference = requires { typename CommonType<T, U>; };
164
165 template<typename... Types>
167
168 template<typename T>
170
171 template<typename T, typename U>
173 struct CommonReferenceHelper<T, U> : TypeConstant<typename SimpleCommonReference<T, U>::Type> {};
174
175 template<typename T, typename U>
176 requires(!HasSimpleCommonReference<T, U> && HasCustomCommonReference<T, U>)
177 struct CommonReferenceHelper<T, U>
178 : TypeConstant<typename CustomCommonReference<T, U, ProjectQualifiers<T>::template Type,
179 ProjectQualifiers<U>::template Type>::Type> {};
180
181 template<typename T, typename U>
182 requires(!HasSimpleCommonReference<T, U> && !HasCustomCommonReference<T, U> && HasValueCommonReference<T, U>)
183 struct CommonReferenceHelper<T, U> : TypeConstant<decltype(false ? __get_value<T>() : __get_value<U>())> {};
184
185 template<typename T, typename U>
186 requires(!HasSimpleCommonReference<T, U> && !HasCustomCommonReference<T, U> && !HasValueCommonReference<T, U> &&
187 HasCommonTypeCommonReference<T, U>)
188 struct CommonReferenceHelper<T, U> : TypeConstant<CommonType<T, U>> {};
189
190 template<typename T, typename U, typename W, typename... Rest>
191 requires(requires { typename CommonReferenceHelper<T, U>::Type; })
192 struct CommonReferenceHelper<T, U, W, Rest...>
193 : CommonReferenceHelper<typename CommonReferenceHelper<T, U>::Type, W, Rest...> {};
194}
195
196template<typename... Types>
197requires(requires { typename detail::CommonReferenceHelper<Types...>::Type; })
199}
200
201namespace di::concepts {
202template<typename T, typename U>
206
207template<typename T, typename U>
216}
Definition common.h:203
Definition common.h:208
Definition operations.h:99
Definition core.h:114
Definition common.h:17
Definition common.h:23
Definition any_storable.h:9
Definition const_sentinel.h:8
auto __get_value() -> T
Definition merge_interfaces.h:6
T::Type Type
Definition core.h:26
detail::CommonTypeHelper< Types... >::Type CommonType
Definition common.h:62
Conditional< concepts::LanguageArray< RemoveReference< T > >, RemoveExtent< RemoveReference< T > > *, Conditional< concepts::LanguageFunction< RemoveReference< T > >, AddPointer< RemoveReference< T > >, RemoveCVRef< T > > > Decay
Definition language.h:574
Type< detail::LikeHelper< T, U > > Like
Definition language.h:468
detail::CommonReferenceHelper< Types... >::Type CommonReference
Definition common.h:198
Type< detail::RemoveReferenceHelper< T > > RemoveReference
Definition core.h:71
Type< detail::AddLValueReferenceHelper< T > > AddLValueReference
Definition language.h:399
Definition vocab.h:96
auto declval() -> meta::AddRValueReference< T >
Definition declval.h:8
auto declval() -> meta::AddRValueReference< T >
Definition declval.h:8
@ U
Definition key.h:30
@ T
Definition key.h:29
Definition common.h:65
Definition common.h:13
Definition core.h:18
Like< T, U > Type
Definition common.h:74
Definition common.h:78