Back to home page

EIC code displayed by LXR

 
 

    


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

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_PUSH_COROUTINE_HPP
0008 #define BOOST_COROUTINES2_DETAIL_PUSH_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 push_coroutine {
0029 private:
0030     template< typename X >
0031     friend class pull_coroutine;
0032 
0033     struct control_block;
0034 
0035     control_block   *   cb_;
0036 
0037     explicit push_coroutine( control_block *) noexcept;
0038 
0039 public:
0040     template< typename Fn,
0041               typename = detail::disable_overload< push_coroutine, Fn >
0042     >
0043     explicit push_coroutine( Fn &&);
0044 
0045     template< typename StackAllocator, typename Fn >
0046     push_coroutine( StackAllocator &&, Fn &&);
0047 
0048     ~push_coroutine();
0049 
0050     push_coroutine( push_coroutine const&) = delete;
0051     push_coroutine & operator=( push_coroutine const&) = delete;
0052 
0053     push_coroutine( push_coroutine &&) noexcept;
0054 
0055     push_coroutine & operator=( push_coroutine && other) noexcept {
0056         if ( this == & other) return * this;
0057         std::swap( cb_, other.cb_);
0058         return * this;
0059     }
0060 
0061     push_coroutine & operator()( T const&);
0062 
0063     push_coroutine & operator()( T &&);
0064 
0065     explicit operator bool() const noexcept;
0066 
0067     bool operator!() const noexcept;
0068 
0069     class iterator {
0070     private:
0071         push_coroutine< T > *   c_{ nullptr };
0072 
0073     public:
0074         typedef std::output_iterator_tag iterator_category;
0075         typedef void value_type;
0076         typedef void difference_type;
0077         typedef void pointer;
0078         typedef void reference;
0079 
0080         iterator() noexcept = default;
0081 
0082         explicit iterator( push_coroutine< T > * c) noexcept :
0083             c_{ c } {
0084         }
0085 
0086         iterator & operator=( T t) {
0087             BOOST_ASSERT( nullptr != c_);
0088             if ( ! ( * c_)( t) ) {
0089                 c_ = nullptr;
0090             }
0091             return * this;
0092         }
0093 
0094         bool operator==( iterator const& other) const noexcept {
0095             return other.c_ == c_;
0096         }
0097 
0098         bool operator!=( iterator const& other) const noexcept {
0099             return other.c_ != c_;
0100         }
0101 
0102         iterator & operator*() noexcept {
0103             return * this;
0104         }
0105 
0106         iterator & operator++() noexcept {
0107             return * this;
0108         }
0109     };
0110 };
0111 
0112 template< typename T >
0113 class push_coroutine< T & > {
0114 private:
0115     template< typename X >
0116     friend class pull_coroutine;
0117 
0118     struct control_block;
0119 
0120     control_block   *   cb_;
0121 
0122     explicit push_coroutine( control_block *) noexcept;
0123 
0124 public:
0125     template< typename Fn,
0126               typename = detail::disable_overload< push_coroutine, Fn >
0127     >
0128     explicit push_coroutine( Fn &&);
0129 
0130     template< typename StackAllocator, typename Fn >
0131     push_coroutine( StackAllocator &&, Fn &&);
0132 
0133     ~push_coroutine();
0134 
0135     push_coroutine( push_coroutine const&) = delete;
0136     push_coroutine & operator=( push_coroutine const&) = delete;
0137 
0138     push_coroutine( push_coroutine &&) noexcept;
0139 
0140     push_coroutine & operator=( push_coroutine && other) noexcept {
0141         if ( this == & other) return * this;
0142         std::swap( cb_, other.cb_);
0143         return * this;
0144     }
0145 
0146     push_coroutine & operator()( T &);
0147 
0148     explicit operator bool() const noexcept;
0149 
0150     bool operator!() const noexcept;
0151 
0152     class iterator {
0153     private:
0154         push_coroutine< T & >   *   c_{ nullptr };
0155 
0156     public:
0157         typedef std::output_iterator_tag iterator_category;
0158         typedef void value_type;
0159         typedef void difference_type;
0160         typedef void pointer;
0161         typedef void reference;
0162 
0163         iterator() noexcept = default;
0164 
0165         explicit iterator( push_coroutine< T & > * c) noexcept :
0166             c_{ c } {
0167         }
0168 
0169         iterator & operator=( T & t) {
0170             BOOST_ASSERT( nullptr != c_);
0171             if ( ! ( * c_)( t) ) {
0172                 c_ = nullptr;
0173             }
0174             return * this;
0175         }
0176 
0177         bool operator==( iterator const& other) const noexcept {
0178             return other.c_ == c_;
0179         }
0180 
0181         bool operator!=( iterator const& other) const noexcept {
0182             return other.c_ != c_;
0183         }
0184 
0185         iterator & operator*() noexcept {
0186             return * this;
0187         }
0188 
0189         iterator & operator++() noexcept {
0190             return * this;
0191         }
0192     };
0193 };
0194 
0195 template<>
0196 class push_coroutine< void > {
0197 private:
0198     template< typename X >
0199     friend class pull_coroutine;
0200 
0201     struct control_block;
0202 
0203     control_block   *   cb_;
0204 
0205     explicit push_coroutine( control_block *) noexcept;
0206 
0207 public:
0208     template< typename Fn,
0209               typename = detail::disable_overload< push_coroutine, Fn >
0210     >
0211     explicit push_coroutine( Fn &&);
0212 
0213     template< typename StackAllocator, typename Fn >
0214     push_coroutine( StackAllocator &&, Fn &&);
0215 
0216     ~push_coroutine();
0217 
0218     push_coroutine( push_coroutine const&) = delete;
0219     push_coroutine & operator=( push_coroutine const&) = delete;
0220 
0221     push_coroutine( push_coroutine &&) noexcept;
0222 
0223     push_coroutine & operator=( push_coroutine && other) noexcept {
0224         if ( this == & other) return * this;
0225         std::swap( cb_, other.cb_);
0226         return * this;
0227     }
0228 
0229     push_coroutine & operator()();
0230 
0231     explicit operator bool() const noexcept;
0232 
0233     bool operator!() const noexcept;
0234 };
0235 
0236 template< typename T >
0237 typename push_coroutine< T >::iterator
0238 begin( push_coroutine< T > & c) {
0239     return typename push_coroutine< T >::iterator( & c);
0240 }
0241 
0242 template< typename T >
0243 typename push_coroutine< T >::iterator
0244 end( push_coroutine< T > &) {
0245     return typename push_coroutine< T >::iterator();
0246 }
0247 
0248 }}}
0249 
0250 #ifdef BOOST_HAS_ABI_HEADERS
0251 #  include BOOST_ABI_SUFFIX
0252 #endif
0253 
0254 #endif // BOOST_COROUTINES2_DETAIL_PUSH_COROUTINE_HPP