[libcxx] r243368 - Get C++03 __invoke working for bullet 5 of INVOKE.

Eric Fiselier eric at efcs.ca
Mon Jul 27 18:52:09 PDT 2015


Author: ericwf
Date: Mon Jul 27 20:52:08 2015
New Revision: 243368

URL: http://llvm.org/viewvc/llvm-project?rev=243368&view=rev
Log:
Get C++03 __invoke working for bullet 5 of INVOKE.

This patch does a couple of things to get __invoke working for free-functions
and call objects.

1. Turn all uses of declval<Tp>() into declval<Tp&>(). The C++03 __invoke only
   supports lvalues but it will be used when the compiler supports rvalue
   references but not variadic templates. This change makes sure we don't
   generate an rvalue.

2. Call objects for bullet 5 are now passed by reference and not value. Copying
   the functor is incorrect. It will fail to compile for non-copyable functors
   and it will discard cv-qualifiers on the call object, possibly leading to the
   wrong function being called. I suspect that the reason the call object
   was originally taken by value was to support temporary call objects.
   However __invoke is only used internally and it is never given a temporary.

Modified:
    libcxx/trunk/include/__functional_base_03

Modified: libcxx/trunk/include/__functional_base_03
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__functional_base_03?rev=243368&r1=243367&r2=243368&view=diff
==============================================================================
--- libcxx/trunk/include/__functional_base_03 (original)
+++ libcxx/trunk/include/__functional_base_03 Mon Jul 27 20:52:08 2015
@@ -433,7 +433,7 @@ struct __4th_helper
 template <class _T1, class _Rp>
 struct __4th_helper<_T1, _Rp, true>
 {
-    typedef typename __apply_cv<decltype(*_VSTD::declval<_T1>()), _Rp>::type type;
+    typedef typename __apply_cv<decltype(*_VSTD::declval<_T1&>()), _Rp>::type type;
 };
 
 template <class _Rp, class _Tp, class _T1>
@@ -452,47 +452,36 @@ __invoke(_Rp _Tp::* __f, _T1& __t1)
 
 template <class _Fp>
 inline _LIBCPP_INLINE_VISIBILITY
-decltype(declval<_Fp>()())
-__invoke(_Fp __f)
+decltype(_VSTD::declval<_Fp&>()())
+__invoke(_Fp& __f)
 {
     return __f();
 }
 
 template <class _Fp, class _A0>
 inline _LIBCPP_INLINE_VISIBILITY
-decltype(declval<_Fp>()(declval<_A0&>()))
-__invoke(_Fp __f, _A0& __a0)
+decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>()))
+__invoke(_Fp& __f, _A0& __a0)
 {
     return __f(__a0);
 }
 
 template <class _Fp, class _A0, class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
-decltype(declval<_Fp>()(declval<_A0&>(), declval<_A1&>()))
-__invoke(_Fp __f, _A0& __a0, _A1& __a1)
+decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>()))
+__invoke(_Fp& __f, _A0& __a0, _A1& __a1)
 {
     return __f(__a0, __a1);
 }
 
 template <class _Fp, class _A0, class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-decltype(declval<_Fp>()(declval<_A0&>(), declval<_A1&>(), declval<_A2&>()))
-__invoke(_Fp __f, _A0& __a0, _A1& __a1, _A2& __a2)
+decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>(), _VSTD::declval<_A2&>()))
+__invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2)
 {
     return __f(__a0, __a1, __a2);
 }
 
-template <class _Tp>
-struct __has_type
-{
-private:
-    struct __two {char __lx; char __lxx;};
-    template <class _Up> static __two __test(...);
-    template <class _Up> static char __test(typename _Up::type* = 0);
-public:
-    static const bool value = sizeof(__test<_Tp>(0)) == 1;
-};
-
 template <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value>
 struct __invoke_return
 {
@@ -502,13 +491,13 @@ struct __invoke_return
 template <class _Fp>
 struct __invoke_return<_Fp, false>
 {
-    typedef decltype(__invoke(_VSTD::declval<_Fp>())) type;
+    typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type;
 };
 
 template <class _Tp, class _A0>
 struct __invoke_return0
 {
-    typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_A0>())) type;
+    typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type;
 };
 
 template <class _Rp, class _Tp, class _A0>
@@ -526,16 +515,16 @@ struct __invoke_return0<_Rp _Tp::*, _A0*
 template <class _Tp, class _A0, class _A1>
 struct __invoke_return1
 {
-    typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_A0>(),
-                                                    _VSTD::declval<_A1>())) type;
+    typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(),
+                                                     _VSTD::declval<_A1&>())) type;
 };
 
 template <class _Tp, class _A0, class _A1, class _A2>
 struct __invoke_return2
 {
-    typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_A0>(),
-                                                    _VSTD::declval<_A1>(),
-                                                    _VSTD::declval<_A2>())) type;
+    typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(),
+                                                      _VSTD::declval<_A1&>(),
+                                                      _VSTD::declval<_A2&>())) type;
 };
 
 #endif  // _LIBCPP_FUNCTIONAL_BASE_03





More information about the cfe-commits mailing list