MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
type_traits.hpp
浏览该文件的文档.
1#ifndef MSTL_CORE_TYPEINFO_TYPE_TRAITS_HPP__
2#define MSTL_CORE_TYPEINFO_TYPE_TRAITS_HPP__
3
10
13
19
29template <typename T, T Value>
31 static constexpr T value = Value;
32
33 using value_type = T;
35
40 constexpr explicit operator value_type() const noexcept {
41 return value;
42 }
43
48 MSTL_NODISCARD constexpr value_type operator ()() const noexcept {
49 return value;
50 }
51};
52
53
59template <bool Value>
61
64
70template <uint32_t Value>
72
78template <uint64_t Value>
80
81
89template <typename... Types>
90using void_t = void;
91
101template <bool Test, typename T = void>
102struct enable_if {};
103
105template <typename T>
106struct enable_if<true, T> {
107 using type = T;
108};
110
115template <bool Test, typename T = void>
117
118
126template <bool Test, typename T1, typename T2>
128 using type = T1;
129};
130
132template <typename T1, typename T2>
133struct conditional<false, T1, T2> {
134 using type = T2;
135};
137
142template <bool Test, typename T1, typename T2>
143using conditional_t = typename conditional<Test, T1, T2>::type;
144
145
153template <typename T>
154struct negation : bool_constant<!static_cast<bool>(T::value)> {};
155
156#ifdef MSTL_STANDARD_14__
161template <typename T>
162MSTL_INLINE17 constexpr bool negation_v = negation<T>::value;
163#endif
164
165
172template <typename T1, typename T2>
173struct is_same : false_type {};
174
176template <typename T>
177struct is_same<T, T> : true_type {};
179
180#ifdef MSTL_STANDARD_14__
185template <typename T1, typename T2>
186MSTL_INLINE17 constexpr bool is_same_v = is_same<T1, T2>::value;
187#endif
188
189
197template <typename T>
199 using type = T;
200};
201
206template <typename T>
207using type_identity_t = typename type_identity<T>::type;
208
209
216template <typename T, typename... Types>
217struct is_any_of;
218
219#ifdef MSTL_STANDARD_17__
220template <typename T, typename... Types>
221struct is_any_of : bool_constant<(is_same_v<T, Types> || ...)> {};
222#else
223template <typename T, typename... Types>
225
227template <typename T, typename U>
228struct is_any_of<T, U> : is_same<T, U> {};
229
230template <typename T, typename U, typename... Types>
231struct is_any_of<T, U, Types...>
232 : conditional<is_same<T, U>::value, true_type, is_any_of<T, Types...>>::type {};
234#endif // MSTL_STANDARD_17__
235
236#ifdef MSTL_STANDARD_14__
241template <typename T, typename... Types>
242MSTL_INLINE17 constexpr bool is_any_of_v = is_any_of<T, Types...>::value;
243#endif
244
245
246
249// 析取辅助实现
250template <bool, typename first, typename...>
251struct __disjunction_aux {
252 using type = first;
253};
254template <typename Curr, typename Next, typename... Rest>
255struct __disjunction_aux<false, Curr, Next, Rest...> {
256 using type = typename __disjunction_aux<static_cast<bool>(Next::value), Next, Rest...>::type;
257};
260
268template <typename... Args>
270
272template <typename First, typename... Rest>
273struct disjunction<First, Rest...>
274 : _INNER __disjunction_aux<static_cast<bool>(First::value), First, Rest...>::type {
275};
277
278#ifdef MSTL_STANDARD_14__
283template <typename... Args>
284MSTL_INLINE17 constexpr bool disjunction_v = disjunction<Args...>::value;
285#endif
286
287
290// 合取辅助实现
291template <bool, typename First, typename...>
292struct __conjunction_aux {
293 using type = First;
294};
295template <typename Curr, typename Next, typename... Rest>
296struct __conjunction_aux<true, Curr, Next, Rest...> {
297 using type = typename __conjunction_aux<static_cast<bool>(Next::value), Next, Rest...>::type;
298};
301
309template <typename... Args>
311
313template <typename First, typename... Rest>
314struct conjunction<First, Rest...>
315 : _INNER __conjunction_aux<static_cast<bool>(First::value), First, Rest...>::type {
316};
318
319#ifdef MSTL_STANDARD_14__
324template <typename... Args>
325MSTL_INLINE17 constexpr bool conjunction_v = conjunction<Args...>::value;
326#endif
327 // TypeTraitsUtilities
329
335
341template <typename T>
343 using type = T;
344};
345
347template <typename T>
348struct remove_const<const T> {
349 using type = T;
350};
352
357template <typename T>
358using remove_const_t = typename remove_const<T>::type;
359
360
366template <typename T>
368 using type = T;
369};
370
372template <typename T>
373struct remove_volatile<volatile T> {
374 using type = T;
375};
377
382template <typename T>
383using remove_volatile_t = typename remove_volatile<T>::type;
384
385
393template <typename T>
394struct remove_cv {
395 using type = T;
396
401 template <typename wrapper>
402 using bind_cv_t = wrapper;
403};
404
406template <typename T>
407struct remove_cv<const T> {
408 using type = T;
409
410 template <typename wrapper>
411 using bind_cv_t = const wrapper;
412};
413
414template <typename T>
415struct remove_cv<volatile T> {
416 using type = T;
417
418 template <typename wrapper>
419 using bind_cv_t = volatile wrapper;
420};
421
422template <typename T>
423struct remove_cv<const volatile T> {
424 using type = T;
425
426 template <typename wrapper>
427 using bind_cv_t = const volatile wrapper;
428};
430
435template <typename T>
436using remove_cv_t = typename remove_cv<T>::type;
437
444template <typename From, typename To>
445using copy_cv_t = typename remove_cv<From>::template bind_cv_t<To>;
446
447
455template <typename T>
457 using type = T;
458
463 template <typename wrapper>
464 using bind_ref_t = wrapper;
465};
466
468template <typename T>
469struct remove_reference<T&> {
470 using type = T;
471
472 template <typename wrapper>
473 using bind_ref_t = wrapper&;
474};
475
476template <typename T>
477struct remove_reference<T&&> {
478 using type = T;
479
480 template <typename wrapper>
481 using bind_ref_t = wrapper&&;
482};
484
489template <typename T>
490using remove_reference_t = typename remove_reference<T>::type;
491
498template <typename From, typename To>
500
507template <typename From, typename To>
509
510
516template <typename T>
519};
520
525template <typename T>
526using remove_cvref_t = typename remove_cvref<T>::type;
527
528
534template <typename T>
536 using type = T;
537};
538
540template <typename T, size_t Idx>
541struct remove_extent<T[Idx]> {
542 using type = T;
543};
544
545template <typename T>
546struct remove_extent<T[]> {
547 using type = T;
548};
550
555template <typename T>
556using remove_extent_t = typename remove_extent<T>::type;
557
558
564template <typename T>
566 using type = T;
567};
568
570template <typename T, size_t Idx>
571struct remove_all_extents<T[Idx]> {
572 using type = typename remove_all_extents<T>::type;
573};
574
575template <typename T>
576struct remove_all_extents<T[]> {
577 using type = typename remove_all_extents<T>::type;
578};
580
585template <typename T>
586using remove_all_extents_t = typename remove_all_extents<T>::type;
587
588
596template <typename T>
598 using type = T;
599
604 template <typename wrapper>
605 using bind_pointer_t = wrapper;
606};
607
609template <typename T>
610struct remove_pointer<T*> {
611 using type = T;
612
613 template <typename wrapper>
614 using bind_pointer_t = wrapper*;
615};
616
617template <typename T>
618struct remove_pointer<T* const> {
619 using type = T;
620
621 template <typename wrapper>
622 using bind_pointer_t = const wrapper*;
623};
624
625template <typename T>
626struct remove_pointer<T* volatile> {
627 using type = T;
628
629 template <typename wrapper>
630 using bind_pointer_t = volatile wrapper*;
631};
632
633template <typename T>
634struct remove_pointer<T* const volatile> {
635 using type = T;
636
637 template <typename wrapper>
638 using bind_pointer_t = volatile const wrapper*;
639};
641
646template <typename T>
647using remove_pointer_t = typename remove_pointer<T>::type;
648
655template <typename From, typename To>
657
658
664template <typename T>
666 using type = T;
667};
668
670
671template <typename Ret, typename... Args>
672struct remove_function_qualifiers<Ret(Args...)> {
673 using type = Ret(Args...);
674};
675
676#define __MSTL_EXPAND_REM_FUNC_QULF(QUF) \
677template <typename Ret, typename... Args> \
678struct remove_function_qualifiers<Ret(Args...) QUF> { \
679 using type = Ret(Args...); \
680};
681
682MSTL_MACRO_RANGES_CV(__MSTL_EXPAND_REM_FUNC_QULF)
683MSTL_MACRO_RANGES_CV_REF(__MSTL_EXPAND_REM_FUNC_QULF)
684MSTL_MACRO_RANGES_CV_REF_NOEXCEPT(__MSTL_EXPAND_REM_FUNC_QULF)
685#undef __MSTL_EXPAND_REM_FUNC_QULF
686
688
693template <typename T>
694using remove_function_qualifiers_t = typename remove_function_qualifiers<T>::type;
695 // RemoveQualifiers
697
703
706template <typename>
707struct __is_void_helper : false_type {};
708
709template <>
710struct __is_void_helper<void> : true_type {};
713
721template <typename T>
722struct is_void : _INNER __is_void_helper<remove_cv_t<T>>::type {};
723
724#ifdef MSTL_STANDARD_14__
729template <typename T>
730MSTL_INLINE17 constexpr bool is_void_v = is_void<T>::value;
731#endif
732
733
740template <typename T, typename Dummy = void>
741struct package {
742 using type = T;
743};
744
749template <typename T>
750using package_t = typename package<T>::type;
751
757template <typename T>
758struct is_packaged : bool_constant<!is_same<package_t<T>, T>::value> {};
759
760#ifdef MSTL_STANDARD_14__
765template <typename T>
766MSTL_INLINE17 constexpr bool is_packaged_v = is_packaged<T>::value;
767#endif
768
775template <typename T, typename Dummy = void>
776struct unpackage {
777 using type = T;
778};
779
784template <typename T>
785using unpackage_t = typename unpackage<T>::type;
786
791template <typename T>
793
799template <typename T>
800struct is_unpackaged : bool_constant<!is_same<unpackage_t<T>, T>::value> {};
801
802#ifdef MSTL_STANDARD_14__
807template <typename T>
808MSTL_INLINE17 constexpr bool is_unpackaged_v = is_unpackaged<T>::value;
809#endif
810
811
817template <typename T>
818struct is_character : bool_constant<is_any_of<unpack_remove_cvref_t<T>,
819 char, signed char, unsigned char, wchar_t,
820#ifdef MSTL_STANDARD_20__
821 char8_t,
822#endif
823 char16_t, char32_t
824>::value> {};
825
826#ifdef MSTL_STANDARD_14__
831template <typename T>
832MSTL_INLINE17 constexpr bool is_character_v = is_character<T>::value;
833#endif
834
835
843template <typename T>
844struct is_standard_character : bool_constant<is_any_of<unpack_remove_cvref_t<T>,
845 char, wchar_t,
846#ifdef MSTL_STANDARD_20__
847 char8_t,
848#endif
849 char16_t, char32_t
850>::value> {};
851
852#ifdef MSTL_STANDARD_14__
857template <typename T>
858MSTL_INLINE17 constexpr bool is_standard_character_v = is_standard_character<T>::value;
859#endif
860
861
867template <typename T>
868struct is_boolean : bool_constant<is_same<unpack_remove_cvref_t<T>, bool>::value> {};
869
870#ifdef MSTL_STANDARD_14__
875template <typename T>
876MSTL_INLINE17 constexpr bool is_boolean_v = is_boolean<T>::value;
877#endif
878
879
887template <typename T>
888struct is_standard_integral : bool_constant<is_any_of<unpack_remove_cvref_t<T>,
889 short, int, long, long long,
890 unsigned short, unsigned int, unsigned long, unsigned long long>::value> {};
891
892#ifdef MSTL_STANDARD_14__
897template <typename T>
898MSTL_INLINE17 constexpr bool is_standard_integral_v = is_standard_integral<T>::value;
899#endif
900
901
909template <typename T>
910struct is_integral : bool_constant<disjunction<is_standard_integral<T>, is_character<T>, is_boolean<T>>::value> {};
911
912#ifdef MSTL_STANDARD_14__
917template <typename T>
918MSTL_INLINE17 constexpr bool is_integral_v = is_integral<T>::value;
919#endif
920
921
927template <typename T>
928struct is_floating_point : bool_constant<is_any_of<unpack_remove_cvref_t<T>, float, double, long double>::value> {};
929
930#ifdef MSTL_STANDARD_14__
935template <typename T> MSTL_INLINE17 constexpr bool is_floating_point_v = is_floating_point<T>::value;
936#endif
937
938
946template <typename T>
947struct is_arithmetic : bool_constant<disjunction<is_integral<T>, is_floating_point<T>>::value> {};
948
949#ifdef MSTL_STANDARD_14__
954template <typename T>
955MSTL_INLINE17 constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
956#endif
957
958
961template <typename T, bool = is_integral<T>::value>
962struct __check_sign_aux {
963 static constexpr bool is_signed = static_cast<remove_cvref_t<T>>(-1) < static_cast<remove_cv_t<T>>(0);
964 static constexpr bool is_unsigned = !is_signed;
965};
966
967template <typename T>
968struct __check_sign_aux<T, false> {
969 static constexpr bool is_signed = is_floating_point<T>::value;
970 static constexpr bool is_unsigned = false;
971};
974
980template <typename T>
981struct is_signed : bool_constant<_INNER __check_sign_aux<unpack_remove_cvref_t<T>>::is_signed> {};
982
983#ifdef MSTL_STANDARD_14__
988template <typename T>
989MSTL_INLINE17 constexpr bool is_signed_v = is_signed<T>::value;
990#endif
991
997template <typename T>
998struct is_unsigned : bool_constant<_INNER __check_sign_aux<unpack_remove_cvref_t<T>>::is_unsigned> {};
999
1000#ifdef MSTL_STANDARD_14__
1005template <typename T>
1006MSTL_INLINE17 constexpr bool is_unsigned_v = is_unsigned<T>::value;
1007#endif
1008 // TypeProperties
1010
1016
1022template <typename T>
1024 using type = const T;
1025};
1026
1031template <typename T>
1032using add_const_t = typename add_const<T>::type;
1033
1041template <typename T>
1042MSTL_NODISCARD constexpr add_const_t<T>& as_const(T& val) noexcept {
1043 return val;
1044}
1045
1047template <typename T>
1048void as_const(const T&&) = delete;
1050
1056template <typename T>
1058 using type = volatile T;
1059};
1060
1065template <typename T>
1066using add_volatile_t = typename add_volatile<T>::type;
1067
1073template <typename T>
1074struct add_cv {
1075 using type = const volatile T;
1076};
1077
1082template <typename T>
1083using add_cv_t = typename add_cv<T>::type;
1084
1085
1094template <typename T, typename Dummy = void>
1096 using lvalue = T;
1097 using rvalue = T;
1098};
1099
1101template <typename T>
1102struct add_reference<T, void_t<T&>> {
1103 using lvalue = T&;
1104 using rvalue = T&&;
1105};
1107
1113template <typename T>
1115 using type = typename add_reference<T>::lvalue;
1116};
1117
1122template <typename T>
1123using add_lvalue_reference_t = typename add_reference<T>::lvalue;
1124
1130template <typename T>
1132 using type = typename add_reference<T>::rvalue;
1133};
1134
1139template <typename T>
1140using add_rvalue_reference_t = typename add_reference<T>::rvalue;
1141
1142
1149template <typename T, typename Dummy = void>
1151 using type = T;
1152};
1153
1155template <typename T>
1156struct add_pointer<T, void_t<remove_reference_t<T>*>> {
1157 using type = remove_reference_t<T>*;
1158};
1160
1165template <typename T>
1166using add_pointer_t = typename add_pointer<T>::type;
1167 // AddQualifiers
1169
1175
1182template <typename T>
1184
1191template <typename T>
1193
1199template <typename T>
1200void declvoid(type_identity_t<T>) noexcept;
1201 // DeclvalTools
1203
1209
1217template <typename T>
1218struct rank : integral_constant<size_t, 0> {};
1219
1221template <typename T, size_t Idx>
1222struct rank<T[Idx]> : integral_constant<size_t, rank<T>::value + 1> {};
1223
1224template <typename T>
1225struct rank<T[]> : integral_constant<size_t, rank<T>::value + 1> {};
1227
1228#ifdef MSTL_STANDARD_14__
1233template <typename T>
1234MSTL_INLINE17 constexpr size_t rank_v = rank<T>::value;
1235#endif
1236
1237
1246template <typename T, uint32_t Idx = 0>
1247struct extent : integral_constant<size_t, 0> {};
1248
1250template <typename T, size_t N>
1251struct extent<T[N], 0> : integral_constant<size_t, N> {};
1252
1253template <typename T, uint32_t Idx, size_t N>
1254struct extent<T[N], Idx> : extent<T, Idx - 1> {};
1255
1256template <typename T, uint32_t Idx>
1257struct extent<T[], Idx> : extent<T, Idx - 1> {};
1259
1260#ifdef MSTL_STANDARD_14__
1265template <typename T, uint32_t Idx = 0>
1266MSTL_INLINE17 constexpr size_t extent_v = extent<T, Idx>::value;
1267#endif
1268 // ArrayProperties
1270
1276
1282template <typename T>
1284
1286template <template <typename, typename...> class T, typename First, typename... Rest>
1287struct get_first_temp_para<T<First, Rest...>> {
1288 using type = First;
1289};
1291
1296template <typename Tmp>
1298
1299
1305template <typename... Types>
1307
1309template <typename First, typename... Rest>
1310struct get_first_para<First, Rest...> {
1311 using type = First;
1312};
1314
1319template <typename... Types>
1320using get_first_para_t = typename get_first_para<Types...>::type;
1321
1322
1331template <typename T, typename Dummy = void>
1333 using type = ptrdiff_t;
1334};
1335
1337template <typename T>
1339 is_same<typename T::difference_type, typename T::difference_type>::value>> {
1340 using type = typename T::difference_type;
1341};
1343
1348template <typename T>
1349using get_ptr_difference_t = typename get_ptr_difference<T>::type;
1350
1351
1358template <typename NewFirst, typename T>
1360
1362template <typename NewFirst, template <typename, typename...> class T, typename First, typename... Rest>
1363struct replace_first_para<NewFirst, T<First, Rest...>> {
1364 using type = T<NewFirst, Rest...>;
1365};
1367
1372template <typename T, typename U>
1374
1375
1385template <typename T, typename U, typename Dummy = void>
1387 using type = replace_first_para_t<U, T>;
1388};
1389
1391template <typename T, typename U>
1392struct get_rebind_type<T, U, enable_if_t<
1393 is_same<typename T::template rebind<U>, typename T::template rebind<U>>::value>> {
1394 using type = typename T::template rebind<U>;
1395};
1397
1402template <typename T, typename U>
1403using get_rebind_type_t = typename get_rebind_type<T, U>::type;
1404 // TemplateTraitsUtilities
1406
1412
1418template <typename T>
1420
1422template <typename T, size_t Idx>
1423struct is_bounded_array<T[Idx]> : true_type {};
1425
1426#ifdef MSTL_STANDARD_14__
1431template <typename T>
1432MSTL_INLINE17 constexpr bool is_bounded_array_v = is_bounded_array<T>::value;
1433#endif
1434
1435
1441template <typename T>
1443
1445template <typename T>
1446struct is_unbounded_array<T[]> : true_type {};
1448
1449#ifdef MSTL_STANDARD_14__
1454template <typename T>
1455MSTL_INLINE17 constexpr bool is_unbounded_array_v = is_unbounded_array<T>::value;
1456#endif
1457
1465template <typename T>
1466struct is_array : bool_constant<is_unbounded_array<T>::value || is_bounded_array<T>::value> {};
1467
1468#ifdef MSTL_STANDARD_14__
1473template <typename T>
1474MSTL_INLINE17 constexpr bool is_array_v = is_array<T>::value;
1475#endif
1476
1477
1483template <typename T>
1485
1487template <typename T>
1488struct is_lvalue_reference<T&> : true_type {};
1490
1491#ifdef MSTL_STANDARD_14__
1496template <typename T>
1497MSTL_INLINE17 constexpr bool is_lvalue_reference_v = is_lvalue_reference<T>::value;
1498#endif
1499
1505template <typename T>
1507
1509template <typename T>
1510struct is_rvalue_reference<T&&> : true_type {};
1512
1513#ifdef MSTL_STANDARD_14__
1518template <typename T>
1519MSTL_INLINE17 constexpr bool is_rvalue_reference_v = is_rvalue_reference<T>::value;
1520#endif
1521
1522
1530template <typename T>
1531struct is_reference : bool_constant<is_lvalue_reference<T>::value || is_rvalue_reference<T>::value> {};
1532
1533#ifdef MSTL_STANDARD_14__
1538template <typename T>
1539MSTL_INLINE17 constexpr bool is_reference_v = is_reference<T>::value;
1540#endif
1541
1542
1548template <typename T>
1549struct is_null_pointer : bool_constant<is_same<remove_cvref_t<T>, nullptr_t>::value> {};
1550
1551#ifdef MSTL_STANDARD_14__
1556template <typename T>
1557MSTL_INLINE17 constexpr bool is_null_pointer_v = is_null_pointer<T>::value;
1558#endif
1559
1560
1568template <typename T>
1570
1572template <typename T>
1573struct is_pointer<T*> : true_type {};
1574
1575template <typename T>
1576struct is_pointer<T* const> : true_type {};
1577
1578template <typename T>
1579struct is_pointer<T* volatile> : true_type {};
1580
1581template <typename T>
1582struct is_pointer<T* const volatile> : true_type {};
1584
1585#ifdef MSTL_STANDARD_14__
1590template <typename T>
1591MSTL_INLINE17 constexpr bool is_pointer_v = is_pointer<T>::value;
1592#endif
1593
1594
1600template <typename T>
1601struct is_enum : bool_constant<__is_enum(T)> {};
1602
1603#ifdef MSTL_STANDARD_14__
1608template <typename T>
1609MSTL_INLINE17 constexpr bool is_enum_v = is_enum<T>::value;
1610#endif
1611
1612
1620template <typename T>
1621struct is_integral_like : bool_constant<disjunction<is_integral<T>, is_enum<T>>::value> {};
1622
1623#ifdef MSTL_STANDARD_14__
1628template <typename T>
1629MSTL_INLINE17 constexpr bool is_integral_like_v = is_integral_like<T>::value;
1630#endif
1631
1632
1638template <typename T>
1639struct is_union : bool_constant<__is_union(T)> {};
1640
1641#ifdef MSTL_STANDARD_14__
1646template <typename T>
1647MSTL_INLINE17 constexpr bool is_union_v = is_union<T>::value;
1648#endif
1649
1650
1656template <typename T>
1657struct is_class : bool_constant<__is_class(T)> {};
1658
1659#ifdef MSTL_STANDARD_14__
1664template <typename T>
1665MSTL_INLINE17 constexpr bool is_class_v = is_class<T>::value;
1666#endif
1667
1668
1676template <typename T>
1678 disjunction<is_arithmetic<T>, is_void<T>, is_null_pointer<T>>::value> {};
1679
1680#ifdef MSTL_STANDARD_14__
1685template <typename T>
1686MSTL_INLINE17 constexpr bool is_fundamental_v = is_fundamental<T>::value;
1687#endif
1688
1689
1697template <typename T>
1698struct is_compound : bool_constant<!is_fundamental<T>::value> {};
1699
1700#ifdef MSTL_STANDARD_14__
1705template <typename T>
1706MSTL_INLINE17 constexpr bool is_compound_v = is_compound<T>::value;
1707#endif
1708
1709
1715template <typename T>
1717
1719template <typename T>
1720struct is_const<const T> : true_type {};
1722
1723#ifdef MSTL_STANDARD_14__
1728template <typename T>
1729MSTL_INLINE17 constexpr bool is_const_v = is_const<T>::value;
1730#endif
1731
1732
1738template <typename T>
1740
1742template <typename T>
1743struct is_volatile<volatile T> : true_type {};
1745
1746#ifdef MSTL_STANDARD_14__
1751template <typename T>
1752MSTL_INLINE17 constexpr bool is_volatile_v = is_volatile<T>::value;
1753#endif
1754
1755
1756#ifdef MSTL_COMPILER_MSVC__
1757// 禁用MSVC警告4180:从const限定的函数类型中移除const
1758#pragma warning(push)
1759#pragma warning(disable: 4180)
1760#endif
1761
1770template <typename T>
1772 !is_const<const remove_function_qualifiers_t<T>>::value
1773 && !is_reference<remove_function_qualifiers_t<T>>::value> {};
1774
1775#ifdef MSTL_STANDARD_14__
1780template <typename T>
1781MSTL_INLINE17 constexpr bool is_function_v = is_function<T>::value;
1782#endif
1783
1784#ifdef MSTL_COMPILER_MSVC__
1785#pragma warning(pop)
1786#endif
1787
1788
1801template <typename T>
1803 !(is_void<T>::value || is_reference<T>::value || is_function<T>::value || is_const<T>::value)
1804 && (sizeof(T) > 0)> {};
1805
1806#ifdef MSTL_STANDARD_14__
1811template <typename T>
1812MSTL_INLINE17 constexpr bool is_allocable_v = is_allocable<T>::value;
1813#endif
1814
1815
1824template <typename T>
1825struct is_object : bool_constant<is_const<const T>::value && !is_void<T>::value> {};
1826
1827#ifdef MSTL_STANDARD_14__
1832template <typename T>
1833MSTL_INLINE17 constexpr bool is_object_v = is_object<T>::value;
1834#endif
1835
1836
1846template <typename T>
1848 (is_pointer<remove_cvref_t<T>>::value &&
1849 is_character<remove_pointer_t<remove_cvref_t<T>>>::value) ||
1850 (is_bounded_array<remove_cvref_t<T>>::value &&
1851 is_character<remove_all_extents_t<remove_cvref_t<T>>>::value)> {};
1852
1853#ifdef MSTL_STANDARD_14__
1858template <typename T>
1859constexpr bool is_cstring_v = is_cstring<T>::value;
1860#endif
1861
1862
1868template <typename T>
1870
1872#ifdef MSTL_COMPILER_CLANG__
1873template <typename T>
1874struct is_member_function_pointer : bool_constant<__is_member_function_pointer(T)> {};
1875#else
1877template <typename>
1878struct __is_member_function_pointer_aux : false_type {};
1879template <typename T, typename C>
1880struct __is_member_function_pointer_aux<T C::*> : is_function<T> {};
1882
1883template <typename T>
1884struct is_member_function_pointer : _INNER __is_member_function_pointer_aux<remove_cv_t<T>> {};
1885#endif
1887
1888#ifdef MSTL_STANDARD_14__
1893template <typename T>
1894MSTL_INLINE17 constexpr bool is_member_function_pointer_v = is_member_function_pointer<T>::value;
1895#endif
1896
1897
1903template <typename T>
1905
1907#ifdef MSTL_COMPILER_CLANG__
1908template <typename T>
1909struct is_member_object_pointer : bool_constant<__is_member_object_pointer(T)> {};
1910#else
1911template <typename T>
1913template <typename T, typename C>
1914struct is_member_object_pointer<T C::*> : bool_constant<!is_function<T>::value> {};
1915#endif
1917
1918#ifdef MSTL_STANDARD_14__
1923template <typename T>
1924MSTL_INLINE17 constexpr bool is_member_object_pointer_v = is_member_object_pointer<remove_cv_t<T>>::value;
1925#endif
1926
1927
1933template <typename T>
1935
1937#ifdef MSTL_COMPILER_CLANG__
1938template <typename T>
1939struct is_member_pointer : bool_constant<__is_member_pointer(T)> {};
1940#else
1941template <typename T>
1942struct is_member_pointer : bool_constant<is_member_object_pointer<T>::value || is_member_function_pointer<T>::value> {};
1943#endif
1945
1946#ifdef MSTL_STANDARD_14__
1951template <typename T>
1952MSTL_INLINE17 constexpr bool is_member_pointer_v = is_member_pointer<T>::value;
1953#endif
1954
1955
1968template <typename T>
1969struct is_scalar : bool_constant<disjunction<
1970 is_arithmetic<T>, is_enum<T>, is_pointer<T>, is_member_pointer<T>, is_null_pointer<T>
1971>::value> {};
1972
1973#ifdef MSTL_STANDARD_14__
1978template <typename T>
1979MSTL_INLINE17 constexpr bool is_scalar_v = is_scalar<T>::value;
1980#endif
1981
1982
1993template <typename T>
1994struct is_empty : bool_constant<__is_empty(T)> {};
1995
1996#ifdef MSTL_STANDARD_14__
2001template <typename T>
2002MSTL_INLINE17 constexpr bool is_empty_v = is_empty<T>::value;
2003#endif
2004
2005
2013template <typename T>
2014struct is_polymorphic : bool_constant<__is_polymorphic(T)> {};
2015
2016#ifdef MSTL_STANDARD_14__
2021template <typename T>
2022MSTL_INLINE17 constexpr bool is_polymorphic_v = is_polymorphic<T>::value;
2023#endif
2024
2025
2033template <typename T>
2034struct is_abstract : bool_constant<__is_abstract(T)> {};
2035
2036#ifdef MSTL_STANDARD_14__
2041template <typename T>
2042MSTL_INLINE17 constexpr bool is_abstract_v = is_abstract<T>::value;
2043#endif
2044
2045
2053template <typename T>
2054struct is_final : bool_constant<__is_final(T)> {};
2055
2056#ifdef MSTL_STANDARD_14__
2061template <typename T>
2062MSTL_INLINE17 constexpr bool is_final_v = is_final<T>::value;
2063#endif
2064
2065
2068template <typename T, bool = is_enum<T>::value>
2069struct __underlying_type_aux {
2070 using type = __underlying_type(T);
2071};
2072template <typename T>
2073struct __underlying_type_aux<T, false> {};
2076
2084template <typename T>
2085struct underlying_type : _INNER __underlying_type_aux<T> {};
2086
2091template <typename T>
2093
2094
2106template <typename T>
2107struct is_standard_layout : bool_constant<__is_standard_layout(T)> {};
2108
2109#ifdef MSTL_STANDARD_14__
2114template <typename T>
2115MSTL_INLINE17 constexpr bool is_standard_layout_v = is_standard_layout<T>::value;
2116#endif
2117
2118
2126template <typename T>
2127struct is_pod : bool_constant<__is_pod(T)> {};
2128
2129#ifdef MSTL_STANDARD_14__
2134template <typename T>
2135MSTL_INLINE17 constexpr bool is_pod_v = is_pod<T>::value;
2136#endif
2137
2138
2151template <typename T>
2152struct has_unique_object_representations : bool_constant<__has_unique_object_representations(T)> {};
2153
2154#ifdef MSTL_STANDARD_14__
2159template <typename T>
2160MSTL_INLINE17 constexpr bool has_unique_object_representations_v = has_unique_object_representations<T>::value;
2161#endif
2162
2163
2176template <typename T>
2178
2180#ifdef MSTL_COMPILER_MSVC__
2181template <typename T>
2182struct is_aggregate : bool_constant<is_array<T>::value || __is_aggregate(T)> {};
2183#else
2184template <typename T>
2185struct is_aggregate : bool_constant<__is_aggregate(remove_cv_t<T>)> {};
2186#endif
2188
2189#ifdef MSTL_STANDARD_14__
2194template <typename T>
2195MSTL_INLINE17 constexpr bool is_aggregate_v = is_aggregate<T>::value;
2196#endif
2197
2198
2199#ifdef MSTL_COMPILER_MSVC__
2210template <typename T1, typename T2>
2211struct is_layout_compatible : bool_constant<__is_layout_compatible(T1, T2)> {};
2212
2217#ifdef MSTL_STANDARD_14__
2218template <typename T1, typename T2>
2219MSTL_INLINE17 constexpr bool is_layout_compatible_v = is_layout_compatible<T1, T2>::value;
2220#endif
2221
2222
2231template <typename Base, typename Derived>
2232struct is_pointer_interconvertible_base_of : bool_constant<
2233 __is_pointer_interconvertible_base_of(Base, Derived)> {};
2234
2235#ifdef MSTL_STANDARD_14__
2240template <typename Base, typename Derived>
2241MSTL_INLINE17 constexpr bool is_pointer_interconvertible_base_of_v = is_pointer_interconvertible_base_of<Base, Derived>::value;
2242#endif
2243#endif
2244
2245
2252template <typename Base, typename Derived>
2253struct is_base_of : bool_constant<__is_base_of(Base, Derived)> {};
2254
2255#ifdef MSTL_STANDARD_14__
2260template <typename Base, typename Derived>
2261MSTL_INLINE17 constexpr bool is_base_of_v = is_base_of<Base, Derived>::value;
2262#endif
2263
2264
2265#ifdef MSTL_STANDARD_20__
2275template <typename T, typename Mem>
2276constexpr bool is_pointer_interconvertible_with_class(Mem T::*mp) noexcept {
2277 return __builtin_is_pointer_interconvertible_with_class(mp);
2278}
2279
2292template <typename S1, typename S2, typename M1, typename M2>
2293constexpr bool is_corresponding_member(M1 S1::* m1, M2 S2::* m2) noexcept {
2294 return __builtin_is_corresponding_member(m1, m2);
2295}
2296#endif
2297 // BaseTypeQualifierCheck
2299
2305
2316template <typename T>
2317struct is_trivial : bool_constant<__is_trivial(T)> {};
2318
2319#ifdef MSTL_STANDARD_14__
2324template <typename T>
2325MSTL_INLINE17 constexpr bool is_trivial_v = is_trivial<T>::value;
2326#endif
2327
2328
2336template <typename T>
2337struct is_trivially_copyable : bool_constant<__is_trivially_copyable(T)> {};
2338
2339#ifdef MSTL_STANDARD_14__
2344template <typename T>
2345MSTL_INLINE17 constexpr bool is_trivially_copyable_v = is_trivially_copyable<T>::value;
2346#endif
2347
2348
2354template <typename T>
2355struct has_virtual_destructor : bool_constant<__has_virtual_destructor(T)> {};
2356
2357#ifdef MSTL_STANDARD_14__
2362template <typename T>
2363MSTL_INLINE17 constexpr bool has_virtual_destructor_v = has_virtual_destructor<T>::value;
2364#endif
2365
2366
2373template <typename T, typename... Args>
2374struct is_constructible : bool_constant<__is_constructible(T, Args...)> {};
2375
2376#ifdef MSTL_STANDARD_14__
2381template <typename T, typename... Args>
2382MSTL_INLINE17 constexpr bool is_constructible_v = is_constructible<T, Args...>::value;
2383#endif
2384
2385
2391template <typename T>
2393 is_constructible<T, add_lvalue_reference_t<const T>>::value> {};
2394
2395#ifdef MSTL_STANDARD_14__
2400template <typename T>
2401MSTL_INLINE17 constexpr bool is_copy_constructible_v = is_copy_constructible<T>::value;
2402#endif
2403
2404
2410template <typename T>
2411struct is_default_constructible : bool_constant<is_constructible<T>::value> {};
2412
2413#ifdef MSTL_STANDARD_14__
2418template <typename T>
2419MSTL_INLINE17 constexpr bool is_default_constructible_v = is_default_constructible<T>::value;
2420#endif
2421
2422
2425template <typename T>
2426void __implicitly_default_construct_aux(const T&) noexcept;
2429
2438template <typename T, typename Dummy = void>
2440
2442template <typename T>
2444 <T, void_t<decltype(_INNER __implicitly_default_construct_aux<T>({}))>> : true_type {};
2446
2447#ifdef MSTL_STANDARD_14__
2452template <typename T>
2453MSTL_INLINE17 constexpr bool is_implicitly_default_constructible_v = is_implicitly_default_constructible<T>::value;
2454#endif
2455
2456
2462template <typename T>
2463struct is_move_constructible : bool_constant<is_constructible<T, T>::value> {};
2464
2465#ifdef MSTL_STANDARD_14__
2470template <typename T>
2471MSTL_INLINE17 constexpr bool is_move_constructible_v = is_move_constructible<T>::value;
2472#endif
2473
2474
2481template <typename To, typename From>
2482struct is_assignable : bool_constant<__is_assignable(To, From)> {};
2483
2484#ifdef MSTL_STANDARD_14__
2489template <typename To, typename From>
2490MSTL_INLINE17 constexpr bool is_assignable_v = is_assignable<To, From>::value;
2491#endif
2492
2493
2501template <typename T>
2503 : bool_constant<is_assignable<add_lvalue_reference_t<T>, add_lvalue_reference_t<const T>>::value> {};
2504
2505#ifdef MSTL_STANDARD_14__
2510template <typename T>
2511MSTL_INLINE17 constexpr bool is_copy_assignable_v = is_copy_assignable<T>::value;
2512#endif
2513
2514
2522template <typename T>
2523struct is_move_assignable : bool_constant<is_assignable<add_lvalue_reference_t<T>, T>::value> {};
2524
2525#ifdef MSTL_STANDARD_14__
2530template <typename T>
2531MSTL_INLINE17 constexpr bool is_move_assignable_v = is_move_assignable<T>::value;
2532#endif
2533
2534
2545template <typename T>
2547
2549#ifdef MSTL_COMPILER_MSVC__
2550template <typename T>
2551struct is_destructible : bool_constant<__is_destructible(T)> {};
2552#else
2554template <typename T>
2555struct __destructible_aux {
2556private:
2557 template <typename T1, typename = decltype(declval<T1&>().~T1())>
2558 static true_type __test(int);
2559 template <typename>
2560 static false_type __test(...);
2561
2562public:
2563 using type = decltype(__test<T>(0));
2564};
2565
2566template <typename T,
2569struct __is_destructible_dispatch;
2570
2571template <typename T>
2572struct __is_destructible_dispatch<T, false, false>
2573 : __destructible_aux<remove_all_extents_t<T>>::type {};
2574
2575template <typename T>
2576struct __is_destructible_dispatch<T, true, false> : false_type {};
2577
2578template <typename T>
2579struct __is_destructible_dispatch<T, false, true> : true_type {};
2580
2582
2583template <typename T>
2584struct is_destructible : _INNER __is_destructible_dispatch<T>::type {};
2585#endif
2587
2588#ifdef MSTL_STANDARD_14__
2593template <typename T>
2594MSTL_INLINE17 constexpr bool is_destructible_v = is_destructible<T>::value;
2595#endif
2596
2597
2606template <typename T, typename... Args>
2607struct is_trivially_constructible : bool_constant<__is_trivially_constructible(T, Args...)> {};
2608
2609#ifdef MSTL_STANDARD_14__
2614template <typename T, typename... Args>
2615MSTL_INLINE17 constexpr bool is_trivially_constructible_v = is_trivially_constructible<T, Args...>::value;
2616#endif
2617
2618
2624template <typename T>
2626 is_trivially_constructible<T, add_lvalue_reference_t<const T>>::value> {};
2627
2628#ifdef MSTL_STANDARD_14__
2633template <typename T>
2634MSTL_INLINE17 constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible<T>::value;
2635#endif
2636
2637
2643template <typename T>
2644struct is_trivially_default_constructible : bool_constant<is_trivially_constructible<T>::value> {};
2645
2646#ifdef MSTL_STANDARD_14__
2651template <typename T>
2652MSTL_INLINE17 constexpr bool is_trivially_default_constructible_v = is_trivially_default_constructible<T>::value;
2653#endif
2654
2655
2661template <typename T>
2662struct is_trivially_move_constructible : bool_constant<is_trivially_constructible<T, T>::value> {};
2663
2664#ifdef MSTL_STANDARD_14__
2669template <typename T>
2670MSTL_INLINE17 constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible<T>::value;
2671#endif
2672
2673
2680template <typename To, typename From>
2681struct is_trivially_assignable : bool_constant<__is_trivially_assignable(To, From)> {};
2682
2683#ifdef MSTL_STANDARD_14__
2688template <typename To, typename From>
2689MSTL_INLINE17 constexpr bool is_trivially_assignable_v = is_trivially_assignable<To, From>::value;
2690#endif
2691
2692
2698template <typename T>
2700 is_trivially_assignable<add_lvalue_reference_t<T>, add_lvalue_reference_t<const T>>::value> {};
2701
2702#ifdef MSTL_STANDARD_14__
2707template <typename T>
2708MSTL_INLINE17 constexpr bool is_trivially_copy_assignable_v = is_trivially_copy_assignable<T>::value;
2709#endif
2710
2711
2717template <typename T>
2719 is_trivially_assignable<add_lvalue_reference_t<T>, T>::value> {};
2720
2721#ifdef MSTL_STANDARD_14__
2726template <typename T>
2727MSTL_INLINE17 constexpr bool is_trivially_move_assignable_v = is_trivially_move_assignable<T>::value;
2728#endif
2729
2730
2738template <typename T>
2740#if defined(MSTL_COMPILER_MSVC__) || defined(MSTL_COMPILER_CLANG__)
2741 bool_constant<__is_trivially_destructible(T)> {};
2742#else
2743 conjunction<is_destructible<T>, bool_constant<__has_trivial_destructor(T)>> {};
2744#endif
2745
2746#ifdef MSTL_STANDARD_14__
2751template <typename T>
2752MSTL_INLINE17 constexpr bool is_trivially_destructible_v = is_trivially_destructible<T>::value;
2753#endif
2754
2755
2762template <typename T, typename... Args>
2764
2770template <typename T>
2772
2774#ifdef MSTL_COMPILER_MSVC__
2775template <typename T, typename... Args>
2776struct is_nothrow_constructible : bool_constant<__is_nothrow_constructible(T, Args...)> {};
2777#else
2779template <typename T, bool = is_array<T>::value>
2780struct __is_nothrow_default_constructible_dispatch;
2781
2782template <typename T>
2783struct __is_nothrow_default_constructible_dispatch<T, true> : conjunction<
2784 is_bounded_array<T>, bool_constant<noexcept(remove_all_extents_t<T>())>> {};
2785
2786template <typename T>
2787struct __is_nothrow_default_constructible_dispatch<T, false>
2788 : bool_constant<noexcept(T())> {};
2789
2791
2792template <typename T>
2794 is_default_constructible<T>, _INNER __is_nothrow_default_constructible_dispatch<T>> {};
2795
2797
2798template <typename T, typename... Args>
2799struct __is_nothrow_constructible_dispatch
2800 : bool_constant<noexcept(T(_MSTL declval<Args>()...))> {};
2801
2802template <typename T>
2803struct __is_nothrow_constructible_dispatch<T>
2805
2807
2808template <typename T, typename... Args>
2810 is_constructible<T, Args...>, _INNER __is_nothrow_constructible_dispatch<T, Args...>> {};
2811#endif
2813
2814#ifdef MSTL_STANDARD_14__
2819template <typename T, typename... Args>
2820MSTL_INLINE17 constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<T, Args...>::value;
2821#endif
2822
2823
2829template <typename T>
2831 is_nothrow_constructible<T, add_lvalue_reference_t<const T>>::value> {};
2832
2833#ifdef MSTL_STANDARD_14__
2838template <typename T>
2839MSTL_INLINE17 constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<T>::value;
2840#endif
2841
2842
2844#ifdef MSTL_COMPILER_MSVC__
2845template <typename T>
2846struct is_nothrow_default_constructible : bool_constant<is_nothrow_constructible_v<T>> {};
2847#endif
2849
2850
2851#ifdef MSTL_STANDARD_14__
2856template <typename T>
2857MSTL_INLINE17 constexpr bool is_nothrow_default_constructible_v = is_nothrow_default_constructible<T>::value;
2858#endif
2859
2860
2866template <typename T>
2867struct is_nothrow_move_constructible : bool_constant<is_nothrow_constructible<T, T>::value> {};
2868
2869#ifdef MSTL_STANDARD_14__
2874template <typename T>
2875MSTL_INLINE17 constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible<T>::value;
2876#endif
2877
2878
2885template <typename To, typename From>
2887
2889template <typename To, typename From>
2890struct is_nothrow_assignable :
2891#ifdef MSTL_COMPILER_MSVC__
2892 bool_constant<__is_nothrow_assignable(To, From)> {};
2893#else
2895 noexcept(_MSTL declval<To>() = _MSTL declval<From>())>> {};
2896#endif
2898
2899#ifdef MSTL_STANDARD_14__
2904template <typename To, typename From>
2905MSTL_INLINE17 constexpr bool is_nothrow_assignable_v = is_nothrow_assignable<To, From>::value;
2906#endif
2907
2908
2914template <typename T>
2916 is_nothrow_assignable<add_lvalue_reference_t<T>, add_lvalue_reference_t<const T>>::value> {};
2917
2918#ifdef MSTL_STANDARD_14__
2923template <typename T>
2924MSTL_INLINE17 constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<T>::value;
2925#endif
2926
2927
2933template <typename T>
2935 is_nothrow_assignable<add_lvalue_reference_t<T>, T>::value> {};
2936
2937#ifdef MSTL_STANDARD_14__
2942template <typename T>
2943MSTL_INLINE17 constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable<T>::value;
2944#endif
2945
2946
2947#ifndef MSTL_COMPILER_MSVC__
2950template <typename T>
2951struct __is_nothrow_destructible_aux {
2952private:
2953 template <typename T1>
2954 static bool_constant<noexcept(declval<T1&>().~T1())> __test(int);
2955
2956 template <typename>
2957 static false_type __test(...);
2958
2959public:
2960 using type = decltype(__test<T>(0));
2961};
2962
2963template <typename T,
2966struct __is_nothrow_destructible_dispatch;
2967
2968template <typename T>
2969struct __is_nothrow_destructible_dispatch<T, false, false>
2970 : __is_nothrow_destructible_aux<remove_all_extents_t<T>>::type {};
2971
2972template <typename T>
2973struct __is_nothrow_destructible_dispatch<T, true, false> : false_type {};
2974
2975template <typename T>
2976struct __is_nothrow_destructible_dispatch<T, false, true> : true_type {};
2979#endif
2980
2981
2987template <typename T>
2989
2991template <typename T>
2993#ifdef MSTL_COMPILER_MSVC__
2994 bool_constant<__is_nothrow_destructible(T)> {};
2995#else
2996 _INNER __is_nothrow_destructible_dispatch<T>::type {};
2997#endif
2999
3000#ifdef MSTL_STANDARD_14__
3005template <typename T>
3006MSTL_INLINE17 constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<T>::value;
3007#endif
3008
3009
3018template <typename T>
3020
3021#ifdef MSTL_STANDARD_14__
3026template <typename T>
3027MSTL_INLINE17 constexpr bool is_location_invariant_v = is_location_invariant<T>::value;
3028#endif
3029 // TypeSpecialMemberFunctionChecks
3031
3037
3046template <typename T>
3047MSTL_NODISCARD constexpr T&& forward(remove_reference_t<T>& x) noexcept {
3048 return static_cast<T&&>(x);
3049}
3050
3060template <typename T>
3061MSTL_NODISCARD constexpr T&& forward(remove_reference_t<T>&& x) noexcept {
3062 static_assert(!is_lvalue_reference<T>::value, "forward failed.");
3063 return static_cast<T&&>(x);
3064}
3065
3074template <typename T>
3075MSTL_NODISCARD constexpr remove_reference_t<T>&& move(T&& x) noexcept {
3076 return static_cast<remove_reference_t<T>&&>(x);
3077}
3078
3087template <typename T>
3088MSTL_NODISCARD constexpr
3090move_if_noexcept(T& x) noexcept {
3091 return _MSTL move(x);
3092}
3093
3102template <typename T>
3103MSTL_NODISCARD constexpr T* addressof(T& x) noexcept {
3104 return __builtin_addressof(x);
3105}
3106
3112template <typename T>
3113const T* addressof(const T&&) = delete;
3114
3115
3116#ifdef MSTL_STANDARD_17__
3123MSTL_NODISCARD constexpr bool is_constant_evaluated() noexcept {
3124 return __builtin_is_constant_evaluated();
3125}
3126#endif
3127 // ArgsForwardFunctions
3129
3135
3136#if !defined(MSTL_COMPILER_MSVC__) && !defined(MSTL_COMPILER_CLANG__)
3139template <typename From, typename To, bool = disjunction_v<is_void<From>, is_function<To>, is_array<To>>>
3140struct __is_convertible_helper {
3141 using type = typename is_void<To>::type;
3142};
3143
3144template <typename From, typename To>
3145struct __is_convertible_helper<From, To, false> {
3146private:
3147 template <typename From1, typename To1, typename = decltype(_MSTL declvoid<To1>(_MSTL declval<From1>()))>
3148 static true_type __test(int);
3149
3150 template <typename, typename>
3151 static false_type __test(...);
3152
3153public:
3154 using type = decltype(__test<From, To>(0));
3155};
3158#endif
3159
3166template <typename From, typename To>
3168#if defined(MSTL_COMPILER_MSVC__)
3169 bool_constant<__is_convertible_to(From, To)> {};
3170#elif defined(MSTL_COMPILER_CLANG__)
3171 bool_constant<__is_convertible(From, To)> {};
3172#else
3173 __is_convertible_helper<From, To>::type {};
3174#endif
3175
3176#ifdef MSTL_STANDARD_14__
3181template <typename From, typename To>
3182MSTL_INLINE17 constexpr bool is_convertible_v = is_convertible<From, To>::value;
3183#endif
3184
3185#if defined(MSTL_STANDARD_20__) || defined(MSTL_DOXYGEN_GENERATE)
3192template <typename From, typename To>
3193concept convertible_to = is_convertible_v<From, To> && requires { static_cast<To>(_MSTL declval<From>()); };
3194#endif // MSTL_STANDARD_20__
3195
3196
3205template <typename ToElement, typename FromElement>
3206using is_array_convertible = is_convertible<FromElement(*)[], ToElement(*)[]>;
3207
3208#ifdef MSTL_STANDARD_14__
3213template <typename ToElement, typename FromElement>
3214MSTL_INLINE17 constexpr bool is_array_convertible_v = is_array_convertible<ToElement, FromElement>::value;
3215#endif
3216
3217
3226template <typename From, typename To,
3227 bool IsConvertible = is_convertible<From, To>::value,
3228 bool IsVoid = is_void<To>::value>
3229struct is_nothrow_convertible : bool_constant<noexcept(_MSTL declcopy<To>(_MSTL declval<From>()))> {};
3230
3232template <typename From, typename To, bool IsVoid>
3233struct is_nothrow_convertible<From, To, false, IsVoid> : false_type {};
3234
3235template <typename From, typename To>
3236struct is_nothrow_convertible<From, To, true, true> : true_type {};
3238
3239#ifdef MSTL_STANDARD_14__
3244template <typename From, typename To>
3245MSTL_INLINE17 constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<From, To>::value;
3246#endif
3247
3248
3256template <typename Iterator, typename Ptr, bool IsPtr = is_pointer<remove_cvref_t<Iterator>>::value>
3257struct is_nothrow_arrow : bool_constant<is_nothrow_convertible<Iterator, Ptr>::value> {};
3258
3260template <typename Iterator, typename Ptr>
3261struct is_nothrow_arrow<Iterator, Ptr, false> : bool_constant<
3262 noexcept(_MSTL declcopy<Ptr>(_MSTL declval<Iterator>().operator->()))> {};
3264
3265#ifdef MSTL_STANDARD_14__
3270template <typename Iterator, typename Ptr>
3271MSTL_INLINE17 constexpr bool is_nothrow_arrow_v = is_nothrow_arrow<Iterator, Ptr>::value;
3272#endif
3273 // ConvertibleChecks
3275
3281
3284template <size_t>
3285struct __sign_byte_aux;
3286
3287template <>
3288struct __sign_byte_aux<1> {
3289 template <typename>
3290 using signed_t = signed char;
3291 template <typename>
3292 using unsigned_t = unsigned char;
3293};
3294template <>
3295struct __sign_byte_aux<2> {
3296 template <typename>
3297 using signed_t = signed short;
3298 template <typename>
3299 using unsigned_t = unsigned short;
3300};
3301template <>
3302struct __sign_byte_aux<4> {
3303#ifdef MSTL_PLATFORM_WINDOWS__
3304 template <typename T>
3305 using signed_t =
3306 conditional_t<is_same_v<T, signed long> || is_same_v<T, unsigned long>, signed long, signed int>;
3307
3308 template <typename T>
3309 using unsigned_t =
3310 conditional_t<is_same_v<T, signed long> || is_same_v<T, unsigned long>, unsigned long, unsigned int>;
3311#elif defined(MSTL_PLATFORM_LINUX__)
3312 template <typename>
3313 using signed_t = signed int;
3314 template <typename>
3315 using unsigned_t = unsigned int;
3316#endif
3317};
3318template <>
3319struct __sign_byte_aux<8> {
3320#ifdef MSTL_PLATFORM_WINDOWS__
3321 template <typename>
3322 using signed_t = signed long long;
3323 template <typename>
3324 using unsigned_t = unsigned long long;
3325#elif defined(MSTL_PLATFORM_LINUX__)
3326 template <typename T>
3327 using signed_t =
3328 conditional_t<is_same<T, signed long>::value || is_same<T, unsigned long>::value, signed long, signed long long>;
3329
3330 template <typename T>
3331 using unsigned_t =
3332 conditional_t<is_same<T, signed long>::value || is_same<T, unsigned long>::value, unsigned long, unsigned long long>;
3333#endif
3334};
3335
3336template <typename T>
3337using __set_signed_byte = typename __sign_byte_aux<sizeof(T)>::template signed_t<T>;
3338template <typename T>
3339using __set_unsigned_byte = typename __sign_byte_aux<sizeof(T)>::template unsigned_t<T>;
3340
3341template <typename T>
3342struct __set_sign {
3344 "make signed only support non-bool && integral-like types");
3345
3346 using signed_type = copy_cv_t<T, __set_signed_byte<T>>;
3347 using unsigned_type = copy_cv_t<T, __set_unsigned_byte<T>>;
3348};
3351
3359template <typename T>
3361 using type = typename _INNER __set_sign<T>::signed_type;
3362};
3363
3368template <typename T>
3369using make_signed_t = typename make_signed<T>::type;
3370
3378template <typename T>
3380 using type = typename _INNER __set_sign<T>::unsigned_type;
3381};
3382
3387template <typename T>
3388using make_unsigned_t = typename make_unsigned<T>::type;
3389
3390
3393template <size_t Size, bool IsSigned>
3394struct __make_integer_impl;
3395
3396template <size_t Size>
3397struct __make_integer_impl<Size, true> {
3398 using type = typename __sign_byte_aux<Size>::template signed_t<int>;
3399};
3400
3401template <size_t Size>
3402struct __make_integer_impl<Size, false> {
3403 using type = typename __sign_byte_aux<Size>::template unsigned_t<int>;
3404};
3407
3414template <size_t Size, bool IsSigned = true>
3416 using type = typename _INNER __make_integer_impl<Size, IsSigned>::type;
3417};
3418
3423template <size_t Size, bool IsSigned = true>
3424using make_integer_t = typename make_integer<Size, IsSigned>::type;
3425
3426
3432template <size_t... Values>
3434
3436template <size_t Value>
3437struct max_value<Value> : integral_constant<size_t, Value> {};
3438
3439template <size_t First, size_t Second, size_t... Rest>
3440struct max_value<First, Second, Rest...> : max_value<(First > Second ? First : Second), Rest...> {};
3442
3443#ifdef MSTL_STANDARD_14__
3444template <size_t... Values>
3445MSTL_INLINE17 constexpr size_t max_value_v = max_value<Values...>::value;
3446#endif
3447 // SignManipulation
3449
3455
3461template <typename T>
3462struct alignment_of : integral_constant<size_t, alignof(T)> {};
3463
3464#ifdef MSTL_STANDARD_14__
3469template <typename T>
3470constexpr size_t alignment_of_v = alignment_of<T>::value;
3471#endif
3472
3473
3480template <size_t Len, size_t Align = alignof(_MSTL max_align_t)>
3482 static_assert((Align & (Align - 1)) == 0, "Alignment must be power of two");
3483
3488 struct alignas(Align) type {
3490 };
3491};
3492
3497template <size_t Len, size_t Align = alignof(_MSTL max_align_t)>
3499
3500
3509template <size_t Len, typename... Types>
3511private:
3512 static constexpr size_t required_alignment = max_value<alignof(Types)...>::value;
3513 static constexpr size_t required_size = max_value<sizeof(Types)...>::value;
3514 static constexpr size_t storage_size = (Len > required_size) ? Len : required_size;
3515
3516 static_assert((required_alignment & (required_alignment - 1)) == 0, "Alignment must be power of two");
3517
3518public:
3522 static constexpr size_t alignment_value = required_alignment;
3526 static constexpr size_t size_value = storage_size;
3527
3532 struct alignas(alignment_value) type {
3533 byte_t data[storage_size];
3534 };
3535
3546 template <typename T>
3547 static constexpr bool is_storable() noexcept {
3549 sizeof(T) <= storage_size &&
3550 alignof(T) <= alignment_value;
3551 }
3552};
3553
3558template <size_t Len, typename... Types>
3559using aligned_union_t = typename aligned_union<Len, Types...>::type;
3560
3561#ifdef MSTL_STANDARD_14__
3566template <size_t Len, typename... Types>
3567constexpr size_t aligned_union_v = aligned_union<Len, Types...>::align_value;
3568#endif
3569 // Alignment
3571
3577
3588template <typename T>
3589struct decay {
3590private:
3591 using remove_ref_t = remove_reference_t<T>;
3593
3594public:
3596};
3597
3602template <typename T>
3603using decay_t = typename decay<T>::type;
3604
3605
3608template <typename Default, typename, template <typename...> class, typename...>
3609struct __detector {
3610 using value_t = false_type;
3611 using type = Default;
3612};
3613template <typename Default, template <typename...> class Op, typename... Args>
3614struct __detector<Default, void_t<Op<Args...>>, Op, Args...> {
3615 using value_t = true_type;
3616 using type = Op<Args...>;
3617};
3620
3628template <typename Default, template <typename...> class Op, typename... Args>
3629using detected_or = _INNER __detector<Default, void, Op, Args...>;
3630
3635template <typename Default, template <typename...> class Op, typename... Args>
3636using detected_or_t = typename detected_or<Default, Op, Args...>::type;
3637
3638
3650template <typename T1, typename T2>
3651using common_ternary_operator_t = decltype(true ? _MSTL declval<T1>() : _MSTL declval<T2>());
3652
3653
3656template <typename, typename, typename = void>
3657struct __oper_decay_aux {};
3658template <typename T1, typename T2>
3659struct __oper_decay_aux<T1, T2, void_t<common_ternary_operator_t<decay_t<T1>, decay_t<T2>>>> {
3661};
3664
3670template <typename... Types>
3672
3677template <typename... Types>
3678using common_type_t = typename common_type<Types...>::type;
3679
3681template <>
3682struct common_type<> {};
3683
3684template <typename T1>
3685struct common_type<T1> : common_type<T1, T1> {};
3686
3687template <typename T1, typename T2>
3688struct common_type<T1, T2> : _INNER __oper_decay_aux<T1, T2> {};
3689
3690template <typename T1, typename T2, typename... Rest>
3691struct common_type<T1, T2, Rest...> : common_type<common_type_t<T1, T2>, Rest...> {};
3693
3694
3695#ifdef MSTL_STANDARD_20__
3696
3702template <typename... Types>
3703struct common_reference;
3704
3709template <typename... Types>
3710using common_reference_t = typename common_reference<Types...>::type;
3711
3713
3714template <>
3715struct common_reference<> {};
3716
3717template <typename T>
3718struct common_reference<T> {
3719 using type = T;
3720};
3721
3722
3724
3725template <typename T1, typename T2>
3726struct __common_reference_base_aux : common_type<T1, T2> {};
3727
3728template <typename T1, typename T2> requires requires {
3730}
3731struct __common_reference_base_aux<T1, T2> {
3733};
3734
3735template <typename, typename, template <typename> typename, template <typename> typename>
3736struct __basic_common_reference {};
3737
3738template <typename T1>
3739struct __add_qualifier_aux {
3740 template <typename T2>
3741 using apply_t = copy_ref_t<T1, copy_cv_t<T1, T2>>;
3742};
3743
3744template <typename T1, typename T2>
3745using qualifier_extract = typename __basic_common_reference<remove_cvref_t<T1>, remove_cvref_t<T2>,
3746 __add_qualifier_aux<T1>::template apply_t, __add_qualifier_aux<T2>::template apply_t>::type;
3747
3748template <typename T1, typename T2>
3749struct __common_ref_qualify_aux : __common_reference_base_aux<T1, T2> {};
3750
3751template <typename T1, typename T2>
3752 requires requires { typename qualifier_extract<T1, T2>; }
3753struct __common_ref_qualify_aux<T1, T2> {
3754 using type = qualifier_extract<T1, T2>;
3755};
3756
3757template <typename T1, typename T2>
3758struct __common_reference_ptr_aux : __common_ref_qualify_aux<T1, T2> {};
3759
3760template <typename T1, typename T2> requires
3761 is_lvalue_reference_v<common_ternary_operator_t<copy_cv_t<T1, T2>&, copy_cv_t<T2, T1>&>>
3763
3764template <typename, typename>
3765struct __common_reference_aux {};
3766
3767template <typename T1, typename T2>
3768 requires requires { typename __common_lvalue_aux<T1, T2>; }
3769struct __common_reference_aux<T1&, T2&> {
3770 using type = __common_lvalue_aux<T1, T2>;
3771};
3772
3773template <typename T1, typename T2> requires
3774 is_convertible_v<T1&&, __common_lvalue_aux<const T1, T2>>
3775struct __common_reference_aux<T1&&, T2&> {
3776 using type = __common_lvalue_aux<const T1, T2>;
3777};
3778
3779template <typename T1, typename T2> requires
3780 is_convertible_v<T2&&, __common_lvalue_aux<const T2, T1>>
3781struct __common_reference_aux<T1&, T2&&> {
3782 using type = __common_lvalue_aux<const T2, T1>;
3783};
3784
3785template <typename T1, typename T2>
3786using __common_rvalue_aux = remove_reference_t<__common_lvalue_aux<T1, T2>>&&;
3787
3788template <typename T1, typename T2> requires
3789 is_convertible_v<T1&&, __common_rvalue_aux<T1, T2>> &&
3790 is_convertible_v<T2&&, __common_rvalue_aux<T1, T2>>
3791struct __common_reference_aux<T1&&, T2&&> {
3792 using type = __common_rvalue_aux<T1, T2>;
3793};
3794
3795template <typename T1, typename T2>
3796using __common_reference_aux_t = typename __common_reference_aux<T1, T2>::type;
3797
3798template <typename T1, typename T2> requires
3799 is_convertible_v<add_pointer_t<T1>, add_pointer_t<__common_reference_aux_t<T1, T2>>> &&
3800 is_convertible_v<add_pointer_t<T2>, add_pointer_t<__common_reference_aux_t<T1, T2>>>
3801struct __common_reference_ptr_aux<T1, T2> {
3802 using type = __common_reference_aux_t<T1, T2>;
3803};
3804
3806
3807
3808template <typename T1, typename T2>
3809struct common_reference<T1, T2> : _INNER __common_reference_ptr_aux<T1, T2> {};
3810
3811template <typename T1, typename T2, typename T3, typename... Rest>
3812struct common_reference<T1, T2, T3, Rest...> {};
3813
3814template <typename T1, typename T2, typename T3, typename... Rest>
3815 requires requires { typename common_reference_t<T1, T2>; }
3816struct common_reference<T1, T2, T3, Rest...> : common_reference<common_reference_t<T1, T2>, T3, Rest...> {};
3817
3819#endif
3820
3821
3830template <typename T, template <typename...> class Template>
3832
3834template <template <typename...> class Template, typename... Args>
3835struct is_specialization<Template<Args...>, Template> : true_type {};
3837
3838#ifdef MSTL_STANDARD_17__
3843template <typename T, template <typename...> class Template>
3844MSTL_INLINE17 constexpr bool is_specialization_v = is_specialization<T, Template>::value;
3845#else
3852template <typename T, template <typename...> class Template>
3856#endif
3857 // TypeAttributeOperations
3859
3865
3866template <typename>
3867struct is_swappable;
3868
3869template <typename>
3870struct is_nothrow_swappable;
3871
3872
3879template <typename T>
3880MSTL_CONSTEXPR14 enable_if_t<conjunction<is_move_constructible<T>, is_move_assignable<T>>::value>
3881swap(T& lhs, T& rhs)
3883
3891template <typename T, size_t Size>
3892MSTL_CONSTEXPR14 enable_if_t<is_swappable<T>::value>
3893swap(T(& lhs)[Size], T(& rhs)[Size])
3895
3899void swap() = delete;
3900
3909template <typename T, typename U = T>
3910MSTL_CONSTEXPR14 T exchange(T& val, U&& new_val)
3912
3913
3921template <typename T1, typename T2, typename Dummy = void>
3923
3925template <typename T1, typename T2>
3926struct is_swappable_from<T1, T2, void_t<decltype(
3927 _MSTL swap(_MSTL declval<T1>(), _MSTL declval<T2>()))>> : true_type {};
3929
3930
3939template <typename T1, typename T2>
3941 conjunction<is_swappable_from<T1, T2>, is_swappable_from<T2, T1>>::value> {};
3942
3943
3949template <typename T>
3951 is_swappable_with<add_lvalue_reference_t<T>, add_lvalue_reference_t<T>>::value> {};
3952
3953#ifdef MSTL_STANDARD_14__
3958template <typename T>
3959MSTL_INLINE17 constexpr bool is_swappable_v = is_swappable<T>::value;
3960#endif
3961
3962
3969template <typename T1, typename T2>
3971 noexcept(_MSTL swap(_MSTL declval<T1>(), _MSTL declval<T2>())) &&
3972 noexcept(_MSTL swap(_MSTL declval<T2>(), _MSTL declval<T1>()))> {};
3973
3974
3981template <typename T1, typename T2>
3983 conjunction<is_swappable_with<T1, T2>, is_nothrow_swappable_from<T1, T2>>::value> {};
3984
3985
3991template <typename T>
3993 is_nothrow_swappable_with<add_lvalue_reference_t<T>, add_lvalue_reference_t<T>>::value> {};
3994
3995#ifdef MSTL_STANDARD_14__
4000template <typename T>
4001MSTL_INLINE17 constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<T>::value;
4002#endif
4003
4004
4015template <typename T, typename Dummy = void>
4017
4019template <typename T>
4020struct is_ADL_swappable<T, void_t<
4021 decltype(swap(_MSTL declval<T&>(), _MSTL declval<T&>()))>> : true_type {};
4023
4024
4036template <typename T>
4038 is_trivially_destructible<T>, is_trivially_move_constructible<T>,
4039 is_trivially_move_assignable<T>, negation<is_ADL_swappable<T>>>::value> {};
4040
4041#ifdef MSTL_STANDARD_14__
4046template <typename T>
4047MSTL_INLINE17 constexpr bool is_trivially_swappable_v = is_trivially_swappable<T>::value;
4048#endif
4049
4050
4051template <typename T>
4053swap(T& lhs, T& rhs)
4055 T tmp = _MSTL move(lhs);
4056 lhs = _MSTL move(rhs);
4057 rhs = _MSTL move(tmp);
4058 return;
4059}
4060
4061template <typename T, size_t Size>
4062MSTL_CONSTEXPR14 enable_if_t<is_swappable<T>::value>
4063swap(T(& lhs)[Size], T(& rhs)[Size])
4065 if (&lhs == &rhs) return;
4066 T* first1 = lhs;
4067 T* last1 = first1 + Size;
4068 T* first2 = rhs;
4069 for (; first1 != last1; ++first1, ++first2) {
4070 _MSTL swap(*first1, *first2);
4071 }
4072 return;
4073}
4074
4075template <typename T, typename U>
4076MSTL_CONSTEXPR14 T exchange(T& val, U&& new_val)
4078 T old_val = _MSTL move(val);
4079 val = _MSTL forward<U>(new_val);
4080 return old_val;
4081}
4082 // SwapUtility
4084
4090
4091#ifdef MSTL_STANDARD_20__
4101template <typename T>
4102concept is_pair_v = requires(T p) {
4103 typename T::first_type;
4104 typename T::second_type;
4105 p.first;
4106 p.second;
4107};
4108#endif // MSTL_STANDARD_20__
4109
4110
4121template <typename Alloc, typename Dummy = void>
4123
4125template <typename Alloc>
4126struct is_allocator<Alloc, void_t<
4127 typename Alloc::value_type, decltype(declval<Alloc&>().allocate(size_t{}))>>
4128 : true_type {};
4130
4131#ifdef MSTL_STANDARD_14__
4136template <typename Alloc>
4137MSTL_INLINE17 constexpr bool is_allocator_v = is_allocator<Alloc>::value;
4138#endif
4139
4140
4143template <typename T>
4144struct __has_valid_begin_end {
4145private:
4146 template <typename U>
4147 static auto __test(int) -> decltype(
4148 declval<U>().begin(), declval<U>().end(),
4149 is_same<decltype(declval<U>().begin()), decltype(declval<U>().end())>(),
4150 true_type{}
4151 );
4152
4153 template <typename U>
4154 static false_type __test(...);
4155
4156public:
4157 static constexpr bool value = decltype(__test<T>(0))::value;
4158};
4161
4162
4168template <typename Iterator>
4170private:
4171 template <typename U>
4172 static auto __test(int) -> decltype(
4173 ++declval<U&>(),
4174 true_type{}
4175 );
4176
4177 template <typename U>
4178 static false_type __test(...);
4179
4180public:
4181 static constexpr bool value = decltype(__test<Iterator>(0))::value;
4182};
4183
4184#ifdef MSTL_STANDARD_14__
4189template <typename Iterator>
4190MSTL_INLINE17 constexpr bool is_incrementible_v = is_incrementible<Iterator>::value;
4191#endif
4192
4193
4199template <typename Iterator>
4201private:
4202 template <typename U>
4203 static auto __test(int) -> decltype(
4204 --declval<U&>(),
4205 true_type{}
4206 );
4207
4208 template <typename U>
4209 static false_type __test(...);
4210public:
4211 static constexpr bool value = decltype(__test<Iterator>(0))::value;
4212};
4213
4214#ifdef MSTL_STANDARD_14__
4219template <typename Iterator>
4220MSTL_INLINE17 constexpr bool is_decrementible_v = is_decrementible<Iterator>::value;
4221#endif
4222
4223
4233template <typename Container>
4235 _INNER __has_valid_begin_end<Container>::value &&
4236 is_incrementible<decltype(declval<Container>().begin())>::value
4237> {};
4238
4239#ifdef MSTL_STANDARD_14__
4244template <typename T>
4245MSTL_INLINE17 constexpr bool is_iterable_v = is_iterable<T>::value;
4246#endif
4247
4248
4251template <typename T>
4252struct __has_first_and_second {
4253private:
4254 template <typename U>
4255 static auto __test(int) -> decltype(
4256 declval<U>().first, declval<U>().second,
4257 true_type{}
4258 );
4259
4260 template <typename U>
4261 static false_type __test(...);
4262
4263public:
4264 static constexpr bool value = decltype(__test<T>(0))::value;
4265};
4268
4278template <typename Map>
4280 is_iterable<Map>::value &&
4281 _INNER __has_first_and_second<decltype(*declval<decltype(declval<Map>().begin())>())>::value
4282> {};
4283
4284#ifdef MSTL_STANDARD_14__
4289template <typename Map>
4290MSTL_INLINE17 constexpr bool is_maplike_v = is_maplike<Map>::value;
4291#endif
4292
4293
4296template <typename Alloc, typename T, typename... Args>
4297struct __has_construct_impl {
4298private:
4299 template <typename Alloc1,
4300 typename = decltype(_MSTL declval<Alloc1*>()->construct(_MSTL declval<T*>(), _MSTL declval<Args>()...))>
4301 static true_type __test(int);
4302
4303 template <typename>
4304 static false_type __test(...);
4305
4306public:
4307 using type = decltype(__test<Alloc>(0));
4308};
4311
4319template <typename Alloc, typename T, typename... Args>
4320struct has_construct : _INNER __has_construct_impl<Alloc, T, Args...>::type {};
4321
4322#ifdef MSTL_STANDARD_14__
4327template <typename Alloc, typename T, typename... Args>
4328MSTL_INLINE17 constexpr bool has_construct_v = has_construct<Alloc, T, Args...>::value;
4329#endif
4330
4331
4334template <typename T>
4335struct __has_base_impl {
4336private:
4337 template <typename U>
4338 static auto __test(int) -> decltype(_MSTL declval<const U>().base(), true_type{});
4339
4340 template <typename U>
4341 static false_type __test(...);
4342public:
4343 static constexpr bool value = decltype(__test<T>(0))::value;
4344};
4347
4353template <typename T>
4354struct has_base : bool_constant<_INNER __has_base_impl<T>::value> {};
4355
4356#ifdef MSTL_STANDARD_14__
4361template <typename T>
4362MSTL_INLINE17 constexpr bool has_base_v = has_base<T>::value;
4363#endif
4364 // TypeActionCheck
4366
4372
4383template <typename T, enable_if_t<is_default_constructible<T>::value, int> = 0>
4384constexpr T initialize() noexcept(is_nothrow_default_constructible<T>::value) {
4385 return T();
4386}
4387
4388#define INITIALIZE_BASIC_FUNCTION__(OPT) \
4389template <> constexpr OPT initialize() noexcept { return static_cast<OPT>(0); }
4390MSTL_MACRO_RANGE_CHARS(INITIALIZE_BASIC_FUNCTION__)
4391MSTL_MACRO_RANGE_FLOAT(INITIALIZE_BASIC_FUNCTION__)
4392MSTL_MACRO_RANGE_INT(INITIALIZE_BASIC_FUNCTION__)
4393
4394#undef INITIALIZE_BASIC_FUNCTION__
4395 // TypeInitializeFunction
4397
4399#endif // MSTL_CORE_TYPEINFO_TYPE_TRAITS_HPP__
检查类型From是否可以转换为类型To
typename add_volatile< T >::type add_volatile_t
add_volatile的便捷别名
MSTL_NODISCARD constexpr add_const_t< T > & as_const(T &val) noexcept
将值转换为const引用
typename add_pointer< T >::type add_pointer_t
add_pointer的便捷别名
typename add_const< T >::type add_const_t
add_const的便捷别名
typename add_cv< T >::type add_cv_t
add_cv的类型别名
typename add_reference< T >::lvalue add_lvalue_reference_t
add_lvalue_reference的便捷别名
typename add_reference< T >::rvalue add_rvalue_reference_t
add_rvalue_reference的便捷别名
typename aligned_union< Len, Types... >::type aligned_union_t
aligned_union的便捷别名
typename aligned_storage< Len, Align >::type aligned_storage_t
aligned_storage的便捷别名
MSTL_NODISCARD constexpr remove_reference_t< T > && move(T &&x) noexcept
无条件转换为右值引用
MSTL_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
MSTL_NODISCARD constexpr conditional_t<!is_nothrow_move_constructible< T >::value &&is_copy_constructible< T >::value, const T &, T && > move_if_noexcept(T &x) noexcept
在安全的情况下执行移动操作
typename unpackage< T >::type unpackage_t
unpackage的便捷别名
unpackage_t< remove_cvref_t< T > > unpack_remove_cvref_t
同时解包并移除cv和引用限定符
typename package< T >::type package_t
package的便捷别名
typename underlying_type< T >::type underlying_type_t
underlying_type的便捷别名
is_convertible< FromElement(*)[], ToElement(*)[]> is_array_convertible
判断数组元素类型FromElement是否可以转换为ToElement
unsigned char byte_t
字节类型,定义为无符号字符
type_identity_t< T > declcopy(type_identity_t< T >) noexcept
获取类型的副本,仅用于非求值上下文
add_rvalue_reference_t< T > declval() noexcept
获取类型的右值引用,仅用于非求值上下文
void declvoid(type_identity_t< T >) noexcept
将类型映射为void,仅用于非求值上下文
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_INNER__
结束inner命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
int64_t ptrdiff_t
指针差类型
typename remove_all_extents< T >::type remove_all_extents_t
remove_all_extents的便捷别名
copy_ref_t< From, copy_cv_t< From, To > > copy_cvref_t
同时复制cv和引用限定符
typename remove_pointer< From >::template bind_pointer_t< To > copy_pointer_t
复制指针限定符
typename remove_function_qualifiers< T >::type remove_function_qualifiers_t
remove_function_qualifiers的便捷别名
typename remove_cvref< T >::type remove_cvref_t
remove_cvref的便捷别名
typename remove_cv< From >::template bind_cv_t< To > copy_cv_t
复制cv限定符
typename remove_volatile< T >::type remove_volatile_t
remove_volatile的便捷别名
typename remove_reference< T >::type remove_reference_t
remove_reference的便捷别名
typename remove_const< T >::type remove_const_t
remove_const的便捷别名
typename remove_pointer< T >::type remove_pointer_t
remove_pointer的便捷别名
typename remove_cv< T >::type remove_cv_t
remove_cv的便捷别名
typename remove_reference< From >::template bind_ref_t< To > copy_ref_t
复制引用限定符
typename remove_extent< T >::type remove_extent_t
remove_extent的便捷别名
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
typename make_integer< Size, IsSigned >::type make_integer_t
make_integer的便捷别名
typename make_unsigned< T >::type make_unsigned_t
make_unsigned的便捷别名
typename make_signed< T >::type make_signed_t
make_signed的便捷别名
void swap()=delete
删除无参数的swap重载
MSTL_CONSTEXPR14 T exchange(T &val, U &&new_val) noexcept(conjunction< is_nothrow_move_constructible< T >, is_nothrow_assignable< T &, U > >::value)
将新值赋给对象并返回旧值
typename get_first_para< Types... >::type get_first_para_t
get_first_para的便捷别名
typename get_ptr_difference< T >::type get_ptr_difference_t
get_ptr_difference的便捷别名
typename replace_first_para< T, U >::type replace_first_para_t
replace_first_para的便捷别名
typename get_first_temp_para< Tmp >::type get_first_temp_para_t
get_first_temp_para的便捷别名
typename get_rebind_type< T, U >::type get_rebind_type_t
get_rebind_type的便捷别名
typename common_type< Types... >::type common_type_t
common_type的便捷别名
typename decay< T >::type decay_t
decay的便捷别名
typename detected_or< Default, Op, Args... >::type detected_or_t
detected_or的便捷别名,返回检测到的类型或默认类型
constexpr bool is_specialization_v()
is_specialization的便捷函数模板
_INNER __detector< Default, void, Op, Args... > detected_or
检测Op<Args...>是否有效,如果无效则使用Default类型
decltype(true ? _MSTL declval< T1 >() :_MSTL declval< T2 >()) common_ternary_operator_t
三目运算符的公共类型推导
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) end(Container &cont) noexcept(noexcept(cont.end()))
获取容器的结束迭代器
constexpr T initialize() noexcept(is_nothrow_default_constructible< T >::value)
返回类型T的默认初始化值
integral_constant< uint64_t, Value > uint64_constant
64位无符号整数常量包装器
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
integral_constant< uint32_t, Value > uint32_constant
32位无符号整数常量包装器
bool_constant< true > true_type
表示true的类型
void void_t
将任意类型映射为void
typename type_identity< T >::type type_identity_t
type_identity的便捷别名
bool_constant< false > false_type
表示false的类型
integral_constant< bool, Value > bool_constant
布尔常量包装器
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
添加const限定符
同时添加const和volatile限定符
添加指针限定符
添加引用限定符
添加volatile限定符
实际的对齐存储类型
byte_t data[Len]
原始存储数据
创建指定大小和对齐要求的存储类型
实际的对齐存储类型
byte_t data[storage_size]
原始存储数据
创建可以容纳多种类型的对齐存储类型
static constexpr bool is_storable() noexcept
检查指定类型是否可以安全存储在aligned_union中
static constexpr size_t size_value
存储的实际大小
static constexpr size_t alignment_value
存储的对齐要求
查询类型的对齐要求
查找多个类型的公共类型
条件选择类型
类型集合的逻辑与操作
模拟函数参数传递中的类型退化
类型集合的逻辑或操作
条件启用模板
查询数组指定维度的大小
提取参数列表的第一个类型参数
提取模板的第一个类型参数
获取指针的差值类型
获取指针的重新绑定类型
判断类型是否具有base成员函数
判断分配器是否具有construct成员函数
判断类型是否具有唯一的对象表示
判断类型是否具有虚析构函数
整数常量包装器
integral_constant< T, Value > type
自身类型
MSTL_NODISCARD constexpr value_type operator()() const noexcept
函数调用运算符,用于获取值
判断类型是否支持通过ADL查找的swap
判断类型是否为抽象类型
判断类型是否为聚合类型
判断类型是否可以进行内存分配
判断类型是否为分配器
判断类型是否在类型集合中
判断类型是否为算术类型
判断类型是否为数组类型
判断类型是否可以使用指定类型的值进行赋值
判断Base是否是Derived的基类
判断类型是否为布尔类型
判断类型是否为有界数组
判断类型是否为字符类型
判断类型是否为类类型
判断类型是否为复合类型
判断类型是否被const限定
判断类型是否可以使用指定参数构造
判断类型From是否可以隐式转换为类型To
判断类型是否可复制赋值
判断类型是否可复制构造
判断类型是否为C风格字符串类型
判断类型是否可以递减
判断类型是否可默认构造
判断类型是否可析构
判断类型是否为空类型
判断类型是否为枚举类型
判断类型是否被final限定
判断类型是否为浮点数类型
判断类型是否为函数类型
判断类型是否为基本类型
判断类型是否可隐式默认构造
判断类型是否可以递增
判断类型是否为类整数类型
判断类型是否为整数类型
判断类型是否可迭代
判断类型是否是位置不变的
判断类型是否为左值引用
判断类型是否类似映射
判断类型是否为成员函数指针
判断类型是否为成员对象指针
判断类型是否为成员指针
判断类型是否可移动赋值
判断类型是否可移动构造
判断迭代器的箭头运算符是否不会抛出异常
判断类型是否可以使用指定类型的值进行无异常赋值
判断类型是否可以使用指定参数无异常构造
判断类型From是否可以无异常地转换为类型To
判断类型是否可无异常复制赋值
判断类型是否可无异常复制构造
判断类型是否可无异常默认构造
判断类型是否可无异常析构
判断类型是否可无异常移动赋值
判断类型是否可无异常移动构造
判断是否可以无异常地从T1交换到T2
判断两个类型是否可以无异常地互相交换
判断类型是否可以与自身无异常交换
判断类型是否为nullptr_t
判断类型是否为对象类型
判断类型是否被包装
判断类型是否为POD类型
判断类型是否为指针类型
判断类型是否为多态类型
判断类型是否为引用类型
判断类型是否为右值引用
判断两个类型是否相同
判断类型是否为标量类型
判断类型是否为有符号类型
判断类型T是否为模板Template的特化
判断类型是否为标准字符类型
判断类型是否为标准整数类型
判断类型是否符合标准布局
判断是否可以调用swap从T1交换到T2
判断两个类型是否可以互相交换
判断类型是否可以与自身交换
判断类型是否为平凡类型
判断类型是否可以使用指定类型的值进行平凡赋值
判断类型是否可以使用指定参数平凡构造
判断类型是否可平凡复制赋值
判断类型是否可平凡复制构造
判断类型是否为平凡可复制类型
判断类型是否可平凡默认构造
判断类型是否可平凡析构
判断类型是否可平凡移动赋值
判断类型是否可平凡移动构造
判断类型是否可以平凡交换
判断类型是否为无界数组
判断类型是否为联合类型
判断类型是否被解包
判断类型是否为无符号类型
判断类型是否为void
判断类型是否被volatile限定
根据大小和符号创建整数类型
将类整数类型转换为对应的有符号类型
将类整数类型转换为对应的无符号类型
获取值列表中的最大值
逻辑非包装器
类型包装器模板
查询数组的维度数
移除数组的所有维度
移除const限定符
移除const和volatile限定符
wrapper bind_cv_t
将原类型的cv限定符应用到其他类型
同时移除cv和引用限定符的类型包装
移除数组的最外层维度
移除函数类型的限定符
移除指针限定符
wrapper bind_pointer_t
将原类型的指针限定符应用到其他类型
移除引用限定符
wrapper bind_ref_t
将原类型的引用限定符应用到其他类型
移除volatile限定符
替换模板的第一个类型参数
类型标识包装器
获取枚举类型的底层整数类型
类型解包器模板
MSTL基本类型别名