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_PUSH_COROUTINE_HPP
8 #define BOOST_COROUTINES2_DETAIL_PUSH_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 push_coroutine {
30 template< typename X >
31 friend class pull_coroutine;
37 explicit push_coroutine( control_block *) noexcept;
40 template< typename Fn,
41 typename = detail::disable_overload< push_coroutine, Fn >
43 explicit push_coroutine( Fn &&);
45 template< typename StackAllocator, typename Fn >
46 push_coroutine( StackAllocator, Fn &&);
48 ~push_coroutine() noexcept;
50 push_coroutine( push_coroutine const&) = delete;
51 push_coroutine & operator=( push_coroutine const&) = delete;
53 push_coroutine( push_coroutine &&) noexcept;
55 push_coroutine & operator=( push_coroutine && other) noexcept {
56 if ( this == & other) return * this;
62 push_coroutine & operator()( T const&);
64 push_coroutine & operator()( T &&);
66 explicit operator bool() const noexcept;
68 bool operator!() const noexcept;
70 class iterator : public std::iterator< std::output_iterator_tag, void, void, void, void > {
72 push_coroutine< T > * c_{ nullptr };
75 constexpr iterator() noexcept = default;
77 explicit iterator( push_coroutine< T > * c) noexcept :
81 iterator & operator=( T t) {
83 if ( ! ( * c_)( t) ) {
89 bool operator==( iterator const& other) const noexcept {
90 return other.c_ == c_;
93 bool operator!=( iterator const& other) const noexcept {
94 return other.c_ != c_;
97 iterator & operator*() noexcept {
101 iterator & operator++() noexcept {
107 template< typename T >
108 class push_coroutine< T & > {
110 template< typename X >
111 friend class pull_coroutine;
113 struct control_block;
117 explicit push_coroutine( control_block *) noexcept;
120 template< typename Fn,
121 typename = detail::disable_overload< push_coroutine, Fn >
123 explicit push_coroutine( Fn &&);
125 template< typename StackAllocator, typename Fn >
126 push_coroutine( StackAllocator, Fn &&);
128 ~push_coroutine() noexcept;
130 push_coroutine( push_coroutine const&) = delete;
131 push_coroutine & operator=( push_coroutine const&) = delete;
133 push_coroutine( push_coroutine &&) noexcept;
135 push_coroutine & operator=( push_coroutine && other) noexcept {
136 if ( this == & other) return * this;
142 push_coroutine & operator()( T &);
144 explicit operator bool() const noexcept;
146 bool operator!() const noexcept;
148 class iterator : public std::iterator< std::output_iterator_tag, void, void, void, void > {
150 push_coroutine< T & > * c_{ nullptr };
153 constexpr iterator() noexcept = default;
155 explicit iterator( push_coroutine< T & > * c) noexcept :
159 iterator & operator=( T & t) {
161 if ( ! ( * c_)( t) ) {
167 bool operator==( iterator const& other) const noexcept {
168 return other.c_ == c_;
171 bool operator!=( iterator const& other) const noexcept {
172 return other.c_ != c_;
175 iterator & operator*() noexcept {
179 iterator & operator++() noexcept {
186 class push_coroutine< void > {
188 template< typename X >
189 friend class pull_coroutine;
191 struct control_block;
195 explicit push_coroutine( control_block *) noexcept;
198 template< typename Fn,
199 typename = detail::disable_overload< push_coroutine, Fn >
201 explicit push_coroutine( Fn &&);
203 template< typename StackAllocator, typename Fn >
204 push_coroutine( StackAllocator, Fn &&);
206 ~push_coroutine() noexcept;
208 push_coroutine( push_coroutine const&) = delete;
209 push_coroutine & operator=( push_coroutine const&) = delete;
211 push_coroutine( push_coroutine &&) noexcept;
213 push_coroutine & operator=( push_coroutine && other) noexcept {
214 if ( this == & other) return * this;
220 push_coroutine & operator()();
222 explicit operator bool() const noexcept;
224 bool operator!() const noexcept;
227 template< typename T >
228 typename push_coroutine< T >::iterator
229 begin( push_coroutine< T > & c) {
230 return typename push_coroutine< T >::iterator( & c);
233 template< typename T >
234 typename push_coroutine< T >::iterator
235 end( push_coroutine< T > &) {
236 return typename push_coroutine< T >::iterator();
241 #ifdef BOOST_HAS_ABI_HEADERS
242 # include BOOST_ABI_SUFFIX
245 #endif // BOOST_COROUTINES2_DETAIL_PUSH_COROUTINE_HPP