|
Boost : |
Subject: Re: [boost] Can C++11 INVOKE be defined with C++98 compilers?
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2013-04-12 01:41:55
Le 12/04/13 06:07, Jeffrey Lee Hellrung, Jr. a écrit :
> On Tue, Apr 9, 2013 at 11:02 PM, Vicente J. Botet Escriba <
> vicente.botet_at_[hidden]> wrote:
>
>> Hi,
>>
>> I would like to implement C++11 INVOKE on C++98 compilers.
>>
>> I have a C++11 implementation on boost/thread/detail/invoke.hpp based on
>> the one of libc++.
>>
>> Could this be done or there is something that can not be done inherently?
>>
> Can you briefly describe what INVOKE does (or...should do)?
>
>
Hi,
from the standard
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2012/n3485.pdf
20.8.2 Requirements [func.require]
1 Deï¬ne INVOKE(f, t1, t2, ..., tN) as follows:
â (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a
class T and t1 is an object of
type T or a reference to an object of type T or a reference to an object
of a type derived from T;
â ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a
class T and t1 is not one of
the types described in the previous item;
â t1.*f when N == 1 and f is a pointer to member data of a class T and
t1 is an object of type T or a
reference to an object of type T or a reference to an object of a type
derived from T;
â (*t1).*f when N == 1 and f is a pointer to member data of a class T
and t1 is not one of the types
described in the previous item;
â f(t1, t2, ..., tN) in all other cases.
2 Deï¬ne INVOKE(f, t1, t2, ..., tN, R) as INVOKE(f, t1, t2, ..., tN)
implicitly converted to R
The libc++ implementation is
// __invoke
// bullets 1 and 2
template <class _Fp, class _A0, class ..._Args>
inline _LIBCPP_INLINE_VISIBILITY
auto
__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
->
decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...))
{
return (_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...);
}
template <class _Fp, class _A0, class ..._Args>
inline _LIBCPP_INLINE_VISIBILITY
auto
__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
->
decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...))
{
return
((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...);
}
// bullets 3 and 4
template <class _Fp, class _A0>
inline _LIBCPP_INLINE_VISIBILITY
auto
__invoke(_Fp&& __f, _A0&& __a0)
-> decltype(_VSTD::forward<_A0>(__a0).*__f)
{
return _VSTD::forward<_A0>(__a0).*__f;
}
template <class _Fp, class _A0>
inline _LIBCPP_INLINE_VISIBILITY
auto
__invoke(_Fp&& __f, _A0&& __a0)
-> decltype((*_VSTD::forward<_A0>(__a0)).*__f)
{
return (*_VSTD::forward<_A0>(__a0)).*__f;
}
// bullet 5
template <class _Fp, class ..._Args>
inline _LIBCPP_INLINE_VISIBILITY
auto
__invoke(_Fp&& __f, _Args&& ...__args)
-> decltype(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...))
{
return _VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...);
}
The result_of is defined as
// __invokable
template <class _Fp, class ..._Args>
struct __invokable_imp
: private __check_complete<_Fp>
{
typedef decltype(
__invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...)
) type;
static const bool value = !is_same<type, __nat>::value;
};
template <class _Fp, class ..._Args>
struct __invokable
: public integral_constant<bool,
__invokable_imp<_Fp, _Args...>::value>
{
};
// __invoke_of
template <bool _Invokable, class _Fp, class ..._Args>
struct __invoke_of_imp // false
{
};
template <class _Fp, class ..._Args>
struct __invoke_of_imp<true, _Fp, _Args...>
{
typedef typename __invokable_imp<_Fp, _Args...>::type type;
};
template <class _Fp, class ..._Args>
struct __invoke_of
: public __invoke_of_imp<__invokable<_Fp, _Args...>::value, _Fp, _Args...>
{
};
template <class _Fp, class ..._Args>
class _LIBCPP_TYPE_VIS result_of<_Fp(_Args...)>
: public __invoke_of<_Fp, _Args...>
{
};
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk