Imported Upstream version 1.64.0
[platform/upstream/boost.git] / boost / coroutine2 / detail / wrap.hpp
1
2 //          Copyright Oliver Kowalke 2014.
3 // Distributed under the Boost Software License, Version 1.0.
4 //    (See accompanying file LICENSE_1_0.txt or copy at
5 //          http://www.boost.org/LICENSE_1_0.txt)
6
7 #ifndef BOOST_COROUTINE2_DETAIL_WRAP_H
8 #define BOOST_COROUTINE2_DETAIL_WRAP_H
9
10 #include <type_traits>
11
12 #include <boost/config.hpp>
13 #include <boost/context/detail/invoke.hpp>
14 #if (BOOST_EXECUTION_CONTEXT==1)
15 # include <boost/context/execution_context.hpp>
16 #else
17 # include <boost/context/continuation.hpp>
18 #endif
19
20 #include <boost/fiber/detail/config.hpp>
21 #include <boost/fiber/detail/data.hpp>
22
23 #ifdef BOOST_HAS_ABI_HEADERS
24 # include BOOST_ABI_PREFIX
25 #endif
26
27 namespace boost {
28 namespace coroutines2 {
29 namespace detail {
30
31 #if (BOOST_EXECUTION_CONTEXT==1)
32 template< typename Fn1, typename Fn2  >
33 class wrapper {
34 private:
35     typename std::decay< Fn1 >::type    fn1_;
36     typename std::decay< Fn2 >::type    fn2_;
37     boost::context::execution_context   ctx_;
38
39 public:
40     wrapper( Fn1 && fn1, Fn2 && fn2,
41              boost::context::execution_context const& ctx) :
42         fn1_( std::move( fn1) ),
43         fn2_( std::move( fn2) ),
44         ctx_{ ctx } {
45     }
46
47     wrapper( wrapper const&) = delete;
48     wrapper & operator=( wrapper const&) = delete;
49
50     wrapper( wrapper && other) = default;
51     wrapper & operator=( wrapper && other) = default;
52
53     void operator()( void * vp) {
54         boost::context::detail::invoke(
55                 std::move( fn1_),
56                 fn2_, ctx_, vp);
57     }
58 };
59
60 template< typename Fn1, typename Fn2  >
61 wrapper< Fn1, Fn2 >
62 wrap( Fn1 && fn1, Fn2 && fn2,
63       boost::context::execution_context const& ctx) {
64     return wrapper< Fn1, Fn2 >(
65             std::forward< Fn1 >( fn1),
66             std::forward< Fn2 >( fn2),
67             ctx);
68 }
69 #else
70 template< typename Fn1, typename Fn2  >
71 class wrapper {
72 private:
73     typename std::decay< Fn1 >::type    fn1_;
74     typename std::decay< Fn2 >::type    fn2_;
75
76 public:
77     wrapper( Fn1 && fn1, Fn2 && fn2) :
78         fn1_( std::move( fn1) ),
79         fn2_( std::move( fn2) ) {
80     }
81
82     wrapper( wrapper const&) = delete;
83     wrapper & operator=( wrapper const&) = delete;
84
85     wrapper( wrapper && other) = default;
86     wrapper & operator=( wrapper && other) = default;
87
88     boost::context::continuation
89     operator()( boost::context::continuation && c) {
90         return boost::context::detail::invoke(
91                 std::move( fn1_),
92                 fn2_,
93                 std::forward< boost::context::continuation >( c) );
94     }
95 };
96
97 template< typename Fn1, typename Fn2 >
98 wrapper< Fn1, Fn2 >
99 wrap( Fn1 && fn1, Fn2 && fn2) {
100     return wrapper< Fn1, Fn2 >(
101             std::forward< Fn1 >( fn1),
102             std::forward< Fn2 >( fn2) );
103 }
104 #endif
105
106 }}}
107
108 #ifdef BOOST_HAS_ABI_HEADERS
109 #include BOOST_ABI_SUFFIX
110 #endif
111
112 #endif // BOOST_COROUTINE2_DETAIL_WRAP_H