13#ifndef CPP_TYPE_TRAITS_HPP
14#define CPP_TYPE_TRAITS_HPP
24 using remove_cvref_t =
25 typename std::remove_cv<
26 typename std::remove_reference<T>::type>::type;
31 template<
typename From,
typename To>
32 using is_convertible = std::is_convertible<meta::_t<std::add_rvalue_reference<From>>, To>;
37 template<
typename,
typename U>
43 template<
typename T,
typename>
46 template<
bool B,
typename T,
typename U>
58 template<
bool B,
typename T =
void>
61 template<
typename From,
typename To>
66 template<
typename From,
typename To>
67 struct _copy_cv_<From const, To>
69 using type = To
const;
71 template<
typename From,
typename To>
72 struct _copy_cv_<From volatile, To>
74 using type = To
volatile;
76 template<
typename From,
typename To>
77 struct _copy_cv_<From const volatile, To>
79 using type = To
const volatile;
81 template<
typename From,
typename To>
85 template<
typename T,
typename U,
typename =
void>
86 struct _builtin_common;
88 template<
typename T,
typename U>
91 template<
typename T,
typename U>
92 using _cond_res =
decltype(
true ? std::declval<T>() : std::declval<U>());
94 template<
typename T,
typename U,
typename R = _builtin_common_t<T &, U &>>
98 template<
typename T,
typename U>
99 using _lref_res = _cond_res<_copy_cv<T, U> &, _copy_cv<U, T> &>;
104 using type = T
const &;
109 using type = T
const &;
112 struct as_cref_<T &&>
114 using type = T
const &;
117 struct as_cref_<void>
122 struct as_cref_<void const>
124 using type =
void const;
128 using as_cref_t =
typename as_cref_<T>::type;
131 using decay_t =
typename std::decay<T>::type;
133 #if !defined(__GNUC__) || defined(__clang__)
134 template<
typename T,
typename U,
typename =
void>
135 struct _builtin_common_3
137 template<
typename T,
typename U>
138 struct _builtin_common_3<T, U,
meta::
void_<_cond_res<as_cref_t<T>, as_cref_t<U>>>>
139 : std::decay<_cond_res<as_cref_t<T>, as_cref_t<U>>>
141 template<
typename T,
typename U,
typename =
void>
142 struct _builtin_common_2
143 : _builtin_common_3<T, U>
145 template<
typename T,
typename U>
146 struct _builtin_common_2<T, U,
meta::
void_<_cond_res<T, U>>>
147 : std::decay<_cond_res<T, U>>
149 template<
typename T,
typename U,
typename >
150 struct _builtin_common
151 : _builtin_common_2<T, U>
153 template<
typename T,
typename U>
154 struct _builtin_common<T &&, U &&, if_t<
155 is_convertible<T &&, _rref_res<T, U>>::value &&
156 is_convertible<U &&, _rref_res<T, U>>::value>>
158 using type = _rref_res<T, U>;
160 template<
typename T,
typename U>
161 struct _builtin_common<T &, U &>
164 template<
typename T,
typename U>
165 struct _builtin_common<T &, U &&, if_t<
166 is_convertible<U &&, _builtin_common_t<T &, U const &>>::value>>
167 : _builtin_common<T &, U const &>
169 template<
typename T,
typename U>
170 struct _builtin_common<T &&, U &>
171 : _builtin_common<U &, T &&>
174 template<
typename T,
typename U,
typename =
void>
175 struct _builtin_common_3
177 template<
typename T,
typename U>
178 struct _builtin_common_3<T, U,
meta::
void_<_cond_res<as_cref_t<T>, as_cref_t<U>>>>
179 : std::decay<_cond_res<as_cref_t<T>, as_cref_t<U>>>
181 template<
typename T,
typename U,
typename =
void>
182 struct _builtin_common_2
183 : _builtin_common_3<T, U>
185 template<
typename T,
typename U>
186 struct _builtin_common_2<T, U,
meta::
void_<_cond_res<T, U>>>
187 : std::decay<_cond_res<T, U>>
189 template<
typename T,
typename U,
typename >
190 struct _builtin_common
191 : _builtin_common_2<T, U>
193 template<
typename T,
typename U,
typename =
void>
194 struct _builtin_common_rr
195 : _builtin_common_2<T &&, U &&>
197 template<
typename T,
typename U>
198 struct _builtin_common_rr<T, U, if_t<
199 is_convertible<T &&, _rref_res<T, U>>::value &&
200 is_convertible<U &&, _rref_res<T, U>>::value>>
202 using type = _rref_res<T, U>;
204 template<
typename T,
typename U>
205 struct _builtin_common<T &&, U &&>
206 : _builtin_common_rr<T, U>
208 template<
typename T,
typename U>
209 struct _builtin_common<T &, U &>
212 template<
typename T,
typename U,
typename =
void>
213 struct _builtin_common_lr
214 : _builtin_common_2<T &, T &&>
216 template<
typename T,
typename U>
217 struct _builtin_common_lr<T, U, if_t<
218 is_convertible<U &&, _builtin_common_t<T &, U const &>>::value>>
219 : _builtin_common<T &, U const &>
221 template<
typename T,
typename U>
222 struct _builtin_common<T &, U &&>
223 : _builtin_common_lr<T, U>
225 template<
typename T,
typename U>
226 struct _builtin_common<T &&, U &>
227 : _builtin_common<U &, T &&>
240 template<
typename ...Ts>
249 template<
typename T,
typename U>
252 (META_IS_SAME(detail::decay_t<T>, T) &&
253 META_IS_SAME(detail::decay_t<U>, U) ),
254 meta::defer<detail::_builtin_common_t, T, U>,
255 common_type<detail::decay_t<T>, detail::decay_t<U>>>
258 template<
typename... Ts>
259 using common_type_t =
typename common_type<Ts...>::type;
261 template<
typename T,
typename U,
typename... Vs>
277 template<
typename>
class TQual,
278 template<
typename>
class UQual>
311 struct _xref<T const>
317 struct _xref<T volatile>
320 using invoke = U
volatile;
323 struct _xref<T const volatile>
326 using invoke = U
const volatile;
329 template<
typename T,
typename U>
330 using _basic_common_reference =
331 basic_common_reference<
334 _xref<T>::template
invoke,
335 _xref<U>::template
invoke>;
337 template<
typename T,
typename U,
typename =
void>
338 struct _common_reference2
340 meta::is_trait<_basic_common_reference<T, U>>::value,
341 _basic_common_reference<T, U>,
345 template<
typename T,
typename U>
346 struct _common_reference2<T, U, if_t<std::is_reference<_builtin_common_t<T, U>>::value>>
347 : _builtin_common<T, U>
354 template<
typename ...Ts>
364 template<
typename T,
typename U>
366 : detail::_common_reference2<T, U>
369 template<
typename... Ts>
372 template<
typename T,
typename U,
typename... Vs>
374 :
meta::lazy::fold<meta::list<U, Vs...>, T, meta::quote<common_reference_t>>
typename T::type _t
Type alias for T::type.
Definition meta.hpp:141
typename Fn::template invoke< Args... > invoke
Evaluate the invocable Fn with the arguments Args.
Definition meta.hpp:541
_t< detail::_if_< list< Args... > > > if_
Select one type or another depending on a compile-time Boolean.
Definition meta.hpp:1247
void void_
An alias for void.
Definition meta.hpp:597
Users can specialize this to hook the common_reference_with concept.
Definition type_traits.hpp:280
Users can specialize this to hook the common_reference_with concept.
Definition type_traits.hpp:356
Users should specialize this to hook the common_with concept until std gets a SFINAE-friendly std::co...
Definition type_traits.hpp:242