diff --git a/include/boost/fiber/detail/invoke.hpp b/include/boost/fiber/detail/invoke.hpp new file mode 100644 index 00000000..dbfde7c0 --- /dev/null +++ b/include/boost/fiber/detail/invoke.hpp @@ -0,0 +1,48 @@ + +// Copyright Oliver Kowalke 2014. +// 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) + +#ifndef BOOST_FIBERS_DETAIL_INVOKE_H +#define BOOST_FIBERS_DETAIL_INVOKE_H + +#include +#include +#include + +#include + +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_PREFIX +#endif + +namespace boost { +namespace fibers { +namespace detail { + +template< typename Fn, typename... Args > +typename std::enable_if< + std::is_member_pointer< typename std::decay< Fn >::type >::value, + typename std::result_of< Fn&&( Args && ...) >::type +>::type +invoke( Fn && fn, Args && ... args) { + return std::mem_fn( fn)( std::forward< Args >( args) ...); +} + +template< typename Fn, typename ... Args > +typename std::enable_if< + ! std::is_member_pointer< typename std::decay< Fn >::type >::value, + typename std::result_of< Fn&&( Args && ...) >::type +>::type +invoke( Fn && fn, Args && ... args) { + return std::forward< Fn >( fn)( std::forward< Args >( args) ...); +} + +}}} + +#ifdef BOOST_HAS_ABI_HEADERS +#include BOOST_ABI_SUFFIX +#endif + +#endif // BOOST_FIBERS_DETAIL_INVOKE_H diff --git a/include/boost/fiber/fiber_context.hpp b/include/boost/fiber/fiber_context.hpp index b430564e..6037d83c 100644 --- a/include/boost/fiber/fiber_context.hpp +++ b/include/boost/fiber/fiber_context.hpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -122,7 +123,7 @@ private: [=,fn=std::forward< Fn >( fn_),tpl=std::forward< Tpl >( tpl_)] () mutable { try { BOOST_ASSERT( is_running() ); - fn( + detail::invoke( fn, // std::tuple_element<> does not perfect forwarding std::forward< decltype( std::get< I >( std::declval< Tpl >() ) ) >( std::get< I >( std::forward< Tpl >( tpl) ) ) ... );