From a49235ef6a2a032508ed541d5bae8ef2587d053b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Art=C3=B6m=20Bakri=20Al-Sarmini?= <3sz3tt+git@gmail.com> Date: Sat, 25 Jan 2020 18:41:42 +0300 Subject: [PATCH 01/13] is_function simplification --- llvm-project | 2 +- stl/inc/type_traits | 66 ++++++++++++++++++++++----------------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/llvm-project b/llvm-project index 45f630d729e..85ee4ff4e47 160000 --- a/llvm-project +++ b/llvm-project @@ -1 +1 @@ -Subproject commit 45f630d729e2cce044ed48e6eaf4b8e61e06fede +Subproject commit 85ee4ff4e474788abc7abdc939114281c2a68ec1 diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 0826981d501..375bc0cff1e 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -87,39 +87,6 @@ struct _Arg_types<_Ty1, _Ty2> { _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty2 second_argument_type; }; -// 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; \ - }; - -_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; \ - }; - -_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 @@ -521,6 +488,39 @@ _INLINE_VAR constexpr bool is_volatile_v = true; template struct is_volatile : bool_constant> {}; +// 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 +}; // still here for _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; \ + }; + +_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; \ + }; + +_CLASS_DEFINE_CV_REF_NOEXCEPT(_IS_FUNCTION_ELLIPSIS) +#undef _IS_FUNCTION_ELLIPSIS + +template +_INLINE_VAR constexpr bool is_function_v = + !is_reference_v<_Ty> && !is_const_v; // determine whether _Ty is a function + +template +struct is_function : 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 From bfeaa12842afa22cf97a74fa3a5ef8713416b8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Art=C3=B6m=20Bakri=20Al-Sarmini?= <3sz3tt+git@gmail.com> Date: Sat, 25 Jan 2020 18:52:33 +0300 Subject: [PATCH 02/13] _Is_function simplification --- stl/inc/type_traits | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 375bc0cff1e..79e7a275169 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -489,31 +489,6 @@ template struct is_volatile : bool_constant> {}; // 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 -}; // still here for _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; \ - }; - -_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; \ - }; - -_CLASS_DEFINE_CV_REF_NOEXCEPT(_IS_FUNCTION_ELLIPSIS) -#undef _IS_FUNCTION_ELLIPSIS - template _INLINE_VAR constexpr bool is_function_v = !is_reference_v<_Ty> && !is_const_v; // determine whether _Ty is a function @@ -521,6 +496,11 @@ _INLINE_VAR constexpr bool is_function_v = template struct is_function : bool_constant> {}; +template +struct _Is_function { // determine whether _Ty is a function + using _Bool_type = is_function<_Ty>; // NB: members are user-visible via _Weak_types +}; + // STRUCT TEMPLATE is_pod template struct _CXX20_DEPRECATE_IS_POD is_pod : bool_constant<__is_pod(_Ty)> {}; // determine whether _Ty is a POD type From a9003c0775bf7911eed49d38cd4b4ccb88001b88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Art=C3=B6m=20Bakri=20Al-Sarmini?= <3sz3tt+git@gmail.com> Date: Sat, 25 Jan 2020 19:18:33 +0300 Subject: [PATCH 03/13] clang-format --- stl/inc/type_traits | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 79e7a275169..eaa62c3aaec 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -494,7 +494,7 @@ _INLINE_VAR constexpr bool is_function_v = !is_reference_v<_Ty> && !is_const_v; // determine whether _Ty is a function template -struct is_function : bool_constant> {}; +struct is_function : bool_constant> {}; template struct _Is_function { // determine whether _Ty is a function From 2e8576cca7f140506ea5ee620fbccc1dfa96cf72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Art=C3=B6m=20Bakri=20Al-Sarmini?= <3sz3tt+git@gmail.com> Date: Sat, 25 Jan 2020 22:30:14 +0300 Subject: [PATCH 04/13] Reverted llvm --- llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm-project b/llvm-project index 85ee4ff4e47..45f630d729e 160000 --- a/llvm-project +++ b/llvm-project @@ -1 +1 @@ -Subproject commit 85ee4ff4e474788abc7abdc939114281c2a68ec1 +Subproject commit 45f630d729e2cce044ed48e6eaf4b8e61e06fede From 1334e4c133d7e3f6fb25cc8a110c91b6554e6837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Art=C3=B6m=20Bakri=20Al-Sarmini?= <3sz3tt+git@gmail.com> Date: Sat, 25 Jan 2020 22:39:25 +0300 Subject: [PATCH 05/13] Fixes, also _Is_function is back --- stl/inc/type_traits | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/stl/inc/type_traits b/stl/inc/type_traits index eaa62c3aaec..e75e7e90953 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -490,16 +490,36 @@ struct is_volatile : bool_constant> {}; // STRUCT TEMPLATE is_function template -_INLINE_VAR constexpr bool is_function_v = - !is_reference_v<_Ty> && !is_const_v; // determine whether _Ty is a function +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; \ + }; + +_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; \ + }; + +_CLASS_DEFINE_CV_REF_NOEXCEPT(_IS_FUNCTION_ELLIPSIS) +#undef _IS_FUNCTION_ELLIPSIS template -struct is_function : bool_constant> {}; +_INLINE_VAR constexpr bool is_function_v = + !is_const_v && !is_reference_v<_Ty>; // determine whether _Ty is a function template -struct _Is_function { // determine whether _Ty is a function - using _Bool_type = is_function<_Ty>; // NB: members are user-visible via _Weak_types -}; +struct is_function : bool_constant> {}; // STRUCT TEMPLATE is_pod template From dea674eadf683c4ce87be3f657f9d531e6914685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Art=C3=B6m=20Bakri=20Al-Sarmini?= <3sz3tt+git@gmail.com> Date: Sat, 25 Jan 2020 23:46:41 +0300 Subject: [PATCH 06/13] is*_pointer --- stl/inc/type_traits | 134 +++++++++++++++++++++++++------------------- 1 file changed, 75 insertions(+), 59 deletions(-) diff --git a/stl/inc/type_traits b/stl/inc/type_traits index e75e7e90953..45c18398f52 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -87,37 +87,6 @@ struct _Arg_types<_Ty1, _Ty2> { _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty2 second_argument_type; }; -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; \ - 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; \ - 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>; @@ -348,33 +317,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 @@ -455,7 +397,10 @@ _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>; +_INLINE_VAR constexpr bool is_member_pointer_v = false; + +template +_INLINE_VAR constexpr bool is_member_pointer_v<_Ty1 _Ty2::*> = true; template struct is_member_pointer : bool_constant> {}; // determine whether _Ty is a pointer to member @@ -521,6 +466,77 @@ _INLINE_VAR constexpr bool is_function_v = template struct is_function : bool_constant> {}; +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; \ + 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; \ + using _Class_type = _Arg0; \ + using _Guide_type = enable_if; \ + }; + +_CLASS_DEFINE_CV_REF_NOEXCEPT(_IS_MEMFUNPTR_ELLIPSIS) +#undef _IS_MEMFUNPTR_ELLIPSIS + +// STRUCT TEMPLATE is_member_function_pointer +template +struct _Is_member_pointer { + static constexpr bool value = false; +}; + +template +struct _Is_member_pointer<_Ty1 _Ty2::*> { + static constexpr bool value = true; + using _Member_type = _Ty2; +}; + +template +_INLINE_VAR constexpr bool is_member_function_pointer_v = // determine whether _Ty is a pointer to member function + conjunction_v, is_function::_Member_type>>; + +template +struct is_member_function_pointer : bool_constant> {}; + + +template > +struct _Is_member_object_pointer { // determine whether _Ty is a pointer to member object + static constexpr bool value = false; +}; + +// STRUCT TEMPLATE is_member_object_pointer +template +_INLINE_VAR constexpr bool is_member_object_pointer_v = // determine whether _Ty is a pointer to member object + conjunction_v<_Is_member_pointer<_Ty>::value, + negation::_Member_type>>>; + +template +struct is_member_object_pointer : bool_constant> {}; + +template +struct _Is_member_object_pointer<_Ty1 _Ty2::*, false> { + static constexpr bool value = true; + using _Class_type = _Ty2; +}; + // STRUCT TEMPLATE is_pod template struct _CXX20_DEPRECATE_IS_POD is_pod : bool_constant<__is_pod(_Ty)> {}; // determine whether _Ty is a POD type From 015fb5a42dd0866af5f1fa6a3be22930e924e149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Art=C3=B6m=20Bakri=20Al-Sarmini?= <3sz3tt+git@gmail.com> Date: Mon, 27 Jan 2020 01:44:46 +0300 Subject: [PATCH 07/13] Renaming; removed _Bool_type; better is_member_*_pointer_v --- stl/inc/functional | 2 +- stl/inc/type_traits | 203 ++++++++++++++++++++------------------------ 2 files changed, 95 insertions(+), 110 deletions(-) diff --git a/stl/inc/functional b/stl/inc/functional index e2b34c2f2b2..fccdc39c43f 100644 --- a/stl/inc/functional +++ b/stl/inc/functional @@ -1277,7 +1277,7 @@ struct _Deduce_signature {}; // can't deduce signature when &_Fx::operator() is template struct _Deduce_signature<_Fx, void_t> - : _Is_memfunptr::_Guide_type {}; // N4842 [func.wrap.func.con]/12 + : _Memfunptr_args::_Guide_type {}; // N4842 [func.wrap.func.con]/12 template function(_Fx)->function::type>; diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 45c18398f52..f696916d9c2 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -72,21 +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; -}; - -template -struct _Arg_types<_Ty1, _Ty2> { - _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty1 first_argument_type; - _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty2 second_argument_type; -}; - // STRUCT TEMPLATE is_void template _INLINE_VAR constexpr bool is_void_v = is_same_v, void>; @@ -220,7 +205,6 @@ struct remove_pointer<_Ty* volatile> { using type = _Ty; }; - template struct remove_pointer<_Ty* const volatile> { using type = _Ty; @@ -365,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)> { @@ -434,31 +411,6 @@ template struct is_volatile : bool_constant> {}; // 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; \ - }; - -_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; \ - }; - -_CLASS_DEFINE_CV_REF_NOEXCEPT(_IS_FUNCTION_ELLIPSIS) -#undef _IS_FUNCTION_ELLIPSIS - template _INLINE_VAR constexpr bool is_function_v = !is_const_v && !is_reference_v<_Ty>; // determine whether _Ty is a function @@ -466,77 +418,35 @@ _INLINE_VAR constexpr bool is_function_v = template struct is_function : bool_constant> {}; +// STRUCT TEMPLATE is_object 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; \ - 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; \ - using _Class_type = _Arg0; \ - using _Guide_type = enable_if; \ - }; +_INLINE_VAR constexpr bool is_object_v = !is_function_v<_Ty> && !is_reference_v<_Ty> && !is_void_v<_Ty>; -_CLASS_DEFINE_CV_REF_NOEXCEPT(_IS_MEMFUNPTR_ELLIPSIS) -#undef _IS_MEMFUNPTR_ELLIPSIS +template +struct is_object : bool_constant> {}; // determine whether _Ty is an object type // STRUCT TEMPLATE is_member_function_pointer -template -struct _Is_member_pointer { - static constexpr bool value = false; -}; +template +_INLINE_VAR constexpr bool is_member_function_pointer_v = // determine whether _Ty is a pointer to member function + false; template -struct _Is_member_pointer<_Ty1 _Ty2::*> { - static constexpr bool value = true; - using _Member_type = _Ty2; -}; - -template -_INLINE_VAR constexpr bool is_member_function_pointer_v = // determine whether _Ty is a pointer to member function - conjunction_v, is_function::_Member_type>>; +_INLINE_VAR constexpr bool is_member_function_pointer_v<_Ty1 _Ty2::*> = is_function_v<_Ty1>; template struct is_member_function_pointer : bool_constant> {}; - -template > -struct _Is_member_object_pointer { // determine whether _Ty is a pointer to member object - static constexpr bool value = false; -}; - // STRUCT TEMPLATE is_member_object_pointer -template +template _INLINE_VAR constexpr bool is_member_object_pointer_v = // determine whether _Ty is a pointer to member object - conjunction_v<_Is_member_pointer<_Ty>::value, - negation::_Member_type>>>; + false; + +template +_INLINE_VAR constexpr bool is_member_object_pointer_v<_Ty1 _Ty2::*> = !is_function_v<_Ty1>; template struct is_member_object_pointer : bool_constant> {}; -template -struct _Is_member_object_pointer<_Ty1 _Ty2::*, false> { - static constexpr bool value = true; - using _Class_type = _Ty2; -}; - // STRUCT TEMPLATE is_pod template struct _CXX20_DEPRECATE_IS_POD is_pod : bool_constant<__is_pod(_Ty)> {}; // determine whether _Ty is a POD type @@ -1489,6 +1399,60 @@ _NODISCARD constexpr conditional_t && is_c return _STD move(_Arg); } +template > +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; +}; + +// 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; +}; + +template +struct _Arg_types<_Ty1, _Ty2> { + _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty1 first_argument_type; + _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty2 second_argument_type; +}; + +template +struct _Memfunptr_args { // base class for member function pointer predicates +}; + +#define _MEMFUNPTR_ARGS(CALL_OPT, CV_OPT, REF_OPT, NOEXCEPT_OPT) \ + template \ + struct _Memfunptr_args<_Ret (CALL_OPT _Arg0::*)(_Types...) CV_OPT REF_OPT NOEXCEPT_OPT> \ + : _Arg_types { \ + _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret result_type; \ + using _Class_type = _Arg0; \ + using _Guide_type = enable_if, _Ret(_Types...)>; \ + }; + +_MEMBER_CALL_CV_REF_NOEXCEPT(_MEMFUNPTR_ARGS) +#undef _MEMFUNPTR_ARGS + +#define _MEMFUNPTR_ARGS_ELLIPSIS(CV_REF_NOEXCEPT_OPT) \ + template \ + struct _Memfunptr_args<_Ret (_Arg0::*)(_Types..., ...) \ + CV_REF_NOEXCEPT_OPT> { /* no calling conventions for ellipsis */ \ + _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret result_type; \ + using _Class_type = _Arg0; \ + using _Guide_type = enable_if; \ + }; + +_CLASS_DEFINE_CV_REF_NOEXCEPT(_MEMFUNPTR_ARGS_ELLIPSIS) +#undef _MEMFUNPTR_ARGS_ELLIPSIS + template class reference_wrapper; @@ -1578,7 +1542,7 @@ class reference_wrapper; \ template \ struct _CONCAT(NAME_PREFIX, _Invoker1)<_Callable, _Ty1, _Removed_cvref, true, false> \ - : conditional_t::_Class_type, remove_reference_t<_Ty1>>, \ + : conditional_t::_Class_type, remove_reference_t<_Ty1>>, \ _CONCAT(NAME_PREFIX, _Invoker_pmf_object), \ conditional_t<_Is_specialization_v<_Remove_cvref_t<_Ty1>, reference_wrapper>, \ _CONCAT(NAME_PREFIX, _Invoker_pmf_refwrap), \ @@ -1662,7 +1626,6 @@ struct _Invoker_ret<_Unforced, false> { // selected for _Rx being _Unforced } }; - // TYPE TRAITS FOR invoke() template void _Implicitly_convert_to(_To) noexcept; // not defined @@ -1806,6 +1769,28 @@ _NODISCARD constexpr bool is_constant_evaluated() noexcept { #endif // _HAS_CXX20 // STRUCT 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; \ + }; + +_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; \ + }; + +_CLASS_DEFINE_CV_REF_NOEXCEPT(_FUNCTION_ARGS_ELLIPSIS) +#undef _FUNCTION_ARGS_ELLIPSIS + template struct _Weak_result_type {}; // default definition @@ -1842,10 +1827,10 @@ _STL_RESTORE_DEPRECATED_WARNING template 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 _F_or_pf_args = _Function_args>; + using _Pmf_args = _Memfunptr_args>; + using type = conditional_t>, _F_or_pf_args, + conditional_t, _Pmf_args, _Weak_binary_args<_Ty>>>; }; // CLASS TEMPLATE reference_wrapper From c7cd8d73e43bb06d6b15f892f87723c1968fe203 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Tue, 28 Jan 2020 12:04:36 -0800 Subject: [PATCH 08/13] Nitpicky formatting --- stl/inc/type_traits | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/stl/inc/type_traits b/stl/inc/type_traits index f696916d9c2..88b739b51f5 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -1426,8 +1426,7 @@ struct _Arg_types<_Ty1, _Ty2> { }; template -struct _Memfunptr_args { // base class for member function pointer predicates -}; +struct _Memfunptr_args {}; // base class for member function pointer predicates #define _MEMFUNPTR_ARGS(CALL_OPT, CV_OPT, REF_OPT, NOEXCEPT_OPT) \ template \ @@ -1770,8 +1769,7 @@ _NODISCARD constexpr bool is_constant_evaluated() noexcept { // STRUCT TEMPLATE _Weak_types template -struct _Function_args { // determine whether _Ty is a function -}; +struct _Function_args {}; // determine whether _Ty is a function #define _FUNCTION_ARGS(CALL_OPT, CV_OPT, REF_OPT, NOEXCEPT_OPT) \ template \ From b4404a32e5ef694857d133f1cbe34ca8c6af55a2 Mon Sep 17 00:00:00 2001 From: ArtemSarmini <3sz3tt+git@gmail.com> Date: Tue, 23 Jun 2020 20:29:39 +0300 Subject: [PATCH 09/13] comments fixes removed pointless comments, provided better _Arg_types description --- stl/inc/type_traits | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 88b739b51f5..dd284845195 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -412,8 +412,8 @@ struct is_volatile : bool_constant> {}; // STRUCT TEMPLATE is_function template -_INLINE_VAR constexpr bool is_function_v = - !is_const_v && !is_reference_v<_Ty>; // determine whether _Ty is a function +_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> {}; @@ -423,12 +423,11 @@ 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 is_object : 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 - false; +_INLINE_VAR constexpr bool is_member_function_pointer_v = false; template _INLINE_VAR constexpr bool is_member_function_pointer_v<_Ty1 _Ty2::*> = is_function_v<_Ty1>; @@ -438,8 +437,7 @@ struct is_member_function_pointer : bool_constant -_INLINE_VAR constexpr bool is_member_object_pointer_v = // determine whether _Ty is a pointer to member object - false; +_INLINE_VAR constexpr bool is_member_object_pointer_v = false; template _INLINE_VAR constexpr bool is_member_object_pointer_v<_Ty1 _Ty2::*> = !is_function_v<_Ty1>; @@ -1400,7 +1398,7 @@ _NODISCARD constexpr conditional_t && is_c } template > -struct _Is_member_object_pointer { // determine whether _Ty is a pointer to member object +struct _Is_member_object_pointer { static constexpr bool value = false; }; @@ -1412,7 +1410,7 @@ struct _Is_member_object_pointer<_Ty1 _Ty2::*, false> { // STRUCT TEMPLATE _Arg_types template -struct _Arg_types {}; // provide argument_type, etc. (sometimes) +struct _Arg_types {}; // provide typedefs for argument types if number of arguments is 1 or 2 template struct _Arg_types<_Ty1> { From bcd53b1af838f7b3e8df3960774c96946b6dab6c Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Fri, 10 Jul 2020 07:39:15 -0700 Subject: [PATCH 10/13] Fix problems: * `is_member_function_pointer_v` should ignore cv-qualifiers (easy to fix) and calling conventions (super hard to fix). Bring back the inefficient `_Is_memfunptr` which is not so bad since (1) cl actually implements `is_member_function_pointer_v` in the compiler and (2) we can use an intrinsic for clang. Drive-by: Make `_Weak_types` an alias template. --- stl/inc/functional | 6 +-- stl/inc/type_traits | 118 ++++++++++++++++++++++---------------------- 2 files changed, 63 insertions(+), 61 deletions(-) diff --git a/stl/inc/functional b/stl/inc/functional index d0b349b9450..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; @@ -1292,7 +1292,7 @@ struct _Deduce_signature {}; // can't deduce signature when &_Fx::operator() is template struct _Deduce_signature<_Fx, void_t> - : _Memfunptr_args::_Guide_type {}; // N4842 [func.wrap.func.con]/12 + : _Is_memfunptr::_Guide_type {}; // N4842 [func.wrap.func.con]/12 template function(_Fx) -> function::type>; @@ -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 3274762e07f..2de87462f95 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -425,12 +425,60 @@ _INLINE_VAR constexpr bool is_object_v = !is_function_v<_Ty> && !is_reference_v< template struct is_object : bool_constant> {}; -// STRUCT TEMPLATE is_member_function_pointer -template -_INLINE_VAR constexpr bool is_member_function_pointer_v = false; +// 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 -_INLINE_VAR constexpr bool is_member_function_pointer_v<_Ty1 _Ty2::*> = is_function_v<_Ty1>; +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_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 + +#ifdef __clang__ +template +_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<_Ty>::_Bool_type::value; +#endif // ^^^ Other ^^^ template struct is_member_function_pointer : bool_constant> {}; @@ -1410,48 +1458,6 @@ struct _Is_member_object_pointer<_Ty1 _Ty2::*, false> { using _Class_type = _Ty2; }; -// 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; -}; - -template -struct _Memfunptr_args {}; // base class for member function pointer predicates - -#define _MEMFUNPTR_ARGS(CALL_OPT, CV_OPT, REF_OPT, NOEXCEPT_OPT) \ - template \ - struct _Memfunptr_args<_Ret (CALL_OPT _Arg0::*)(_Types...) CV_OPT REF_OPT NOEXCEPT_OPT> \ - : _Arg_types { \ - _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret result_type; \ - using _Class_type = _Arg0; \ - using _Guide_type = enable_if, _Ret(_Types...)>; \ - }; - -_MEMBER_CALL_CV_REF_NOEXCEPT(_MEMFUNPTR_ARGS) -#undef _MEMFUNPTR_ARGS - -#define _MEMFUNPTR_ARGS_ELLIPSIS(CV_REF_NOEXCEPT_OPT) \ - template \ - struct _Memfunptr_args<_Ret (_Arg0::*)(_Types..., ...) \ - CV_REF_NOEXCEPT_OPT> { /* no calling conventions for ellipsis */ \ - _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret result_type; \ - using _Class_type = _Arg0; \ - using _Guide_type = enable_if; \ - }; - -_CLASS_DEFINE_CV_REF_NOEXCEPT(_MEMFUNPTR_ARGS_ELLIPSIS) -#undef _MEMFUNPTR_ARGS_ELLIPSIS - template class reference_wrapper; @@ -1789,14 +1795,14 @@ 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; \ + _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret _RESULT_TYPE_NAME; \ }; _NON_MEMBER_CALL_CV_REF_NOEXCEPT(_FUNCTION_ARGS) @@ -1805,7 +1811,7 @@ _NON_MEMBER_CALL_CV_REF_NOEXCEPT(_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; \ + _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret _RESULT_TYPE_NAME; \ }; _CLASS_DEFINE_CV_REF_NOEXCEPT(_FUNCTION_ARGS_ELLIPSIS) @@ -1826,8 +1832,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 +1852,8 @@ struct _Weak_binary_args<_Ty, void_t -struct _Weak_types { // provide nested types (sometimes) - using _F_or_pf_args = _Function_args>; - using _Pmf_args = _Memfunptr_args>; - using type = conditional_t>, _F_or_pf_args, - conditional_t, _Pmf_args, _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 +1870,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: From 9a37223ab63040ee558f3bf306de6d801b91df10 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Sat, 11 Jul 2020 18:18:23 -0700 Subject: [PATCH 11/13] Moar bugs: * `_Is_memfunptr` is sensitive to cv-qualifiers, they need to be stripped from its argument * `is_member_pointer_v` needs to work with calling conventions just like `is_member_function_pointer_v` does. --- stl/inc/type_traits | 114 +++++++++--------- .../test.cpp | 8 ++ 2 files changed, 68 insertions(+), 54 deletions(-) diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 2de87462f95..46bb915a992 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -372,59 +372,6 @@ 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 = false; - -template -_INLINE_VAR constexpr bool is_member_pointer_v<_Ty1 _Ty2::*> = true; - -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_const -template -_INLINE_VAR constexpr bool is_const_v = false; // determine whether type argument is const qualified - -template -_INLINE_VAR constexpr bool is_const_v = true; - -template -struct is_const : bool_constant> {}; - -// STRUCT TEMPLATE is_volatile -template -_INLINE_VAR constexpr bool is_volatile_v = false; // determine whether type argument is volatile qualified - -template -_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 = !is_function_v<_Ty> && !is_reference_v<_Ty> && !is_void_v<_Ty>; - -template -struct is_object : bool_constant> {}; - // STRUCT TEMPLATE _Arg_types template struct _Arg_types {}; // provide argument_type, etc. when sizeof...(_Types) is 1 or 2 @@ -472,17 +419,76 @@ _MEMBER_CALL_CV_REF_NOEXCEPT(_IS_MEMFUNPTR) _CLASS_DEFINE_CV_REF_NOEXCEPT(_IS_MEMFUNPTR_ELLIPSIS) #undef _IS_MEMFUNPTR_ELLIPSIS +// STRUCT TEMPLATE is_member_function_pointer #ifdef __clang__ template _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<_Ty>::_Bool_type::value; +_INLINE_VAR constexpr bool is_member_function_pointer_v = _Is_memfunptr>::_Bool_type::value; #endif // ^^^ Other ^^^ template struct is_member_function_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_function_pointer_v<_Ty>; + +template +_INLINE_VAR constexpr bool is_member_pointer_v<_Ty1 _Ty2::*> = true; +#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_const +template +_INLINE_VAR constexpr bool is_const_v = false; // determine whether type argument is const qualified + +template +_INLINE_VAR constexpr bool is_const_v = true; + +template +struct is_const : bool_constant> {}; + +// STRUCT TEMPLATE is_volatile +template +_INLINE_VAR constexpr bool is_volatile_v = false; // determine whether type argument is volatile qualified + +template +_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 = !is_function_v<_Ty> && !is_reference_v<_Ty> && !is_void_v<_Ty>; + +template +struct is_object : bool_constant> {}; + // STRUCT TEMPLATE is_member_object_pointer template _INLINE_VAR constexpr bool is_member_object_pointer_v = false; 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); From 1b643b70ba7f424a904c44b95eb27e69f4f339a9 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Sun, 12 Jul 2020 19:21:31 -0700 Subject: [PATCH 12/13] `is_member_pointer` and `is_member_object_pointer` also need to ignore cv-qualifiers. --- stl/inc/type_traits | 72 ++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 46bb915a992..6cc1cfd2527 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -419,7 +419,6 @@ _MEMBER_CALL_CV_REF_NOEXCEPT(_IS_MEMFUNPTR) _CLASS_DEFINE_CV_REF_NOEXCEPT(_IS_MEMFUNPTR_ELLIPSIS) #undef _IS_MEMFUNPTR_ELLIPSIS -// STRUCT TEMPLATE is_member_function_pointer #ifdef __clang__ template _INLINE_VAR constexpr bool is_member_function_pointer_v = __is_member_function_pointer(_Ty); @@ -431,29 +430,6 @@ _INLINE_VAR constexpr bool is_member_function_pointer_v = _Is_memfunptr struct is_member_function_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_function_pointer_v<_Ty>; - -template -_INLINE_VAR constexpr bool is_member_pointer_v<_Ty1 _Ty2::*> = true; -#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_const template _INLINE_VAR constexpr bool is_const_v = false; // determine whether type argument is const qualified @@ -491,14 +467,47 @@ struct is_object : bool_constant> {}; // STRUCT TEMPLATE is_member_object_pointer template -_INLINE_VAR constexpr bool is_member_object_pointer_v = false; +struct _Is_member_object_pointer { + static constexpr bool value = false; +}; template -_INLINE_VAR constexpr bool is_member_object_pointer_v<_Ty1 _Ty2::*> = !is_function_v<_Ty1>; +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 @@ -1453,17 +1462,6 @@ _NODISCARD constexpr conditional_t && is_c return _STD move(_Arg); } -template > -struct _Is_member_object_pointer { - static constexpr bool value = false; -}; - -template -struct _Is_member_object_pointer<_Ty1 _Ty2::*, false> { - static constexpr bool value = true; - using _Class_type = _Ty2; -}; - template class reference_wrapper; From 39c295533604a4b2fd1c1dc42763610d7e57e0e1 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 31 Jul 2020 16:50:26 -0700 Subject: [PATCH 13/13] Also optimize is_object_v. --- stl/inc/type_traits | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 6cc1cfd2527..41438975b0f 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -460,7 +460,8 @@ struct is_function : bool_constant> {}; // STRUCT TEMPLATE is_object template -_INLINE_VAR constexpr bool is_object_v = !is_function_v<_Ty> && !is_reference_v<_Ty> && !is_void_v<_Ty>; +_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> {};