summaryrefslogtreecommitdiff
path: root/boost/fiber/detail/wrap.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/fiber/detail/wrap.hpp')
-rw-r--r--boost/fiber/detail/wrap.hpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/boost/fiber/detail/wrap.hpp b/boost/fiber/detail/wrap.hpp
new file mode 100644
index 0000000000..850763b4c8
--- /dev/null
+++ b/boost/fiber/detail/wrap.hpp
@@ -0,0 +1,113 @@
+
+// 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_FIBER_DETAIL_WRAP_H
+#define BOOST_FIBER_DETAIL_WRAP_H
+
+#include <type_traits>
+
+#include <boost/config.hpp>
+#include <boost/context/detail/invoke.hpp>
+#include <boost/context/execution_context.hpp>
+
+#include <boost/fiber/detail/config.hpp>
+#include <boost/fiber/detail/data.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace fibers {
+namespace detail {
+
+#if (BOOST_EXECUTION_CONTEXT==1)
+template< typename Fn1, typename Fn2, typename Tpl >
+class wrapper {
+private:
+ typename std::decay< Fn1 >::type fn1_;
+ typename std::decay< Fn2 >::type fn2_;
+ typename std::decay< Tpl >::type tpl_;
+ boost::context::execution_context ctx_;
+
+public:
+ wrapper( Fn1 && fn1, Fn2 && fn2, Tpl && tpl,
+ boost::context::execution_context const& ctx) :
+ fn1_( std::move( fn1) ),
+ fn2_( std::move( fn2) ),
+ tpl_( std::move( tpl) ),
+ ctx_{ ctx } {
+ }
+
+ wrapper( wrapper const&) = delete;
+ wrapper & operator=( wrapper const&) = delete;
+
+ wrapper( wrapper && other) = default;
+ wrapper & operator=( wrapper && other) = default;
+
+ void operator()( void * vp) {
+ boost::context::detail::invoke(
+ std::move( fn1_),
+ fn2_, tpl_, ctx_, vp);
+ }
+};
+
+template< typename Fn1, typename Fn2, typename Tpl >
+wrapper< Fn1, Fn2, Tpl >
+wrap( Fn1 && fn1, Fn2 && fn2, Tpl && tpl,
+ boost::context::execution_context const& ctx) {
+ return wrapper< Fn1, Fn2, Tpl >(
+ std::forward< Fn1 >( fn1),
+ std::forward< Fn2 >( fn2),
+ std::forward< Tpl >( tpl),
+ ctx);
+}
+#else
+template< typename Fn1, typename Fn2, typename Tpl >
+class wrapper {
+private:
+ typename std::decay< Fn1 >::type fn1_;
+ typename std::decay< Fn2 >::type fn2_;
+ typename std::decay< Tpl >::type tpl_;
+
+public:
+ wrapper( Fn1 && fn1, Fn2 && fn2, Tpl && tpl) :
+ fn1_( std::move( fn1) ),
+ fn2_( std::move( fn2) ),
+ tpl_( std::move( tpl) ) {
+ }
+
+ wrapper( wrapper const&) = delete;
+ wrapper & operator=( wrapper const&) = delete;
+
+ wrapper( wrapper && other) = default;
+ wrapper & operator=( wrapper && other) = default;
+
+ boost::context::execution_context< data_t * >
+ operator()( boost::context::execution_context< data_t * > ctx, data_t * dp) {
+ return boost::context::detail::invoke(
+ std::move( fn1_),
+ fn2_, tpl_, std::move( ctx), dp);
+ }
+};
+
+template< typename Fn1, typename Fn2, typename Tpl >
+wrapper< Fn1, Fn2, Tpl >
+wrap( Fn1 && fn1, Fn2 && fn2, Tpl && tpl) {
+ return wrapper< Fn1, Fn2, Tpl >(
+ std::forward< Fn1 >( fn1),
+ std::forward< Fn2 >( fn2),
+ std::forward< Tpl >( tpl) );
+}
+#endif
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+#include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_FIBER_DETAIL_WRAP_H