Skip to content

Commit 10bf563

Browse files
committed
Simplify <type_traits> implementations.
This patch rewrites a number of old meta-function implementations that assumed const/volatile could not be safely applied to all types. This is no longer the case, though for some types (Ex function types), the const qualifier can be ignored. The largest improvement in this patch is the reduction of is_function. Thanks to Matt Calabrese for the improved implementation. llvm-svn: 367749
1 parent 96bb347 commit 10bf563

File tree

1 file changed

+36
-67
lines changed

1 file changed

+36
-67
lines changed

libcxx/include/type_traits

Lines changed: 36 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -886,56 +886,40 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_class_v
886886

887887
// is_function
888888

889-
namespace __libcpp_is_function_imp
890-
{
891-
struct __dummy_type {};
892-
template <class _Tp> char __test(_Tp*);
893-
template <class _Tp> char __test(__dummy_type);
894-
template <class _Tp> __two __test(...);
895-
template <class _Tp> _Tp& __source(int);
896-
template <class _Tp> __dummy_type __source(...);
897-
}
898-
899-
template <class _Tp, bool = is_class<_Tp>::value ||
900-
is_union<_Tp>::value ||
901-
is_void<_Tp>::value ||
902-
is_reference<_Tp>::value ||
903-
__is_nullptr_t<_Tp>::value >
904-
struct __libcpp_is_function
905-
: public integral_constant<bool, sizeof(__libcpp_is_function_imp::__test<_Tp>(__libcpp_is_function_imp::__source<_Tp>(0))) == 1>
906-
{};
907-
template <class _Tp> struct __libcpp_is_function<_Tp, true> : public false_type {};
908-
909889
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_function
910-
: public __libcpp_is_function<_Tp> {};
890+
: public _BoolConstant<
891+
#ifdef __clang__
892+
__is_function(_Tp)
893+
#else
894+
!(is_reference<_Tp>::value || is_const<const _Tp>::value)
895+
#endif
896+
> {};
897+
911898

912899
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
913900
template <class _Tp>
914901
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_function_v
915902
= is_function<_Tp>::value;
916903
#endif
917904

918-
// is_member_function_pointer
919-
920-
// template <class _Tp> struct __libcpp_is_member_function_pointer : public false_type {};
921-
// template <class _Tp, class _Up> struct __libcpp_is_member_function_pointer<_Tp _Up::*> : public is_function<_Tp> {};
922-
//
923-
924-
template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr>
925-
struct __member_pointer_traits_imp
926-
{ // forward declaration; specializations later
905+
template <class _Tp> struct __libcpp_is_member_pointer {
906+
enum {
907+
__is_member = false,
908+
__is_func = false,
909+
__is_obj = false
910+
};
911+
};
912+
template <class _Tp, class _Up> struct __libcpp_is_member_pointer<_Tp _Up::*> {
913+
enum {
914+
__is_member = true,
915+
__is_func = is_function<_Tp>::value,
916+
__is_obj = !__is_func,
917+
};
927918
};
928919

929920

930-
template <class _Tp> struct __libcpp_is_member_function_pointer
931-
: public false_type {};
932-
933-
template <class _Ret, class _Class>
934-
struct __libcpp_is_member_function_pointer<_Ret _Class::*>
935-
: public is_function<_Ret> {};
936-
937921
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
938-
: public __libcpp_is_member_function_pointer<typename remove_cv<_Tp>::type>::type {};
922+
: public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_func > {};
939923

940924
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
941925
template <class _Tp>
@@ -945,11 +929,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_function_pointer_v
945929

946930
// is_member_pointer
947931

948-
template <class _Tp> struct __libcpp_is_member_pointer : public false_type {};
949-
template <class _Tp, class _Up> struct __libcpp_is_member_pointer<_Tp _Up::*> : public true_type {};
950-
951932
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_pointer
952-
: public __libcpp_is_member_pointer<typename remove_cv<_Tp>::type> {};
933+
: public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_member > {};
953934

954935
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
955936
template <class _Tp>
@@ -960,8 +941,7 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_pointer_v
960941
// is_member_object_pointer
961942

962943
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
963-
: public integral_constant<bool, is_member_pointer<_Tp>::value &&
964-
!is_member_function_pointer<_Tp>::value> {};
944+
: public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_obj > {};
965945

966946
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
967947
template <class _Tp>
@@ -1080,42 +1060,28 @@ struct __is_referenceable : integral_constant<bool,
10801060

10811061
// add_const
10821062

1083-
template <class _Tp, bool = is_reference<_Tp>::value ||
1084-
is_function<_Tp>::value ||
1085-
is_const<_Tp>::value >
1086-
struct __add_const {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};
1087-
1088-
template <class _Tp>
1089-
struct __add_const<_Tp, false> {typedef _LIBCPP_NODEBUG_TYPE const _Tp type;};
1090-
1091-
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_const
1092-
{typedef _LIBCPP_NODEBUG_TYPE typename __add_const<_Tp>::type type;};
1063+
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_const {
1064+
typedef _LIBCPP_NODEBUG_TYPE const _Tp type;
1065+
};
10931066

10941067
#if _LIBCPP_STD_VER > 11
10951068
template <class _Tp> using add_const_t = typename add_const<_Tp>::type;
10961069
#endif
10971070

10981071
// add_volatile
10991072

1100-
template <class _Tp, bool = is_reference<_Tp>::value ||
1101-
is_function<_Tp>::value ||
1102-
is_volatile<_Tp>::value >
1103-
struct __add_volatile {typedef _Tp type;};
1104-
1105-
template <class _Tp>
1106-
struct __add_volatile<_Tp, false> {typedef volatile _Tp type;};
1107-
1108-
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_volatile
1109-
{typedef _LIBCPP_NODEBUG_TYPE typename __add_volatile<_Tp>::type type;};
1073+
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_volatile {
1074+
typedef _LIBCPP_NODEBUG_TYPE volatile _Tp type;
1075+
};
11101076

11111077
#if _LIBCPP_STD_VER > 11
11121078
template <class _Tp> using add_volatile_t = typename add_volatile<_Tp>::type;
11131079
#endif
11141080

11151081
// add_cv
1116-
1117-
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_cv
1118-
{typedef _LIBCPP_NODEBUG_TYPE typename add_const<typename add_volatile<_Tp>::type>::type type;};
1082+
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_cv {
1083+
typedef _LIBCPP_NODEBUG_TYPE const volatile _Tp type;
1084+
};
11191085

11201086
#if _LIBCPP_STD_VER > 11
11211087
template <class _Tp> using add_cv_t = typename add_cv<_Tp>::type;
@@ -2307,6 +2273,9 @@ __decay_copy(_Tp&& __t)
23072273
return _VSTD::forward<_Tp>(__t);
23082274
}
23092275

2276+
template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr>
2277+
struct __member_pointer_traits_imp;
2278+
23102279
template <class _Rp, class _Class, class ..._Param>
23112280
struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false>
23122281
{

0 commit comments

Comments
 (0)