Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:33

0001 
0002 //          Copyright Oliver Kowalke 2014.
0003 // Distributed under the Boost Software License, Version 1.0.
0004 //    (See accompanying file LICENSE_1_0.txt or copy at
0005 //          http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #ifndef BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_HPP
0008 #define BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_HPP
0009 
0010 #include <iterator>
0011 #include <type_traits>
0012 
0013 #include <boost/assert.hpp>
0014 #include <boost/config.hpp>
0015 
0016 #include <boost/coroutine2/detail/config.hpp>
0017 #include <boost/coroutine2/detail/disable_overload.hpp>
0018 
0019 #ifdef BOOST_HAS_ABI_HEADERS
0020 #  include BOOST_ABI_PREFIX
0021 #endif
0022 
0023 namespace boost {
0024 namespace coroutines2 {
0025 namespace detail {
0026 
0027 template< typename T >
0028 class pull_coroutine {
0029 private:
0030     template< typename X >
0031     friend class push_coroutine;
0032 
0033     struct control_block;
0034 
0035     control_block   *   cb_;
0036 
0037     explicit pull_coroutine( control_block *) noexcept;
0038 
0039     bool has_result_() const noexcept;
0040 
0041 public:
0042     template< typename Fn,
0043               typename = detail::disable_overload< pull_coroutine, Fn >
0044     >
0045     explicit pull_coroutine( Fn &&);
0046 
0047     template< typename StackAllocator, typename Fn >
0048     pull_coroutine( StackAllocator &&, Fn &&);
0049 
0050     ~pull_coroutine();
0051 
0052     pull_coroutine( pull_coroutine const&) = delete;
0053     pull_coroutine & operator=( pull_coroutine const&) = delete;
0054 
0055     pull_coroutine( pull_coroutine &&) noexcept;
0056 
0057     pull_coroutine & operator=( pull_coroutine && other) noexcept {
0058         std::swap( cb_, other.cb_);
0059         return * this;
0060     }
0061 
0062     pull_coroutine & operator()();
0063 
0064     explicit operator bool() const noexcept;
0065 
0066     bool operator!() const noexcept;
0067 
0068     T get() noexcept;
0069 
0070     class iterator {
0071     private:
0072         pull_coroutine< T > *   c_{ nullptr };
0073 
0074         void fetch_() noexcept {
0075             BOOST_ASSERT( nullptr != c_);
0076             if ( ! ( * c_) ) {
0077                 c_ = nullptr;
0078                 return;
0079             }
0080         }
0081 
0082         void increment_() {
0083             BOOST_ASSERT( nullptr != c_);
0084             BOOST_ASSERT( * c_);
0085             ( * c_)();
0086             fetch_();
0087         }
0088 
0089     public:
0090         typedef std::input_iterator_tag iterator_category;
0091         typedef typename std::remove_reference< T >::type value_type;
0092         typedef std::ptrdiff_t difference_type;
0093         typedef value_type * pointer;
0094         typedef value_type & reference;
0095 
0096         typedef pointer   pointer_t;
0097         typedef reference reference_t;
0098 
0099         iterator() noexcept = default;
0100 
0101         explicit iterator( pull_coroutine< T > * c) noexcept :
0102             c_{ c } {
0103             fetch_();
0104         }
0105 
0106         bool operator==( iterator const& other) const noexcept {
0107             return other.c_ == c_;
0108         }
0109 
0110         bool operator!=( iterator const& other) const noexcept {
0111             return other.c_ != c_;
0112         }
0113 
0114         iterator & operator++() {
0115             increment_();
0116             return * this;
0117         }
0118 
0119         void operator++( int) {
0120             increment_();
0121         }
0122 
0123         reference_t operator*() const noexcept {
0124             return c_->cb_->get();
0125         }
0126 
0127         pointer_t operator->() const noexcept {
0128             return std::addressof( c_->cb_->get() );
0129         }
0130     };
0131 
0132     friend class iterator;
0133 
0134     iterator begin() { return iterator (this); }
0135     iterator end() { return iterator(); }
0136 };
0137 
0138 template< typename T >
0139 class pull_coroutine< T & > {
0140 private:
0141     template< typename X >
0142     friend class push_coroutine;
0143 
0144     struct control_block;
0145 
0146     control_block   *   cb_;
0147 
0148     explicit pull_coroutine( control_block *) noexcept;
0149 
0150     bool has_result_() const noexcept;
0151 
0152 public:
0153     template< typename Fn,
0154               typename = detail::disable_overload< pull_coroutine, Fn >
0155     >
0156     explicit pull_coroutine( Fn &&);
0157 
0158     template< typename StackAllocator, typename Fn >
0159     pull_coroutine( StackAllocator &&, Fn &&);
0160 
0161     ~pull_coroutine();
0162 
0163     pull_coroutine( pull_coroutine const&) = delete;
0164     pull_coroutine & operator=( pull_coroutine const&) = delete;
0165 
0166     pull_coroutine( pull_coroutine &&) noexcept;
0167 
0168     pull_coroutine & operator=( pull_coroutine && other) noexcept {
0169         std::swap( cb_, other.cb_);
0170         return * this;
0171     }
0172 
0173     pull_coroutine & operator()();
0174 
0175     explicit operator bool() const noexcept;
0176 
0177     bool operator!() const noexcept;
0178 
0179     T & get() noexcept;
0180 
0181     class iterator {
0182     private:
0183         pull_coroutine< T & > *   c_{ nullptr };
0184 
0185         void fetch_() noexcept {
0186             BOOST_ASSERT( nullptr != c_);
0187             if ( ! ( * c_) ) {
0188                 c_ = nullptr;
0189                 return;
0190             }
0191         }
0192 
0193         void increment_() {
0194             BOOST_ASSERT( nullptr != c_);
0195             BOOST_ASSERT( * c_);
0196             ( * c_)();
0197             fetch_();
0198         }
0199 
0200     public:
0201         typedef std::input_iterator_tag iterator_category;
0202         typedef typename std::remove_reference< T >::type value_type;
0203         typedef std::ptrdiff_t difference_type;
0204         typedef value_type * pointer;
0205         typedef value_type & reference;
0206 
0207         typedef pointer   pointer_t;
0208         typedef reference reference_t;
0209 
0210         iterator() noexcept = default;
0211 
0212         explicit iterator( pull_coroutine< T & > * c) noexcept :
0213             c_{ c } {
0214             fetch_();
0215         }
0216 
0217         bool operator==( iterator const& other) const noexcept {
0218             return other.c_ == c_;
0219         }
0220 
0221         bool operator!=( iterator const& other) const noexcept {
0222             return other.c_ != c_;
0223         }
0224 
0225         iterator & operator++() {
0226             increment_();
0227             return * this;
0228         }
0229 
0230         void operator++( int) {
0231             increment_();
0232         }
0233 
0234         reference_t operator*() const noexcept {
0235             return c_->cb_->get();
0236         }
0237 
0238         pointer_t operator->() const noexcept {
0239             return std::addressof( c_->cb_->get() );
0240         }
0241     };
0242 
0243     friend class iterator;
0244 
0245     iterator begin() { return iterator (this); }
0246     iterator end() { return iterator(); }
0247 };
0248 
0249 template<>
0250 class pull_coroutine< void > {
0251 private:
0252     template< typename X >
0253     friend class push_coroutine;
0254 
0255     struct control_block;
0256 
0257     control_block   *   cb_;
0258 
0259     explicit pull_coroutine( control_block *) noexcept;
0260 
0261 public:
0262     template< typename Fn,
0263               typename = detail::disable_overload< pull_coroutine, Fn >
0264     >
0265     explicit pull_coroutine( Fn &&);
0266 
0267     template< typename StackAllocator, typename Fn >
0268     pull_coroutine( StackAllocator &&, Fn &&);
0269 
0270     ~pull_coroutine();
0271 
0272     pull_coroutine( pull_coroutine const&) = delete;
0273     pull_coroutine & operator=( pull_coroutine const&) = delete;
0274 
0275     pull_coroutine( pull_coroutine &&) noexcept;
0276 
0277     pull_coroutine & operator=( pull_coroutine && other) noexcept {
0278         std::swap( cb_, other.cb_);
0279         return * this;
0280     }
0281 
0282     pull_coroutine & operator()();
0283 
0284     explicit operator bool() const noexcept;
0285 
0286     bool operator!() const noexcept;
0287 
0288 
0289 };
0290 
0291 template< typename T >
0292 typename pull_coroutine< T >::iterator
0293 begin( pull_coroutine< T > & c) {
0294     return typename pull_coroutine< T >::iterator( & c);
0295 }
0296 
0297 template< typename T >
0298 typename pull_coroutine< T >::iterator
0299 end( pull_coroutine< T > &) {
0300     return typename pull_coroutine< T >::iterator();
0301 }
0302 
0303 }}}
0304 
0305 #ifdef BOOST_HAS_ABI_HEADERS
0306 #  include BOOST_ABI_SUFFIX
0307 #endif
0308 
0309 #endif // BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_HPP