]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/coroutine2/detail/pull_coroutine.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / coroutine2 / detail / pull_coroutine.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_COROUTINES2_DETAIL_PULL_COROUTINE_HPP
8 #define BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_HPP
9
10 #include <iterator>
11 #include <type_traits>
12
13 #include <boost/assert.hpp>
14 #include <boost/config.hpp>
15
16 #include <boost/coroutine2/detail/config.hpp>
17 #include <boost/coroutine2/detail/disable_overload.hpp>
18
19 #ifdef BOOST_HAS_ABI_HEADERS
20 # include BOOST_ABI_PREFIX
21 #endif
22
23 namespace boost {
24 namespace coroutines2 {
25 namespace detail {
26
27 template< typename T >
28 class pull_coroutine {
29 private:
30 template< typename X >
31 friend class push_coroutine;
32
33 struct control_block;
34
35 control_block * cb_;
36
37 explicit pull_coroutine( control_block *) noexcept;
38
39 bool has_result_() const noexcept;
40
41 public:
42 template< typename Fn,
43 typename = detail::disable_overload< pull_coroutine, Fn >
44 >
45 explicit pull_coroutine( Fn &&);
46
47 template< typename StackAllocator, typename Fn >
48 pull_coroutine( StackAllocator &&, Fn &&);
49
50 ~pull_coroutine();
51
52 pull_coroutine( pull_coroutine const&) = delete;
53 pull_coroutine & operator=( pull_coroutine const&) = delete;
54
55 pull_coroutine( pull_coroutine &&) noexcept;
56
57 pull_coroutine & operator=( pull_coroutine && other) noexcept {
58 if ( this == & other) return * this;
59 std::swap( cb_, other.cb_);
60 return * this;
61 }
62
63 pull_coroutine & operator()();
64
65 explicit operator bool() const noexcept;
66
67 bool operator!() const noexcept;
68
69 T get() noexcept;
70
71 class iterator {
72 private:
73 pull_coroutine< T > * c_{ nullptr };
74
75 void fetch_() noexcept {
76 BOOST_ASSERT( nullptr != c_);
77 if ( ! ( * c_) ) {
78 c_ = nullptr;
79 return;
80 }
81 }
82
83 void increment_() {
84 BOOST_ASSERT( nullptr != c_);
85 BOOST_ASSERT( * c_);
86 ( * c_)();
87 fetch_();
88 }
89
90 public:
91 typedef std::input_iterator_tag iterator_category;
92 typedef typename std::remove_reference< T >::type value_type;
93 typedef std::ptrdiff_t difference_type;
94 typedef value_type * pointer;
95 typedef value_type & reference;
96
97 typedef pointer pointer_t;
98 typedef reference reference_t;
99
100 iterator() noexcept = default;
101
102 explicit iterator( pull_coroutine< T > * c) noexcept :
103 c_{ c } {
104 fetch_();
105 }
106
107 iterator( iterator const& other) noexcept :
108 c_{ other.c_ } {
109 }
110
111 iterator & operator=( iterator const& other) noexcept {
112 if ( this == & other) return * this;
113 c_ = other.c_;
114 return * this;
115 }
116
117 bool operator==( iterator const& other) const noexcept {
118 return other.c_ == c_;
119 }
120
121 bool operator!=( iterator const& other) const noexcept {
122 return other.c_ != c_;
123 }
124
125 iterator & operator++() {
126 increment_();
127 return * this;
128 }
129
130 iterator operator++( int) = delete;
131
132 reference_t operator*() const noexcept {
133 return c_->cb_->get();
134 }
135
136 pointer_t operator->() const noexcept {
137 return std::addressof( c_->cb_->get() );
138 }
139 };
140
141 friend class iterator;
142 };
143
144 template< typename T >
145 class pull_coroutine< T & > {
146 private:
147 template< typename X >
148 friend class push_coroutine;
149
150 struct control_block;
151
152 control_block * cb_;
153
154 explicit pull_coroutine( control_block *) noexcept;
155
156 bool has_result_() const noexcept;
157
158 public:
159 template< typename Fn,
160 typename = detail::disable_overload< pull_coroutine, Fn >
161 >
162 explicit pull_coroutine( Fn &&);
163
164 template< typename StackAllocator, typename Fn >
165 pull_coroutine( StackAllocator &&, Fn &&);
166
167 ~pull_coroutine();
168
169 pull_coroutine( pull_coroutine const&) = delete;
170 pull_coroutine & operator=( pull_coroutine const&) = delete;
171
172 pull_coroutine( pull_coroutine &&) noexcept;
173
174 pull_coroutine & operator=( pull_coroutine && other) noexcept {
175 if ( this == & other) return * this;
176 std::swap( cb_, other.cb_);
177 return * this;
178 }
179
180 pull_coroutine & operator()();
181
182 explicit operator bool() const noexcept;
183
184 bool operator!() const noexcept;
185
186 T & get() noexcept;
187
188 class iterator {
189 private:
190 pull_coroutine< T & > * c_{ nullptr };
191
192 void fetch_() noexcept {
193 BOOST_ASSERT( nullptr != c_);
194 if ( ! ( * c_) ) {
195 c_ = nullptr;
196 return;
197 }
198 }
199
200 void increment_() {
201 BOOST_ASSERT( nullptr != c_);
202 BOOST_ASSERT( * c_);
203 ( * c_)();
204 fetch_();
205 }
206
207 public:
208 typedef std::input_iterator_tag iterator_category;
209 typedef typename std::remove_reference< T >::type value_type;
210 typedef std::ptrdiff_t difference_type;
211 typedef value_type * pointer;
212 typedef value_type & reference;
213
214 typedef pointer pointer_t;
215 typedef reference reference_t;
216
217 iterator() noexcept = default;
218
219 explicit iterator( pull_coroutine< T & > * c) noexcept :
220 c_{ c } {
221 fetch_();
222 }
223
224 iterator( iterator const& other) noexcept :
225 c_{ other.c_ } {
226 }
227
228 iterator & operator=( iterator const& other) noexcept {
229 if ( this == & other) return * this;
230 c_ = other.c_;
231 return * this;
232 }
233
234 bool operator==( iterator const& other) const noexcept {
235 return other.c_ == c_;
236 }
237
238 bool operator!=( iterator const& other) const noexcept {
239 return other.c_ != c_;
240 }
241
242 iterator & operator++() {
243 increment_();
244 return * this;
245 }
246
247 iterator operator++( int) = delete;
248
249 reference_t operator*() const noexcept {
250 return c_->cb_->get();
251 }
252
253 pointer_t operator->() const noexcept {
254 return std::addressof( c_->cb_->get() );
255 }
256 };
257
258 friend class iterator;
259 };
260
261 template<>
262 class pull_coroutine< void > {
263 private:
264 template< typename X >
265 friend class push_coroutine;
266
267 struct control_block;
268
269 control_block * cb_;
270
271 explicit pull_coroutine( control_block *) noexcept;
272
273 public:
274 template< typename Fn,
275 typename = detail::disable_overload< pull_coroutine, Fn >
276 >
277 explicit pull_coroutine( Fn &&);
278
279 template< typename StackAllocator, typename Fn >
280 pull_coroutine( StackAllocator &&, Fn &&);
281
282 ~pull_coroutine();
283
284 pull_coroutine( pull_coroutine const&) = delete;
285 pull_coroutine & operator=( pull_coroutine const&) = delete;
286
287 pull_coroutine( pull_coroutine &&) noexcept;
288
289 pull_coroutine & operator=( pull_coroutine && other) noexcept {
290 if ( this == & other) return * this;
291 std::swap( cb_, other.cb_);
292 return * this;
293 }
294
295 pull_coroutine & operator()();
296
297 explicit operator bool() const noexcept;
298
299 bool operator!() const noexcept;
300 };
301
302 template< typename T >
303 typename pull_coroutine< T >::iterator
304 begin( pull_coroutine< T > & c) {
305 return typename pull_coroutine< T >::iterator( & c);
306 }
307
308 template< typename T >
309 typename pull_coroutine< T >::iterator
310 end( pull_coroutine< T > &) {
311 return typename pull_coroutine< T >::iterator();
312 }
313
314 }}}
315
316 #ifdef BOOST_HAS_ABI_HEADERS
317 # include BOOST_ABI_SUFFIX
318 #endif
319
320 #endif // BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_HPP