
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@wanadoo.fr> 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 Define 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 Define 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...> { };