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 &&);
50 ~pull_coroutine() noexcept;
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;
64 pull_coroutine & operator()();
66 explicit operator bool() const noexcept;
68 bool operator!() const noexcept;
72 class iterator : public std::iterator< std::input_iterator_tag, typename std::remove_reference< T >::type > {
74 pull_coroutine< T > * c_{ nullptr };
76 void fetch_() noexcept {
77 BOOST_ASSERT( nullptr != c_);
85 BOOST_ASSERT( nullptr != c_);
92 typedef typename iterator::pointer pointer_t;
93 typedef typename iterator::reference reference_t;
95 constexpr iterator() noexcept = default;
97 explicit iterator( pull_coroutine< T > * c) noexcept :
102 iterator( iterator const& other) noexcept :
106 iterator & operator=( iterator const& other) noexcept {
107 if ( this == & other) return * this;
112 bool operator==( iterator const& other) const noexcept {
113 return other.c_ == c_;
116 bool operator!=( iterator const& other) const noexcept {
117 return other.c_ != c_;
120 iterator & operator++() {
125 iterator operator++( int) = delete;
127 reference_t operator*() const noexcept {
128 return c_->cb_->get();
131 pointer_t operator->() const noexcept {
132 return std::addressof( c_->cb_->get() );
136 friend class iterator;
139 template< typename T >
140 class pull_coroutine< T & > {
142 template< typename X >
143 friend class push_coroutine;
145 struct control_block;
149 explicit pull_coroutine( control_block *) noexcept;
151 bool has_result_() const noexcept;
154 template< typename Fn,
155 typename = detail::disable_overload< pull_coroutine, Fn >
157 explicit pull_coroutine( Fn &&);
159 template< typename StackAllocator, typename Fn >
160 pull_coroutine( StackAllocator, Fn &&);
162 ~pull_coroutine() noexcept;
164 pull_coroutine( pull_coroutine const&) = delete;
165 pull_coroutine & operator=( pull_coroutine const&) = delete;
167 pull_coroutine( pull_coroutine &&) noexcept;
169 pull_coroutine & operator=( pull_coroutine && other) noexcept {
170 if ( this == & other) return * this;
176 pull_coroutine & operator()();
178 explicit operator bool() const noexcept;
180 bool operator!() const noexcept;
184 class iterator : public std::iterator< std::input_iterator_tag, typename std::remove_reference< T >::type > {
186 pull_coroutine< T & > * c_{ nullptr };
188 void fetch_() noexcept {
189 BOOST_ASSERT( nullptr != c_);
197 BOOST_ASSERT( nullptr != c_);
204 typedef typename iterator::pointer pointer_t;
205 typedef typename iterator::reference reference_t;
207 constexpr iterator() noexcept = default;
209 explicit iterator( pull_coroutine< T & > * c) noexcept :
214 iterator( iterator const& other) noexcept :
218 iterator & operator=( iterator const& other) noexcept {
219 if ( this == & other) return * this;
224 bool operator==( iterator const& other) const noexcept {
225 return other.c_ == c_;
228 bool operator!=( iterator const& other) const noexcept {
229 return other.c_ != c_;
232 iterator & operator++() {
237 iterator operator++( int) = delete;
239 reference_t operator*() const noexcept {
240 return c_->cb_->get();
243 pointer_t operator->() const noexcept {
244 return std::addressof( c_->cb_->get() );
248 friend class iterator;
252 class pull_coroutine< void > {
254 template< typename X >
255 friend class push_coroutine;
257 struct control_block;
261 explicit pull_coroutine( control_block *) noexcept;
264 template< typename Fn,
265 typename = detail::disable_overload< pull_coroutine, Fn >
267 explicit pull_coroutine( Fn &&);
269 template< typename StackAllocator, typename Fn >
270 pull_coroutine( StackAllocator, Fn &&);
272 ~pull_coroutine() noexcept;
274 pull_coroutine( pull_coroutine const&) = delete;
275 pull_coroutine & operator=( pull_coroutine const&) = delete;
277 pull_coroutine( pull_coroutine &&) noexcept;
279 pull_coroutine & operator=( pull_coroutine && other) noexcept {
280 if ( this == & other) return * this;
286 pull_coroutine & operator()();
288 explicit operator bool() const noexcept;
290 bool operator!() const noexcept;
293 template< typename T >
294 typename pull_coroutine< T >::iterator
295 begin( pull_coroutine< T > & c) {
296 return typename pull_coroutine< T >::iterator( & c);
299 template< typename T >
300 typename pull_coroutine< T >::iterator
301 end( pull_coroutine< T > &) {
302 return typename pull_coroutine< T >::iterator();
307 #ifdef BOOST_HAS_ABI_HEADERS
308 # include BOOST_ABI_SUFFIX
311 #endif // BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_HPP