Back to home page

EIC code displayed by LXR

 
 

    


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

0001 
0002 //          Copyright Oliver Kowalke 2009.
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_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_YIELD_H
0008 #define BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_YIELD_H
0009 
0010 #include <algorithm>
0011 
0012 #include <boost/assert.hpp>
0013 #include <boost/config.hpp>
0014 #include <boost/move/move.hpp>
0015 #include <boost/throw_exception.hpp>
0016 #include <boost/type_traits/is_same.hpp>
0017 #include <boost/utility/enable_if.hpp>
0018 #include <boost/utility/explicit_operator_bool.hpp>
0019 
0020 #include <boost/coroutine/detail/config.hpp>
0021 #include <boost/coroutine/exceptions.hpp>
0022 
0023 #ifdef BOOST_HAS_ABI_HEADERS
0024 #  include BOOST_ABI_PREFIX
0025 #endif
0026 
0027 namespace boost {
0028 namespace coroutines {
0029 namespace detail {
0030 
0031 template< typename R >
0032 class symmetric_coroutine_yield
0033 {
0034 private:
0035     template< typename X, typename Y, typename Z >
0036     friend class symmetric_coroutine_object;
0037 
0038     typedef symmetric_coroutine_impl< R >       impl_type;
0039 
0040     struct dummy {};
0041 
0042     BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_yield)
0043 
0044     impl_type   *   impl_;
0045     R           *   result_;
0046 
0047     symmetric_coroutine_yield( impl_type * impl, R * result) BOOST_NOEXCEPT :
0048         impl_( impl),
0049         result_( result)
0050     {
0051         BOOST_ASSERT( 0 != impl_);
0052         BOOST_ASSERT( 0 != result_);
0053     }
0054 
0055 public:
0056     symmetric_coroutine_yield() BOOST_NOEXCEPT :
0057         impl_( 0),
0058         result_( 0)
0059     {}
0060 
0061     symmetric_coroutine_yield( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT :
0062         impl_( 0),
0063         result_( 0)
0064     { swap( other); }
0065 
0066     symmetric_coroutine_yield & operator=( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT
0067     {
0068         symmetric_coroutine_yield tmp( boost::move( other) );
0069         swap( tmp);
0070         return * this;
0071     }
0072 
0073     BOOST_EXPLICIT_OPERATOR_BOOL();
0074 
0075     bool operator!() const BOOST_NOEXCEPT
0076     { return 0 == impl_; }
0077 
0078     void swap( symmetric_coroutine_yield & other) BOOST_NOEXCEPT
0079     {
0080         std::swap( impl_, other.impl_);
0081         std::swap( result_, other.result_);
0082     }
0083 
0084     symmetric_coroutine_yield & operator()()
0085     {
0086         result_ = impl_->yield();
0087         return * this;
0088     }
0089 
0090     template< typename Coro >
0091     symmetric_coroutine_yield & operator()( Coro & other, typename Coro::value_type x,
0092                                             typename disable_if<
0093                                                 is_same< typename Coro::value_type, void >,
0094                                                 dummy*
0095                                             >::type = 0)
0096     {
0097         BOOST_ASSERT( other);
0098 
0099         result_ = impl_->yield_to( other.impl_, x);
0100         return * this;
0101     }
0102 
0103     template< typename Coro >
0104     symmetric_coroutine_yield & operator()( Coro & other,
0105                                             typename enable_if<
0106                                                 is_same< typename Coro::value_type, void >,
0107                                                 dummy*
0108                                             >::type = 0)
0109     {
0110         BOOST_ASSERT( other);
0111 
0112         result_ = impl_->yield_to( other.impl_);
0113         return * this;
0114     }
0115 
0116     R get() const
0117     {
0118         if ( 0 == result_)
0119             boost::throw_exception(
0120                 invalid_result() );
0121 
0122         return * result_; 
0123     }
0124 };
0125 
0126 template< typename R >
0127 class symmetric_coroutine_yield< R & >
0128 {
0129 private:
0130     template< typename X, typename Y, typename Z >
0131     friend class symmetric_coroutine_object;
0132 
0133     typedef symmetric_coroutine_impl< R & >     impl_type;
0134 
0135     struct dummy {};
0136 
0137     BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_yield)
0138 
0139     impl_type   *   impl_;
0140     R           *   result_;
0141 
0142     symmetric_coroutine_yield( impl_type * impl, R * result) BOOST_NOEXCEPT :
0143         impl_( impl),
0144         result_( result)
0145     {
0146         BOOST_ASSERT( 0 != impl_);
0147         BOOST_ASSERT( 0 != result_);
0148     }
0149 
0150 public:
0151     symmetric_coroutine_yield() BOOST_NOEXCEPT :
0152         impl_( 0),
0153         result_( 0)
0154     {}
0155 
0156     symmetric_coroutine_yield( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT :
0157         impl_( 0),
0158         result_( 0)
0159     { swap( other); }
0160 
0161     symmetric_coroutine_yield & operator=( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT
0162     {
0163         symmetric_coroutine_yield tmp( boost::move( other) );
0164         swap( tmp);
0165         return * this;
0166     }
0167 
0168     BOOST_EXPLICIT_OPERATOR_BOOL();
0169 
0170     bool operator!() const BOOST_NOEXCEPT
0171     { return 0 == impl_; }
0172 
0173     void swap( symmetric_coroutine_yield & other) BOOST_NOEXCEPT
0174     {
0175         std::swap( impl_, other.impl_);
0176         std::swap( result_, other.result_);
0177     }
0178 
0179     symmetric_coroutine_yield & operator()()
0180     {
0181         result_ = impl_->yield();
0182         return * this;
0183     }
0184 
0185     template< typename Coro >
0186     symmetric_coroutine_yield & operator()( Coro & other, typename Coro::value_type & x,
0187                                             typename disable_if<
0188                                                 is_same< typename Coro::value_type, void >,
0189                                                 dummy*
0190                                             >::type = 0)
0191     {
0192         BOOST_ASSERT( other);
0193 
0194         result_ = impl_->yield_to( other.impl_, x);
0195         return * this;
0196     }
0197 
0198     template< typename Coro >
0199     symmetric_coroutine_yield & operator()( Coro & other,
0200                                             typename enable_if<
0201                                                 is_same< typename Coro::value_type, void >,
0202                                                 dummy*
0203                                             >::type = 0)
0204     {
0205         BOOST_ASSERT( other);
0206 
0207         result_ = impl_->yield_to( other.impl_);
0208         return * this;
0209     }
0210 
0211     R & get() const
0212     {
0213         if ( 0 == result_)
0214             boost::throw_exception(
0215                 invalid_result() );
0216 
0217         return * result_; 
0218     }
0219 };
0220 
0221 template<>
0222 class symmetric_coroutine_yield< void >
0223 {
0224 private:
0225     template< typename X, typename Y, typename Z >
0226     friend class symmetric_coroutine_object;
0227 
0228     typedef symmetric_coroutine_impl< void >    impl_type;
0229 
0230     struct dummy {};
0231 
0232     BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_yield)
0233 
0234     impl_type   *   impl_;
0235 
0236     symmetric_coroutine_yield( impl_type * impl) BOOST_NOEXCEPT :
0237         impl_( impl)
0238     { BOOST_ASSERT( 0 != impl_); }
0239 
0240 public:
0241     symmetric_coroutine_yield() BOOST_NOEXCEPT :
0242         impl_( 0)
0243     {}
0244 
0245     symmetric_coroutine_yield( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT :
0246         impl_( 0)
0247     { swap( other); }
0248 
0249     symmetric_coroutine_yield & operator=( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT
0250     {
0251         symmetric_coroutine_yield tmp( boost::move( other) );
0252         swap( tmp);
0253         return * this;
0254     }
0255 
0256     BOOST_EXPLICIT_OPERATOR_BOOL();
0257 
0258     inline bool operator!() const BOOST_NOEXCEPT
0259     { return 0 == impl_; }
0260 
0261     inline void swap( symmetric_coroutine_yield & other) BOOST_NOEXCEPT
0262     { std::swap( impl_, other.impl_); }
0263 
0264     inline symmetric_coroutine_yield & operator()()
0265     {
0266         impl_->yield();
0267         return * this;
0268     }
0269 
0270     template< typename Coro >
0271     symmetric_coroutine_yield & operator()( Coro & other, typename Coro::value_type & x,
0272                                             typename disable_if<
0273                                                 is_same< typename Coro::value_type, void >,
0274                                                 dummy*
0275                                             >::type = 0)
0276     {
0277         BOOST_ASSERT( other);
0278 
0279         impl_->yield_to( other.impl_, x);
0280         return * this;
0281     }
0282 
0283     template< typename Coro >
0284     symmetric_coroutine_yield & operator()( Coro & other,
0285                                             typename enable_if<
0286                                                 is_same< typename Coro::value_type, void >,
0287                                                 dummy*
0288                                             >::type = 0)
0289     {
0290         BOOST_ASSERT( other);
0291 
0292         impl_->yield_to( other.impl_);
0293         return * this;
0294     }
0295 };
0296 
0297 template< typename R >
0298 void swap( symmetric_coroutine_yield< R > & l, symmetric_coroutine_yield< R > & r)
0299 { l.swap( r); }
0300 
0301 }}}
0302 
0303 #ifdef BOOST_HAS_ABI_HEADERS
0304 #  include BOOST_ABI_SUFFIX
0305 #endif
0306 
0307 #endif // BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_YIELD_H