2 // Copyright Oliver Kowalke 2009.
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_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_YIELD_H
8 #define BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_YIELD_H
12 #include <boost/assert.hpp>
13 #include <boost/config.hpp>
14 #include <boost/move/move.hpp>
15 #include <boost/throw_exception.hpp>
16 #include <boost/type_traits/is_same.hpp>
17 #include <boost/utility/enable_if.hpp>
18 #include <boost/utility/explicit_operator_bool.hpp>
20 #include <boost/coroutine/detail/config.hpp>
21 #include <boost/coroutine/exceptions.hpp>
23 #ifdef BOOST_HAS_ABI_HEADERS
24 # include BOOST_ABI_PREFIX
28 namespace coroutines {
31 template< typename R >
32 class symmetric_coroutine_yield
35 template< typename X, typename Y, typename Z >
36 friend class symmetric_coroutine_object;
38 typedef symmetric_coroutine_impl< R > impl_type;
42 BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_yield)
47 symmetric_coroutine_yield( impl_type * impl, R * result) BOOST_NOEXCEPT :
51 BOOST_ASSERT( 0 != impl_);
52 BOOST_ASSERT( 0 != result_);
56 symmetric_coroutine_yield() BOOST_NOEXCEPT :
61 symmetric_coroutine_yield( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT :
66 symmetric_coroutine_yield & operator=( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT
68 symmetric_coroutine_yield tmp( boost::move( other) );
73 BOOST_EXPLICIT_OPERATOR_BOOL();
75 bool operator!() const BOOST_NOEXCEPT
76 { return 0 == impl_; }
78 void swap( symmetric_coroutine_yield & other) BOOST_NOEXCEPT
80 std::swap( impl_, other.impl_);
81 std::swap( result_, other.result_);
84 symmetric_coroutine_yield & operator()()
86 result_ = impl_->yield();
90 template< typename Coro >
91 symmetric_coroutine_yield & operator()( Coro & other, typename Coro::value_type x,
93 is_same< typename Coro::value_type, void >,
99 result_ = impl_->yield_to( other.impl_, x);
103 template< typename Coro >
104 symmetric_coroutine_yield & operator()( Coro & other,
106 is_same< typename Coro::value_type, void >,
110 BOOST_ASSERT( other);
112 result_ = impl_->yield_to( other.impl_);
119 boost::throw_exception(
126 template< typename R >
127 class symmetric_coroutine_yield< R & >
130 template< typename X, typename Y, typename Z >
131 friend class symmetric_coroutine_object;
133 typedef symmetric_coroutine_impl< R & > impl_type;
137 BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_yield)
142 symmetric_coroutine_yield( impl_type * impl, R * result) BOOST_NOEXCEPT :
146 BOOST_ASSERT( 0 != impl_);
147 BOOST_ASSERT( 0 != result_);
151 symmetric_coroutine_yield() BOOST_NOEXCEPT :
156 symmetric_coroutine_yield( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT :
161 symmetric_coroutine_yield & operator=( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT
163 symmetric_coroutine_yield tmp( boost::move( other) );
168 BOOST_EXPLICIT_OPERATOR_BOOL();
170 bool operator!() const BOOST_NOEXCEPT
171 { return 0 == impl_; }
173 void swap( symmetric_coroutine_yield & other) BOOST_NOEXCEPT
175 std::swap( impl_, other.impl_);
176 std::swap( result_, other.result_);
179 symmetric_coroutine_yield & operator()()
181 result_ = impl_->yield();
185 template< typename Coro >
186 symmetric_coroutine_yield & operator()( Coro & other, typename Coro::value_type & x,
188 is_same< typename Coro::value_type, void >,
192 BOOST_ASSERT( other);
194 result_ = impl_->yield_to( other.impl_, x);
198 template< typename Coro >
199 symmetric_coroutine_yield & operator()( Coro & other,
201 is_same< typename Coro::value_type, void >,
205 BOOST_ASSERT( other);
207 result_ = impl_->yield_to( other.impl_);
214 boost::throw_exception(
222 class symmetric_coroutine_yield< void >
225 template< typename X, typename Y, typename Z >
226 friend class symmetric_coroutine_object;
228 typedef symmetric_coroutine_impl< void > impl_type;
232 BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_yield)
236 symmetric_coroutine_yield( impl_type * impl) BOOST_NOEXCEPT :
238 { BOOST_ASSERT( 0 != impl_); }
241 symmetric_coroutine_yield() BOOST_NOEXCEPT :
245 symmetric_coroutine_yield( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT :
249 symmetric_coroutine_yield & operator=( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT
251 symmetric_coroutine_yield tmp( boost::move( other) );
256 BOOST_EXPLICIT_OPERATOR_BOOL();
258 inline bool operator!() const BOOST_NOEXCEPT
259 { return 0 == impl_; }
261 inline void swap( symmetric_coroutine_yield & other) BOOST_NOEXCEPT
262 { std::swap( impl_, other.impl_); }
264 inline symmetric_coroutine_yield & operator()()
270 template< typename Coro >
271 symmetric_coroutine_yield & operator()( Coro & other, typename Coro::value_type & x,
273 is_same< typename Coro::value_type, void >,
277 BOOST_ASSERT( other);
279 impl_->yield_to( other.impl_, x);
283 template< typename Coro >
284 symmetric_coroutine_yield & operator()( Coro & other,
286 is_same< typename Coro::value_type, void >,
290 BOOST_ASSERT( other);
292 impl_->yield_to( other.impl_);
297 template< typename R >
298 void swap( symmetric_coroutine_yield< R > & l, symmetric_coroutine_yield< R > & r)
303 #ifdef BOOST_HAS_ABI_HEADERS
304 # include BOOST_ABI_SUFFIX
307 #endif // BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_YIELD_H