]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/coroutine/detail/symmetric_coroutine_yield.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / coroutine / detail / symmetric_coroutine_yield.hpp
1
2 // Copyright Oliver Kowalke 2009.
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_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_YIELD_H
8 #define BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_YIELD_H
9
10 #include <algorithm>
11
12 #include <boost/assert.hpp>
13 #include <boost/config.hpp>
14 #include <boost/move/move.hpp>
15 #include <boost/throw_exception.hpp>
16 #include <boost/type_traits/is_same.hpp>
17 #include <boost/utility/enable_if.hpp>
18 #include <boost/utility/explicit_operator_bool.hpp>
19
20 #include <boost/coroutine/detail/config.hpp>
21 #include <boost/coroutine/exceptions.hpp>
22
23 #ifdef BOOST_HAS_ABI_HEADERS
24 # include BOOST_ABI_PREFIX
25 #endif
26
27 namespace boost {
28 namespace coroutines {
29 namespace detail {
30
31 template< typename R >
32 class symmetric_coroutine_yield
33 {
34 private:
35 template< typename X, typename Y, typename Z >
36 friend class symmetric_coroutine_object;
37
38 typedef symmetric_coroutine_impl< R > impl_type;
39
40 struct dummy {};
41
42 BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_yield)
43
44 impl_type * impl_;
45 R * result_;
46
47 symmetric_coroutine_yield( impl_type * impl, R * result) BOOST_NOEXCEPT :
48 impl_( impl),
49 result_( result)
50 {
51 BOOST_ASSERT( 0 != impl_);
52 BOOST_ASSERT( 0 != result_);
53 }
54
55 public:
56 symmetric_coroutine_yield() BOOST_NOEXCEPT :
57 impl_( 0),
58 result_( 0)
59 {}
60
61 symmetric_coroutine_yield( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT :
62 impl_( 0),
63 result_( 0)
64 { swap( other); }
65
66 symmetric_coroutine_yield & operator=( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT
67 {
68 symmetric_coroutine_yield tmp( boost::move( other) );
69 swap( tmp);
70 return * this;
71 }
72
73 BOOST_EXPLICIT_OPERATOR_BOOL();
74
75 bool operator!() const BOOST_NOEXCEPT
76 { return 0 == impl_; }
77
78 void swap( symmetric_coroutine_yield & other) BOOST_NOEXCEPT
79 {
80 std::swap( impl_, other.impl_);
81 std::swap( result_, other.result_);
82 }
83
84 symmetric_coroutine_yield & operator()()
85 {
86 result_ = impl_->yield();
87 return * this;
88 }
89
90 template< typename Coro >
91 symmetric_coroutine_yield & operator()( Coro & other, typename Coro::value_type x,
92 typename disable_if<
93 is_same< typename Coro::value_type, void >,
94 dummy*
95 >::type = 0)
96 {
97 BOOST_ASSERT( other);
98
99 result_ = impl_->yield_to( other.impl_, x);
100 return * this;
101 }
102
103 template< typename Coro >
104 symmetric_coroutine_yield & operator()( Coro & other,
105 typename enable_if<
106 is_same< typename Coro::value_type, void >,
107 dummy*
108 >::type = 0)
109 {
110 BOOST_ASSERT( other);
111
112 result_ = impl_->yield_to( other.impl_);
113 return * this;
114 }
115
116 R get() const
117 {
118 if ( 0 == result_)
119 boost::throw_exception(
120 invalid_result() );
121
122 return * result_;
123 }
124 };
125
126 template< typename R >
127 class symmetric_coroutine_yield< R & >
128 {
129 private:
130 template< typename X, typename Y, typename Z >
131 friend class symmetric_coroutine_object;
132
133 typedef symmetric_coroutine_impl< R & > impl_type;
134
135 struct dummy {};
136
137 BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_yield)
138
139 impl_type * impl_;
140 R * result_;
141
142 symmetric_coroutine_yield( impl_type * impl, R * result) BOOST_NOEXCEPT :
143 impl_( impl),
144 result_( result)
145 {
146 BOOST_ASSERT( 0 != impl_);
147 BOOST_ASSERT( 0 != result_);
148 }
149
150 public:
151 symmetric_coroutine_yield() BOOST_NOEXCEPT :
152 impl_( 0),
153 result_( 0)
154 {}
155
156 symmetric_coroutine_yield( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT :
157 impl_( 0),
158 result_( 0)
159 { swap( other); }
160
161 symmetric_coroutine_yield & operator=( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT
162 {
163 symmetric_coroutine_yield tmp( boost::move( other) );
164 swap( tmp);
165 return * this;
166 }
167
168 BOOST_EXPLICIT_OPERATOR_BOOL();
169
170 bool operator!() const BOOST_NOEXCEPT
171 { return 0 == impl_; }
172
173 void swap( symmetric_coroutine_yield & other) BOOST_NOEXCEPT
174 {
175 std::swap( impl_, other.impl_);
176 std::swap( result_, other.result_);
177 }
178
179 symmetric_coroutine_yield & operator()()
180 {
181 result_ = impl_->yield();
182 return * this;
183 }
184
185 template< typename Coro >
186 symmetric_coroutine_yield & operator()( Coro & other, typename Coro::value_type & x,
187 typename disable_if<
188 is_same< typename Coro::value_type, void >,
189 dummy*
190 >::type = 0)
191 {
192 BOOST_ASSERT( other);
193
194 result_ = impl_->yield_to( other.impl_, x);
195 return * this;
196 }
197
198 template< typename Coro >
199 symmetric_coroutine_yield & operator()( Coro & other,
200 typename enable_if<
201 is_same< typename Coro::value_type, void >,
202 dummy*
203 >::type = 0)
204 {
205 BOOST_ASSERT( other);
206
207 result_ = impl_->yield_to( other.impl_);
208 return * this;
209 }
210
211 R & get() const
212 {
213 if ( 0 == result_)
214 boost::throw_exception(
215 invalid_result() );
216
217 return * result_;
218 }
219 };
220
221 template<>
222 class symmetric_coroutine_yield< void >
223 {
224 private:
225 template< typename X, typename Y, typename Z >
226 friend class symmetric_coroutine_object;
227
228 typedef symmetric_coroutine_impl< void > impl_type;
229
230 struct dummy {};
231
232 BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_yield)
233
234 impl_type * impl_;
235
236 symmetric_coroutine_yield( impl_type * impl) BOOST_NOEXCEPT :
237 impl_( impl)
238 { BOOST_ASSERT( 0 != impl_); }
239
240 public:
241 symmetric_coroutine_yield() BOOST_NOEXCEPT :
242 impl_( 0)
243 {}
244
245 symmetric_coroutine_yield( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT :
246 impl_( 0)
247 { swap( other); }
248
249 symmetric_coroutine_yield & operator=( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT
250 {
251 symmetric_coroutine_yield tmp( boost::move( other) );
252 swap( tmp);
253 return * this;
254 }
255
256 BOOST_EXPLICIT_OPERATOR_BOOL();
257
258 inline bool operator!() const BOOST_NOEXCEPT
259 { return 0 == impl_; }
260
261 inline void swap( symmetric_coroutine_yield & other) BOOST_NOEXCEPT
262 { std::swap( impl_, other.impl_); }
263
264 inline symmetric_coroutine_yield & operator()()
265 {
266 impl_->yield();
267 return * this;
268 }
269
270 template< typename Coro >
271 symmetric_coroutine_yield & operator()( Coro & other, typename Coro::value_type & x,
272 typename disable_if<
273 is_same< typename Coro::value_type, void >,
274 dummy*
275 >::type = 0)
276 {
277 BOOST_ASSERT( other);
278
279 impl_->yield_to( other.impl_, x);
280 return * this;
281 }
282
283 template< typename Coro >
284 symmetric_coroutine_yield & operator()( Coro & other,
285 typename enable_if<
286 is_same< typename Coro::value_type, void >,
287 dummy*
288 >::type = 0)
289 {
290 BOOST_ASSERT( other);
291
292 impl_->yield_to( other.impl_);
293 return * this;
294 }
295 };
296
297 template< typename R >
298 void swap( symmetric_coroutine_yield< R > & l, symmetric_coroutine_yield< R > & r)
299 { l.swap( r); }
300
301 }}}
302
303 #ifdef BOOST_HAS_ABI_HEADERS
304 # include BOOST_ABI_SUFFIX
305 #endif
306
307 #endif // BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_YIELD_H