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