From ffc0c289c0d4823d82297a00484f71dfe248be2a Mon Sep 17 00:00:00 2001 From: Victor Chernyakin Date: Fri, 23 May 2025 16:18:19 -0700 Subject: [PATCH 01/26] Mark templates users shouldn't specialize with _NO_SPECIALIZATIONS --- .clang-format | 4 +- stl/inc/__msvc_chrono.hpp | 6 +- stl/inc/__msvc_iter_core.hpp | 2 +- stl/inc/__msvc_ranges_tuple_formatter.hpp | 2 +- stl/inc/compare | 2 +- stl/inc/coroutine | 2 +- stl/inc/functional | 4 +- stl/inc/generator | 2 +- stl/inc/initializer_list | 2 +- stl/inc/ranges | 2 +- stl/inc/ratio | 12 +- stl/inc/type_traits | 420 ++++++++++++---------- stl/inc/utility | 4 +- stl/inc/variant | 5 +- stl/inc/xmemory | 5 +- stl/inc/xtr1common | 41 +-- stl/inc/xutility | 4 +- stl/inc/yvals_core.h | 39 +- 18 files changed, 312 insertions(+), 246 deletions(-) diff --git a/.clang-format b/.clang-format index 035d0c1f84b..249be9c1781 100644 --- a/.clang-format +++ b/.clang-format @@ -103,8 +103,8 @@ AllowShortFunctionsOnASingleLine: Empty # AllowShortLoopsOnASingleLine: false # AlwaysBreakAfterDefinitionReturnType: None # AlwaysBreakBeforeMultilineStrings: false -# AttributeMacros: -# - __capability +AttributeMacros: + - _NO_SPECIALIZATIONS # BinPackArguments: true # BinPackParameters: true # BitFieldColonSpacing: Both diff --git a/stl/inc/__msvc_chrono.hpp b/stl/inc/__msvc_chrono.hpp index 8a89e462473..28bfb9e2afd 100644 --- a/stl/inc/__msvc_chrono.hpp +++ b/stl/inc/__msvc_chrono.hpp @@ -31,7 +31,7 @@ namespace chrono { struct treat_as_floating_point : is_floating_point<_Rep> {}; // tests for floating-point type _EXPORT_STD template - constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value; + _NO_SPECIALIZATIONS constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value; _EXPORT_STD template struct duration_values { // gets arithmetic properties of a type @@ -53,7 +53,7 @@ namespace chrono { #if _HAS_CXX20 _EXPORT_STD template - constexpr bool is_clock_v = requires { + _NO_SPECIALIZATIONS constexpr bool is_clock_v = requires { typename _Clock::rep; typename _Clock::period; typename _Clock::duration; @@ -62,7 +62,7 @@ namespace chrono { _Clock::now(); }; _EXPORT_STD template - struct is_clock : bool_constant> {}; + struct _NO_SPECIALIZATIONS is_clock : bool_constant> {}; template constexpr bool _Is_clock_v = is_clock_v<_Clock>; diff --git a/stl/inc/__msvc_iter_core.hpp b/stl/inc/__msvc_iter_core.hpp index e77903479a1..912a78eba89 100644 --- a/stl/inc/__msvc_iter_core.hpp +++ b/stl/inc/__msvc_iter_core.hpp @@ -34,7 +34,7 @@ _EXPORT_STD template struct uses_allocator : _Has_allocator_type<_Ty, _Alloc>::type {}; _EXPORT_STD template -constexpr bool uses_allocator_v = uses_allocator<_Ty, _Alloc>::value; +_NO_SPECIALIZATIONS constexpr bool uses_allocator_v = uses_allocator<_Ty, _Alloc>::value; // from _EXPORT_STD struct input_iterator_tag {}; diff --git a/stl/inc/__msvc_ranges_tuple_formatter.hpp b/stl/inc/__msvc_ranges_tuple_formatter.hpp index 677997e3abb..39deeadd4c8 100644 --- a/stl/inc/__msvc_ranges_tuple_formatter.hpp +++ b/stl/inc/__msvc_ranges_tuple_formatter.hpp @@ -229,7 +229,7 @@ struct _Format_handler; _FMT_P2286_END _EXPORT_STD template -class basic_format_arg { +class _NO_SPECIALIZATIONS basic_format_arg { public: using _CharType = _Context::char_type; diff --git a/stl/inc/compare b/stl/inc/compare index 37f9f7f40a2..3a3c3041e48 100644 --- a/stl/inc/compare +++ b/stl/inc/compare @@ -321,7 +321,7 @@ using compare_three_way_result_t = decltype(_STD declval&>() <=> _STD declval&>()); _EXPORT_STD template -struct compare_three_way_result {}; +struct _NO_SPECIALIZATIONS compare_three_way_result {}; template requires requires { typename compare_three_way_result_t<_Ty1, _Ty2>; } diff --git a/stl/inc/coroutine b/stl/inc/coroutine index 94933610fbe..141748644c7 100644 --- a/stl/inc/coroutine +++ b/stl/inc/coroutine @@ -46,7 +46,7 @@ _EXPORT_STD template struct coroutine_traits : _Coroutine_traits<_Ret> {}; _EXPORT_STD template -struct coroutine_handle; +struct _NO_SPECIALIZATIONS coroutine_handle; template <> struct coroutine_handle { diff --git a/stl/inc/functional b/stl/inc/functional index 21c0e80ccc7..4fdde18c95b 100644 --- a/stl/inc/functional +++ b/stl/inc/functional @@ -2004,7 +2004,7 @@ template struct is_placeholder : is_placeholder<_Tx>::type {}; // ignore cv-qualifiers _EXPORT_STD template -constexpr int is_placeholder_v = is_placeholder<_Ty>::value; +_NO_SPECIALIZATIONS constexpr int is_placeholder_v = is_placeholder<_Ty>::value; template class _Binder; @@ -2025,7 +2025,7 @@ template struct is_bind_expression : is_bind_expression<_Tx>::type {}; // ignore cv-qualifiers _EXPORT_STD template -constexpr bool is_bind_expression_v = is_bind_expression<_Ty>::value; +_NO_SPECIALIZATIONS constexpr bool is_bind_expression_v = is_bind_expression<_Ty>::value; template , reference_wrapper>, bool = is_bind_expression_v<_Cv_TiD>, int = is_placeholder_v<_Cv_TiD>> diff --git a/stl/inc/generator b/stl/inc/generator index fbc69d90e11..f583aa13ec9 100644 --- a/stl/inc/generator +++ b/stl/inc/generator @@ -518,7 +518,7 @@ namespace _Gen_detail { } // namespace _Gen_detail _EXPORT_STD template -class generator : public _RANGES view_interface> { +class _NO_SPECIALIZATIONS generator : public _RANGES view_interface> { private: static_assert(_Gen_detail::_Valid_allocator<_Alloc>, "generator allocators must use raw pointers (N4988 [coro.generator.class]/1.1)"); diff --git a/stl/inc/initializer_list b/stl/inc/initializer_list index 8ef3c5e90cf..32b9345f98a 100644 --- a/stl/inc/initializer_list +++ b/stl/inc/initializer_list @@ -18,7 +18,7 @@ _STL_DISABLE_CLANG_WARNINGS _STD_BEGIN _EXPORT_STD template -class initializer_list { +class _NO_SPECIALIZATIONS initializer_list { public: using value_type = _Elem; using reference = const _Elem&; diff --git a/stl/inc/ranges b/stl/inc/ranges index 0033e663051..97d4b2e7a6c 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -546,7 +546,7 @@ namespace ranges { #if _HAS_CXX23 _EXPORT_STD template requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> - class range_adaptor_closure : public _Pipe::_Base<_Derived> {}; + class _NO_SPECIALIZATIONS range_adaptor_closure : public _Pipe::_Base<_Derived> {}; #endif // _HAS_CXX23 _EXPORT_STD template diff --git a/stl/inc/ratio b/stl/inc/ratio index ea8ecdf7495..59ac5806b50 100644 --- a/stl/inc/ratio +++ b/stl/inc/ratio @@ -167,7 +167,7 @@ struct ratio_equal : bool_constant<_Rx1::num == _Rx2::num && _Rx1::den == _Rx2:: }; _EXPORT_STD template -constexpr bool ratio_equal_v = ratio_equal<_Rx1, _Rx2>::value; +_NO_SPECIALIZATIONS constexpr bool ratio_equal_v = ratio_equal<_Rx1, _Rx2>::value; _EXPORT_STD template struct ratio_not_equal : bool_constant> { // tests if ratio != ratio @@ -175,7 +175,7 @@ struct ratio_not_equal : bool_constant> { // tests if }; _EXPORT_STD template -constexpr bool ratio_not_equal_v = ratio_not_equal<_Rx1, _Rx2>::value; +_NO_SPECIALIZATIONS constexpr bool ratio_not_equal_v = ratio_not_equal<_Rx1, _Rx2>::value; struct _Big_uint128 { uint64_t _Upper; @@ -231,7 +231,7 @@ struct ratio_less : bool_constant<_Ratio_less(_Rx1::num, _Rx1::den, _Rx2::num, _ }; _EXPORT_STD template -constexpr bool ratio_less_v = ratio_less<_Rx1, _Rx2>::value; +_NO_SPECIALIZATIONS constexpr bool ratio_less_v = ratio_less<_Rx1, _Rx2>::value; _EXPORT_STD template struct ratio_less_equal : bool_constant> { // tests if ratio <= ratio @@ -240,7 +240,7 @@ struct ratio_less_equal : bool_constant> { // tests if }; _EXPORT_STD template -constexpr bool ratio_less_equal_v = ratio_less_equal<_Rx1, _Rx2>::value; +_NO_SPECIALIZATIONS constexpr bool ratio_less_equal_v = ratio_less_equal<_Rx1, _Rx2>::value; _EXPORT_STD template struct ratio_greater : ratio_less<_Rx2, _Rx1>::type { // tests if ratio > ratio @@ -248,7 +248,7 @@ struct ratio_greater : ratio_less<_Rx2, _Rx1>::type { // tests if ratio > ratio }; _EXPORT_STD template -constexpr bool ratio_greater_v = ratio_greater<_Rx1, _Rx2>::value; +_NO_SPECIALIZATIONS constexpr bool ratio_greater_v = ratio_greater<_Rx1, _Rx2>::value; _EXPORT_STD template struct ratio_greater_equal : bool_constant> { // tests if ratio >= ratio @@ -257,7 +257,7 @@ struct ratio_greater_equal : bool_constant> { // tests }; _EXPORT_STD template -constexpr bool ratio_greater_equal_v = ratio_greater_equal<_Rx1, _Rx2>::value; +_NO_SPECIALIZATIONS constexpr bool ratio_greater_equal_v = ratio_greater_equal<_Rx1, _Rx2>::value; _EXPORT_STD using atto = ratio<1, 1000000000000000000LL>; _EXPORT_STD using femto = ratio<1, 1000000000000000LL>; diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 9c8e1d740dd..574bda52f05 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -41,7 +41,7 @@ struct _Conjunction { // the first trait is true, }; _EXPORT_STD template -struct conjunction : true_type {}; // If _Traits is empty, true_type +struct _NO_SPECIALIZATIONS conjunction : true_type {}; // If _Traits is empty, true_type template struct conjunction<_First, _Rest...> : _Conjunction(_First::value), _First, _Rest...>::type { @@ -49,19 +49,21 @@ struct conjunction<_First, _Rest...> : _Conjunction(_First::va }; _EXPORT_STD template -constexpr bool conjunction_v = conjunction<_Traits...>::value; +_NO_SPECIALIZATIONS constexpr bool conjunction_v = conjunction<_Traits...>::value; _EXPORT_STD template -struct negation : bool_constant(_Trait::value)> {}; // The negated result of _Trait +struct _NO_SPECIALIZATIONS negation : bool_constant(_Trait::value)> { + // The negated result of _Trait +}; _EXPORT_STD template -constexpr bool negation_v = negation<_Trait>::value; +_NO_SPECIALIZATIONS constexpr bool negation_v = negation<_Trait>::value; _EXPORT_STD template -constexpr bool is_void_v = is_same_v, void>; +_NO_SPECIALIZATIONS constexpr bool is_void_v = is_same_v, void>; _EXPORT_STD template -struct is_void : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_void : bool_constant> {}; _EXPORT_STD template using void_t = void; @@ -75,7 +77,7 @@ using _Identity_t _MSVC_KNOWN_SEMANTICS = typename _Identity<_Ty>::type; // Type modifiers _EXPORT_STD template -struct add_const { // add top-level const qualifier +struct _NO_SPECIALIZATIONS add_const { // add top-level const qualifier using type = const _Ty; }; @@ -83,7 +85,7 @@ _EXPORT_STD template using add_const_t = typename add_const<_Ty>::type; _EXPORT_STD template -struct add_volatile { // add top-level volatile qualifier +struct _NO_SPECIALIZATIONS add_volatile { // add top-level volatile qualifier using type = volatile _Ty; }; @@ -91,7 +93,7 @@ _EXPORT_STD template using add_volatile_t = typename add_volatile<_Ty>::type; _EXPORT_STD template -struct add_cv { // add top-level const and volatile qualifiers +struct _NO_SPECIALIZATIONS add_cv { // add top-level const and volatile qualifiers using type = const volatile _Ty; }; @@ -111,7 +113,7 @@ struct _Add_reference<_Ty, void_t<_Ty&>> { // (referenceable type) }; _EXPORT_STD template -struct add_lvalue_reference { +struct _NO_SPECIALIZATIONS add_lvalue_reference { using type = typename _Add_reference<_Ty>::_Lvalue; }; @@ -119,7 +121,7 @@ _EXPORT_STD template using add_lvalue_reference_t = typename _Add_reference<_Ty>::_Lvalue; _EXPORT_STD template -struct add_rvalue_reference { +struct _NO_SPECIALIZATIONS add_rvalue_reference { using type = typename _Add_reference<_Ty>::_Rvalue; }; @@ -132,7 +134,7 @@ add_rvalue_reference_t<_Ty> declval() noexcept { } _EXPORT_STD template -struct remove_extent { // remove array extent +struct _NO_SPECIALIZATIONS remove_extent { // remove array extent using type = _Ty; }; @@ -150,7 +152,7 @@ _EXPORT_STD template using remove_extent_t = typename remove_extent<_Ty>::type; _EXPORT_STD template -struct remove_all_extents { // remove all array extents +struct _NO_SPECIALIZATIONS remove_all_extents { // remove all array extents using type = _Ty; }; @@ -168,7 +170,7 @@ _EXPORT_STD template using remove_all_extents_t = typename remove_all_extents<_Ty>::type; _EXPORT_STD template -struct remove_pointer { +struct _NO_SPECIALIZATIONS remove_pointer { using type = _Ty; }; @@ -206,7 +208,7 @@ struct _Add_pointer<_Ty, void_t*>> { // (pointer type ca }; _EXPORT_STD template -struct add_pointer { +struct _NO_SPECIALIZATIONS add_pointer { using type = typename _Add_pointer<_Ty>::type; }; @@ -214,7 +216,7 @@ _EXPORT_STD template using add_pointer_t = typename _Add_pointer<_Ty>::type; _EXPORT_STD template -constexpr bool is_array_v = false; // determine whether type argument is an array +_NO_SPECIALIZATIONS constexpr bool is_array_v = false; // determine whether type argument is an array template constexpr bool is_array_v<_Ty[_Nx]> = true; @@ -223,48 +225,50 @@ template constexpr bool is_array_v<_Ty[]> = true; _EXPORT_STD template -struct is_array : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_array : bool_constant> {}; #if _HAS_CXX20 _EXPORT_STD template -constexpr bool is_bounded_array_v = false; +_NO_SPECIALIZATIONS constexpr bool is_bounded_array_v = false; template constexpr bool is_bounded_array_v<_Ty[_Nx]> = true; _EXPORT_STD template -struct is_bounded_array : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_bounded_array : bool_constant> {}; _EXPORT_STD template -constexpr bool is_unbounded_array_v = false; +_NO_SPECIALIZATIONS constexpr bool is_unbounded_array_v = false; template constexpr bool is_unbounded_array_v<_Ty[]> = true; _EXPORT_STD template -struct is_unbounded_array : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_unbounded_array : bool_constant> {}; #endif // _HAS_CXX20 _EXPORT_STD template -constexpr bool is_lvalue_reference_v = false; // determine whether type argument is an lvalue reference +_NO_SPECIALIZATIONS constexpr bool is_lvalue_reference_v = + false; // determine whether type argument is an lvalue reference template constexpr bool is_lvalue_reference_v<_Ty&> = true; _EXPORT_STD template -struct is_lvalue_reference : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_lvalue_reference : bool_constant> {}; _EXPORT_STD template -constexpr bool is_rvalue_reference_v = false; // determine whether type argument is an rvalue reference +_NO_SPECIALIZATIONS constexpr bool is_rvalue_reference_v = + false; // determine whether type argument is an rvalue reference template constexpr bool is_rvalue_reference_v<_Ty&&> = true; _EXPORT_STD template -struct is_rvalue_reference : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_rvalue_reference : bool_constant> {}; _EXPORT_STD template -constexpr bool is_reference_v = false; // determine whether type argument is a reference +_NO_SPECIALIZATIONS constexpr bool is_reference_v = false; // determine whether type argument is a reference template constexpr bool is_reference_v<_Ty&> = true; @@ -273,10 +277,10 @@ template constexpr bool is_reference_v<_Ty&&> = true; _EXPORT_STD template -struct is_reference : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_reference : bool_constant> {}; _EXPORT_STD template -constexpr bool is_pointer_v = false; // determine whether _Ty is a pointer +_NO_SPECIALIZATIONS constexpr bool is_pointer_v = false; // determine whether _Ty is a pointer template constexpr bool is_pointer_v<_Ty*> = true; @@ -291,69 +295,73 @@ template constexpr bool is_pointer_v<_Ty* const volatile> = true; _EXPORT_STD template -struct is_pointer : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_pointer : bool_constant> {}; _EXPORT_STD template -constexpr bool is_null_pointer_v = +_NO_SPECIALIZATIONS constexpr bool is_null_pointer_v = is_same_v, nullptr_t>; // determine whether _Ty is cv-qualified nullptr_t _EXPORT_STD template -struct is_null_pointer : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_null_pointer : bool_constant> {}; _EXPORT_STD template -struct is_union : bool_constant<__is_union(_Ty)> {}; // determine whether _Ty is a union +struct _NO_SPECIALIZATIONS is_union : bool_constant<__is_union(_Ty)> {}; // determine whether _Ty is a union _EXPORT_STD template -constexpr bool is_union_v = __is_union(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_union_v = __is_union(_Ty); _EXPORT_STD template -struct is_class : bool_constant<__is_class(_Ty)> {}; // determine whether _Ty is a class +struct _NO_SPECIALIZATIONS is_class : bool_constant<__is_class(_Ty)> {}; // determine whether _Ty is a class _EXPORT_STD template -constexpr bool is_class_v = __is_class(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_class_v = __is_class(_Ty); _EXPORT_STD template -constexpr bool is_fundamental_v = is_arithmetic_v<_Ty> || is_void_v<_Ty> || is_null_pointer_v<_Ty>; +_NO_SPECIALIZATIONS constexpr bool is_fundamental_v = is_arithmetic_v<_Ty> || is_void_v<_Ty> || is_null_pointer_v<_Ty>; _EXPORT_STD template -struct is_fundamental : bool_constant> {}; // determine whether _Ty is a fundamental type +struct _NO_SPECIALIZATIONS is_fundamental : bool_constant> { + // determine whether _Ty is a fundamental type +}; _EXPORT_STD template -struct is_convertible : bool_constant<__is_convertible_to(_From, _To)> { +struct _NO_SPECIALIZATIONS is_convertible : bool_constant<__is_convertible_to(_From, _To)> { // determine whether _From is convertible to _To }; _EXPORT_STD template -constexpr bool is_convertible_v = __is_convertible_to(_From, _To); +_NO_SPECIALIZATIONS constexpr bool is_convertible_v = __is_convertible_to(_From, _To); _EXPORT_STD template -struct is_enum : bool_constant<__is_enum(_Ty)> {}; // determine whether _Ty is an enumerated type +struct _NO_SPECIALIZATIONS is_enum : bool_constant<__is_enum(_Ty)> {}; // determine whether _Ty is an enumerated type _EXPORT_STD template -constexpr bool is_enum_v = __is_enum(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_enum_v = __is_enum(_Ty); #if _HAS_CXX23 #if defined(__clang__) && !defined(__EDG__) \ && __clang_major__ >= 16 // TRANSITION, DevCom-10870354 (MSVC, EDG), VSO-2397560 (RWC relying on ancient Clang) _EXPORT_STD template -constexpr bool is_scoped_enum_v = __is_scoped_enum(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_scoped_enum_v = __is_scoped_enum(_Ty); _EXPORT_STD template -struct is_scoped_enum : bool_constant<__is_scoped_enum(_Ty)> {}; +struct _NO_SPECIALIZATIONS is_scoped_enum : bool_constant<__is_scoped_enum(_Ty)> {}; #else // ^^^ no workaround / workaround vvv _EXPORT_STD template -constexpr bool is_scoped_enum_v = conjunction_v, negation>>; +_NO_SPECIALIZATIONS constexpr bool is_scoped_enum_v = conjunction_v, negation>>; _EXPORT_STD template -struct is_scoped_enum : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_scoped_enum : bool_constant> {}; #endif // ^^^ workaround ^^^ #endif // _HAS_CXX23 _EXPORT_STD template -struct is_compound : bool_constant> {}; // determine whether _Ty is a compound type +struct _NO_SPECIALIZATIONS is_compound : bool_constant> { + // determine whether _Ty is a compound type +}; _EXPORT_STD template -constexpr bool is_compound_v = !is_fundamental_v<_Ty>; +_NO_SPECIALIZATIONS constexpr bool is_compound_v = !is_fundamental_v<_Ty>; #define _EMIT_CDECL(FUNC, OPT1, OPT2, OPT3) FUNC(__cdecl, OPT1, OPT2, OPT3) @@ -541,46 +549,46 @@ _NON_MEMBER_CALL(_IS_MEMFUNPTR_EXPLICIT_THIS_GUIDES, , , noexcept) #ifdef __clang__ _EXPORT_STD template -constexpr bool is_member_function_pointer_v = __is_member_function_pointer(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_member_function_pointer_v = __is_member_function_pointer(_Ty); #else // ^^^ Clang / Other vvv _EXPORT_STD template -constexpr bool is_member_function_pointer_v = _Is_memfunptr>::_Bool_type::value; +_NO_SPECIALIZATIONS constexpr bool is_member_function_pointer_v = _Is_memfunptr>::_Bool_type::value; #endif // ^^^ Other ^^^ _EXPORT_STD template -struct is_member_function_pointer : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_member_function_pointer : bool_constant> {}; _EXPORT_STD template -constexpr bool is_const_v = false; // determine whether type argument is const qualified +_NO_SPECIALIZATIONS constexpr bool is_const_v = false; // determine whether type argument is const qualified template constexpr bool is_const_v = true; _EXPORT_STD template -struct is_const : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_const : bool_constant> {}; _EXPORT_STD template -constexpr bool is_volatile_v = false; // determine whether type argument is volatile qualified +_NO_SPECIALIZATIONS constexpr bool is_volatile_v = false; // determine whether type argument is volatile qualified template constexpr bool is_volatile_v = true; _EXPORT_STD template -struct is_volatile : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_volatile : bool_constant> {}; _EXPORT_STD template -constexpr bool is_function_v = // only function types and reference types can't be const qualified +_NO_SPECIALIZATIONS constexpr bool is_function_v = // only function types and reference types can't be const qualified !is_const_v && !is_reference_v<_Ty>; _EXPORT_STD template -struct is_function : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_function : bool_constant> {}; _EXPORT_STD template -constexpr bool is_object_v = // only function types and reference types can't be const qualified +_NO_SPECIALIZATIONS constexpr bool is_object_v = // only function types and reference types can't be const qualified is_const_v && !is_void_v<_Ty>; _EXPORT_STD template -struct is_object : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_object : bool_constant> {}; template struct _Is_member_object_pointer { @@ -595,151 +603,163 @@ struct _Is_member_object_pointer<_Ty1 _Ty2::*> { #ifdef __clang__ _EXPORT_STD template -constexpr bool is_member_object_pointer_v = __is_member_object_pointer(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_member_object_pointer_v = __is_member_object_pointer(_Ty); #else // ^^^ Clang / Other vvv _EXPORT_STD template -constexpr bool is_member_object_pointer_v = _Is_member_object_pointer>::value; +_NO_SPECIALIZATIONS constexpr bool is_member_object_pointer_v = _Is_member_object_pointer>::value; #endif // ^^^ Other ^^^ _EXPORT_STD template -struct is_member_object_pointer : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_member_object_pointer : bool_constant> {}; #ifdef __clang__ _EXPORT_STD template -constexpr bool is_member_pointer_v = __is_member_pointer(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_member_pointer_v = __is_member_pointer(_Ty); #else // ^^^ Clang / Other vvv _EXPORT_STD template -constexpr bool is_member_pointer_v = is_member_object_pointer_v<_Ty> || is_member_function_pointer_v<_Ty>; +_NO_SPECIALIZATIONS constexpr bool is_member_pointer_v = + is_member_object_pointer_v<_Ty> || is_member_function_pointer_v<_Ty>; #endif // ^^^ Other ^^^ _EXPORT_STD template -struct is_member_pointer : bool_constant> {}; // determine whether _Ty is a pointer to member +struct _NO_SPECIALIZATIONS is_member_pointer : bool_constant> { + // determine whether _Ty is a pointer to member +}; _EXPORT_STD template -constexpr bool is_scalar_v = // determine whether _Ty is a scalar type +_NO_SPECIALIZATIONS constexpr bool is_scalar_v = // determine whether _Ty is a scalar type is_arithmetic_v<_Ty> || is_enum_v<_Ty> || is_pointer_v<_Ty> || is_member_pointer_v<_Ty> || is_null_pointer_v<_Ty>; _EXPORT_STD template -struct is_scalar : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_scalar : bool_constant> {}; _EXPORT_STD template -struct _CXX20_DEPRECATE_IS_POD is_pod : bool_constant<__is_pod(_Ty)> {}; // determine whether _Ty is a POD type +struct _CXX20_DEPRECATE_IS_POD _NO_SPECIALIZATIONS is_pod : bool_constant<__is_pod(_Ty)> { + // determine whether _Ty is a POD type +}; _EXPORT_STD template -_CXX20_DEPRECATE_IS_POD constexpr bool is_pod_v = __is_pod(_Ty); +_CXX20_DEPRECATE_IS_POD _NO_SPECIALIZATIONS constexpr bool is_pod_v = __is_pod(_Ty); _EXPORT_STD template -struct is_empty : bool_constant<__is_empty(_Ty)> {}; // determine whether _Ty is an empty class +struct _NO_SPECIALIZATIONS is_empty : bool_constant<__is_empty(_Ty)> {}; // determine whether _Ty is an empty class _EXPORT_STD template -constexpr bool is_empty_v = __is_empty(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_empty_v = __is_empty(_Ty); _EXPORT_STD template -struct is_polymorphic : bool_constant<__is_polymorphic(_Ty)> {}; // determine whether _Ty is a polymorphic type +struct _NO_SPECIALIZATIONS is_polymorphic : bool_constant<__is_polymorphic(_Ty)> { + // determine whether _Ty is a polymorphic type +}; _EXPORT_STD template -constexpr bool is_polymorphic_v = __is_polymorphic(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_polymorphic_v = __is_polymorphic(_Ty); _EXPORT_STD template -struct is_abstract : bool_constant<__is_abstract(_Ty)> {}; // determine whether _Ty is an abstract class +struct _NO_SPECIALIZATIONS is_abstract : bool_constant<__is_abstract(_Ty)> { + // determine whether _Ty is an abstract class +}; _EXPORT_STD template -constexpr bool is_abstract_v = __is_abstract(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_abstract_v = __is_abstract(_Ty); _EXPORT_STD template -struct is_final : bool_constant<__is_final(_Ty)> {}; // determine whether _Ty is a final class +struct _NO_SPECIALIZATIONS is_final : bool_constant<__is_final(_Ty)> {}; // determine whether _Ty is a final class _EXPORT_STD template -constexpr bool is_final_v = __is_final(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_final_v = __is_final(_Ty); _EXPORT_STD template -struct is_standard_layout : bool_constant<__is_standard_layout(_Ty)> {}; // determine whether _Ty is standard layout +struct _NO_SPECIALIZATIONS is_standard_layout : bool_constant<__is_standard_layout(_Ty)> { + // determine whether _Ty is standard layout +}; _EXPORT_STD template -constexpr bool is_standard_layout_v = __is_standard_layout(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_standard_layout_v = __is_standard_layout(_Ty); #if _HAS_DEPRECATED_IS_LITERAL_TYPE _EXPORT_STD template -struct _CXX17_DEPRECATE_IS_LITERAL_TYPE is_literal_type : bool_constant<__is_literal_type(_Ty)> { +struct _CXX17_DEPRECATE_IS_LITERAL_TYPE _NO_SPECIALIZATIONS is_literal_type : bool_constant<__is_literal_type(_Ty)> { // determine whether _Ty is a literal type }; _EXPORT_STD template -_CXX17_DEPRECATE_IS_LITERAL_TYPE constexpr bool is_literal_type_v = __is_literal_type(_Ty); +_CXX17_DEPRECATE_IS_LITERAL_TYPE _NO_SPECIALIZATIONS constexpr bool is_literal_type_v = __is_literal_type(_Ty); #endif // _HAS_DEPRECATED_IS_LITERAL_TYPE _EXPORT_STD template -struct is_trivial : bool_constant<__is_trivial(_Ty)> {}; // determine whether _Ty is a trivial type +struct _NO_SPECIALIZATIONS is_trivial : bool_constant<__is_trivial(_Ty)> {}; // determine whether _Ty is a trivial type _EXPORT_STD template -constexpr bool is_trivial_v = __is_trivial(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_trivial_v = __is_trivial(_Ty); _EXPORT_STD template -struct is_trivially_copyable : bool_constant<__is_trivially_copyable(_Ty)> { +struct _NO_SPECIALIZATIONS is_trivially_copyable : bool_constant<__is_trivially_copyable(_Ty)> { // determine whether _Ty is a trivially copyable type }; _EXPORT_STD template -constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Ty); _EXPORT_STD template -struct has_virtual_destructor : bool_constant<__has_virtual_destructor(_Ty)> { +struct _NO_SPECIALIZATIONS has_virtual_destructor : bool_constant<__has_virtual_destructor(_Ty)> { // determine whether _Ty has a virtual destructor }; _EXPORT_STD template -constexpr bool has_virtual_destructor_v = __has_virtual_destructor(_Ty); +_NO_SPECIALIZATIONS constexpr bool has_virtual_destructor_v = __has_virtual_destructor(_Ty); #if _HAS_CXX17 _EXPORT_STD template -struct has_unique_object_representations : bool_constant<__has_unique_object_representations(_Ty)> { +struct _NO_SPECIALIZATIONS has_unique_object_representations : bool_constant<__has_unique_object_representations(_Ty)> { // determine whether _Ty has unique object representations }; _EXPORT_STD template -constexpr bool has_unique_object_representations_v = __has_unique_object_representations(_Ty); +_NO_SPECIALIZATIONS constexpr bool has_unique_object_representations_v = __has_unique_object_representations(_Ty); #ifdef __EDG__ // TRANSITION, VSO-1690654 template struct _Is_aggregate_impl : bool_constant<__is_aggregate(_Ty)> {}; _EXPORT_STD template -constexpr bool is_aggregate_v = disjunction_v, _Is_aggregate_impl<_Ty>>; +_NO_SPECIALIZATIONS constexpr bool is_aggregate_v = disjunction_v, _Is_aggregate_impl<_Ty>>; _EXPORT_STD template -struct is_aggregate : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_aggregate : bool_constant> {}; #else // ^^^ workaround / no workaround vvv _EXPORT_STD template -struct is_aggregate : bool_constant<__is_aggregate(_Ty)> {}; +struct _NO_SPECIALIZATIONS is_aggregate : bool_constant<__is_aggregate(_Ty)> {}; _EXPORT_STD template -constexpr bool is_aggregate_v = __is_aggregate(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_aggregate_v = __is_aggregate(_Ty); #endif // ^^^ no workaround ^^^ #endif // _HAS_CXX17 _EXPORT_STD template -struct is_constructible : bool_constant<__is_constructible(_Ty, _Args...)> { +struct _NO_SPECIALIZATIONS is_constructible : bool_constant<__is_constructible(_Ty, _Args...)> { // determine whether _Ty can be direct-initialized with _Args... }; _EXPORT_STD template -constexpr bool is_constructible_v = __is_constructible(_Ty, _Args...); +_NO_SPECIALIZATIONS constexpr bool is_constructible_v = __is_constructible(_Ty, _Args...); _EXPORT_STD template -struct is_copy_constructible : bool_constant<__is_constructible(_Ty, add_lvalue_reference_t)> { +struct _NO_SPECIALIZATIONS is_copy_constructible + : bool_constant<__is_constructible(_Ty, add_lvalue_reference_t)> { // determine whether _Ty can be direct-initialized with an lvalue const _Ty }; _EXPORT_STD template -constexpr bool is_copy_constructible_v = __is_constructible(_Ty, add_lvalue_reference_t); +_NO_SPECIALIZATIONS constexpr bool is_copy_constructible_v = __is_constructible(_Ty, add_lvalue_reference_t); _EXPORT_STD template -struct is_default_constructible : bool_constant<__is_constructible(_Ty)> { +struct _NO_SPECIALIZATIONS is_default_constructible : bool_constant<__is_constructible(_Ty)> { // determine whether _Ty can be value-initialized }; _EXPORT_STD template -constexpr bool is_default_constructible_v = __is_constructible(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_default_constructible_v = __is_constructible(_Ty); template struct _Is_implicitly_default_constructible : false_type { @@ -754,18 +774,20 @@ struct _Is_implicitly_default_constructible<_Ty, void_t -struct is_move_constructible : bool_constant<__is_constructible(_Ty, _Ty)> { +struct _NO_SPECIALIZATIONS is_move_constructible : bool_constant<__is_constructible(_Ty, _Ty)> { // determine whether _Ty can be direct-initialized from an rvalue _Ty }; _EXPORT_STD template -constexpr bool is_move_constructible_v = __is_constructible(_Ty, _Ty); +_NO_SPECIALIZATIONS constexpr bool is_move_constructible_v = __is_constructible(_Ty, _Ty); _EXPORT_STD template -struct is_assignable : bool_constant<__is_assignable(_To, _From)> {}; // determine whether _From can be assigned to _To +struct _NO_SPECIALIZATIONS is_assignable : bool_constant<__is_assignable(_To, _From)> { + // determine whether _From can be assigned to _To +}; _EXPORT_STD template -constexpr bool is_assignable_v = __is_assignable(_To, _From); +_NO_SPECIALIZATIONS constexpr bool is_assignable_v = __is_assignable(_To, _From); #if defined(_IS_ASSIGNABLE_NOCHECK_SUPPORTED) && !defined(__CUDACC__) template @@ -776,13 +798,14 @@ using _Is_assignable_no_precondition_check = is_assignable<_To, _From>; #endif // ^^^ intrinsic not supported ^^^ _EXPORT_STD template -struct is_copy_assignable +struct _NO_SPECIALIZATIONS is_copy_assignable : bool_constant<__is_assignable(add_lvalue_reference_t<_Ty>, add_lvalue_reference_t)> { // determine whether an lvalue const _Ty can be assigned to an lvalue _Ty }; _EXPORT_STD template -constexpr bool is_copy_assignable_v = __is_assignable(add_lvalue_reference_t<_Ty>, add_lvalue_reference_t); +_NO_SPECIALIZATIONS constexpr bool is_copy_assignable_v = + __is_assignable(add_lvalue_reference_t<_Ty>, add_lvalue_reference_t); #if defined(_IS_ASSIGNABLE_NOCHECK_SUPPORTED) && !defined(__CUDACC__) template @@ -802,12 +825,12 @@ constexpr bool _Is_copy_assignable_unchecked_v = is_copy_assignable_v<_Ty>; #endif // ^^^ intrinsic not supported ^^^ _EXPORT_STD template -struct is_move_assignable : bool_constant<__is_assignable(add_lvalue_reference_t<_Ty>, _Ty)> { +struct _NO_SPECIALIZATIONS is_move_assignable : bool_constant<__is_assignable(add_lvalue_reference_t<_Ty>, _Ty)> { // determine whether an rvalue _Ty can be assigned to an lvalue _Ty }; _EXPORT_STD template -constexpr bool is_move_assignable_v = __is_assignable(add_lvalue_reference_t<_Ty>, _Ty); +_NO_SPECIALIZATIONS constexpr bool is_move_assignable_v = __is_assignable(add_lvalue_reference_t<_Ty>, _Ty); #if defined(_IS_ASSIGNABLE_NOCHECK_SUPPORTED) && !defined(__CUDACC__) template @@ -826,148 +849,154 @@ constexpr bool _Is_move_assignable_unchecked_v = is_move_assignable_v<_Ty>; #endif // ^^^ intrinsic not supported ^^^ _EXPORT_STD template -struct is_destructible : bool_constant<__is_destructible(_Ty)> { +struct _NO_SPECIALIZATIONS is_destructible : bool_constant<__is_destructible(_Ty)> { // true iff remove_all_extents_t<_Ty> is a reference type, or can be explicitly destroyed }; _EXPORT_STD template -constexpr bool is_destructible_v = __is_destructible(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_destructible_v = __is_destructible(_Ty); _EXPORT_STD template -struct is_trivially_constructible : bool_constant<__is_trivially_constructible(_Ty, _Args...)> { +struct _NO_SPECIALIZATIONS is_trivially_constructible : bool_constant<__is_trivially_constructible(_Ty, _Args...)> { // determine whether direct-initialization of _Ty with _Args... is trivial }; _EXPORT_STD template -constexpr bool is_trivially_constructible_v = __is_trivially_constructible(_Ty, _Args...); +_NO_SPECIALIZATIONS constexpr bool is_trivially_constructible_v = __is_trivially_constructible(_Ty, _Args...); _EXPORT_STD template -struct is_trivially_copy_constructible +struct _NO_SPECIALIZATIONS is_trivially_copy_constructible : bool_constant<__is_trivially_constructible(_Ty, add_lvalue_reference_t)> { // determine whether direct-initialization of _Ty with an lvalue const _Ty is trivial }; _EXPORT_STD template -constexpr bool is_trivially_copy_constructible_v = __is_trivially_constructible(_Ty, add_lvalue_reference_t); +_NO_SPECIALIZATIONS constexpr bool is_trivially_copy_constructible_v = + __is_trivially_constructible(_Ty, add_lvalue_reference_t); _EXPORT_STD template -struct is_trivially_default_constructible : bool_constant<__is_trivially_constructible(_Ty)> { +struct _NO_SPECIALIZATIONS is_trivially_default_constructible : bool_constant<__is_trivially_constructible(_Ty)> { // determine whether value-initialization of _Ty is trivial }; _EXPORT_STD template -constexpr bool is_trivially_default_constructible_v = __is_trivially_constructible(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_trivially_default_constructible_v = __is_trivially_constructible(_Ty); _EXPORT_STD template -struct is_trivially_move_constructible : bool_constant<__is_trivially_constructible(_Ty, _Ty)> { +struct _NO_SPECIALIZATIONS is_trivially_move_constructible : bool_constant<__is_trivially_constructible(_Ty, _Ty)> { // determine whether direct-initialization of _Ty with an rvalue _Ty is trivial }; _EXPORT_STD template -constexpr bool is_trivially_move_constructible_v = __is_trivially_constructible(_Ty, _Ty); +_NO_SPECIALIZATIONS constexpr bool is_trivially_move_constructible_v = __is_trivially_constructible(_Ty, _Ty); _EXPORT_STD template -struct is_trivially_assignable : bool_constant<__is_trivially_assignable(_To, _From)> { +struct _NO_SPECIALIZATIONS is_trivially_assignable : bool_constant<__is_trivially_assignable(_To, _From)> { // determine whether _From can be trivially assigned to _To }; _EXPORT_STD template -constexpr bool is_trivially_assignable_v = __is_trivially_assignable(_To, _From); +_NO_SPECIALIZATIONS constexpr bool is_trivially_assignable_v = __is_trivially_assignable(_To, _From); _EXPORT_STD template -struct is_trivially_copy_assignable +struct _NO_SPECIALIZATIONS is_trivially_copy_assignable : bool_constant<__is_trivially_assignable(add_lvalue_reference_t<_Ty>, add_lvalue_reference_t)> { // determine whether an lvalue const _Ty can be trivially assigned to an lvalue _Ty }; _EXPORT_STD template -constexpr bool is_trivially_copy_assignable_v = +_NO_SPECIALIZATIONS constexpr bool is_trivially_copy_assignable_v = __is_trivially_assignable(add_lvalue_reference_t<_Ty>, add_lvalue_reference_t); _EXPORT_STD template -struct is_trivially_move_assignable : bool_constant<__is_trivially_assignable(add_lvalue_reference_t<_Ty>, _Ty)> { +struct _NO_SPECIALIZATIONS is_trivially_move_assignable + : bool_constant<__is_trivially_assignable(add_lvalue_reference_t<_Ty>, _Ty)> { // determine whether an rvalue _Ty can be trivially assigned to an lvalue _Ty }; _EXPORT_STD template -constexpr bool is_trivially_move_assignable_v = __is_trivially_assignable(add_lvalue_reference_t<_Ty>, _Ty); +_NO_SPECIALIZATIONS constexpr bool is_trivially_move_assignable_v = + __is_trivially_assignable(add_lvalue_reference_t<_Ty>, _Ty); _EXPORT_STD template -struct is_trivially_destructible : bool_constant<__is_trivially_destructible(_Ty)> { +struct _NO_SPECIALIZATIONS is_trivially_destructible : bool_constant<__is_trivially_destructible(_Ty)> { // determine whether remove_all_extents_t<_Ty> is a reference type or can trivially be explicitly destroyed }; _EXPORT_STD template -constexpr bool is_trivially_destructible_v = __is_trivially_destructible(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_trivially_destructible_v = __is_trivially_destructible(_Ty); _EXPORT_STD template -struct is_nothrow_constructible : bool_constant<__is_nothrow_constructible(_Ty, _Args...)> { +struct _NO_SPECIALIZATIONS is_nothrow_constructible : bool_constant<__is_nothrow_constructible(_Ty, _Args...)> { // determine whether direct-initialization of _Ty from _Args... is both valid and not potentially-throwing }; _EXPORT_STD template -constexpr bool is_nothrow_constructible_v = __is_nothrow_constructible(_Ty, _Args...); +_NO_SPECIALIZATIONS constexpr bool is_nothrow_constructible_v = __is_nothrow_constructible(_Ty, _Args...); _EXPORT_STD template -struct is_nothrow_copy_constructible +struct _NO_SPECIALIZATIONS is_nothrow_copy_constructible : bool_constant<__is_nothrow_constructible(_Ty, add_lvalue_reference_t)> { // determine whether direct-initialization of _Ty from an lvalue const _Ty is both valid // and not potentially-throwing }; _EXPORT_STD template -constexpr bool is_nothrow_copy_constructible_v = __is_nothrow_constructible(_Ty, add_lvalue_reference_t); +_NO_SPECIALIZATIONS constexpr bool is_nothrow_copy_constructible_v = + __is_nothrow_constructible(_Ty, add_lvalue_reference_t); _EXPORT_STD template -struct is_nothrow_default_constructible : bool_constant<__is_nothrow_constructible(_Ty)> { +struct _NO_SPECIALIZATIONS is_nothrow_default_constructible : bool_constant<__is_nothrow_constructible(_Ty)> { // determine whether value-initialization of _Ty is both valid and not potentially-throwing }; _EXPORT_STD template -constexpr bool is_nothrow_default_constructible_v = __is_nothrow_constructible(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_nothrow_default_constructible_v = __is_nothrow_constructible(_Ty); _EXPORT_STD template -struct is_nothrow_move_constructible : bool_constant<__is_nothrow_constructible(_Ty, _Ty)> { +struct _NO_SPECIALIZATIONS is_nothrow_move_constructible : bool_constant<__is_nothrow_constructible(_Ty, _Ty)> { // determine whether direct-initialization of _Ty from an rvalue _Ty is both valid and not potentially-throwing }; _EXPORT_STD template -constexpr bool is_nothrow_move_constructible_v = __is_nothrow_constructible(_Ty, _Ty); +_NO_SPECIALIZATIONS constexpr bool is_nothrow_move_constructible_v = __is_nothrow_constructible(_Ty, _Ty); _EXPORT_STD template -struct is_nothrow_assignable : bool_constant<__is_nothrow_assignable(_To, _From)> { +struct _NO_SPECIALIZATIONS is_nothrow_assignable : bool_constant<__is_nothrow_assignable(_To, _From)> { // determine whether assignment of _From to _To is both valid and not potentially-throwing }; _EXPORT_STD template -constexpr bool is_nothrow_assignable_v = __is_nothrow_assignable(_To, _From); +_NO_SPECIALIZATIONS constexpr bool is_nothrow_assignable_v = __is_nothrow_assignable(_To, _From); _EXPORT_STD template -struct is_nothrow_copy_assignable +struct _NO_SPECIALIZATIONS is_nothrow_copy_assignable : bool_constant<__is_nothrow_assignable(add_lvalue_reference_t<_Ty>, add_lvalue_reference_t)> { // determine whether assignment of an lvalue const _Ty to an lvalue _Ty is both valid and not potentially-throwing }; _EXPORT_STD template -constexpr bool is_nothrow_copy_assignable_v = +_NO_SPECIALIZATIONS constexpr bool is_nothrow_copy_assignable_v = __is_nothrow_assignable(add_lvalue_reference_t<_Ty>, add_lvalue_reference_t); _EXPORT_STD template -struct is_nothrow_move_assignable : bool_constant<__is_nothrow_assignable(add_lvalue_reference_t<_Ty>, _Ty)> { +struct _NO_SPECIALIZATIONS is_nothrow_move_assignable + : bool_constant<__is_nothrow_assignable(add_lvalue_reference_t<_Ty>, _Ty)> { // determine whether assignment of an rvalue _Ty to an lvalue _Ty is both valid and not potentially-throwing }; _EXPORT_STD template -constexpr bool is_nothrow_move_assignable_v = __is_nothrow_assignable(add_lvalue_reference_t<_Ty>, _Ty); +_NO_SPECIALIZATIONS constexpr bool is_nothrow_move_assignable_v = + __is_nothrow_assignable(add_lvalue_reference_t<_Ty>, _Ty); _EXPORT_STD template -struct is_nothrow_destructible : bool_constant<__is_nothrow_destructible(_Ty)> { +struct _NO_SPECIALIZATIONS is_nothrow_destructible : bool_constant<__is_nothrow_destructible(_Ty)> { // determine whether remove_all_extents_t<_Ty> is a reference type or has // non-potentially-throwing explicit destruction }; _EXPORT_STD template -constexpr bool is_nothrow_destructible_v = __is_nothrow_destructible(_Ty); +_NO_SPECIALIZATIONS constexpr bool is_nothrow_destructible_v = __is_nothrow_destructible(_Ty); template > struct _Sign_base { // determine whether integral type _Ty is signed or unsigned @@ -985,16 +1014,20 @@ struct _Sign_base<_Ty, false> { // floating-point _Ty is signed }; _EXPORT_STD template -struct is_signed : bool_constant<_Sign_base<_Ty>::_Signed> {}; // determine whether _Ty is a signed type +struct _NO_SPECIALIZATIONS is_signed : bool_constant<_Sign_base<_Ty>::_Signed> { + // determine whether _Ty is a signed type +}; _EXPORT_STD template -constexpr bool is_signed_v = _Sign_base<_Ty>::_Signed; +_NO_SPECIALIZATIONS constexpr bool is_signed_v = _Sign_base<_Ty>::_Signed; _EXPORT_STD template -struct is_unsigned : bool_constant<_Sign_base<_Ty>::_Unsigned> {}; // determine whether _Ty is an unsigned type +struct _NO_SPECIALIZATIONS is_unsigned : bool_constant<_Sign_base<_Ty>::_Unsigned> { + // determine whether _Ty is an unsigned type +}; _EXPORT_STD template -constexpr bool is_unsigned_v = _Sign_base<_Ty>::_Unsigned; +_NO_SPECIALIZATIONS constexpr bool is_unsigned_v = _Sign_base<_Ty>::_Unsigned; template constexpr bool _Is_nonbool_integral = is_integral_v<_Ty> && !is_same_v, bool>; @@ -1044,7 +1077,7 @@ using _Make_signed1 = // signed partner to cv-unqualified _Ty typename _Make_signed2::template _Apply<_Ty>; _EXPORT_STD template -struct make_signed { // signed partner to _Ty +struct _NO_SPECIALIZATIONS make_signed { // signed partner to _Ty static_assert(_Is_nonbool_integral<_Ty> || is_enum_v<_Ty>, "make_signed requires that T shall be a (possibly cv-qualified) " "integral type or enumeration but not a bool type."); @@ -1089,7 +1122,7 @@ using _Make_unsigned1 = // unsigned partner to cv-unqualified _Ty typename _Make_unsigned2::template _Apply<_Ty>; _EXPORT_STD template -struct make_unsigned { // unsigned partner to _Ty +struct _NO_SPECIALIZATIONS make_unsigned { // unsigned partner to _Ty static_assert(_Is_nonbool_integral<_Ty> || is_enum_v<_Ty>, "make_unsigned requires that T shall be a (possibly cv-qualified) " "integral type or enumeration but not a bool type."); @@ -1106,10 +1139,10 @@ constexpr make_unsigned_t<_Rep> _Unsigned_value(_Rep _Val) { // makes _Val unsig } _EXPORT_STD template -struct alignment_of : integral_constant {}; // determine alignment of _Ty +struct _NO_SPECIALIZATIONS alignment_of : integral_constant {}; // determine alignment of _Ty _EXPORT_STD template -constexpr size_t alignment_of_v = alignof(_Ty); +_NO_SPECIALIZATIONS constexpr size_t alignment_of_v = alignof(_Ty); template union _Align_type { // union with size _Len bytes and alignment of _Ty @@ -1180,7 +1213,8 @@ template using _Aligned_storage_t = typename _Aligned_storage<_Len, _Align>::type; _EXPORT_STD template -struct _CXX23_DEPRECATE_ALIGNED_STORAGE aligned_storage { // define type with size _Len and alignment _Align +struct _CXX23_DEPRECATE_ALIGNED_STORAGE _NO_SPECIALIZATIONS aligned_storage { + // define type with size _Len and alignment _Align using type = _Aligned_storage_t<_Len, _Align>; }; @@ -1202,7 +1236,7 @@ struct _Maximum<_First, _Second, _Rest...> : _Maximum<(_First < _Second ? _Secon }; _EXPORT_STD template -struct _CXX23_DEPRECATE_ALIGNED_UNION aligned_union { +struct _CXX23_DEPRECATE_ALIGNED_UNION _NO_SPECIALIZATIONS aligned_union { // define type with size at least _Len, for storing anything in _Types static constexpr size_t _Max_len = _Maximum<_Len, sizeof(_Types)...>::value; // NOT sizeof...(_Types) static constexpr size_t alignment_value = _Maximum::value; @@ -1224,13 +1258,13 @@ template struct _Underlying_type<_Ty, false> {}; _EXPORT_STD template -struct underlying_type : _Underlying_type<_Ty> {}; // determine underlying type for enum +struct _NO_SPECIALIZATIONS underlying_type : _Underlying_type<_Ty> {}; // determine underlying type for enum _EXPORT_STD template using underlying_type_t = typename _Underlying_type<_Ty>::type; _EXPORT_STD template -constexpr size_t rank_v = 0; // determine number of dimensions of array _Ty +_NO_SPECIALIZATIONS constexpr size_t rank_v = 0; // determine number of dimensions of array _Ty template constexpr size_t rank_v<_Ty[_Nx]> = rank_v<_Ty> + 1; @@ -1239,10 +1273,10 @@ template constexpr size_t rank_v<_Ty[]> = rank_v<_Ty> + 1; _EXPORT_STD template -struct rank : integral_constant> {}; +struct _NO_SPECIALIZATIONS rank : integral_constant> {}; _EXPORT_STD template -constexpr size_t extent_v = 0; // determine extent of dimension _Ix of array _Ty +_NO_SPECIALIZATIONS constexpr size_t extent_v = 0; // determine extent of dimension _Ix of array _Ty template constexpr size_t extent_v<_Ty[_Nx], 0> = _Nx; @@ -1254,18 +1288,18 @@ template constexpr size_t extent_v<_Ty[], _Ix> = extent_v<_Ty, _Ix - 1>; _EXPORT_STD template -struct extent : integral_constant> {}; +struct _NO_SPECIALIZATIONS extent : integral_constant> {}; _EXPORT_STD template -struct is_base_of : bool_constant<__is_base_of(_Base, _Derived)> { +struct _NO_SPECIALIZATIONS is_base_of : bool_constant<__is_base_of(_Base, _Derived)> { // determine whether _Base is a base of or the same as _Derived }; _EXPORT_STD template -constexpr bool is_base_of_v = __is_base_of(_Base, _Derived); +_NO_SPECIALIZATIONS constexpr bool is_base_of_v = __is_base_of(_Base, _Derived); _EXPORT_STD template -struct decay { // determines decayed version of _Ty +struct _NO_SPECIALIZATIONS decay { // determines decayed version of _Ty using _Ty1 = remove_reference_t<_Ty>; using _Ty2 = typename _Select>::template _Apply, remove_cv<_Ty1>>; using type = typename _Select>::template _Apply>, _Ty2>::type; @@ -1384,7 +1418,9 @@ using _Cond_res = // N4950 [meta.trans.other]/2.4 decltype(false ? _Returns_exactly<_Ty1>() : _Returns_exactly<_Ty2>()); _EXPORT_STD template -struct common_reference; +struct _NO_SPECIALIZATIONS_MSG("Users are not allowed to specialize std::common_reference directly. " + "You should instead specialize std::basic_common_reference, " + "which std::common_reference will dispatch to.") common_reference; _EXPORT_STD template using common_reference_t = common_reference<_Types...>::type; @@ -1490,7 +1526,7 @@ struct common_reference<_Ty1, _Ty2, _Ty3, _Rest...> : common_reference -struct type_identity { +struct _NO_SPECIALIZATIONS type_identity { using type = _Ty; }; _EXPORT_STD template @@ -1730,10 +1766,10 @@ struct _Is_nothrow_convertible : bool_constant<_Is_nothrow_convertible_v<_From, #if _HAS_CXX20 _EXPORT_STD template -constexpr bool is_nothrow_convertible_v = _Is_nothrow_convertible_v<_From, _To>; +_NO_SPECIALIZATIONS constexpr bool is_nothrow_convertible_v = _Is_nothrow_convertible_v<_From, _To>; _EXPORT_STD template -struct is_nothrow_convertible : bool_constant<_Is_nothrow_convertible_v<_From, _To>> {}; +struct _NO_SPECIALIZATIONS is_nothrow_convertible : bool_constant<_Is_nothrow_convertible_v<_From, _To>> {}; #endif // _HAS_CXX20 template @@ -1805,7 +1841,7 @@ using _Select_invoke_traits = conditional_t -struct _CXX17_DEPRECATE_RESULT_OF result_of { // explain usage +struct _CXX17_DEPRECATE_RESULT_OF _NO_SPECIALIZATIONS result_of { // explain usage static_assert(_Always_false<_Fty>, "result_of is invalid; use " "result_of instead."); }; @@ -1838,7 +1874,7 @@ struct _Is_invocable_r : _Is_invocable_r_<_Rx, _Callable, _Args...> { #if _HAS_CXX17 _EXPORT_STD template -struct invoke_result : _Select_invoke_traits<_Callable, _Args...> { +struct _NO_SPECIALIZATIONS invoke_result : _Select_invoke_traits<_Callable, _Args...> { // determine the result type of invoking _Callable with _Args }; @@ -1846,60 +1882,66 @@ _EXPORT_STD template using invoke_result_t = typename _Select_invoke_traits<_Callable, _Args...>::type; _EXPORT_STD template -struct is_invocable : _Select_invoke_traits<_Callable, _Args...>::_Is_invocable { +struct _NO_SPECIALIZATIONS is_invocable : _Select_invoke_traits<_Callable, _Args...>::_Is_invocable { // determines whether _Callable is callable with _Args }; _EXPORT_STD template -constexpr bool is_invocable_v = _Select_invoke_traits<_Callable, _Args...>::_Is_invocable::value; +_NO_SPECIALIZATIONS constexpr bool is_invocable_v = _Select_invoke_traits<_Callable, _Args...>::_Is_invocable::value; _EXPORT_STD template -struct is_nothrow_invocable : _Select_invoke_traits<_Callable, _Args...>::_Is_nothrow_invocable { +struct _NO_SPECIALIZATIONS is_nothrow_invocable : _Select_invoke_traits<_Callable, _Args...>::_Is_nothrow_invocable { // determines whether _Callable is nothrow-callable with _Args }; _EXPORT_STD template -constexpr bool is_nothrow_invocable_v = _Select_invoke_traits<_Callable, _Args...>::_Is_nothrow_invocable::value; +_NO_SPECIALIZATIONS constexpr bool is_nothrow_invocable_v = + _Select_invoke_traits<_Callable, _Args...>::_Is_nothrow_invocable::value; _EXPORT_STD template -struct is_invocable_r : _Is_invocable_r_<_Rx, _Callable, _Args...> { +struct _NO_SPECIALIZATIONS is_invocable_r : _Is_invocable_r_<_Rx, _Callable, _Args...> { // determines whether _Callable is callable with _Args and return type _Rx }; _EXPORT_STD template -constexpr bool is_invocable_r_v = _Is_invocable_r_<_Rx, _Callable, _Args...>::value; +_NO_SPECIALIZATIONS constexpr bool is_invocable_r_v = _Is_invocable_r_<_Rx, _Callable, _Args...>::value; _EXPORT_STD template -struct is_nothrow_invocable_r : _Select_invoke_traits<_Callable, _Args...>::template _Is_nothrow_invocable_r<_Rx> { +struct _NO_SPECIALIZATIONS is_nothrow_invocable_r + : _Select_invoke_traits<_Callable, _Args...>::template _Is_nothrow_invocable_r<_Rx> { // determines whether _Callable is nothrow-callable with _Args and return type _Rx }; _EXPORT_STD template -constexpr bool is_nothrow_invocable_r_v = +_NO_SPECIALIZATIONS constexpr bool is_nothrow_invocable_r_v = _Select_invoke_traits<_Callable, _Args...>::template _Is_nothrow_invocable_r<_Rx>::value; #endif // _HAS_CXX17 #if _HAS_CXX20 #ifndef __clang__ // TRANSITION, LLVM-48860 _EXPORT_STD template -struct is_layout_compatible : bool_constant<__is_layout_compatible(_Ty1, _Ty2)> {}; +struct _NO_SPECIALIZATIONS is_layout_compatible : bool_constant<__is_layout_compatible(_Ty1, _Ty2)> {}; _EXPORT_STD template -constexpr bool is_layout_compatible_v = __is_layout_compatible(_Ty1, _Ty2); +_NO_SPECIALIZATIONS constexpr bool is_layout_compatible_v = __is_layout_compatible(_Ty1, _Ty2); _EXPORT_STD template -struct is_pointer_interconvertible_base_of : bool_constant<__is_pointer_interconvertible_base_of(_Base, _Derived)> {}; +struct _NO_SPECIALIZATIONS is_pointer_interconvertible_base_of + : bool_constant<__is_pointer_interconvertible_base_of(_Base, _Derived)> {}; _EXPORT_STD template -constexpr bool is_pointer_interconvertible_base_of_v = __is_pointer_interconvertible_base_of(_Base, _Derived); +_NO_SPECIALIZATIONS constexpr bool is_pointer_interconvertible_base_of_v = + __is_pointer_interconvertible_base_of(_Base, _Derived); _EXPORT_STD template -_NODISCARD constexpr bool is_pointer_interconvertible_with_class(_MemberTy _ClassTy::* _Pm) noexcept { +_NODISCARD _NO_SPECIALIZATIONS constexpr bool is_pointer_interconvertible_with_class( + _MemberTy _ClassTy::* _Pm) noexcept { return __is_pointer_interconvertible_with_class(_ClassTy, _Pm); } _EXPORT_STD template -_NODISCARD constexpr bool is_corresponding_member(_MemberTy1 _ClassTy1::* _Pm1, _MemberTy2 _ClassTy2::* _Pm2) noexcept { +_NODISCARD _NO_SPECIALIZATIONS constexpr bool is_corresponding_member( + _MemberTy1 _ClassTy1::* _Pm1, _MemberTy2 _ClassTy2::* _Pm2) noexcept { return __is_corresponding_member(_ClassTy1, _ClassTy2, _Pm1, _Pm2); } #endif // ^^^ no workaround ^^^ @@ -2050,7 +2092,7 @@ _NODISCARD _CONSTEXPR20 reference_wrapper cref(reference_wrapper<_Ty> #if _HAS_CXX20 _EXPORT_STD template -struct unwrap_reference { +struct _NO_SPECIALIZATIONS unwrap_reference { using type = _Ty; }; template @@ -2063,7 +2105,7 @@ using unwrap_reference_t = unwrap_reference<_Ty>::type; _EXPORT_STD template using unwrap_ref_decay_t = unwrap_reference_t>; _EXPORT_STD template -struct unwrap_ref_decay { +struct _NO_SPECIALIZATIONS unwrap_ref_decay { using type = unwrap_ref_decay_t<_Ty>; }; #endif // _HAS_CXX20 @@ -2124,37 +2166,39 @@ struct _Is_nothrow_swappable #if _HAS_CXX17 _EXPORT_STD template -struct is_swappable_with : _Is_swappable_with<_Ty1, _Ty2>::type { +struct _NO_SPECIALIZATIONS is_swappable_with : _Is_swappable_with<_Ty1, _Ty2>::type { // Determine if expressions with type and value category _Ty1 and _Ty2 // can be swapped (and vice versa) }; _EXPORT_STD template -constexpr bool is_swappable_with_v = +_NO_SPECIALIZATIONS constexpr bool is_swappable_with_v = conjunction_v<_Swappable_with_helper<_Ty1, _Ty2>, _Swappable_with_helper<_Ty2, _Ty1>>; _EXPORT_STD template -struct is_swappable : _Is_swappable<_Ty>::type {}; // Determine if _Ty lvalues satisfy is_swappable_with +struct _NO_SPECIALIZATIONS is_swappable : _Is_swappable<_Ty>::type { + // Determine if _Ty lvalues satisfy is_swappable_with +}; _EXPORT_STD template -constexpr bool is_swappable_v = _Is_swappable<_Ty>::value; +_NO_SPECIALIZATIONS constexpr bool is_swappable_v = _Is_swappable<_Ty>::value; _EXPORT_STD template -struct is_nothrow_swappable_with : _Is_nothrow_swappable_with<_Ty1, _Ty2>::type { +struct _NO_SPECIALIZATIONS is_nothrow_swappable_with : _Is_nothrow_swappable_with<_Ty1, _Ty2>::type { // Determine if expressions with type and value category _Ty1 and _Ty2 // satisfy is_swappable_with, and can be swapped without emitting exceptions }; _EXPORT_STD template -constexpr bool is_nothrow_swappable_with_v = _Is_nothrow_swappable_with<_Ty1, _Ty2>::value; +_NO_SPECIALIZATIONS constexpr bool is_nothrow_swappable_with_v = _Is_nothrow_swappable_with<_Ty1, _Ty2>::value; _EXPORT_STD template -struct is_nothrow_swappable : _Is_nothrow_swappable<_Ty>::type { +struct _NO_SPECIALIZATIONS is_nothrow_swappable : _Is_nothrow_swappable<_Ty>::type { // Determine if _Ty lvalues satisfy is_nothrow_swappable_with }; _EXPORT_STD template -constexpr bool is_nothrow_swappable_v = _Is_nothrow_swappable<_Ty>::value; +_NO_SPECIALIZATIONS constexpr bool is_nothrow_swappable_v = _Is_nothrow_swappable<_Ty>::value; #endif // _HAS_CXX17 namespace _Has_ADL_swap_detail { diff --git a/stl/inc/utility b/stl/inc/utility index 4570a7bb790..59692f40296 100644 --- a/stl/inc/utility +++ b/stl/inc/utility @@ -158,7 +158,7 @@ struct _Ignore { // struct that ignores assignments _EXPORT_STD _INLINE_VAR constexpr _Ignore ignore{}; _EXPORT_STD template -class tuple; +class _NO_SPECIALIZATIONS tuple; _EXPORT_STD template struct pair; @@ -170,7 +170,7 @@ _EXPORT_STD template struct tuple_size; _EXPORT_STD template -constexpr size_t tuple_size_v = tuple_size<_Ty>::value; +_NO_SPECIALIZATIONS constexpr size_t tuple_size_v = tuple_size<_Ty>::value; _EXPORT_STD template struct tuple_element; diff --git a/stl/inc/variant b/stl/inc/variant index c17d88fe17e..e0748526c6f 100644 --- a/stl/inc/variant +++ b/stl/inc/variant @@ -294,7 +294,7 @@ struct _CXX20_DEPRECATE_VOLATILE variant_size : variant_size<_Ty>: template struct _CXX20_DEPRECATE_VOLATILE variant_size : variant_size<_Ty>::type {}; _EXPORT_STD template -constexpr size_t variant_size_v = variant_size<_Ty>::value; +_NO_SPECIALIZATIONS constexpr size_t variant_size_v = variant_size<_Ty>::value; template struct variant_size> : integral_constant {}; @@ -928,7 +928,8 @@ template constexpr bool _Is_in_place_index_specialization> = true; _EXPORT_STD template -class variant : private _SMF_control<_Variant_destroy_layer<_Types...>, _Types...> { // discriminated union +class _NO_SPECIALIZATIONS variant + : private _SMF_control<_Variant_destroy_layer<_Types...>, _Types...> { // discriminated union public: static_assert(conjunction_v..., negation>..., is_destructible<_Types>...>, "variant requires all of the Types to meet the Cpp17Destructible requirements " diff --git a/stl/inc/xmemory b/stl/inc/xmemory index e4cfa3008b5..f44163aed6b 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -756,8 +756,9 @@ struct _Default_allocator_traits { // traits for std::allocator }; _EXPORT_STD template -struct allocator_traits : conditional_t<_Is_default_allocator<_Alloc>::value, _Default_allocator_traits<_Alloc>, - _Normal_allocator_traits<_Alloc>> {}; +struct _NO_SPECIALIZATIONS allocator_traits : conditional_t<_Is_default_allocator<_Alloc>::value, + _Default_allocator_traits<_Alloc>, _Normal_allocator_traits<_Alloc>> { +}; // _Choose_pocca_v returns whether an attempt to propagate allocators is necessary in copy assignment operations. // Note that even when false_type, callers should call _Pocca as we want to assign allocators even when equal. diff --git a/stl/inc/xtr1common b/stl/inc/xtr1common index b1829b8b323..6b26aa9f245 100644 --- a/stl/inc/xtr1common +++ b/stl/inc/xtr1common @@ -23,7 +23,7 @@ _STL_DISABLE_CLANG_WARNINGS _STD_BEGIN _EXPORT_STD template -struct integral_constant { +struct _NO_SPECIALIZATIONS integral_constant { static constexpr _Ty value = _Val; using value_type = _Ty; @@ -45,7 +45,7 @@ _EXPORT_STD using true_type = bool_constant; _EXPORT_STD using false_type = bool_constant; _EXPORT_STD template -struct enable_if {}; // no member "type" when !_Test +struct _NO_SPECIALIZATIONS enable_if {}; // no member "type" when !_Test template struct enable_if { // type is _Ty for _Test @@ -56,7 +56,7 @@ _EXPORT_STD template using enable_if_t = typename enable_if<_Test, _Ty>::type; _EXPORT_STD template -struct conditional { // Choose _Ty1 if _Test is true, and _Ty2 otherwise +struct _NO_SPECIALIZATIONS conditional { // Choose _Ty1 if _Test is true, and _Ty2 otherwise using type = _Ty1; }; @@ -70,22 +70,22 @@ using conditional_t = typename conditional<_Test, _Ty1, _Ty2>::type; #ifdef __clang__ _EXPORT_STD template -constexpr bool is_same_v = __is_same(_Ty1, _Ty2); +_NO_SPECIALIZATIONS constexpr bool is_same_v = __is_same(_Ty1, _Ty2); _EXPORT_STD template -struct is_same : bool_constant<__is_same(_Ty1, _Ty2)> {}; +struct _NO_SPECIALIZATIONS is_same : bool_constant<__is_same(_Ty1, _Ty2)> {}; #else // ^^^ Clang / not Clang vvv _EXPORT_STD template -constexpr bool is_same_v = false; // determine whether arguments are the same type +_NO_SPECIALIZATIONS constexpr bool is_same_v = false; // determine whether arguments are the same type template constexpr bool is_same_v<_Ty, _Ty> = true; _EXPORT_STD template -struct is_same : bool_constant> {}; +struct _NO_SPECIALIZATIONS is_same : bool_constant> {}; #endif // ^^^ not Clang ^^^ _EXPORT_STD template -struct remove_const { // remove top-level const qualifier +struct _NO_SPECIALIZATIONS remove_const { // remove top-level const qualifier using type = _Ty; }; @@ -98,7 +98,7 @@ _EXPORT_STD template using remove_const_t = typename remove_const<_Ty>::type; _EXPORT_STD template -struct remove_volatile { // remove top-level volatile qualifier +struct _NO_SPECIALIZATIONS remove_volatile { // remove top-level volatile qualifier using type = _Ty; }; @@ -111,7 +111,7 @@ _EXPORT_STD template using remove_volatile_t = typename remove_volatile<_Ty>::type; _EXPORT_STD template -struct remove_cv { // remove top-level const and volatile qualifiers +struct _NO_SPECIALIZATIONS remove_cv { // remove top-level const and volatile qualifiers using type = _Ty; template