diff options
author | Eric Fiselier <eric@efcs.ca> | 2015-07-28 01:52:08 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2015-07-28 01:52:08 +0000 |
commit | fda20d94e7f84537d5c71a3e14ee851f8a022268 (patch) | |
tree | e3919324686d0480dcd3fcc975bf5fd5b665855d /libcxx/include | |
parent | 2e9f29932d8eba649f21a56c2e15f4c0c19ffd21 (diff) | |
download | bcm5719-llvm-fda20d94e7f84537d5c71a3e14ee851f8a022268.tar.gz bcm5719-llvm-fda20d94e7f84537d5c71a3e14ee851f8a022268.zip |
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.
llvm-svn: 243368
Diffstat (limited to 'libcxx/include')
-rw-r--r-- | libcxx/include/__functional_base_03 | 43 |
1 files changed, 16 insertions, 27 deletions
diff --git a/libcxx/include/__functional_base_03 b/libcxx/include/__functional_base_03 index f408f467f50..e2f0e3e78ee 100644 --- a/libcxx/include/__functional_base_03 +++ b/libcxx/include/__functional_base_03 @@ -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 |