[libcxx] r243370 - Cleanup C++03 __invoke for Bullets 3 and 4.

Eric Fiselier eric at efcs.ca
Mon Jul 27 19:15:53 PDT 2015

Author: ericwf
Date: Mon Jul 27 21:15:53 2015
New Revision: 243370

URL: http://llvm.org/viewvc/llvm-project?rev=243370&view=rev
Cleanup C++03 __invoke for Bullets 3 and 4.

The key changes in this patch are:

1. Remove the zero-argument overload in mem_fn. A member function must always
   be invoked with at least one argument, the class instance. The zero-argument
   operator()() in mem_fn would cause mem_fn to fail to compile when because
   the call to '__invoke(pm)' is not well formed.

2. Prevent evaluation of '__apply_cv<Tp, Ret>' when 'Ret' is a function type.
   'Ret' is a function type whenever 'Ret Tp::*' is a pointer to member function.
   Attempting to add cv and ref qualifiers to a function type can cause a hard
   compile error.

3. Remove the dummy overload __invoke(Rp Tp::*). It was present to help work
   around #1. It will be replaced with a different '__invoke' overload that
   represents a bad call to invoke.

After applying this patch the test func.wrap.func.inv/invoke.pass.cpp now


Modified: libcxx/trunk/include/__functional_base_03
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__functional_base_03?rev=243370&r1=243369&r2=243370&view=diff
--- libcxx/trunk/include/__functional_base_03 (original)
+++ libcxx/trunk/include/__functional_base_03 Mon Jul 27 21:15:53 2015
@@ -408,20 +408,15 @@ template <class _Rp, class _Tp, class _T
 typename enable_if
+    is_member_object_pointer<_Rp _Tp::*>::value &&
     is_base_of<_Tp, typename remove_reference<_T1>::type>::value,
-    typename __apply_cv<_T1, _Rp>::type&
+   __apply_cv<_T1, _Rp>
 __invoke(_Rp _Tp::* __f, _T1& __t1)
     return __t1.*__f;
-template <class _Rp, class _Tp>
-__invoke(_Rp _Tp::*)
 // forth bullet
@@ -439,10 +434,9 @@ struct __4th_helper<_T1, _Rp, true>
 template <class _Rp, class _Tp, class _T1>
 typename __4th_helper<_T1, _Rp,
-                      !is_base_of<_Tp,
-                                  typename remove_reference<_T1>::type
-                                 >::value
-                     >::type&
+    is_member_object_pointer<_Rp _Tp::*>::value &&
+    !is_base_of<_Tp, typename remove_reference<_T1>::type>::value
 __invoke(_Rp _Tp::* __f, _T1& __t1)
     return (*__t1).*__f;
@@ -494,20 +488,20 @@ struct __invoke_return<_Fp, false>
     typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type;
-template <class _Tp, class _A0>
+template <class _Tp, class _A0, bool = is_member_object_pointer<_Tp>::value>
 struct __invoke_return0
     typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type;
 template <class _Rp, class _Tp, class _A0>
-struct __invoke_return0<_Rp _Tp::*, _A0>
+struct __invoke_return0<_Rp _Tp::*, _A0, true>
     typedef typename __apply_cv<_A0, _Rp>::type& type;
 template <class _Rp, class _Tp, class _A0>
-struct __invoke_return0<_Rp _Tp::*, _A0*>
+struct __invoke_return0<_Rp _Tp::*, _A0*, true>
     typedef typename __apply_cv<_A0, _Rp>::type& type;

Modified: libcxx/trunk/include/functional
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/functional?rev=243370&r1=243369&r2=243370&view=diff
--- libcxx/trunk/include/functional (original)
+++ libcxx/trunk/include/functional Mon Jul 27 21:15:53 2015
@@ -1260,10 +1260,6 @@ public:
         return __invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...);
-    typename __invoke_return<type>::type
-    operator() () const {
-        return __invoke(__f_);
-    }
     template <class _A0>
     typename __invoke_return0<type, _A0>::type

More information about the cfe-commits mailing list