Skip to content

Commit 9074b35

Browse files
ZERICO2005adriweb
authored andcommitted
Expanded type_traits and switched __has_feature to __has_builtin
1 parent 6d40e82 commit 9074b35

File tree

3 files changed

+142
-85
lines changed

3 files changed

+142
-85
lines changed

src/libcxx/header_test.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <__config>
2+
#include <algorithm>
23
#include <bit>
34
#include <cassert>
45
#include <cctype>

src/libcxx/include/type_traits

Lines changed: 139 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,21 @@ template<class...> using void_t = void;
3838

3939
template<class...> using __require = true_type;
4040

41+
// type relationships:
4142
template<class, class> struct is_same : false_type {};
4243
template<class _Tp> struct is_same<_Tp, _Tp> : true_type {};
4344
template<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:
4657
template<class...> struct conjunction : true_type {};
4758
template<class _Tp> struct conjunction<_Tp> : _Tp {};
@@ -77,6 +88,23 @@ template<class> struct is_volatile : false_type {};
7788
template<class _Tp> struct is_volatile<_Tp volatile> : true_type {};
7889
template<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:
80108
template<class _Tp> using is_void = is_same<remove_cv_t<_Tp>, void>;
81109
template<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 {};
114142
template<class _Tp> using is_floating_point = __floating_point<remove_cv_t<_Tp>>;
115143
template<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)
142151
template<class _Tp> inline constexpr bool is_enum_v = __is_enum(_Tp);
143152
template<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)
147156
template<class _Tp> inline constexpr bool is_union_v = __is_union(_Tp);
148157
template<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)
152161
template<class _Tp> inline constexpr bool is_class_v = __is_class(_Tp);
153162
template<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)
157211
template<class _Tp> inline constexpr bool is_trivial_v = __is_trivial(_Tp);
158212
template<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)
162216
template<class _Tp> inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp);
163217
template<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)
167221
template<class _Tp> inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp);
168222
template<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)
172226
template<class _Tp> inline constexpr bool is_pod_v = __is_pod(_Tp);
173227
template<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)
177241
template<class _Tp> inline constexpr bool is_empty_v = __is_empty(_Tp);
178242
template<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)
182246
template<class _Tp> inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp);
183247
template<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)
187251
template<class _Tp> inline constexpr bool is_abstract_v = __is_abstract(_Tp);
188252
template<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)
192256
template<class _Tp> inline constexpr bool is_final_v = __is_final(_Tp);
193257
template<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:
247276
template<class _Tp> using add_const = conditional<disjunction_v<is_reference<_Tp>, is_function<_Tp>, is_const<_Tp>>,
@@ -341,6 +370,17 @@ public:
341370
};
342371
template <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:
345385
template<class _Tp> add_rvalue_reference_t<_Tp> declval() noexcept;
346386

@@ -350,7 +390,7 @@ template<class, class...> auto __constructible(...) -> false_type;
350390
template<class _Tp, class... _As> using is_constructible = decltype(__constructible<_Tp, _As...>(0));
351391
template<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)
354394
template<class _Tp, class... _As> inline constexpr bool is_trivially_constructible_v = __is_trivially_constructible(_Tp, _As...);
355395
template<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;
392432
template<class _Lp, class _Rp> using is_assignable = decltype(__assignable<_Lp, _Rp>(0));
393433
template<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+
395440
template<class _Lp, class _Rp> auto __nt_assignable(int) -> enable_if_t<noexcept(declval<_Lp>() = declval<_Rp>()), true_type>;
396441
template<class, class> auto __nt_assignable(...) -> false_type;
397442
template<class _Lp, class _Rp> using is_nothrow_assignable = decltype(__nt_assignable<_Lp, _Rp>(0));
398443
template<class _Lp, class _Rp> inline constexpr bool is_nothrow_assignable_v = is_nothrow_assignable<_Lp, _Rp>::value;
399444

400445
template<class _Tp> using is_copy_assignable = is_assignable<add_lvalue_reference_t<_Tp>,
401446
add_lvalue_reference_t<add_const_t<_Tp>>>;
447+
402448
template<class _Tp> inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value;
403449

404450
template<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>>;
414460
template<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)
417473
template<class _Tp> inline constexpr bool has_virtual_destructor_v = __has_virtual_destructor(_Tp);
418474
template<class _Tp> using has_virtual_destructor = bool_constant<has_virtual_destructor_v<_Tp>>;
419475
#endif

src/libcxx/include/version

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@
5353
// # define __cpp_lib_filesystem 201703L
5454
// # define __cpp_lib_gcd_lcm 201606L
5555
// # define __cpp_lib_hardware_interference_size 201703L
56-
// # define __cpp_lib_has_unique_object_representations 201606L
56+
# define __cpp_lib_has_unique_object_representations 201606L
5757
# define __cpp_lib_hypot 201603L
5858
// # define __cpp_lib_incomplete_container_elements 201505L
5959
// # define __cpp_lib_invoke 201411L
60-
// # define __cpp_lib_is_aggregate 201703L
60+
# define __cpp_lib_is_aggregate 201703L
6161
// # define __cpp_lib_is_invocable 201703L
6262
// # define __cpp_lib_is_swappable 201603L
6363
// # define __cpp_lib_launder 201606L

0 commit comments

Comments
 (0)