@@ -38,10 +38,21 @@ template<class...> using void_t = void;
3838
3939template <class ...> using __require = true_type;
4040
41+ // type relationships:
4142template <class , class > struct is_same : false_type {};
4243template <class _Tp > struct is_same <_Tp, _Tp> : true_type {};
4344template <class _Lp , class _Rp > inline constexpr bool is_same_v = is_same<_Lp, _Rp>::value;
4445
46+ #if __has_builtin(__is_base_of)
47+ template <class _Lp , class _Rp > inline constexpr bool is_base_of_v = __is_base_of(_Lp, _Rp);
48+ template <class _Lp , class _Rp > using is_base_of = bool_constant<is_base_of_v<_Lp, _Rp>>;
49+ #endif
50+
51+ #if __has_builtin(__is_convertible)
52+ template <class _Lp , class _Rp > inline constexpr bool is_convertible_v = __is_convertible(_Lp, _Rp);
53+ template <class _Lp , class _Rp > using is_convertible = bool_constant<is_convertible_v<_Lp, _Rp>>;
54+ #endif
55+
4556// logical operator traits:
4657template <class ...> struct conjunction : true_type {};
4758template <class _Tp > struct conjunction <_Tp> : _Tp {};
@@ -77,6 +88,23 @@ template<class> struct is_volatile : false_type {};
7788template <class _Tp > struct is_volatile <_Tp volatile > : true_type {};
7889template <class _Tp > inline constexpr bool is_volatile_v = is_volatile<_Tp>::value;
7990
91+ template <class > struct is_lvalue_reference : false_type {};
92+ template <class _Tp > struct is_lvalue_reference <_Tp&> : true_type {};
93+ template <class _Tp > inline constexpr bool is_lvalue_reference_v = is_lvalue_reference<_Tp>::value;
94+
95+ template <class > struct is_rvalue_reference : false_type {};
96+ template <class _Tp > struct is_rvalue_reference <_Tp&&> : true_type {};
97+ template <class _Tp > inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<_Tp>::value;
98+
99+ template <class _Tp > using is_reference = disjunction<is_lvalue_reference<_Tp>, is_rvalue_reference<_Tp>>;
100+ template <class _Tp > inline constexpr bool is_reference_v = is_reference<_Tp>::value;
101+
102+ template <class _Tp > struct __member_pointer : false_type {};
103+ template <class _Tp , class _Cp > struct __member_pointer <_Tp _Cp::*> : true_type {};
104+ template <class _Tp > using is_member_pointer = __member_pointer<remove_cv_t <_Tp>>;
105+ template <class _Tp > inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
106+
107+ // primary type categories:
80108template <class _Tp > using is_void = is_same<remove_cv_t <_Tp>, void >;
81109template <class _Tp > inline constexpr bool is_void_v = is_void<_Tp>::value;
82110
@@ -114,134 +142,135 @@ template<> struct __floating_point<long double> : true_type {};
114142template <class _Tp > using is_floating_point = __floating_point<remove_cv_t <_Tp>>;
115143template <class _Tp > inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value;
116144
117- template <class _Tp > using is_arithmetic = disjunction<is_integral<_Tp>, is_floating_point<_Tp>>;
118- template <class _Tp > inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
119-
120- template <class _Tp > using is_fundamental = disjunction<is_void<_Tp>, is_null_pointer<_Tp>, is_arithmetic<_Tp>>;
121- template <class _Tp > inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
122-
123- template <class _Tp > struct is_compound : std::integral_constant<bool , !std::is_fundamental<_Tp>::value> {};
124- template <class _Tp > inline constexpr bool is_compound_v = is_compound<_Tp>::value;
125-
126- template <class _Tp , bool = is_arithmetic<_Tp>::value> struct __is_signed : integral_constant<bool , _Tp(-1 ) < _Tp(0 )> {};
127- template <class _Tp > struct __is_signed <_Tp, false > : false_type {};
128- template <class _Tp > struct is_signed : __is_signed<_Tp>::type {};
129- template <class _Tp > constexpr bool is_signed_v = is_signed<_Tp>::value;
130-
131- template <class _Tp , bool = is_arithmetic<_Tp>::value> struct __is_unsigned : integral_constant<bool , _Tp(0 ) < _Tp(-1 )> {};
132- template <class _Tp > struct __is_unsigned <_Tp, false > : false_type {};
133- template <class _Tp > struct is_unsigned : __is_unsigned<_Tp>::type {};
134- template <class _Tp > constexpr bool is_unsigned_v = is_unsigned<_Tp>::value;
135-
136- template <class > struct is_array : false_type {};
137- template <class _Tp > struct is_array <_Tp[]> : true_type {};
138- template <class _Tp , size_t _Np> struct is_array <_Tp[_Np]> : true_type {};
139- template <class _Tp > inline constexpr bool is_array_v = is_array<_Tp>::value;
145+ #if __has_builtin(__is_array)
146+ template <class _Tp > inline constexpr bool is_array_v = __is_array(_Tp);
147+ template <class _Tp > using is_array = bool_constant<is_array_v<_Tp>>;
148+ #endif
140149
141- #if __has_feature(is_enum )
150+ #if __has_builtin(__is_enum )
142151template <class _Tp > inline constexpr bool is_enum_v = __is_enum(_Tp);
143152template <class _Tp > using is_enum = bool_constant<is_enum_v<_Tp>>;
144153#endif
145154
146- #if __has_feature(is_union )
155+ #if __has_builtin(__is_union )
147156template <class _Tp > inline constexpr bool is_union_v = __is_union(_Tp);
148157template <class _Tp > using is_union = bool_constant<is_union_v<_Tp>>;
149158#endif
150159
151- #if __has_feature(is_class )
160+ #if __has_builtin(__is_class )
152161template <class _Tp > inline constexpr bool is_class_v = __is_class(_Tp);
153162template <class _Tp > using is_class = bool_constant<is_class_v<_Tp>>;
154163#endif
155164
156- #if __has_feature(is_trivial)
165+ template <class _Tp > using is_function = negation<disjunction<is_const<_Tp const >, is_reference<_Tp>>>;
166+ template <class _Tp > inline constexpr bool is_function_v = is_function<_Tp>::value;
167+
168+ template <class > struct is_pointer : false_type {};
169+ template <class _Tp > struct is_pointer <_Tp*> : true_type {};
170+ template <class _Tp > inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
171+
172+ template <class _Tp > struct __member_function_pointer : false_type {};
173+ template <class _Tp , class _Cp > struct __member_function_pointer <_Tp _Cp::*> : is_function<_Tp> {};
174+ template <class _Tp > using is_member_function_pointer = __member_function_pointer<remove_cv_t <_Tp>>;
175+ template <class _Tp > inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<_Tp>::value;
176+
177+ template <class _Tp > struct __member_object_pointer : false_type {};
178+ template <class _Tp , class _Cp > struct __member_object_pointer <_Tp _Cp::*> : negation<is_function<_Tp>> {};
179+ template <class _Tp > using is_member_object_pointer = __member_object_pointer<remove_cv_t <_Tp>>;
180+ template <class _Tp > inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Tp>::value;
181+
182+ // composite type categories:
183+
184+ template <class _Tp > using is_arithmetic = disjunction<is_integral<_Tp>, is_floating_point<_Tp>>;
185+ template <class _Tp > inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value;
186+
187+ template <class _Tp > using is_fundamental = disjunction<is_void<_Tp>, is_null_pointer<_Tp>, is_arithmetic<_Tp>>;
188+ template <class _Tp > inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value;
189+
190+ template <class _Tp > struct is_scalar : public integral_constant <bool ,
191+ is_arithmetic<_Tp>::value ||
192+ is_member_pointer<_Tp>::value ||
193+ is_pointer<_Tp>::value ||
194+ is_null_pointer<_Tp>::value ||
195+ is_enum<_Tp>::value
196+ > {};
197+ template <class _Tp > inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
198+
199+ template <class _Tp > struct is_object : integral_constant<bool ,
200+ is_scalar<_Tp>::value ||
201+ is_array<_Tp>::value ||
202+ is_union<_Tp>::value ||
203+ is_class<_Tp>::value
204+ > {};
205+ template <class _Tp > inline constexpr bool is_object_v = is_object<_Tp>::value;
206+
207+ template <class _Tp > struct is_compound : std::integral_constant<bool , !std::is_fundamental<_Tp>::value> {};
208+ template <class _Tp > inline constexpr bool is_compound_v = is_compound<_Tp>::value;
209+
210+ #if __has_builtin(__is_trivial)
157211template <class _Tp > inline constexpr bool is_trivial_v = __is_trivial(_Tp);
158212template <class _Tp > using is_trivial = bool_constant<is_trivial_v<_Tp>>;
159213#endif
160214
161- #if __has_feature(is_trivially_copyable )
215+ #if __has_builtin(__is_trivially_copyable )
162216template <class _Tp > inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp);
163217template <class _Tp > using is_trivially_copyable = bool_constant<is_trivially_copyable_v<_Tp>>;
164218#endif
165219
166- #if __has_feature(is_standard_layout )
220+ #if __has_builtin(__is_standard_layout )
167221template <class _Tp > inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp);
168222template <class _Tp > using is_standard_layout = bool_constant<is_standard_layout_v<_Tp>>;
169223#endif
170224
171- #if __has_feature(is_pod )
225+ #if __has_builtin(__is_pod )
172226template <class _Tp > inline constexpr bool is_pod_v = __is_pod(_Tp);
173227template <class _Tp > using is_pod = bool_constant<is_pod_v<_Tp>>;
174228#endif
175229
176- #if __has_feature(is_empty)
230+ #if __has_builtin(__is_literal_type)
231+ template <class _Tp > inline constexpr bool is_literal_type_v = __is_literal_type(_Tp);
232+ template <class _Tp > using is_literal_type = bool_constant<is_literal_type_v<_Tp>>;
233+ #endif
234+
235+ #if __has_builtin(__has_unique_object_representations)
236+ template <class _Tp > inline constexpr bool has_unique_object_representations_v = __has_unique_object_representations(_Tp);
237+ template <class _Tp > using has_unique_object_representations = bool_constant<has_unique_object_representations_v<_Tp>>;
238+ #endif
239+
240+ #if __has_builtin(__is_empty)
177241template <class _Tp > inline constexpr bool is_empty_v = __is_empty(_Tp);
178242template <class _Tp > using is_empty = bool_constant<is_empty_v<_Tp>>;
179243#endif
180244
181- #if __has_feature(is_polymorphic )
245+ #if __has_builtin(__is_polymorphic )
182246template <class _Tp > inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp);
183247template <class _Tp > using is_polymorphic = bool_constant<is_polymorphic_v<_Tp>>;
184248#endif
185249
186- #if __has_feature(is_abstract )
250+ #if __has_builtin(__is_abstract )
187251template <class _Tp > inline constexpr bool is_abstract_v = __is_abstract(_Tp);
188252template <class _Tp > using is_abstract = bool_constant<is_abstract_v<_Tp>>;
189253#endif
190254
191- #if __has_feature(is_final )
255+ #if __has_builtin(__is_final )
192256template <class _Tp > inline constexpr bool is_final_v = __is_final(_Tp);
193257template <class _Tp > using is_final = bool_constant<is_final_v<_Tp>>;
194258#endif
195259
196- template <class > struct is_pointer : false_type {};
197- template <class _Tp > struct is_pointer <_Tp*> : true_type {};
198- template <class _Tp > inline constexpr bool is_pointer_v = is_pointer<_Tp>::value;
199-
200- template <class > struct is_lvalue_reference : false_type {};
201- template <class _Tp > struct is_lvalue_reference <_Tp&> : true_type {};
202- template <class _Tp > inline constexpr bool is_lvalue_reference_v = is_lvalue_reference<_Tp>::value;
203-
204- template <class > struct is_rvalue_reference : false_type {};
205- template <class _Tp > struct is_rvalue_reference <_Tp&&> : true_type {};
206- template <class _Tp > inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<_Tp>::value;
207-
208- template <class _Tp > using is_reference = disjunction<is_lvalue_reference<_Tp>, is_rvalue_reference<_Tp>>;
209- template <class _Tp > inline constexpr bool is_reference_v = is_reference<_Tp>::value;
210-
211- template <class _Tp > using is_function = negation<disjunction<is_const<_Tp const >, is_reference<_Tp>>>;
212- template <class _Tp > inline constexpr bool is_function_v = is_function<_Tp>::value;
213-
214- template <class _Tp > struct __member_pointer : false_type {};
215- template <class _Tp , class _Cp > struct __member_pointer <_Tp _Cp::*> : true_type {};
216- template <class _Tp > using is_member_pointer = __member_pointer<remove_cv_t <_Tp>>;
217- template <class _Tp > inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value;
218-
219- template <class _Tp > struct __member_function_pointer : false_type {};
220- template <class _Tp , class _Cp > struct __member_function_pointer <_Tp _Cp::*> : is_function<_Tp> {};
221- template <class _Tp > using is_member_function_pointer = __member_function_pointer<remove_cv_t <_Tp>>;
222- template <class _Tp > inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<_Tp>::value;
223-
224- template <class _Tp > struct __member_object_pointer : false_type {};
225- template <class _Tp , class _Cp > struct __member_object_pointer <_Tp _Cp::*> : negation<is_function<_Tp>> {};
226- template <class _Tp > using is_member_object_pointer = __member_object_pointer<remove_cv_t <_Tp>>;
227- template <class _Tp > inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Tp>::value;
260+ #if __has_builtin(__is_aggregate)
261+ template <class _Tp > inline constexpr bool is_aggregate_v = __is_aggregate(_Tp);
262+ template <class _Tp > using is_aggregate = bool_constant<is_aggregate_v<_Tp>>;
263+ #endif
228264
229- template <class _Tp > struct is_scalar : public integral_constant <bool ,
230- is_arithmetic<_Tp>::value ||
231- is_member_pointer<_Tp>::value ||
232- is_pointer<_Tp>::value ||
233- is_null_pointer<_Tp>::value ||
234- is_enum<_Tp>::value
235- > {};
236- template <class _Tp > inline constexpr bool is_scalar_v = is_scalar<_Tp>::value;
265+ #if __has_builtin(__is_signed)
266+ template <class _Tp > inline constexpr bool is_signed_v = __is_signed(_Tp);
267+ template <class _Tp > using is_signed = bool_constant<is_signed_v<_Tp>>;
268+ #endif
237269
238- template <class _Tp > struct is_object : integral_constant<bool ,
239- is_scalar<_Tp>::value ||
240- is_array<_Tp>::value ||
241- is_union<_Tp>::value ||
242- is_class<_Tp>::value
243- > {};
244- template <class _Tp > inline constexpr bool is_object_v = is_object<_Tp>::value;
270+ #if __has_builtin(__is_unsigned)
271+ template <class _Tp > inline constexpr bool is_unsigned_v = __is_unsigned(_Tp);
272+ template <class _Tp > using is_unsigned = bool_constant<is_unsigned_v<_Tp>>;
273+ #endif
245274
246275// const/volatile addition traits:
247276template <class _Tp > using add_const = conditional<disjunction_v<is_reference<_Tp>, is_function<_Tp>, is_const<_Tp>>,
@@ -341,6 +370,17 @@ public:
341370};
342371template <class _Tp > using decay_t = typename decay<_Tp>::type;
343372
373+ // underlying_type:
374+
375+ #if __has_builtin(__underlying_type)
376+ template <class _Tp , bool = is_enum<_Tp>::value> struct __underlying_type_impl ;
377+ template <class _Tp > struct __underlying_type_impl <_Tp, false > {};
378+ template <class _Tp > struct __underlying_type_impl <_Tp, true > { typedef __underlying_type (_Tp) type; };
379+
380+ template <class _Tp > struct underlying_type : __underlying_type_impl<_Tp, is_enum<_Tp>::value> {};
381+ template <class _Tp > using underlying_type_t = typename underlying_type<_Tp>::type;
382+ #endif
383+
344384// <utility> functions:
345385template <class _Tp > add_rvalue_reference_t <_Tp> declval () noexcept ;
346386
@@ -350,7 +390,7 @@ template<class, class...> auto __constructible(...) -> false_type;
350390template <class _Tp , class ... _As> using is_constructible = decltype (__constructible<_Tp, _As...>(0 ));
351391template <class _Tp , class ... _As> inline constexpr bool is_constructible_v = is_constructible<_Tp, _As...>::value;
352392
353- #if __has_feature(is_trivially_constructible )
393+ #if __has_builtin(__is_trivially_constructible )
354394template <class _Tp , class ... _As> inline constexpr bool is_trivially_constructible_v = __is_trivially_constructible(_Tp, _As...);
355395template <class _Tp , class ... _As> using is_trivially_constructible = bool_constant<is_trivially_constructible_v<_Tp, _As...>>;
356396#endif
@@ -392,13 +432,19 @@ template<class, class> auto __assignable(...) -> false_type;
392432template <class _Lp , class _Rp > using is_assignable = decltype (__assignable<_Lp, _Rp>(0 ));
393433template <class _Lp , class _Rp > inline constexpr bool is_assignable_v = is_assignable<_Lp, _Rp>::value;
394434
435+ #if __has_builtin(__is_trivially_assignable)
436+ template <class _Lp , class _Rp > inline constexpr bool is_trivially_assignable_v = __is_trivially_assignable(_Lp, _Rp);
437+ template <class _Lp , class _Rp > using is_trivially_assignable = bool_constant<is_trivially_assignable_v<_Lp, _Rp>>;
438+ #endif
439+
395440template <class _Lp , class _Rp > auto __nt_assignable (int ) -> enable_if_t<noexcept (declval<_Lp>() = declval<_Rp>()), true_type>;
396441template <class , class > auto __nt_assignable (...) -> false_type;
397442template <class _Lp , class _Rp > using is_nothrow_assignable = decltype (__nt_assignable<_Lp, _Rp>(0 ));
398443template <class _Lp , class _Rp > inline constexpr bool is_nothrow_assignable_v = is_nothrow_assignable<_Lp, _Rp>::value;
399444
400445template <class _Tp > using is_copy_assignable = is_assignable<add_lvalue_reference_t <_Tp>,
401446 add_lvalue_reference_t <add_const_t <_Tp>>>;
447+
402448template <class _Tp > inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value;
403449
404450template <class _Tp > using is_nothrow_copy_assignable = is_nothrow_assignable<add_lvalue_reference_t <_Tp>,
@@ -413,7 +459,17 @@ template<class _Tp> using is_nothrow_move_assignable = is_nothrow_assignable<add
413459 add_rvalue_reference_t <_Tp>>;
414460template <class _Tp > inline constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable<_Tp>::value;
415461
416- #if __has_feature(has_virtual_destructor)
462+ #if __has_builtin(__is_destructible)
463+ template <class _Tp > inline constexpr bool is_destructible_v = __is_destructible(_Tp);
464+ template <class _Tp > using is_destructible = bool_constant<is_destructible_v<_Tp>>;
465+ #endif
466+
467+ #if __has_builtin(__is_trivially_destructible)
468+ template <class _Tp > inline constexpr bool is_trivially_destructible_v = __is_trivially_destructible(_Tp);
469+ template <class _Tp > using is_trivially_destructible = bool_constant<is_trivially_destructible_v<_Tp>>;
470+ #endif
471+
472+ #if __has_builtin(__has_virtual_destructor)
417473template <class _Tp > inline constexpr bool has_virtual_destructor_v = __has_virtual_destructor(_Tp);
418474template <class _Tp > using has_virtual_destructor = bool_constant<has_virtual_destructor_v<_Tp>>;
419475#endif
0 commit comments