]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/fiber/future/detail/task_object.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / fiber / future / detail / task_object.hpp
1
2 // Copyright Oliver Kowalke 2013.
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_FIBERS_DETAIL_TASK_OBJECT_H
8 #define BOOST_FIBERS_DETAIL_TASK_OBJECT_H
9
10 #include <exception>
11 #include <memory>
12 #include <tuple>
13 #include <utility>
14
15 #include <boost/config.hpp>
16 #if defined(BOOST_NO_CXX17_STD_APPLY)
17 #include <boost/context/detail/apply.hpp>
18 #endif
19 #include <boost/core/pointer_traits.hpp>
20
21 #include <boost/fiber/detail/config.hpp>
22 #include <boost/fiber/future/detail/task_base.hpp>
23
24 #ifdef BOOST_HAS_ABI_HEADERS
25 # include BOOST_ABI_PREFIX
26 #endif
27
28 namespace boost {
29 namespace fibers {
30 namespace detail {
31
32 template< typename Fn, typename Allocator, typename R, typename ... Args >
33 class task_object : public task_base< R, Args ... > {
34 private:
35 typedef task_base< R, Args ... > base_type;
36 typedef std::allocator_traits< Allocator > allocator_traits;
37
38 public:
39 typedef typename allocator_traits::template rebind_alloc<
40 task_object
41 > allocator_type;
42
43 task_object( allocator_type const& alloc, Fn const& fn) :
44 base_type{},
45 fn_{ fn },
46 alloc_{ alloc } {
47 }
48
49 task_object( allocator_type const& alloc, Fn && fn) :
50 base_type{},
51 fn_{ std::move( fn) },
52 alloc_{ alloc } {
53 }
54
55 void run( Args && ... args) override final {
56 try {
57 this->set_value(
58 #if defined(BOOST_NO_CXX17_STD_APPLY)
59 boost::context::detail::apply(
60 fn_, std::make_tuple( std::forward< Args >( args) ... ) )
61 #else
62 std::apply(
63 fn_, std::make_tuple( std::forward< Args >( args) ... ) )
64 #endif
65 );
66 } catch (...) {
67 this->set_exception( std::current_exception() );
68 }
69 }
70
71 typename base_type::ptr_type reset() override final {
72 typedef std::allocator_traits< allocator_type > traity_type;
73 typedef pointer_traits< typename traity_type::pointer> ptrait_type;
74
75 typename traity_type::pointer ptr{ traity_type::allocate( alloc_, 1) };
76 typename ptrait_type::element_type* p = boost::to_address(ptr);
77 try {
78 traity_type::construct( alloc_, p, alloc_, std::move( fn_) );
79 } catch (...) {
80 traity_type::deallocate( alloc_, ptr, 1);
81 throw;
82 }
83 return { p };
84 }
85
86 protected:
87 void deallocate_future() noexcept override final {
88 destroy_( alloc_, this);
89 }
90
91 private:
92 Fn fn_;
93 allocator_type alloc_;
94
95 static void destroy_( allocator_type const& alloc, task_object * p) noexcept {
96 allocator_type a{ alloc };
97 typedef std::allocator_traits< allocator_type > traity_type;
98 traity_type::destroy( a, p);
99 traity_type::deallocate( a, p, 1);
100 }
101 };
102
103 template< typename Fn, typename Allocator, typename ... Args >
104 class task_object< Fn, Allocator, void, Args ... > : public task_base< void, Args ... > {
105 private:
106 typedef task_base< void, Args ... > base_type;
107 typedef std::allocator_traits< Allocator > allocator_traits;
108
109 public:
110 typedef typename allocator_traits::template rebind_alloc<
111 task_object< Fn, Allocator, void, Args ... >
112 > allocator_type;
113
114 task_object( allocator_type const& alloc, Fn const& fn) :
115 base_type{},
116 fn_{ fn },
117 alloc_{ alloc } {
118 }
119
120 task_object( allocator_type const& alloc, Fn && fn) :
121 base_type{},
122 fn_{ std::move( fn) },
123 alloc_{ alloc } {
124 }
125
126 void run( Args && ... args) override final {
127 try {
128 #if defined(BOOST_NO_CXX17_STD_APPLY)
129 boost::context::detail::apply(
130 fn_, std::make_tuple( std::forward< Args >( args) ... ) );
131 #else
132 std::apply(
133 fn_, std::make_tuple( std::forward< Args >( args) ... ) );
134 #endif
135 this->set_value();
136 } catch (...) {
137 this->set_exception( std::current_exception() );
138 }
139 }
140
141 typename base_type::ptr_type reset() override final {
142 typedef std::allocator_traits< allocator_type > traity_type;
143 typedef pointer_traits< typename traity_type::pointer> ptrait_type;
144
145 typename traity_type::pointer ptr{ traity_type::allocate( alloc_, 1) };
146 typename ptrait_type::element_type* p = boost::to_address(ptr);
147 try {
148 traity_type::construct( alloc_, p, alloc_, std::move( fn_) );
149 } catch (...) {
150 traity_type::deallocate( alloc_, ptr, 1);
151 throw;
152 }
153 return { p };
154 }
155
156 protected:
157 void deallocate_future() noexcept override final {
158 destroy_( alloc_, this);
159 }
160
161 private:
162 Fn fn_;
163 allocator_type alloc_;
164
165 static void destroy_( allocator_type const& alloc, task_object * p) noexcept {
166 allocator_type a{ alloc };
167 typedef std::allocator_traits< allocator_type > traity_type;
168 traity_type::destroy( a, p);
169 traity_type::deallocate( a, p, 1);
170 }
171 };
172
173 }}}
174
175 #ifdef BOOST_HAS_ABI_HEADERS
176 # include BOOST_ABI_SUFFIX
177 #endif
178
179 #endif // BOOST_FIBERS_DETAIL_TASK_OBJECT_H