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