[cfe-commits] [libcxx] r131407 - in /libcxx/trunk: include/type_traits test/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp
Howard Hinnant
hhinnant at apple.com
Mon May 16 09:17:21 PDT 2011
Author: hhinnant
Date: Mon May 16 11:17:21 2011
New Revision: 131407
URL: http://llvm.org/viewvc/llvm-project?rev=131407&view=rev
Log:
Redesign of result_of to handle reference-qualified member functions
Modified:
libcxx/trunk/include/type_traits
libcxx/trunk/test/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp
Modified: libcxx/trunk/include/type_traits
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/type_traits?rev=131407&r1=131406&r2=131407&view=diff
==============================================================================
--- libcxx/trunk/include/type_traits (original)
+++ libcxx/trunk/include/type_traits Mon May 16 11:17:21 2011
@@ -1419,51 +1419,261 @@
>::type type;
};
-// result_of
+template <class _MP, bool _IsMemberFuctionPtr, bool _IsMemberObjectPtr>
+struct __member_pointer_traits_imp
+{
+};
-template <class> class result_of;
+#ifndef _LIBCPP_HAS_NO_VARIADICS
-template <class _Fn, bool>
-class __result_of
+template <class _R, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_R (_Class::*)(_Param...), true, false>
{
+ typedef _Class _ClassType;
+ typedef _R _ReturnType;
};
-#ifndef _LIBCPP_HAS_NO_VARIADICS
+template <class _R, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_R (_Class::*)(_Param...) const, true, false>
+{
+ typedef _Class const _ClassType;
+ typedef _R _ReturnType;
+};
-template <class _Fn, class ..._ArgTypes>
-class __result_of<_Fn(_ArgTypes...), true>
+template <class _R, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_R (_Class::*)(_Param...) volatile, true, false>
{
-public:
- typedef decltype(declval<_Fn>()(declval<_ArgTypes>()...)) type;
+ typedef _Class volatile _ClassType;
+ typedef _R _ReturnType;
};
-template <class _MP, class _Tp, bool _IsMemberFunctionPtr, class ..._Args>
-struct __result_of_mp {};
+template <class _R, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_R (_Class::*)(_Param...) const volatile, true, false>
+{
+ typedef _Class const volatile _ClassType;
+ typedef _R _ReturnType;
+};
-// member function pointer
+#if __has_feature(cxx_reference_qualified_functions)
+
+template <class _R, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_R (_Class::*)(_Param...) &, true, false>
+{
+ typedef _Class& _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_R (_Class::*)(_Param...) const&, true, false>
+{
+ typedef _Class const& _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_R (_Class::*)(_Param...) volatile&, true, false>
+{
+ typedef _Class volatile& _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_R (_Class::*)(_Param...) const volatile&, true, false>
+{
+ typedef _Class const volatile& _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_R (_Class::*)(_Param...) &&, true, false>
+{
+ typedef _Class&& _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_R (_Class::*)(_Param...) const&&, true, false>
+{
+ typedef _Class const&& _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_R (_Class::*)(_Param...) volatile&&, true, false>
+{
+ typedef _Class volatile&& _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class ..._Param>
+struct __member_pointer_traits_imp<_R (_Class::*)(_Param...) const volatile&&, true, false>
+{
+ typedef _Class const volatile&& _ClassType;
+ typedef _R _ReturnType;
+};
+
+#endif // __has_feature(cxx_reference_qualified_functions)
+
+#else // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _R, class _Class>
+struct __member_pointer_traits_imp<_R (_Class::*)(), true, false>
+{
+ typedef _Class _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class _P0>
+struct __member_pointer_traits_imp<_R (_Class::*)(_P0), true, false>
+{
+ typedef _Class _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class _P0, class _P1>
+struct __member_pointer_traits_imp<_R (_Class::*)(_P0, _P1), true, false>
+{
+ typedef _Class _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class _P0, class _P1, class _P2>
+struct __member_pointer_traits_imp<_R (_Class::*)(_P0, _P1, _P2), true, false>
+{
+ typedef _Class _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class>
+struct __member_pointer_traits_imp<_R (_Class::*)() const, true, false>
+{
+ typedef _Class const _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class _P0>
+struct __member_pointer_traits_imp<_R (_Class::*)(_P0) const, true, false>
+{
+ typedef _Class const _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class _P0, class _P1>
+struct __member_pointer_traits_imp<_R (_Class::*)(_P0, _P1) const, true, false>
+{
+ typedef _Class const _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class _P0, class _P1, class _P2>
+struct __member_pointer_traits_imp<_R (_Class::*)(_P0, _P1, _P2) const, true, false>
+{
+ typedef _Class const _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class>
+struct __member_pointer_traits_imp<_R (_Class::*)() volatile, true, false>
+{
+ typedef _Class volatile _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class _P0>
+struct __member_pointer_traits_imp<_R (_Class::*)(_P0) volatile, true, false>
+{
+ typedef _Class volatile _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class _P0, class _P1>
+struct __member_pointer_traits_imp<_R (_Class::*)(_P0, _P1) volatile, true, false>
+{
+ typedef _Class volatile _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class _P0, class _P1, class _P2>
+struct __member_pointer_traits_imp<_R (_Class::*)(_P0, _P1, _P2) volatile, true, false>
+{
+ typedef _Class volatile _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class>
+struct __member_pointer_traits_imp<_R (_Class::*)() const volatile, true, false>
+{
+ typedef _Class const volatile _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class _P0>
+struct __member_pointer_traits_imp<_R (_Class::*)(_P0) const volatile, true, false>
+{
+ typedef _Class const volatile _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class _P0, class _P1>
+struct __member_pointer_traits_imp<_R (_Class::*)(_P0, _P1) const volatile, true, false>
+{
+ typedef _Class const volatile _ClassType;
+ typedef _R _ReturnType;
+};
+
+template <class _R, class _Class, class _P0, class _P1, class _P2>
+struct __member_pointer_traits_imp<_R (_Class::*)(_P0, _P1, _P2) const volatile, true, false>
+{
+ typedef _Class const volatile _ClassType;
+ typedef _R _ReturnType;
+};
+
+#endif // _LIBCPP_HAS_NO_VARIADICS
+
+template <class _R, class _Class>
+struct __member_pointer_traits_imp<_R _Class::*, false, true>
+{
+ typedef _Class _ClassType;
+ typedef _R _ReturnType;
+};
-template <class _R, class _Class, class _Tp, class ..._Params, class ..._Args>
-struct __result_of_mp<_R (_Class::*)(_Params...), _Tp, true, _Args...>
+template <class _MP>
+struct __member_pointer_traits
+ : public __member_pointer_traits_imp<_MP,
+ is_member_function_pointer<_MP>::value,
+ is_member_object_pointer<_MP>::value>
{
- typedef _R type;
+// typedef ... _ClassType;
+// typedef ... _ReturnType;
};
-template <class _R, class _Class, class _Tp, class ..._Params, class ..._Args>
-struct __result_of_mp<_R (_Class::*)(_Params...) const, _Tp, true, _Args...>
+// result_of
+
+template <class> class result_of;
+
+template <class _Fn, bool, bool>
+class __result_of
{
- typedef _R type;
};
-template <class _R, class _Class, class _Tp, class ..._Params, class ..._Args>
-struct __result_of_mp<_R (_Class::*)(_Params...) volatile, _Tp, true, _Args...>
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _Fn, class ..._ArgTypes>
+class __result_of<_Fn(_ArgTypes...), true, false>
{
- typedef _R type;
+public:
+ typedef decltype(declval<_Fn>()(declval<_ArgTypes>()...)) type;
};
-template <class _R, class _Class, class _Tp, class ..._Params, class ..._Args>
-struct __result_of_mp<_R (_Class::*)(_Params...) const volatile, _Tp, true, _Args...>
+template <class _MP, class _Tp, bool _IsMemberFunctionPtr>
+struct __result_of_mp;
+
+// member function pointer
+
+template <class _MP, class _Tp>
+struct __result_of_mp<_MP, _Tp, true>
+ : public common_type<typename __member_pointer_traits<_MP>::_ReturnType>
{
- typedef _R type;
};
// member data pointer
@@ -1474,7 +1684,7 @@
template <class _R, class _Class, class _Tp>
struct __result_of_mdp<_R _Class::*, _Tp, false>
{
- typedef typename __apply_cv<decltype(*_STD::declval<_Tp>()), _R>::type type;
+ typedef typename __apply_cv<decltype(*_STD::declval<_Tp>()), _R>::type&& type;
};
template <class _R, class _Class, class _Tp>
@@ -1491,9 +1701,10 @@
};
template <class _Fn, class _Tp, class ..._ArgTypes>
-class __result_of<_Fn(_Tp, _ArgTypes...), false> // _Fn must be member pointer
- : public __result_of_mp<_Fn, _Tp, is_member_function_pointer<_Fn>::value,
- _ArgTypes...>
+class __result_of<_Fn(_Tp, _ArgTypes...), false, true> // _Fn must be member pointer
+ : public __result_of_mp<typename remove_reference<_Fn>::type,
+ _Tp,
+ is_member_function_pointer<typename remove_reference<_Fn>::type>::value>
{
};
@@ -1503,10 +1714,8 @@
class _LIBCPP_VISIBLE result_of<_Fn(_ArgTypes...)>
: public __result_of<_Fn(_ArgTypes...),
is_class<typename remove_reference<_Fn>::type>::value ||
- is_function<typename remove_pointer<
- typename remove_reference<_Fn>::type
- >::type
- >::value
+ is_function<typename remove_reference<_Fn>::type>::value,
+ is_member_pointer<typename remove_reference<_Fn>::type>::value
>
{
};
@@ -1514,41 +1723,110 @@
#else // _LIBCPP_HAS_NO_VARIADICS
template <class _Fn>
-class __result_of<_Fn(), true>
+class __result_of<_Fn(), true, false>
{
public:
typedef decltype(declval<_Fn>()()) type;
};
template <class _Fn, class _A0>
-class __result_of<_Fn(_A0), true>
+class __result_of<_Fn(_A0), true, false>
{
public:
typedef decltype(declval<_Fn>()(declval<_A0>())) type;
};
template <class _Fn, class _A0, class _A1>
-class __result_of<_Fn(_A0, _A1), true>
+class __result_of<_Fn(_A0, _A1), true, false>
{
public:
typedef decltype(declval<_Fn>()(declval<_A0>(), declval<_A1>())) type;
};
template <class _Fn, class _A0, class _A1, class _A2>
-class __result_of<_Fn(_A0, _A1, _A2), true>
+class __result_of<_Fn(_A0, _A1, _A2), true, false>
{
public:
typedef decltype(declval<_Fn>()(declval<_A0>(), declval<_A1>(), declval<_A2>())) type;
};
+template <class _MP, class _Tp, bool _IsMemberFunctionPtr>
+struct __result_of_mp;
+
+// member function pointer
+
+template <class _MP, class _Tp>
+struct __result_of_mp<_MP, _Tp, true>
+ : public common_type<typename __member_pointer_traits<_MP>::_ReturnType>
+{
+};
+
+// member data pointer
+
+template <class _MP, class _Tp, bool>
+struct __result_of_mdp;
+
+template <class _R, class _Class, class _Tp>
+struct __result_of_mdp<_R _Class::*, _Tp, false>
+{
+ typedef typename __apply_cv<decltype(*_STD::declval<_Tp>()), _R>::type& type;
+};
+
+template <class _R, class _Class, class _Tp>
+struct __result_of_mdp<_R _Class::*, _Tp, true>
+{
+ typedef typename __apply_cv<_Tp, _R>::type& type;
+};
+
+template <class _R, class _Class, class _Tp>
+struct __result_of_mp<_R _Class::*, _Tp, false>
+ : public __result_of_mdp<_R _Class::*, _Tp,
+ is_base_of<_Class, typename remove_reference<_Tp>::type>::value>
+{
+};
+
+
+
+template <class _Fn, class _Tp>
+class __result_of<_Fn(_Tp), false, true> // _Fn must be member pointer
+ : public __result_of_mp<typename remove_reference<_Fn>::type,
+ _Tp,
+ is_member_function_pointer<typename remove_reference<_Fn>::type>::value>
+{
+};
+
+template <class _Fn, class _Tp, class _A0>
+class __result_of<_Fn(_Tp, _A0), false, true> // _Fn must be member pointer
+ : public __result_of_mp<typename remove_reference<_Fn>::type,
+ _Tp,
+ is_member_function_pointer<typename remove_reference<_Fn>::type>::value>
+{
+};
+
+template <class _Fn, class _Tp, class _A0, class _A1>
+class __result_of<_Fn(_Tp, _A0, _A1), false, true> // _Fn must be member pointer
+ : public __result_of_mp<typename remove_reference<_Fn>::type,
+ _Tp,
+ is_member_function_pointer<typename remove_reference<_Fn>::type>::value>
+{
+};
+
+template <class _Fn, class _Tp, class _A0, class _A1, class _A2>
+class __result_of<_Fn(_Tp, _A0, _A1, _A2), false, true> // _Fn must be member pointer
+ : public __result_of_mp<typename remove_reference<_Fn>::type,
+ _Tp,
+ is_member_function_pointer<typename remove_reference<_Fn>::type>::value>
+{
+};
+
+// result_of
+
template <class _Fn>
class _LIBCPP_VISIBLE result_of<_Fn()>
: public __result_of<_Fn(),
is_class<typename remove_reference<_Fn>::type>::value ||
- is_function<typename remove_pointer<
- typename remove_reference<_Fn>::type
- >::type
- >::value
+ is_function<typename remove_reference<_Fn>::type>::value,
+ is_member_pointer<typename remove_reference<_Fn>::type>::value
>
{
};
@@ -1557,10 +1835,8 @@
class _LIBCPP_VISIBLE result_of<_Fn(_A0)>
: public __result_of<_Fn(_A0),
is_class<typename remove_reference<_Fn>::type>::value ||
- is_function<typename remove_pointer<
- typename remove_reference<_Fn>::type
- >::type
- >::value
+ is_function<typename remove_reference<_Fn>::type>::value,
+ is_member_pointer<typename remove_reference<_Fn>::type>::value
>
{
};
@@ -1569,10 +1845,8 @@
class _LIBCPP_VISIBLE result_of<_Fn(_A0, _A1)>
: public __result_of<_Fn(_A0, _A1),
is_class<typename remove_reference<_Fn>::type>::value ||
- is_function<typename remove_pointer<
- typename remove_reference<_Fn>::type
- >::type
- >::value
+ is_function<typename remove_reference<_Fn>::type>::value,
+ is_member_pointer<typename remove_reference<_Fn>::type>::value
>
{
};
@@ -1581,10 +1855,8 @@
class _LIBCPP_VISIBLE result_of<_Fn(_A0, _A1, _A2)>
: public __result_of<_Fn(_A0, _A1, _A2),
is_class<typename remove_reference<_Fn>::type>::value ||
- is_function<typename remove_pointer<
- typename remove_reference<_Fn>::type
- >::type
- >::value
+ is_function<typename remove_reference<_Fn>::type>::value,
+ is_member_pointer<typename remove_reference<_Fn>::type>::value
>
{
};
Modified: libcxx/trunk/test/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp?rev=131407&r1=131406&r2=131407&view=diff
==============================================================================
--- libcxx/trunk/test/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp (original)
+++ libcxx/trunk/test/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp Mon May 16 11:17:21 2011
@@ -34,6 +34,10 @@
static_assert((std::is_same<std::result_of<S&(unsigned char, int&)>::type, double>::value), "Error!");
static_assert((std::is_same<std::result_of<PF1()>::type, bool>::value), "Error!");
static_assert((std::is_same<std::result_of<PMS(std::unique_ptr<S>, int)>::type, void>::value), "Error!");
+ static_assert((std::is_same<std::result_of<PMS(S, int)>::type, void>::value), "Error!");
+ static_assert((std::is_same<std::result_of<PMS(const S&, int)>::type, void>::value), "Error!");
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
static_assert((std::is_same<std::result_of<PMD(S)>::type, char&&>::value), "Error!");
+#endif
static_assert((std::is_same<std::result_of<PMD(const S*)>::type, const char&>::value), "Error!");
}
More information about the cfe-commits
mailing list