]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/fiber/include/boost/fiber/future/promise.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / fiber / include / boost / fiber / future / promise.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_PROMISE_HPP
8 #define BOOST_FIBERS_PROMISE_HPP
9
10 #include <algorithm>
11 #include <memory>
12 #include <utility>
13
14 #include <boost/config.hpp>
15
16 #include <boost/fiber/detail/convert.hpp>
17 #include <boost/fiber/exceptions.hpp>
18 #include <boost/fiber/future/detail/shared_state.hpp>
19 #include <boost/fiber/future/detail/shared_state_object.hpp>
20 #include <boost/fiber/future/future.hpp>
21
22 namespace boost {
23 namespace fibers {
24 namespace detail {
25
26 template< typename R >
27 struct promise_base {
28 typedef typename shared_state< R >::ptr_t ptr_t;
29
30 bool obtained_{ false };
31 ptr_t future_{};
32
33 promise_base() :
34 promise_base{ std::allocator_arg, std::allocator< promise_base >{} } {
35 }
36
37 template< typename Allocator >
38 promise_base( std::allocator_arg_t, Allocator alloc) {
39 typedef detail::shared_state_object< R, Allocator > object_t;
40 typedef std::allocator_traits< typename object_t::allocator_t > traits_t;
41 typename object_t::allocator_t a{ alloc };
42 typename traits_t::pointer ptr{ traits_t::allocate( a, 1) };
43
44 try {
45 traits_t::construct( a, ptr, a);
46 } catch (...) {
47 traits_t::deallocate( a, ptr, 1);
48 throw;
49 }
50 future_.reset( convert( ptr) );
51 }
52
53 ~promise_base() {
54 if ( future_) {
55 future_->owner_destroyed();
56 }
57 }
58
59 promise_base( promise_base const&) = delete;
60 promise_base & operator=( promise_base const&) = delete;
61
62 promise_base( promise_base && other) noexcept :
63 obtained_{ other.obtained_ },
64 future_{ std::move( other.future_) } {
65 other.obtained_ = false;
66 }
67
68 promise_base & operator=( promise_base && other) noexcept {
69 if ( this == & other) return * this;
70 promise_base tmp{ std::move( other) };
71 swap( tmp);
72 return * this;
73 }
74
75 future< R > get_future() {
76 if ( obtained_) {
77 throw future_already_retrieved{};
78 }
79 if ( ! future_) {
80 throw promise_uninitialized{};
81 }
82 obtained_ = true;
83 return future< R >{ future_ };
84 }
85
86 void swap( promise_base & other) noexcept {
87 std::swap( obtained_, other.obtained_);
88 future_.swap( other.future_);
89 }
90
91 void set_exception( std::exception_ptr p) {
92 if ( ! future_) {
93 throw promise_uninitialized{};
94 }
95 future_->set_exception( p);
96 }
97 };
98
99 }
100
101 template< typename R >
102 class promise : private detail::promise_base< R > {
103 private:
104 typedef detail::promise_base< R > base_t;
105
106 public:
107 promise() = default;
108
109 template< typename Allocator >
110 promise( std::allocator_arg_t, Allocator alloc) :
111 base_t{ std::allocator_arg, alloc } {
112 }
113
114 promise( promise const&) = delete;
115 promise & operator=( promise const&) = delete;
116
117 promise( promise && other) noexcept = default;
118 promise & operator=( promise && other) = default;
119
120 void set_value( R const& value) {
121 if ( ! base_t::future_) {
122 throw promise_uninitialized{};
123 }
124 base_t::future_->set_value( value);
125 }
126
127 void set_value( R && value) {
128 if ( ! base_t::future_) {
129 throw promise_uninitialized{};
130 }
131 base_t::future_->set_value( std::move( value) );
132 }
133
134 void swap( promise & other) noexcept {
135 base_t::swap( other);
136 }
137
138 using base_t::get_future;
139 using base_t::set_exception;
140 };
141
142 template< typename R >
143 class promise< R & > : private detail::promise_base< R & > {
144 private:
145 typedef detail::promise_base< R & > base_t;
146
147 public:
148 promise() = default;
149
150 template< typename Allocator >
151 promise( std::allocator_arg_t, Allocator alloc) :
152 base_t{ std::allocator_arg, alloc } {
153 }
154
155 promise( promise const&) = delete;
156 promise & operator=( promise const&) = delete;
157
158 promise( promise && other) noexcept = default;
159 promise & operator=( promise && other) noexcept = default;
160
161 void set_value( R & value) {
162 if ( ! base_t::future_) {
163 throw promise_uninitialized{};
164 }
165 base_t::future_->set_value( value);
166 }
167
168 void swap( promise & other) noexcept {
169 base_t::swap( other);
170 }
171
172 using base_t::get_future;
173 using base_t::set_exception;
174 };
175
176 template<>
177 class promise< void > : private detail::promise_base< void > {
178 private:
179 typedef detail::promise_base< void > base_t;
180
181 public:
182 promise() = default;
183
184 template< typename Allocator >
185 promise( std::allocator_arg_t, Allocator alloc) :
186 base_t{ std::allocator_arg, alloc } {
187 }
188
189 promise( promise const&) = delete;
190 promise & operator=( promise const&) = delete;
191
192 promise( promise && other) noexcept = default;
193 promise & operator=( promise && other) noexcept = default;
194
195 inline
196 void set_value() {
197 if ( ! base_t::future_) {
198 throw promise_uninitialized{};
199 }
200 base_t::future_->set_value();
201 }
202
203 inline
204 void swap( promise & other) noexcept {
205 base_t::swap( other);
206 }
207
208 using base_t::get_future;
209 using base_t::set_exception;
210 };
211
212 template< typename R >
213 void swap( promise< R > & l, promise< R > & r) noexcept {
214 l.swap( r);
215 }
216
217 }}
218
219 #endif // BOOST_FIBERS_PROMISE_HPP