[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