[cfe-commits] [libcxx] r131761 - in /libcxx/trunk/include: __functional_base type_traits

Howard Hinnant hhinnant at apple.com
Fri May 20 15:02:54 PDT 2011


Author: hhinnant
Date: Fri May 20 17:02:53 2011
New Revision: 131761

URL: http://llvm.org/viewvc/llvm-project?rev=131761&view=rev
Log:
This is a simplified (and superior) implementation of __invoke, __invokable and __invoke_of.  It is superior in that __invoke now handles reference qualified member functions whereas the previous implementation did not.  And it simply has less infrastructure in its implementation.  I'm still learning how to program in C++11 (and probably will be for a long time).  This change does not impact the behavior we're seeing in http://llvm.org/bugs/show_bug.cgi?id=9975

Modified:
    libcxx/trunk/include/__functional_base
    libcxx/trunk/include/type_traits

Modified: libcxx/trunk/include/__functional_base
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__functional_base?rev=131761&r1=131760&r2=131761&view=diff
==============================================================================
--- libcxx/trunk/include/__functional_base (original)
+++ libcxx/trunk/include/__functional_base Fri May 20 17:02:53 2011
@@ -281,169 +281,55 @@
 
 // __invoke
 
-// first bullet
+// bullets 1 and 2
 
-template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
+template <class _F, class _A0, class ..._Args>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    sizeof...(_Param) == sizeof...(_Arg) &&
-    is_base_of<_T, typename remove_reference<_T1>::type>::value,
-    _R
->::type
-__invoke(_R (_T::*__f)(_Param...), _T1&& __t1, _Arg&& ...__arg)
+auto
+__invoke(_F&& __f, _A0&& __a0, _Args&& ...__args)
+    -> decltype((_STD::forward<_A0>(__a0).*__f)(_STD::forward<_Args>(__args)...))
 {
-    return (_STD::forward<_T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...);
+    return (_STD::forward<_A0>(__a0).*__f)(_STD::forward<_Args>(__args)...);
 }
 
-template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
+template <class _F, class _A0, class ..._Args>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    sizeof...(_Param) == sizeof...(_Arg) &&
-    is_base_of<_T, typename remove_reference<_T1>::type>::value,
-    _R
->::type
-__invoke(_R (_T::*__f)(_Param...) const, _T1&& __t1, _Arg&& ...__arg)
+auto
+__invoke(_F&& __f, _A0&& __a0, _Args&& ...__args)
+    -> decltype(((*_STD::forward<_A0>(__a0)).*__f)(_STD::forward<_Args>(__args)...))
 {
-    return (_STD::forward<const _T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...);
+    return ((*_STD::forward<_A0>(__a0)).*__f)(_STD::forward<_Args>(__args)...);
 }
 
-template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    sizeof...(_Param) == sizeof...(_Arg) &&
-    is_base_of<_T, typename remove_reference<_T1>::type>::value,
-    _R
->::type
-__invoke(_R (_T::*__f)(_Param...) volatile, _T1&& __t1, _Arg&& ...__arg)
-{
-    return (_STD::forward<volatile _T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...);
-}
-
-template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    sizeof...(_Param) == sizeof...(_Arg) &&
-    is_base_of<_T, typename remove_reference<_T1>::type>::value,
-    _R
->::type
-__invoke(_R (_T::*__f)(_Param...) const volatile, _T1&& __t1, _Arg&& ...__arg)
-{
-    return (_STD::forward<const volatile _T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...);
-}
-
-// second bullet
-
-template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    sizeof...(_Param) == sizeof...(_Arg) &&
-    !is_base_of<_T, typename remove_reference<_T1>::type>::value,
-    _R
->::type
-__invoke(_R (_T::*__f)(_Param...), _T1&& __t1, _Arg&& ...__arg)
-{
-    return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
-}
-
-template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    sizeof...(_Param) == sizeof...(_Arg) &&
-    !is_base_of<_T, typename remove_reference<_T1>::type>::value,
-    _R
->::type
-__invoke(_R (_T::*__f)(_Param...) const, _T1&& __t1, _Arg&& ...__arg)
-{
-    return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
-}
-
-template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    sizeof...(_Param) == sizeof...(_Arg) &&
-    !is_base_of<_T, typename remove_reference<_T1>::type>::value,
-    _R
->::type
-__invoke(_R (_T::*__f)(_Param...) volatile, _T1&& __t1, _Arg&& ...__arg)
-{
-    return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
-}
+// bullets 3 and 4
 
-template <class _R, class _T, class _T1, class ..._Param, class ..._Arg>
+template <class _F, class _A0>
 inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    sizeof...(_Param) == sizeof...(_Arg) &&
-    !is_base_of<_T, typename remove_reference<_T1>::type>::value,
-    _R
->::type
-__invoke(_R (_T::*__f)(_Param...) const volatile, _T1&& __t1, _Arg&& ...__arg)
+auto
+__invoke(_F&& __f, _A0&& __a0)
+    -> decltype(_STD::forward<_A0>(__a0).*__f)
 {
-    return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...);
+    return _STD::forward<_A0>(__a0).*__f;
 }
 
-// third bullet
-
-template <class _R, class _T, class _T1>
-inline _LIBCPP_INLINE_VISIBILITY
-typename enable_if
-<
-    is_base_of<_T, typename remove_reference<_T1>::type>::value,
-    typename __apply_cv<_T1, _R>::type&&
->::type
-__invoke(_R _T::* __f, _T1&& __t1)
-{
-    return _STD::forward<_T1>(__t1).*__f;
-}
-
-// forth bullet
-
-template <class _T1, class _R, bool>
-struct __4th_helper
-{
-};
-
-template <class _T1, class _R>
-struct __4th_helper<_T1, _R, true>
-{
-    typedef typename __apply_cv<decltype(*_STD::declval<_T1>()), _R>::type type;
-};
-
-template <class _R, class _T, class _T1>
+template <class _F, class _A0>
 inline _LIBCPP_INLINE_VISIBILITY
-typename __4th_helper<_T1, _R,
-                      !is_base_of<_T,
-                                  typename remove_reference<_T1>::type
-                                 >::value
-                     >::type&&
-__invoke(_R _T::* __f, _T1&& __t1)
+auto
+__invoke(_F&& __f, _A0&& __a0)
+    -> decltype((*_STD::forward<_A0>(__a0)).*__f)
 {
-    return (*_STD::forward<_T1>(__t1)).*__f;
+    return (*_STD::forward<_A0>(__a0)).*__f;
 }
 
-// fifth bullet
-
-template <class _R, class ..._Param, class ..._Args>
-inline _LIBCPP_INLINE_VISIBILITY
-_R
-__invoke(_R (*__f)(_Param...), _Args&& ...__args)
-{
-    return __f(_STD::forward<_Args>(__args)...);
-}
+// bullet 5
 
-template <class _F, class ..._T>
+template <class _F, class ..._Args>
 inline _LIBCPP_INLINE_VISIBILITY
-typename __invoke_of<_F, _T...>::type
-__invoke(_F&& __f, _T&& ...__t)
+auto
+__invoke(_F&& __f, _Args&& ...__args)
+    -> decltype(_STD::forward<_F>(__f)(_STD::forward<_Args>(__args)...))
 {
-    return _STD::forward<_F>(__f)(_STD::forward<_T>(__t)...);
+    return _STD::forward<_F>(__f)(_STD::forward<_Args>(__args)...);
 }
 
 template <class _Tp, class ..._Args>

Modified: libcxx/trunk/include/type_traits
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/type_traits?rev=131761&r1=131760&r2=131761&view=diff
==============================================================================
--- libcxx/trunk/include/type_traits (original)
+++ libcxx/trunk/include/type_traits Fri May 20 17:02:53 2011
@@ -2775,105 +2775,61 @@
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
 
-// __invokable
-
-template <unsigned, class _F, class ..._Args>
-struct __invokable_imp
-    : false_type
-{
-};
+// __invoke forward declarations
 
-// __invokable member function pointer
+// fall back - none of the bullets
 
-template <class _A0, class _F, class ..._Args>
+template <class ..._Args>
 auto
-__invokable_mfp_test(_A0&& __a0, _F __f, _Args&& ...__args)
-    -> decltype((_STD::forward<_A0>(__a0).*__f)(_STD::forward<_Args>(__args)...));
+__invoke(__any, _Args&& ...__args)
+    -> __nat;
 
-template <class _A0, class _F, class ..._Args>
-auto
-__invokable_mfp_test(_A0&& __a0, _F __f, _Args&& ...__args)
-    -> decltype(((*_STD::forward<_A0>(__a0)).*__f)(_STD::forward<_Args>(__args)...));
+// bullets 1 and 2
 
-template <class _F, class ..._Args>
+template <class _F, class _A0, class ..._Args>
 auto
-__invokable_mfp_test(__any, _F __f, _Args&& ...__args)
-    -> __nat;
+__invoke(_F&& __f, _A0&& __a0, _Args&& ...__args)
+    -> decltype((_STD::forward<_A0>(__a0).*__f)(_STD::forward<_Args>(__args)...));
 
 template <class _F, class _A0, class ..._Args>
-struct __invokable_imp<2, _F, _A0, _Args...>
-{
-    typedef decltype(
-            __invokable_mfp_test(_STD::declval<_A0>(), _STD::declval<_F>(),
-                                 _STD::declval<_Args>()...)
-                    ) type;
-    static const bool value = !is_same<type, __nat>::value;
-};
+auto
+__invoke(_F&& __f, _A0&& __a0, _Args&& ...__args)
+    -> decltype(((*_STD::forward<_A0>(__a0)).*__f)(_STD::forward<_Args>(__args)...));
 
-// __invokable member object pointer
+// bullets 3 and 4
 
-template <class _A0, class _F>
+template <class _F, class _A0>
 auto
-__invokable_mop_test(_A0&& __a0, _F __f)
+__invoke(_F&& __f, _A0&& __a0)
     -> decltype(_STD::forward<_A0>(__a0).*__f);
 
-template <class _A0, class _F>
+template <class _F, class _A0>
 auto
-__invokable_mop_test(_A0&& __a0, _F __f)
+__invoke(_F&& __f, _A0&& __a0)
     -> decltype((*_STD::forward<_A0>(__a0)).*__f);
 
-template <class _F>
-auto
-__invokable_mop_test(__any, _F __f)
-    -> __nat;
-
-template <class _F, class _A0>
-struct __invokable_imp<1, _F, _A0>
-{
-    typedef decltype(
-                 __invokable_mop_test(_STD::declval<_A0>(), _STD::declval<_F>())
-                    ) type;
-    static const bool value = !is_same<type, __nat>::value;
-};
-
-// __invokable other
+// bullet 5
 
 template <class _F, class ..._Args>
 auto
-__invokable_other_test(_F&& __f, _Args&& ...__args)
+__invoke(_F&& __f, _Args&& ...__args)
     -> decltype(_STD::forward<_F>(__f)(_STD::forward<_Args>(__args)...));
 
-template <class ..._Args>
-auto
-__invokable_other_test(__any, _Args&& ...__args)
-    -> __nat;
+// __invokable
 
 template <class _F, class ..._Args>
-struct __invokable_imp<0, _F, _Args...>
+struct __invokable_imp
 {
     typedef decltype(
-            __invokable_other_test(_STD::declval<_F>(), _STD::declval<_Args>()...)
+            __invoke(_STD::declval<_F>(), _STD::declval<_Args>()...)
                     ) type;
     static const bool value = !is_same<type, __nat>::value;
 };
 
-// __invokable_classify
-
-template <class _F>
-struct __invokable_classify
-{
-    typedef typename remove_reference<_F>::type _FR;
-    static const unsigned value = is_member_function_pointer<_FR>::value ?
-                                  2 :
-                                  is_member_object_pointer<_FR>::value ?
-                                  1 :
-                                  0;
-};
-
 template <class _F, class ..._Args>
 struct __invokable
     : public integral_constant<bool,
-          __invokable_imp<__invokable_classify<_F>::value, _F, _Args...>::value>
+          __invokable_imp<_F, _Args...>::value>
 {
 };
 
@@ -2887,7 +2843,7 @@
 template <class _F, class ..._Args>
 struct __invoke_of_imp<true, _F, _Args...>
 {
-    typedef typename __invokable_imp<__invokable_classify<_F>::value, _F, _Args...>::type type;
+    typedef typename __invokable_imp<_F, _Args...>::type type;
 };
 
 template <class _F, class ..._Args>





More information about the cfe-commits mailing list