// Copyright (C) 2012-2013 Vicente J. Botet Escriba // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 2013/04 Vicente J. Botet Escriba // Provide implementation up to 9 parameters when BOOST_NO_CXX11_VARIADIC_TEMPLATES is defined. // Make use of Boost.Move // Make use of Boost.Tuple (movable) // 2012 Vicente J. Botet Escriba // Provide implementation _RET using bind when BOOST_NO_CXX11_HDR_FUNCTIONAL and BOOST_NO_SFINAE_EXPR are not defined // 2012 Vicente J. Botet Escriba // Adapt to boost libc++ implementation //===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // // The invoke code is based on the one from libcxx. //===----------------------------------------------------------------------===// #ifndef BOOST_THREAD_DETAIL_INVOKE_HPP #define BOOST_THREAD_DETAIL_INVOKE_HPP #include #include #include #include #include #ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL #include #endif namespace boost { namespace detail { #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ ! defined(BOOST_NO_SFINAE_EXPR) && \ ! defined(BOOST_NO_CXX11_DECLTYPE) && \ ! defined(BOOST_NO_CXX11_DECLTYPE_N3276) && \ ! defined(BOOST_NO_CXX11_AUTO) #define BOOST_THREAD_PROVIDES_INVOKE #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) // bullets 1 and 2 template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args) -> decltype((boost::forward(a0).*f)(boost::forward(args)...)) { return (boost::forward(a0).*f)(boost::forward(args)...); } template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args) -> decltype(((*boost::forward(a0)).*f)(boost::forward(args)...)) { return ((*boost::forward(a0)).*f)(boost::forward(args)...); } // bullets 3 and 4 template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0) -> decltype(boost::forward(a0).*f) { return boost::forward(a0).*f; } template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0) -> decltype((*boost::forward(a0)).*f) { return (*boost::forward(a0)).*f; } // bullet 5 template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args) -> decltype(boost::forward(f)(boost::forward(args)...)) { return boost::forward(f)(boost::forward(args)...); } #else // BOOST_NO_CXX11_VARIADIC_TEMPLATES // bullets 1 and 2 template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0) -> decltype((boost::forward(a0).*f)()) { return (boost::forward(a0).*f)(); } template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1) -> decltype((boost::forward(a0).*f)(boost::forward(a1))) { return (boost::forward(a0).*f)(boost::forward(a1)); } template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2) -> decltype((boost::forward(a0).*f)(boost::forward(a1), boost::forward(a2))) { return (boost::forward(a0).*f)(boost::forward(a1), boost::forward(a2)); } template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0) -> decltype(((*boost::forward(a0)).*f)()) { return ((*boost::forward(a0)).*f)(); } template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1) -> decltype(((*boost::forward(a0)).*f)(boost::forward(a1))) { return ((*boost::forward(a0)).*f)(boost::forward(a1)); } template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2) -> decltype(((*boost::forward(a0)).*f)(boost::forward(a1), boost::forward(a2))) { return ((*boost::forward(a0)).*f)(boost::forward(a1), boost::forward(a2)); } // bullets 3 and 4 template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0) -> decltype(boost::forward(a0).*f) { return boost::forward(a0).*f; } template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0) -> decltype((*boost::forward(a0)).*f) { return (*boost::forward(a0)).*f; } // bullet 5 template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f) -> decltype(boost::forward(f)()) { return boost::forward(f)(); } template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) a1) -> decltype(boost::forward(f)(boost::forward(a1))) { return boost::forward(f)(boost::forward(a1)); } template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2) -> decltype(boost::forward(f)(boost::forward(a1), boost::forward(a2))) { return boost::forward(f)(boost::forward(a1), boost::forward(a2)); } template inline auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3) -> decltype(boost::forward(f)(boost::forward(a1), boost::forward(a2), boost::forward(a3))) { return boost::forward(f)(boost::forward(a1), boost::forward(a2), boost::forward(a3)); } #endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES #elif ! defined(BOOST_NO_SFINAE_EXPR) && \ ! defined BOOST_NO_CXX11_HDR_FUNCTIONAL && \ defined BOOST_MSVC template inline Ret invoke(BOOST_THREAD_RV_REF(Fp) f) { return f(); } template inline Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1) { return std::bind(boost::forward(f), boost::forward(a1))(); } template inline Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2) { return std::bind(boost::forward(f), boost::forward(a1), boost::forward(a2))(); } template inline Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3) { return std::bind(boost::forward(f), boost::forward(a1), boost::forward(a2), boost::forward(a3))(); } #define BOOST_THREAD_PROVIDES_INVOKE_RET #elif ! defined BOOST_MSVC //!!!!! WARNING !!!!! THIS DOESN'T WORKS YET #define BOOST_THREAD_PROVIDES_INVOKE_RET #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) // bullet 1 // (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 template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(Args...), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args) { return (boost::forward(a0).*f)(boost::forward(args)...); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(Args...) const, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args) { return (boost::forward(a0).*f)(boost::forward(args)...); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(Args...) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args) { return (boost::forward(a0).*f)(boost::forward(args)...); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(Args...) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args) { return (boost::forward(a0).*f)(boost::forward(args)...); } // bullet 2 // ((*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; template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(Args...), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args) { return ((*boost::forward(a0)).*f)(boost::forward(args)...); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(Args...) const, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args) { return ((*boost::forward(a0)).*f)(boost::forward(args)...); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(Args...) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args) { return ((*boost::forward(a0)).*f)(boost::forward(args)...); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(Args...) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args) { return ((*boost::forward(a0)).*f)(boost::forward(args)...); } // bullet 3 // 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; // template // inline // typename enable_if_c // < // is_base_of::type>::value, // typename detail::apply_cv::type& // >::type // invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0) // { // return boost::forward(a0).*f; // } // bullet 4 // (*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; // template // struct d4th_helper // { // }; // // template // struct d4th_helper // { // typedef typename apply_cv()), Ret>::type type; // }; // // template // inline // typename detail::4th_helper::type // >::value // >::type& // invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0) // { // return (*boost::forward(a0)).*f; // } // template // inline // typename enable_if_c // < // !is_base_of::type>::value, // typename detail::ref_return1::type // >::type // invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0) // { // return (*boost::forward(a0)).*f; // } // bullet 5 // f(t1, t2, ..., tN) in all other cases. template inline typename enable_if_c < ! is_member_function_pointer::value, Ret >::type invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args) { return boost::forward(f)(boost::forward(args)...); } template inline Ret invoke(Ret(*f)(Args... ), BOOST_THREAD_RV_REF(Args) ...args) { return f(boost::forward(args)...); } #else // BOOST_NO_CXX11_VARIADIC_TEMPLATES // bullet 1 // (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 template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(), BOOST_THREAD_RV_REF(A0) a0) { return (boost::forward(a0).*f)(); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1) { return (boost::forward(a0).*f)(boost::forward(a1)); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1), A0 a0, A1 a1) { return (a0.*f)(a1); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2 ) { return (boost::forward(a0).*f)(boost::forward(a1), boost::forward(a2)); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2), A0 a0, A1 a1, A2 a2) { return (a0.*f)(a1, a2); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2, A3), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3) { return (boost::forward(a0).*f)(boost::forward(a1), boost::forward(a2), boost::forward(a3)); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2, A3), A0 a0, A1 a1, A2 a2, A3 a3) { return (a0.*f)(a1, a2, a3); } /// template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)() const, BOOST_THREAD_RV_REF(A0) a0) { return (boost::forward(a0).*f)(); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1) const, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1) { return (boost::forward(a0).*f)(boost::forward(a1)); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1) const, A0 a0, A1 a1) { return (a0.*f)(a1); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2) const, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2 ) { return (boost::forward(a0).*f)(boost::forward(a1), boost::forward(a2) ); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2) const, A0 a0, A1 a1, A2 a2) { return (a0.*f)(a1, a2); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2, A3) const, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3 ) { return (boost::forward(a0).*f)(boost::forward(a1), boost::forward(a2), boost::forward(a3)); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2, A3) const, A0 a0, A1 a1, A2 a2, A3 a3) { return (a0.*f)(a1, a2, a3); } /// template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)() volatile, BOOST_THREAD_RV_REF(A0) a0) { return (boost::forward(a0).*f)(); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1) { return (boost::forward(a0).*f)(boost::forward(a1)); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1) volatile, A0 a0, A1 a1) { return (a0.*f)(a1); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2) { return (boost::forward(a0).*f)(boost::forward(a1), boost::forward(a2)); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2) volatile, A0 a0, A1 a1, A2 a2 ) { return (a0.*f)(a1, a2); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2, A3) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3 ) { return (boost::forward(a0).*f)(boost::forward(a1), boost::forward(a2), boost::forward(a3)); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3) { return (a0.*f)(a1, a2, a3); } /// template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)() const volatile, BOOST_THREAD_RV_REF(A0) a0) { return (boost::forward(a0).*f)(); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1) { return (boost::forward(a0).*f)(boost::forward(a1)); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1) const volatile, A0 a0, A1 a1) { return (a0.*f)(a1); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2 ) { return (boost::forward(a0).*f)(boost::forward(a1), boost::forward(a2)); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2) const volatile, A0 a0, A1 a1, A2 a2 ) { return (a0.*f)(a1, a2); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2, A3) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3 ) { return (boost::forward(a0).*f)(boost::forward(a1), boost::forward(a2), boost::forward(a3)); } template inline typename enable_if_c < is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2, A3) const volatile, A0 a0, A1 a1, A2 a2, A3 a3 ) { return (a0.*f)(a1, a2, a3); } // bullet 2 // ((*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; template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(), BOOST_THREAD_RV_REF(A0) a0) { return ((*boost::forward(a0)).*f)(); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1) { return ((*boost::forward(a0)).*f)(boost::forward(a1)); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1), A0 a0, A1 a1) { return ((*a0).*f)(a1); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, BOOST_THREAD_RV_REF(A2)), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2) { return ((*boost::forward(a0)).*f)(boost::forward(a1), boost::forward(a2)); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2), A0 a0, A1 a1, A2 a2) { return ((*a0).*f)(a1, a2); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, BOOST_THREAD_RV_REF(A2), BOOST_THREAD_RV_REF(A3)), BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3) { return ((*boost::forward(a0)).*f)(boost::forward(a1), boost::forward(a2), boost::forward(a3) ); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2, A3), A0 a0, A1 a1, A2 a2, A3 a3) { return ((*a0).*f)(a1, a2, a3); } /// template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)() const, BOOST_THREAD_RV_REF(A0) a0) { return ((*boost::forward(a0)).*f)(); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1) const, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1) { return ((*boost::forward(a0)).*f)(boost::forward(a1)); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1) const, BOOST_THREAD_RV_REF(A0) a0, A1 a1) { return ((*boost::forward(a0)).*f)(a1); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1) const, A0 a0, A1 a1) { return ((*a0).*f)(a1); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2) const, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2) { return ((*boost::forward(a0)).*f)(boost::forward(a1), boost::forward(a2)); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2) const, A0 a0, A1 a1, A2 a2) { return ((*a0).*f)(a1, a2); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2, A3) const, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3) { return ((*boost::forward(a0)).*f)(boost::forward(a1), boost::forward(a2), boost::forward(a3)); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2, A3) const, A0 a0, A1 a1, A2 a2, A3 a3) { return ((*a0).*f)(a1, a2, a3); } /// template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)() volatile, BOOST_THREAD_RV_REF(A0) a0) { return ((*boost::forward(a0)).*f)(); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1) { return ((*boost::forward(a0)).*f)(boost::forward(a1)); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1) volatile, A0 a0, A1 a1) { return ((*a0).*f)(a1); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2) { return ((*boost::forward(a0)).*f)(boost::forward(a1), boost::forward(a2)); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2) volatile, A0 a0, A1 a1, A2 a2) { return ((*a0).*f)(a1, a2); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2, A3) volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3) { return ((*boost::forward(a0)).*f)(boost::forward(a1), boost::forward(a2), boost::forward(a3)); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2, A3) volatile, A0 a0, A1 a1, A2 a2, A3 a3) { return ((*a0).*f)(a1, a2, a3); } /// template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)() const volatile, BOOST_THREAD_RV_REF(A0) a0) { return ((*boost::forward(a0)).*f)(); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)() const volatile, A0 a0) { return ((*a0).*f)(); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1) { return ((*boost::forward(a0)).*f)(boost::forward(a1)); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1) const volatile, A0 a0, A1 a1) { return ((*a0).*f)(a1); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2) { return ((*boost::forward(a0)).*f)(boost::forward(a1), boost::forward(a2)); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2) const volatile, A0 a0, A1 a1, A2 a2) { return ((*a0).*f)(a1, a2); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2, A3) const volatile, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3) { return ((*boost::forward(a0)).*f)(boost::forward(a1), boost::forward(a2), boost::forward(a3)); } template inline typename enable_if_c < ! is_base_of::type>::value, Ret >::type invoke(Ret (A::*f)(A1, A2, A3) const volatile, A0 a0, A1 a1, A2 a2, A3 a3) { return ((*a0).*f)(a1, a2, a3); } // bullet 3 // 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; // template // inline // typename enable_if_c // < // is_base_of::type>::value, // typename detail::apply_cv::type& // >::type // invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0) // { // return boost::forward(a0).*f; // } // bullet 4 // (*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; // template // struct d4th_helper // { // }; // // template // struct d4th_helper // { // typedef typename apply_cv()), Ret>::type type; // }; // // template // inline // typename detail::4th_helper::type // >::value // >::type& // invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0) // { // return (*boost::forward(a0)).*f; // } // template // inline // typename enable_if_c // < // !is_base_of::type>::value, // typename detail::ref_return1::type // >::type // invoke(Ret A::* f, BOOST_THREAD_RV_REF(A0) a0) // { // return (*boost::forward(a0)).*f; // } // bullet 5 // f(t1, t2, ..., tN) in all other cases. template inline typename enable_if_c < ! is_member_function_pointer::value, Ret >::type invoke(BOOST_THREAD_RV_REF(Fp) f) { return boost::forward(f)(); } template inline typename enable_if_c < ! is_member_function_pointer::value, Ret >::type invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1) { return boost::forward(f)(boost::forward(a1)); } template inline typename enable_if_c < ! is_member_function_pointer::value, Ret >::type invoke(BOOST_THREAD_RV_REF(Fp) f, A1 a1) { return boost::forward(f)(a1); } template inline typename enable_if_c < ! is_member_function_pointer::value, Ret >::type invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2) { return boost::forward(f)(boost::forward(a1), boost::forward(a2)); } template inline typename enable_if_c < ! is_member_function_pointer::value, Ret >::type invoke(BOOST_THREAD_RV_REF(Fp) f, A1 a1, A2 a2) { return boost::forward(f)(a1, a2); } template inline typename enable_if_c < ! is_member_function_pointer::value, Ret >::type invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3) { return boost::forward(f)(boost::forward(a1), boost::forward(a2), boost::forward(a3)); } template inline typename enable_if_c < ! is_member_function_pointer::value, Ret >::type invoke(BOOST_THREAD_RV_REF(Fp) f, A1 a1, A2 a2, A3 a3) { return boost::forward(f)(a1, a2, a3); } /// template inline typename enable_if_c < ! is_member_function_pointer::value, Ret >::type invoke(Fp const &f) { return f(); } template inline typename enable_if_c < ! is_member_function_pointer::value, Ret >::type invoke(Fp const &f, BOOST_THREAD_RV_REF(A1) a1) { return f(boost::forward(a1)); } template inline typename enable_if_c < ! is_member_function_pointer::value, Ret >::type invoke(Fp const &f, A1 a1) { return f(a1); } template inline typename enable_if_c < ! is_member_function_pointer::value, Ret >::type invoke(Fp const &f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2) { return f(boost::forward(a1), boost::forward(a2)); } template inline typename enable_if_c < ! is_member_function_pointer::value, Ret >::type invoke(Fp const &f, A1 a1, A2 a2) { return f(a1, a2); } template inline typename enable_if_c < ! is_member_function_pointer::value, Ret >::type invoke(Fp const &f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3) { return f(boost::forward(a1), boost::forward(a2), boost::forward(a3)); } template inline typename enable_if_c < ! is_member_function_pointer::value, Ret >::type invoke(Fp const &f, A1 a1, A2 a2, A3 a3) { return f(a1, a2, a3); } /// template inline Ret invoke(Ret(*f)()) { return f(); } template inline Ret invoke(Ret(*f)(A1), BOOST_THREAD_RV_REF(A1) a1) { return f(boost::forward(a1)); } template inline Ret invoke(Ret(*f)(A1, A2), BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2) { return f(boost::forward(a1), boost::forward(a2)); } template inline Ret invoke(Ret(*f)(A1, A2, A3), BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3) { return f(boost::forward(a1), boost::forward(a2), boost::forward(a3)); } #endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES #endif // all } } #endif // header