File indexing completed on 2025-01-18 09:30:34
0001
0002
0003
0004
0005
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