mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-28 02:37:37 +00:00
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
This commit is contained in:
parent
2e9f29932d
commit
fda20d94e7
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user