diff options
| author | Eric Fiselier <eric@efcs.ca> | 2015-07-28 02:15:53 +0000 |
|---|---|---|
| committer | Eric Fiselier <eric@efcs.ca> | 2015-07-28 02:15:53 +0000 |
| commit | e62bda70aabf7e821ecbc9b940084e1411e35e10 (patch) | |
| tree | cc351c73c12dddc6e45af0c4449d6f636ad42043 /libcxx | |
| parent | d29116331d89902aea9a5c71c284a09043a991e9 (diff) | |
| download | bcm5719-llvm-e62bda70aabf7e821ecbc9b940084e1411e35e10.tar.gz bcm5719-llvm-e62bda70aabf7e821ecbc9b940084e1411e35e10.zip | |
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
passes.
llvm-svn: 243370
Diffstat (limited to 'libcxx')
| -rw-r--r-- | libcxx/include/__functional_base_03 | 24 | ||||
| -rw-r--r-- | libcxx/include/functional | 4 |
2 files changed, 9 insertions, 19 deletions
diff --git a/libcxx/include/__functional_base_03 b/libcxx/include/__functional_base_03 index e2f0e3e78ee..0a7ff62ed69 100644 --- a/libcxx/include/__functional_base_03 +++ b/libcxx/include/__functional_base_03 @@ -408,20 +408,15 @@ template <class _Rp, class _Tp, class _T1> inline _LIBCPP_INLINE_VISIBILITY 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& ->::type + __apply_cv<_T1, _Rp> +>::type::type& __invoke(_Rp _Tp::* __f, _T1& __t1) { return __t1.*__f; } -template <class _Rp, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -void -__invoke(_Rp _Tp::*) -{ -} // forth bullet @@ -439,10 +434,9 @@ struct __4th_helper<_T1, _Rp, true> template <class _Rp, class _Tp, class _T1> inline _LIBCPP_INLINE_VISIBILITY 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 +>::type& __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; }; diff --git a/libcxx/include/functional b/libcxx/include/functional index 939486ffc1f..6c57de037b5 100644 --- a/libcxx/include/functional +++ b/libcxx/include/functional @@ -1260,10 +1260,6 @@ public: return __invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...); } #else - typename __invoke_return<type>::type - operator() () const { - return __invoke(__f_); - } template <class _A0> typename __invoke_return0<type, _A0>::type |

