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)
7 #ifndef BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_HPP
8 #define BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_HPP
11 #include <type_traits>
13 #include <boost/assert.hpp>
14 #include <boost/config.hpp>
16 #include <boost/coroutine2/detail/config.hpp>
17 #include <boost/coroutine2/detail/disable_overload.hpp>
19 #ifdef BOOST_HAS_ABI_HEADERS
20 # include BOOST_ABI_PREFIX
24 namespace coroutines2 {
27 template< typename T >
28 class pull_coroutine {
30 template< typename X >
31 friend class push_coroutine;
37 explicit pull_coroutine( control_block *) noexcept;
39 bool has_result_() const noexcept;
42 template< typename Fn,
43 typename = detail::disable_overload< pull_coroutine, Fn >
45 explicit pull_coroutine( Fn &&);
47 template< typename StackAllocator, typename Fn >
48 pull_coroutine( StackAllocator &&, Fn &&);
52 pull_coroutine( pull_coroutine const&) = delete;
53 pull_coroutine & operator=( pull_coroutine const&) = delete;
55 pull_coroutine( pull_coroutine &&) noexcept;
57 pull_coroutine & operator=( pull_coroutine && other) noexcept {
58 if ( this == & other) return * this;
59 std::swap( cb_, other.cb_);
63 pull_coroutine & operator()();
65 explicit operator bool() const noexcept;
67 bool operator!() const noexcept;
73 pull_coroutine< T > * c_{ nullptr };
75 void fetch_() noexcept {
76 BOOST_ASSERT( nullptr != c_);
84 BOOST_ASSERT( nullptr != c_);
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;
97 typedef pointer pointer_t;
98 typedef reference reference_t;
100 iterator() noexcept = default;
102 explicit iterator( pull_coroutine< T > * c) noexcept :
107 iterator( iterator const& other) noexcept :
111 iterator & operator=( iterator const& other) noexcept {
112 if ( this == & other) return * this;
117 bool operator==( iterator const& other) const noexcept {
118 return other.c_ == c_;
121 bool operator!=( iterator const& other) const noexcept {
122 return other.c_ != c_;
125 iterator & operator++() {
130 iterator operator++( int) = delete;
132 reference_t operator*() const noexcept {
133 return c_->cb_->get();
136 pointer_t operator->() const noexcept {
137 return std::addressof( c_->cb_->get() );
141 friend class iterator;
144 template< typename T >
145 class pull_coroutine< T & > {
147 template< typename X >
148 friend class push_coroutine;
150 struct control_block;
154 explicit pull_coroutine( control_block *) noexcept;
156 bool has_result_() const noexcept;
159 template< typename Fn,
160 typename = detail::disable_overload< pull_coroutine, Fn >
162 explicit pull_coroutine( Fn &&);
164 template< typename StackAllocator, typename Fn >
165 pull_coroutine( StackAllocator &&, Fn &&);
169 pull_coroutine( pull_coroutine const&) = delete;
170 pull_coroutine & operator=( pull_coroutine const&) = delete;
172 pull_coroutine( pull_coroutine &&) noexcept;
174 pull_coroutine & operator=( pull_coroutine && other) noexcept {
175 if ( this == & other) return * this;
176 std::swap( cb_, other.cb_);
180 pull_coroutine & operator()();
182 explicit operator bool() const noexcept;
184 bool operator!() const noexcept;
190 pull_coroutine< T & > * c_{ nullptr };
192 void fetch_() noexcept {
193 BOOST_ASSERT( nullptr != c_);
201 BOOST_ASSERT( nullptr != c_);
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;
214 typedef pointer pointer_t;
215 typedef reference reference_t;
217 iterator() noexcept = default;
219 explicit iterator( pull_coroutine< T & > * c) noexcept :
224 iterator( iterator const& other) noexcept :
228 iterator & operator=( iterator const& other) noexcept {
229 if ( this == & other) return * this;
234 bool operator==( iterator const& other) const noexcept {
235 return other.c_ == c_;
238 bool operator!=( iterator const& other) const noexcept {
239 return other.c_ != c_;
242 iterator & operator++() {
247 iterator operator++( int) = delete;
249 reference_t operator*() const noexcept {
250 return c_->cb_->get();
253 pointer_t operator->() const noexcept {
254 return std::addressof( c_->cb_->get() );
258 friend class iterator;
262 class pull_coroutine< void > {
264 template< typename X >
265 friend class push_coroutine;
267 struct control_block;
271 explicit pull_coroutine( control_block *) noexcept;
274 template< typename Fn,
275 typename = detail::disable_overload< pull_coroutine, Fn >
277 explicit pull_coroutine( Fn &&);
279 template< typename StackAllocator, typename Fn >
280 pull_coroutine( StackAllocator &&, Fn &&);
284 pull_coroutine( pull_coroutine const&) = delete;
285 pull_coroutine & operator=( pull_coroutine const&) = delete;
287 pull_coroutine( pull_coroutine &&) noexcept;
289 pull_coroutine & operator=( pull_coroutine && other) noexcept {
290 if ( this == & other) return * this;
291 std::swap( cb_, other.cb_);
295 pull_coroutine & operator()();
297 explicit operator bool() const noexcept;
299 bool operator!() const noexcept;
302 template< typename T >
303 typename pull_coroutine< T >::iterator
304 begin( pull_coroutine< T > & c) {
305 return typename pull_coroutine< T >::iterator( & c);
308 template< typename T >
309 typename pull_coroutine< T >::iterator
310 end( pull_coroutine< T > &) {
311 return typename pull_coroutine< T >::iterator();
316 #ifdef BOOST_HAS_ABI_HEADERS
317 # include BOOST_ABI_SUFFIX
320 #endif // BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_HPP