diff --git a/stl/inc/functional b/stl/inc/functional index 42f68a52603..05b969b5ef2 100644 --- a/stl/inc/functional +++ b/stl/inc/functional @@ -638,7 +638,7 @@ _NODISCARD const_mem_fun1_ref_t<_Result, _Ty, _Arg> mem_fun_ref(_Result (_Ty::*_ // FUNCTION TEMPLATE mem_fn template -class _Mem_fn : public _Weak_types<_Memptr>::type { +class _Mem_fn : public _Weak_types<_Memptr> { private: _Memptr _Pm; @@ -1449,7 +1449,7 @@ template struct _Binder_result_type { // provide result_type (sometimes) using _Decayed = decay_t<_Fx>; - using _All_weak_types = typename _Weak_types<_Decayed>::type; + using _All_weak_types = _Weak_types<_Decayed>; using type = conditional_t, _Weak_result_type<_All_weak_types>, _Forced_result_type<_Ret>>; diff --git a/stl/inc/type_traits b/stl/inc/type_traits index e17f1b7381c..41438975b0f 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -72,84 +72,6 @@ struct negation : bool_constant(_Trait::value)> {}; // The ne template _INLINE_VAR constexpr bool negation_v = negation<_Trait>::value; -// STRUCT TEMPLATE _Arg_types -template -struct _Arg_types {}; // provide argument_type, etc. (sometimes) - -template -struct _Arg_types<_Ty1> { - _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty1 _ARGUMENT_TYPE_NAME; -}; - -template -struct _Arg_types<_Ty1, _Ty2> { - _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty1 _FIRST_ARGUMENT_TYPE_NAME; - _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty2 _SECOND_ARGUMENT_TYPE_NAME; -}; - -// STRUCT TEMPLATE is_function -template -struct _Is_function { // determine whether _Ty is a function - using _Bool_type = false_type; // NB: members are user-visible via _Weak_types -}; - -#define _IS_FUNCTION(CALL_OPT, CV_OPT, REF_OPT, NOEXCEPT_OPT) \ - template \ - struct _Is_function<_Ret CALL_OPT(_Types...) CV_OPT REF_OPT NOEXCEPT_OPT> : _Arg_types<_Types...> { \ - using _Bool_type = true_type; \ - _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret _RESULT_TYPE_NAME; \ - }; - -_NON_MEMBER_CALL_CV_REF_NOEXCEPT(_IS_FUNCTION) -#undef _IS_FUNCTION - -#define _IS_FUNCTION_ELLIPSIS(CV_REF_NOEXCEPT_OPT) \ - template \ - struct _Is_function<_Ret(_Types..., ...) CV_REF_NOEXCEPT_OPT> { /* no calling conventions for ellipsis */ \ - using _Bool_type = true_type; \ - _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret _RESULT_TYPE_NAME; \ - }; - -_CLASS_DEFINE_CV_REF_NOEXCEPT(_IS_FUNCTION_ELLIPSIS) -#undef _IS_FUNCTION_ELLIPSIS - -template -struct is_function : _Is_function<_Ty>::_Bool_type {}; // determine whether _Ty is a function - -template -_INLINE_VAR constexpr bool is_function_v = _Is_function<_Ty>::_Bool_type::value; - -template -struct _Is_memfunptr { // base class for member function pointer predicates - using _Bool_type = false_type; // NB: members are user-visible via _Weak_types -}; - -#define _IS_MEMFUNPTR(CALL_OPT, CV_OPT, REF_OPT, NOEXCEPT_OPT) \ - template \ - struct _Is_memfunptr<_Ret (CALL_OPT _Arg0::*)(_Types...) CV_OPT REF_OPT NOEXCEPT_OPT> \ - : _Arg_types { \ - using _Bool_type = true_type; \ - _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret _RESULT_TYPE_NAME; \ - using _Class_type = _Arg0; \ - using _Guide_type = enable_if, _Ret(_Types...)>; \ - }; - -_MEMBER_CALL_CV_REF_NOEXCEPT(_IS_MEMFUNPTR) -#undef _IS_MEMFUNPTR - -#define _IS_MEMFUNPTR_ELLIPSIS(CV_REF_NOEXCEPT_OPT) \ - template \ - struct _Is_memfunptr<_Ret (_Arg0::*)(_Types..., ...) \ - CV_REF_NOEXCEPT_OPT> { /* no calling conventions for ellipsis */ \ - using _Bool_type = true_type; \ - _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret _RESULT_TYPE_NAME; \ - using _Class_type = _Arg0; \ - using _Guide_type = enable_if; \ - }; - -_CLASS_DEFINE_CV_REF_NOEXCEPT(_IS_MEMFUNPTR_ELLIPSIS) -#undef _IS_MEMFUNPTR_ELLIPSIS - // STRUCT TEMPLATE is_void template _INLINE_VAR constexpr bool is_void_v = is_same_v, void>; @@ -379,33 +301,6 @@ _INLINE_VAR constexpr bool is_reference_v<_Ty&&> = true; template struct is_reference : bool_constant> {}; -// STRUCT TEMPLATE is_member_object_pointer -template ::_Bool_type::value> -struct _Is_member_object_pointer { // determine whether _Ty is a pointer to member object - static constexpr bool value = false; -}; - -template -struct _Is_member_object_pointer<_Ty1 _Ty2::*, false> { - static constexpr bool value = true; - using _Class_type = _Ty2; -}; - -template -_INLINE_VAR constexpr bool is_member_object_pointer_v = // determine whether _Ty is a pointer to member object - _Is_member_object_pointer>::value; - -template -struct is_member_object_pointer : bool_constant> {}; - -// STRUCT TEMPLATE is_member_function_pointer -template -_INLINE_VAR constexpr bool is_member_function_pointer_v = // determine whether _Ty is a pointer to member function - _Is_memfunptr>::_Bool_type::value; - -template -struct is_member_function_pointer : bool_constant> {}; - // STRUCT TEMPLATE is_pointer template _INLINE_VAR constexpr bool is_pointer_v = false; // determine whether _Ty is a pointer @@ -454,13 +349,6 @@ _INLINE_VAR constexpr bool is_fundamental_v = is_arithmetic_v<_Ty> || is_void_v< template struct is_fundamental : bool_constant> {}; // determine whether _Ty is a fundamental type -// STRUCT TEMPLATE is_object -template -_INLINE_VAR constexpr bool is_object_v = !is_function_v<_Ty> && !is_reference_v<_Ty> && !is_void_v<_Ty>; - -template -struct is_object : bool_constant> {}; // determine whether _Ty is an object type - // STRUCT TEMPLATE is_convertible template struct is_convertible : bool_constant<__is_convertible_to(_From, _To)> { @@ -484,20 +372,63 @@ struct is_compound : bool_constant> {}; // determine whet template _INLINE_VAR constexpr bool is_compound_v = !is_fundamental_v<_Ty>; -// STRUCT TEMPLATE is_member_pointer -template -_INLINE_VAR constexpr bool is_member_pointer_v = is_member_object_pointer_v<_Ty> || is_member_function_pointer_v<_Ty>; +// STRUCT TEMPLATE _Arg_types +template +struct _Arg_types {}; // provide argument_type, etc. when sizeof...(_Types) is 1 or 2 + +template +struct _Arg_types<_Ty1> { + _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty1 _ARGUMENT_TYPE_NAME; +}; + +template +struct _Arg_types<_Ty1, _Ty2> { + _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty1 _FIRST_ARGUMENT_TYPE_NAME; + _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty2 _SECOND_ARGUMENT_TYPE_NAME; +}; +// STRUCT TEMPLATE is_member_function_pointer template -struct is_member_pointer : bool_constant> {}; // determine whether _Ty is a pointer to member +struct _Is_memfunptr { // base class for member function pointer predicates + using _Bool_type = false_type; // NB: members are user-visible via _Weak_types +}; -// STRUCT TEMPLATE is_scalar +#define _IS_MEMFUNPTR(CALL_OPT, CV_OPT, REF_OPT, NOEXCEPT_OPT) \ + template \ + struct _Is_memfunptr<_Ret (CALL_OPT _Arg0::*)(_Types...) CV_OPT REF_OPT NOEXCEPT_OPT> \ + : _Arg_types { \ + using _Bool_type = true_type; \ + _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret _RESULT_TYPE_NAME; \ + using _Class_type = _Arg0; \ + using _Guide_type = enable_if, _Ret(_Types...)>; \ + }; + +_MEMBER_CALL_CV_REF_NOEXCEPT(_IS_MEMFUNPTR) +#undef _IS_MEMFUNPTR + +#define _IS_MEMFUNPTR_ELLIPSIS(CV_REF_NOEXCEPT_OPT) \ + template \ + struct _Is_memfunptr<_Ret (_Arg0::*)(_Types..., ...) \ + CV_REF_NOEXCEPT_OPT> { /* no calling conventions for ellipsis */ \ + using _Bool_type = true_type; \ + _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret _RESULT_TYPE_NAME; \ + using _Class_type = _Arg0; \ + using _Guide_type = enable_if; \ + }; + +_CLASS_DEFINE_CV_REF_NOEXCEPT(_IS_MEMFUNPTR_ELLIPSIS) +#undef _IS_MEMFUNPTR_ELLIPSIS + +#ifdef __clang__ template -_INLINE_VAR 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>; +_INLINE_VAR constexpr bool is_member_function_pointer_v = __is_member_function_pointer(_Ty); +#else // ^^^ Clang ^^^ / vvv Other vvv +template +_INLINE_VAR constexpr bool is_member_function_pointer_v = _Is_memfunptr>::_Bool_type::value; +#endif // ^^^ Other ^^^ template -struct is_scalar : bool_constant> {}; +struct is_member_function_pointer : bool_constant> {}; // STRUCT TEMPLATE is_const template @@ -519,6 +450,65 @@ _INLINE_VAR constexpr bool is_volatile_v = true; template struct is_volatile : bool_constant> {}; +// STRUCT TEMPLATE is_function +template +_INLINE_VAR constexpr bool is_function_v = // only function types and reference types can't be const qualified + !is_const_v && !is_reference_v<_Ty>; + +template +struct is_function : bool_constant> {}; + +// STRUCT TEMPLATE is_object +template +_INLINE_VAR constexpr bool is_object_v = // only function types and reference types can't be const qualified + is_const_v && !is_void_v<_Ty>; + +template +struct is_object : bool_constant> {}; + +// STRUCT TEMPLATE is_member_object_pointer +template +struct _Is_member_object_pointer { + static constexpr bool value = false; +}; + +template +struct _Is_member_object_pointer<_Ty1 _Ty2::*> { + static constexpr bool value = !is_function_v<_Ty1>; + using _Class_type = _Ty2; +}; + +#ifdef __clang__ +template +_INLINE_VAR constexpr bool is_member_object_pointer_v = __is_member_object_pointer(_Ty); +#else // ^^^ Clang / Other vvv +template +_INLINE_VAR constexpr bool is_member_object_pointer_v = _Is_member_object_pointer>::value; +#endif // ^^^ Other ^^^ + +template +struct is_member_object_pointer : bool_constant> {}; + +// STRUCT TEMPLATE is_member_pointer +#ifdef __clang__ +template +_INLINE_VAR constexpr bool is_member_pointer_v = __is_member_pointer(_Ty); +#else // ^^^ Clang / Other vvv +template +_INLINE_VAR constexpr bool is_member_pointer_v = is_member_object_pointer_v<_Ty> || is_member_function_pointer_v<_Ty>; +#endif // ^^^ Other ^^^ + +template +struct is_member_pointer : bool_constant> {}; // determine whether _Ty is a pointer to member + +// STRUCT TEMPLATE is_scalar +template +_INLINE_VAR 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>; + +template +struct is_scalar : bool_constant> {}; + // STRUCT TEMPLATE is_pod template struct _CXX20_DEPRECATE_IS_POD is_pod : bool_constant<__is_pod(_Ty)> {}; // determine whether _Ty is a POD type @@ -1810,7 +1800,28 @@ inline constexpr bool is_nothrow_invocable_r_v = _Select_invoke_traits<_Callable, _Args...>::template _Is_nothrow_invocable_r<_Rx>::value; #endif // _HAS_CXX17 -// STRUCT TEMPLATE _Weak_types +// ALIAS TEMPLATE _Weak_types +template +struct _Function_args {}; // determine whether _Ty is a function + +#define _FUNCTION_ARGS(CALL_OPT, CV_OPT, REF_OPT, NOEXCEPT_OPT) \ + template \ + struct _Function_args<_Ret CALL_OPT(_Types...) CV_OPT REF_OPT NOEXCEPT_OPT> : _Arg_types<_Types...> { \ + _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret _RESULT_TYPE_NAME; \ + }; + +_NON_MEMBER_CALL_CV_REF_NOEXCEPT(_FUNCTION_ARGS) +#undef _FUNCTION_ARGS + +#define _FUNCTION_ARGS_ELLIPSIS(CV_REF_NOEXCEPT_OPT) \ + template \ + struct _Function_args<_Ret(_Types..., ...) CV_REF_NOEXCEPT_OPT> { /* no calling conventions for ellipsis */ \ + _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret _RESULT_TYPE_NAME; \ + }; + +_CLASS_DEFINE_CV_REF_NOEXCEPT(_FUNCTION_ARGS_ELLIPSIS) +#undef _FUNCTION_ARGS_ELLIPSIS + template struct _Weak_result_type {}; // default definition @@ -1826,8 +1837,8 @@ struct _Weak_argument_type : _Weak_result_type<_Ty> {}; // default definition _STL_DISABLE_DEPRECATED_WARNING template -struct _Weak_argument_type<_Ty, void_t> - : _Weak_result_type<_Ty> { // defined if _Ty::argument_type exists +struct _Weak_argument_type<_Ty, void_t> : _Weak_result_type<_Ty> { + // defined if _Ty::argument_type exists _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef typename _Ty::argument_type _ARGUMENT_TYPE_NAME; }; _STL_RESTORE_DEPRECATED_WARNING @@ -1846,12 +1857,8 @@ struct _Weak_binary_args<_Ty, void_t -struct _Weak_types { // provide nested types (sometimes) - using _Is_f_or_pf = _Is_function>; - using _Is_pmf = _Is_memfunptr>; - using type = conditional_t>, _Is_f_or_pf, - conditional_t, _Is_pmf, _Weak_binary_args<_Ty>>>; -}; +using _Weak_types = conditional_t>, _Function_args>, + conditional_t, _Is_memfunptr>, _Weak_binary_args<_Ty>>>; // CLASS TEMPLATE reference_wrapper template @@ -1868,7 +1875,7 @@ struct _Refwrap_has_ctor_from<_Ty, _Uty, void_t( template class reference_wrapper #if !_HAS_CXX20 - : public _Weak_types<_Ty>::type + : public _Weak_types<_Ty> #endif // !_HAS_CXX20 { public: diff --git a/tests/std/tests/Dev09_158457_tr1_mem_fn_calling_conventions/test.cpp b/tests/std/tests/Dev09_158457_tr1_mem_fn_calling_conventions/test.cpp index c303105ce08..1c2aa9b9537 100644 --- a/tests/std/tests/Dev09_158457_tr1_mem_fn_calling_conventions/test.cpp +++ b/tests/std/tests/Dev09_158457_tr1_mem_fn_calling_conventions/test.cpp @@ -168,6 +168,14 @@ STATIC_ASSERT(is_member_function_pointer_v); STATIC_ASSERT(is_member_function_pointer_v); STATIC_ASSERT(is_member_function_pointer_v); +STATIC_ASSERT(is_member_pointer_v); +STATIC_ASSERT(is_member_pointer_v); +STATIC_ASSERT(is_member_pointer_v); +STATIC_ASSERT(is_member_pointer_v); +STATIC_ASSERT(is_member_pointer_v); +STATIC_ASSERT(is_member_pointer_v); +STATIC_ASSERT(is_member_pointer_v); + STATIC_ASSERT(is_function_v); STATIC_ASSERT(is_function_v); STATIC_ASSERT(is_function_v);