BVB Source Codes

mars Show asymmetric_coroutine.hpp Source code

Return Download mars: download asymmetric_coroutine.hpp Source code - Download mars Source code - Type:.hpp
  1.  
  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)
  6.  
  7. #ifndef BOOST_COROUTINES_ASYMMETRIC_COROUTINE_H
  8. #define BOOST_COROUTINES_ASYMMETRIC_COROUTINE_H
  9.  
  10. #include <cstddef>
  11. #include <iterator>
  12. #include <memory>
  13.  
  14. #include <boost/assert.hpp>
  15. #include <boost/config.hpp>
  16. #include <boost/move/move.hpp>
  17. #include <boost/range.hpp>
  18. #include <boost/throw_exception.hpp>
  19. #include <boost/utility/explicit_operator_bool.hpp>
  20.  
  21. #include <boost/coroutine/attributes.hpp>
  22. #include <boost/coroutine/detail/config.hpp>
  23. #include <boost/coroutine/detail/coroutine_context.hpp>
  24. #include <boost/coroutine/detail/parameters.hpp>
  25. #include <boost/coroutine/exceptions.hpp>
  26. #include <boost/coroutine/stack_allocator.hpp>
  27. #include <boost/coroutine/detail/pull_coroutine_impl.hpp>
  28. #include <boost/coroutine/detail/pull_coroutine_object.hpp>
  29. #include <boost/coroutine/detail/pull_coroutine_synthesized.hpp>
  30. #include <boost/coroutine/detail/push_coroutine_impl.hpp>
  31. #include <boost/coroutine/detail/push_coroutine_object.hpp>
  32. #include <boost/coroutine/detail/push_coroutine_synthesized.hpp>
  33. #include <boost/coroutine/stack_context.hpp>
  34.  
  35. #ifdef BOOST_HAS_ABI_HEADERS
  36. #  include BOOST_ABI_PREFIX
  37. #endif
  38.  
  39. namespace mars_boost {} namespace boost = mars_boost; namespace mars_boost {
  40. namespace coroutines {
  41.  
  42. template< typename R >
  43. class pull_coroutine;
  44.  
  45. template< typename Arg >
  46. class push_coroutine
  47. {
  48. private:
  49.     template< typename V, typename X, typename Y, typename Z >
  50.     friend class detail::pull_coroutine_object;
  51.  
  52.     typedef detail::push_coroutine_impl< Arg >          impl_type;
  53.     typedef detail::push_coroutine_synthesized< Arg >   synth_type;
  54.     typedef detail::parameters< Arg >                   param_type;
  55.  
  56.     struct dummy {};
  57.  
  58.     impl_type       *   impl_;
  59.  
  60.     BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine)
  61.  
  62.     explicit push_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
  63.         impl_( & impl)
  64.     { BOOST_ASSERT( impl_); }
  65.  
  66. public:
  67.     push_coroutine() BOOST_NOEXCEPT :
  68.         impl_( 0)
  69.     {}
  70.  
  71. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  72. # ifdef BOOST_MSVC
  73.     typedef void ( * coroutine_fn)( pull_coroutine< Arg > &);
  74.  
  75.     explicit push_coroutine( coroutine_fn,
  76.                              attributes const& = attributes() );
  77.  
  78.     template< typename StackAllocator >
  79.     explicit push_coroutine( coroutine_fn,
  80.                              attributes const&,
  81.                              StackAllocator);
  82. # endif
  83.     template< typename Fn >
  84.     explicit push_coroutine( BOOST_RV_REF( Fn),
  85.                              attributes const& = attributes() );
  86.  
  87.     template< typename Fn, typename StackAllocator >
  88.     explicit push_coroutine( BOOST_RV_REF( Fn),
  89.                              attributes const&,
  90.                              StackAllocator);
  91. #else
  92.     template< typename Fn >
  93.     explicit push_coroutine( Fn fn,
  94.                              attributes const& = attributes() );
  95.  
  96.     template< typename Fn, typename StackAllocator >
  97.     explicit push_coroutine( Fn fn,
  98.                              attributes const&,
  99.                              StackAllocator);
  100.  
  101.     template< typename Fn >
  102.     explicit push_coroutine( BOOST_RV_REF( Fn),
  103.                              attributes const& = attributes() );
  104.  
  105.     template< typename Fn, typename StackAllocator >
  106.     explicit push_coroutine( BOOST_RV_REF( Fn),
  107.                              attributes const&,
  108.                              StackAllocator);
  109. #endif
  110.  
  111.     ~push_coroutine()
  112.     {
  113.         if ( 0 != impl_)
  114.         {
  115.             impl_->destroy();
  116.             impl_ = 0;
  117.         }
  118.     }
  119.  
  120.     push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT :
  121.         impl_( 0)
  122.     { swap( other); }
  123.  
  124.     push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT
  125.     {
  126.         push_coroutine tmp( mars_boost::move( other) );
  127.         swap( tmp);
  128.         return * this;
  129.     }
  130.  
  131.     BOOST_EXPLICIT_OPERATOR_BOOL();
  132.  
  133.     bool operator!() const BOOST_NOEXCEPT
  134.     { return 0 == impl_ || impl_->is_complete(); }
  135.  
  136.     void swap( push_coroutine & other) BOOST_NOEXCEPT
  137.     { std::swap( impl_, other.impl_); }
  138.  
  139.     push_coroutine & operator()( Arg arg)
  140.     {
  141.         BOOST_ASSERT( * this);
  142.  
  143.         impl_->push( arg);
  144.         return * this;
  145.     }
  146.  
  147.     class iterator : public std::iterator< std::output_iterator_tag, void, void, void, void >
  148.     {
  149.     private:
  150.        push_coroutine< Arg >    *   c_;
  151.  
  152.     public:
  153.         iterator() :
  154.            c_( 0)
  155.         {}
  156.  
  157.         explicit iterator( push_coroutine< Arg > * c) :
  158.             c_( c)
  159.         {}
  160.  
  161.         iterator & operator=( Arg a)
  162.         {
  163.             BOOST_ASSERT( c_);
  164.             if ( ! ( * c_)( a) ) c_ = 0;
  165.             return * this;
  166.         }
  167.  
  168.         bool operator==( iterator const& other) const
  169.         { return other.c_ == c_; }
  170.  
  171.         bool operator!=( iterator const& other) const
  172.         { return other.c_ != c_; }
  173.  
  174.         iterator & operator*()
  175.         { return * this; }
  176.  
  177.         iterator & operator++()
  178.         { return * this; }
  179.     };
  180.  
  181.     struct const_iterator;
  182. };
  183.  
  184. template< typename Arg >
  185. class push_coroutine< Arg & >
  186. {
  187. private:
  188.     template< typename V, typename X, typename Y, typename Z >
  189.     friend class detail::pull_coroutine_object;
  190.  
  191.     typedef detail::push_coroutine_impl< Arg & >          impl_type;
  192.     typedef detail::push_coroutine_synthesized< Arg & >   synth_type;
  193.     typedef detail::parameters< Arg & >                   param_type;
  194.  
  195.     struct dummy {};
  196.  
  197.     impl_type       *   impl_;
  198.  
  199.     BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine)
  200.  
  201.     explicit push_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
  202.         impl_( & impl)
  203.     { BOOST_ASSERT( impl_); }
  204.  
  205. public:
  206.     push_coroutine() BOOST_NOEXCEPT :
  207.         impl_( 0)
  208.     {}
  209.  
  210. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  211. # ifdef BOOST_MSVC
  212.     typedef void ( * coroutine_fn)( pull_coroutine< Arg & > &);
  213.  
  214.     explicit push_coroutine( coroutine_fn,
  215.                              attributes const& = attributes() );
  216.  
  217.     template< typename StackAllocator >
  218.     explicit push_coroutine( coroutine_fn,
  219.                              attributes const&,
  220.                              StackAllocator);
  221. # endif
  222.     template< typename Fn >
  223.     explicit push_coroutine( BOOST_RV_REF( Fn),
  224.                              attributes const& = attributes() );
  225.  
  226.     template< typename Fn, typename StackAllocator >
  227.     explicit push_coroutine( BOOST_RV_REF( Fn),
  228.                              attributes const&,
  229.                              StackAllocator);
  230. #else
  231.     template< typename Fn >
  232.     explicit push_coroutine( Fn,
  233.                              attributes const& = attributes() );
  234.  
  235.     template< typename Fn, typename StackAllocator >
  236.     explicit push_coroutine( Fn,
  237.                              attributes const&,
  238.                              StackAllocator);
  239.  
  240.     template< typename Fn >
  241.     explicit push_coroutine( BOOST_RV_REF( Fn),
  242.                              attributes const& = attributes() );
  243.  
  244.     template< typename Fn, typename StackAllocator >
  245.     explicit push_coroutine( BOOST_RV_REF( Fn),
  246.                              attributes const&,
  247.                              StackAllocator);
  248. #endif
  249.  
  250.     ~push_coroutine()
  251.     {
  252.         if ( 0 != impl_)
  253.         {
  254.             impl_->destroy();
  255.             impl_ = 0;
  256.         }
  257.     }
  258.  
  259.     push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT :
  260.         impl_( 0)
  261.     { swap( other); }
  262.  
  263.     push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT
  264.     {
  265.         push_coroutine tmp( mars_boost::move( other) );
  266.         swap( tmp);
  267.         return * this;
  268.     }
  269.  
  270.     BOOST_EXPLICIT_OPERATOR_BOOL();
  271.  
  272.     bool operator!() const BOOST_NOEXCEPT
  273.     { return 0 == impl_ || impl_->is_complete(); }
  274.  
  275.     void swap( push_coroutine & other) BOOST_NOEXCEPT
  276.     { std::swap( impl_, other.impl_); }
  277.  
  278.     push_coroutine & operator()( Arg & arg)
  279.     {
  280.         BOOST_ASSERT( * this);
  281.  
  282.         impl_->push( arg);
  283.         return * this;
  284.     }
  285.  
  286.     class iterator : public std::iterator< std::output_iterator_tag, void, void, void, void >
  287.     {
  288.     private:
  289.        push_coroutine< Arg & >  *   c_;
  290.  
  291.     public:
  292.         iterator() :
  293.            c_( 0)
  294.         {}
  295.  
  296.         explicit iterator( push_coroutine< Arg & > * c) :
  297.             c_( c)
  298.         {}
  299.  
  300.         iterator & operator=( Arg & a)
  301.         {
  302.             BOOST_ASSERT( c_);
  303.             if ( ! ( * c_)( a) ) c_ = 0;
  304.             return * this;
  305.         }
  306.  
  307.         bool operator==( iterator const& other) const
  308.         { return other.c_ == c_; }
  309.  
  310.         bool operator!=( iterator const& other) const
  311.         { return other.c_ != c_; }
  312.  
  313.         iterator & operator*()
  314.         { return * this; }
  315.  
  316.         iterator & operator++()
  317.         { return * this; }
  318.     };
  319.  
  320.     struct const_iterator;
  321. };
  322.  
  323. template<>
  324. class push_coroutine< void >
  325. {
  326. private:
  327.     template< typename V, typename X, typename Y, typename Z >
  328.     friend class detail::pull_coroutine_object;
  329.  
  330.     typedef detail::push_coroutine_impl< void >          impl_type;
  331.     typedef detail::push_coroutine_synthesized< void >   synth_type;
  332.     typedef detail::parameters< void >                   param_type;
  333.  
  334.     struct dummy {};
  335.  
  336.     impl_type       *   impl_;
  337.  
  338.     BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine)
  339.  
  340.     explicit push_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
  341.         impl_( & impl)
  342.     { BOOST_ASSERT( impl_); }
  343.  
  344. public:
  345.     push_coroutine() BOOST_NOEXCEPT :
  346.         impl_( 0)
  347.     {}
  348.  
  349. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  350. # ifdef BOOST_MSVC
  351.     typedef void ( * coroutine_fn)( pull_coroutine< void > &);
  352.  
  353.     explicit push_coroutine( coroutine_fn,
  354.                              attributes const& = attributes() );
  355.  
  356.     template< typename StackAllocator >
  357.     explicit push_coroutine( coroutine_fn,
  358.                              attributes const&,
  359.                              StackAllocator);
  360. # endif
  361.     template< typename Fn >
  362.     explicit push_coroutine( BOOST_RV_REF( Fn),
  363.                              attributes const& = attributes() );
  364.  
  365.     template< typename Fn, typename StackAllocator >
  366.     explicit push_coroutine( BOOST_RV_REF( Fn),
  367.                              attributes const&,
  368.                              StackAllocator);
  369. #else
  370.     template< typename Fn >
  371.     explicit push_coroutine( Fn,
  372.                              attributes const& = attributes() );
  373.  
  374.     template< typename Fn, typename StackAllocator >
  375.     explicit push_coroutine( Fn,
  376.                              attributes const&,
  377.                              StackAllocator);
  378.  
  379.     template< typename Fn >
  380.     explicit push_coroutine( BOOST_RV_REF( Fn),
  381.                              attributes const& = attributes() );
  382.  
  383.     template< typename Fn, typename StackAllocator >
  384.     explicit push_coroutine( BOOST_RV_REF( Fn),
  385.                              attributes const&,
  386.                              StackAllocator);
  387. #endif
  388.  
  389.     ~push_coroutine()
  390.     {
  391.         if ( 0 != impl_)
  392.         {
  393.             impl_->destroy();
  394.             impl_ = 0;
  395.         }
  396.     }
  397.  
  398.     inline push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT :
  399.         impl_( 0)
  400.     { swap( other); }
  401.  
  402.     inline push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT
  403.     {
  404.         push_coroutine tmp( mars_boost::move( other) );
  405.         swap( tmp);
  406.         return * this;
  407.     }
  408.  
  409.     BOOST_EXPLICIT_OPERATOR_BOOL();
  410.  
  411.     inline bool operator!() const BOOST_NOEXCEPT
  412.     { return 0 == impl_ || impl_->is_complete(); }
  413.  
  414.     inline void swap( push_coroutine & other) BOOST_NOEXCEPT
  415.     { std::swap( impl_, other.impl_); }
  416.  
  417.     inline push_coroutine & operator()()
  418.     {
  419.         BOOST_ASSERT( * this);
  420.  
  421.         impl_->push();
  422.         return * this;
  423.     }
  424.  
  425.     struct iterator;
  426.     struct const_iterator;
  427. };
  428.  
  429.  
  430.  
  431. template< typename R >
  432. class pull_coroutine
  433. {
  434. private:
  435.     template< typename V, typename X, typename Y, typename Z >
  436.     friend class detail::push_coroutine_object;
  437.  
  438.     typedef detail::pull_coroutine_impl< R >            impl_type;
  439.     typedef detail::pull_coroutine_synthesized< R >     synth_type;
  440.     typedef detail::parameters< R >                     param_type;
  441.  
  442.     struct dummy {};
  443.  
  444.     impl_type       *   impl_;
  445.  
  446.     BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine)
  447.  
  448.     explicit pull_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
  449.         impl_( & impl)
  450.     { BOOST_ASSERT( impl_); }
  451.  
  452. public:
  453.     pull_coroutine() BOOST_NOEXCEPT :
  454.         impl_( 0)
  455.     {}
  456.  
  457. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  458. # ifdef BOOST_MSVC
  459.     typedef void ( * coroutine_fn)( push_coroutine< R > &);
  460.  
  461.     explicit pull_coroutine( coroutine_fn fn,
  462.                              attributes const& attrs = attributes() ) :
  463.         impl_( 0)
  464.     {
  465.         // create a stack-context
  466.         stack_context stack_ctx;
  467.         stack_allocator stack_alloc;
  468.         // allocate the coroutine-stack
  469.         stack_alloc.allocate( stack_ctx, attrs.size);
  470.         BOOST_ASSERT( 0 != stack_ctx.sp);
  471.         // typedef of internal coroutine-type
  472.         typedef detail::pull_coroutine_object<
  473.             push_coroutine< R >, R, coroutine_fn, stack_allocator
  474.         >                                                        object_t;
  475.         // reserve space on top of coroutine-stack for internal coroutine-type
  476.         std::size_t size = stack_ctx.size - sizeof( object_t);
  477.         BOOST_ASSERT( 0 != size);
  478.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  479.         BOOST_ASSERT( 0 != sp);
  480.         // placement new for internal coroutine
  481.         impl_ = new ( sp) object_t(
  482.                 mars_boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  483.         BOOST_ASSERT( impl_);
  484.         impl_->pull();
  485.     }
  486.  
  487.     template< typename StackAllocator >
  488.     explicit pull_coroutine( coroutine_fn fn,
  489.                              attributes const& attrs,
  490.                              StackAllocator stack_alloc) :
  491.         impl_( 0)
  492.     {
  493.         // create a stack-context
  494.         stack_context stack_ctx;
  495.         // allocate the coroutine-stack
  496.         stack_alloc.allocate( stack_ctx, attrs.size);
  497.         BOOST_ASSERT( 0 != stack_ctx.sp);
  498.         // typedef of internal coroutine-type
  499.         typedef detail::pull_coroutine_object<
  500.             push_coroutine< R >, R, coroutine_fn, StackAllocator
  501.         >                                                        object_t;
  502.         // reserve space on top of coroutine-stack for internal coroutine-type
  503.         std::size_t size = stack_ctx.size - sizeof( object_t);
  504.         BOOST_ASSERT( 0 != size);
  505.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  506.         BOOST_ASSERT( 0 != sp);
  507.         // placement new for internal coroutine
  508.         impl_ = new ( sp) object_t(
  509.                 mars_boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  510.         BOOST_ASSERT( impl_);
  511.         impl_->pull();
  512.     }
  513. # endif
  514.     template< typename Fn >
  515.     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
  516.                              attributes const& attrs = attributes() ) :
  517.         impl_( 0)
  518.     {
  519.         // create a stack-context
  520.         stack_context stack_ctx;
  521.         stack_allocator stack_alloc;
  522.         // allocate the coroutine-stack
  523.         stack_alloc.allocate( stack_ctx, attrs.size);
  524.         BOOST_ASSERT( 0 != stack_ctx.sp);
  525.         // typedef of internal coroutine-type
  526.         typedef detail::pull_coroutine_object<
  527.             push_coroutine< R >, R, Fn, stack_allocator
  528.         >                                                        object_t;
  529.         // reserve space on top of coroutine-stack for internal coroutine-type
  530.         std::size_t size = stack_ctx.size - sizeof( object_t);
  531.         BOOST_ASSERT( 0 != size);
  532.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  533.         BOOST_ASSERT( 0 != sp);
  534.         // placement new for internal coroutine
  535.         impl_ = new ( sp) object_t(
  536.                 mars_boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  537.         BOOST_ASSERT( impl_);
  538.         impl_->pull();
  539.     }
  540.  
  541.     template< typename Fn, typename StackAllocator >
  542.     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
  543.                              attributes const& attrs,
  544.                              StackAllocator stack_alloc) :
  545.         impl_( 0)
  546.     {
  547.         // create a stack-context
  548.         stack_context stack_ctx;
  549.         // allocate the coroutine-stack
  550.         stack_alloc.allocate( stack_ctx, attrs.size);
  551.         BOOST_ASSERT( 0 != stack_ctx.sp);
  552.         // typedef of internal coroutine-type
  553.         typedef detail::pull_coroutine_object<
  554.             push_coroutine< R >, R, Fn, StackAllocator
  555.         >                                                        object_t;
  556.         // reserve space on top of coroutine-stack for internal coroutine-type
  557.         std::size_t size = stack_ctx.size - sizeof( object_t);
  558.         BOOST_ASSERT( 0 != size);
  559.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  560.         BOOST_ASSERT( 0 != sp);
  561.         // placement new for internal coroutine
  562.         impl_ = new ( sp) object_t(
  563.                 mars_boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  564.         BOOST_ASSERT( impl_);
  565.         impl_->pull();
  566.     }
  567. #else
  568.     template< typename Fn >
  569.     explicit pull_coroutine( Fn fn,
  570.                              attributes const& attrs = attributes() ) :
  571.         impl_( 0)
  572.     {
  573.         // create a stack-context
  574.         stack_context stack_ctx;
  575.         stack_allocator stack_alloc;
  576.         // allocate the coroutine-stack
  577.         stack_alloc.allocate( stack_ctx, attrs.size);
  578.         BOOST_ASSERT( 0 != stack_ctx.sp);
  579.         // typedef of internal coroutine-type
  580.         typedef detail::pull_coroutine_object<
  581.             push_coroutine< R >, R, Fn, stack_allocator
  582.         >                                                        object_t;
  583.         // reserve space on top of coroutine-stack for internal coroutine-type
  584.         std::size_t size = stack_ctx.size - sizeof( object_t);
  585.         BOOST_ASSERT( 0 != size);
  586.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  587.         BOOST_ASSERT( 0 != sp);
  588.         // placement new for internal coroutine
  589.         impl_ = new ( sp) object_t(
  590.                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  591.         BOOST_ASSERT( impl_);
  592.         impl_->pull();
  593.     }
  594.  
  595.     template< typename Fn, typename StackAllocator >
  596.     explicit pull_coroutine( Fn fn,
  597.                              attributes const& attrs,
  598.                              StackAllocator stack_alloc) :
  599.         impl_( 0)
  600.     {
  601.         // create a stack-context
  602.         stack_context stack_ctx;
  603.         // allocate the coroutine-stack
  604.         stack_alloc.allocate( stack_ctx, attrs.size);
  605.         BOOST_ASSERT( 0 != stack_ctx.sp);
  606.         // typedef of internal coroutine-type
  607.         typedef detail::pull_coroutine_object<
  608.             push_coroutine< R >, R, Fn, StackAllocator
  609.         >                                                        object_t;
  610.         // reserve space on top of coroutine-stack for internal coroutine-type
  611.         std::size_t size = stack_ctx.size - sizeof( object_t);
  612.         BOOST_ASSERT( 0 != size);
  613.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  614.         BOOST_ASSERT( 0 != sp);
  615.         // placement new for internal coroutine
  616.         impl_ = new ( sp) object_t(
  617.                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  618.         BOOST_ASSERT( impl_);
  619.         impl_->pull();
  620.     }
  621.  
  622.     template< typename Fn >
  623.     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
  624.                              attributes const& attrs = attributes() ) :
  625.         impl_( 0)
  626.     {
  627.         // create a stack-context
  628.         stack_context stack_ctx;
  629.         stack_allocator stack_alloc;
  630.         // allocate the coroutine-stack
  631.         stack_alloc.allocate( stack_ctx, attrs.size);
  632.         BOOST_ASSERT( 0 != stack_ctx.sp);
  633.         // typedef of internal coroutine-type
  634.         typedef detail::pull_coroutine_object<
  635.             push_coroutine< R >, R, Fn, stack_allocator
  636.         >                                                        object_t;
  637.         // reserve space on top of coroutine-stack for internal coroutine-type
  638.         std::size_t size = stack_ctx.size - sizeof( object_t);
  639.         BOOST_ASSERT( 0 != size);
  640.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  641.         BOOST_ASSERT( 0 != sp);
  642.         // placement new for internal coroutine
  643.         impl_ = new ( sp) object_t(
  644.                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  645.         BOOST_ASSERT( impl_);
  646.         impl_->pull();
  647.     }
  648.  
  649.     template< typename Fn, typename StackAllocator >
  650.     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
  651.                              attributes const& attrs,
  652.                              StackAllocator stack_alloc) :
  653.         impl_( 0)
  654.     {
  655.         // create a stack-context
  656.         stack_context stack_ctx;
  657.         // allocate the coroutine-stack
  658.         stack_alloc.allocate( stack_ctx, attrs.size);
  659.         BOOST_ASSERT( 0 != stack_ctx.sp);
  660.         // typedef of internal coroutine-type
  661.         typedef detail::pull_coroutine_object<
  662.             push_coroutine< R >, R, Fn, StackAllocator
  663.         >                                                        object_t;
  664.         // reserve space on top of coroutine-stack for internal coroutine-type
  665.         std::size_t size = stack_ctx.size - sizeof( object_t);
  666.         BOOST_ASSERT( 0 != size);
  667.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  668.         BOOST_ASSERT( 0 != sp);
  669.         // placement new for internal coroutine
  670.         impl_ = new ( sp) object_t(
  671.                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  672.         BOOST_ASSERT( impl_);
  673.         impl_->pull();
  674.     }
  675. #endif
  676.  
  677.     ~pull_coroutine()
  678.     {
  679.         if ( 0 != impl_)
  680.         {
  681.             impl_->destroy();
  682.             impl_ = 0;
  683.         }
  684.     }
  685.  
  686.     pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT :
  687.         impl_( 0)
  688.     { swap( other); }
  689.  
  690.     pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT
  691.     {
  692.         pull_coroutine tmp( mars_boost::move( other) );
  693.         swap( tmp);
  694.         return * this;
  695.     }
  696.  
  697.     BOOST_EXPLICIT_OPERATOR_BOOL();
  698.  
  699.     bool operator!() const BOOST_NOEXCEPT
  700.     { return 0 == impl_ || impl_->is_complete(); }
  701.  
  702.     void swap( pull_coroutine & other) BOOST_NOEXCEPT
  703.     { std::swap( impl_, other.impl_); }
  704.  
  705.     pull_coroutine & operator()()
  706.     {
  707.         BOOST_ASSERT( * this);
  708.  
  709.         impl_->pull();
  710.         return * this;
  711.     }
  712.  
  713.     R get() const
  714.     {
  715.         BOOST_ASSERT( 0 != impl_);
  716.  
  717.         return impl_->get();
  718.     }
  719.  
  720.     class iterator : public std::iterator< std::input_iterator_tag, typename remove_reference< R >::type >
  721.     {
  722.     private:
  723.         pull_coroutine< R > *   c_;
  724.         R                   *   val_;
  725.  
  726.         void fetch_()
  727.         {
  728.             BOOST_ASSERT( c_);
  729.  
  730.             if ( ! ( * c_) )
  731.             {
  732.                 c_ = 0;
  733.                 val_ = 0;
  734.                 return;
  735.             }
  736.             val_ = c_->impl_->get_pointer();
  737.         }
  738.  
  739.         void increment_()
  740.         {
  741.             BOOST_ASSERT( c_);
  742.             BOOST_ASSERT( * c_);
  743.  
  744.             ( * c_)();
  745.             fetch_();
  746.         }
  747.  
  748.     public:
  749.         typedef typename iterator::pointer      pointer_t;
  750.         typedef typename iterator::reference    reference_t;
  751.  
  752.         iterator() :
  753.             c_( 0), val_( 0)
  754.         {}
  755.  
  756.         explicit iterator( pull_coroutine< R > * c) :
  757.             c_( c), val_( 0)
  758.         { fetch_(); }
  759.  
  760.         iterator( iterator const& other) :
  761.             c_( other.c_), val_( other.val_)
  762.         {}
  763.  
  764.         iterator & operator=( iterator const& other)
  765.         {
  766.             if ( this == & other) return * this;
  767.             c_ = other.c_;
  768.             val_ = other.val_;
  769.             return * this;
  770.         }
  771.  
  772.         bool operator==( iterator const& other) const
  773.         { return other.c_ == c_ && other.val_ == val_; }
  774.  
  775.         bool operator!=( iterator const& other) const
  776.         { return other.c_ != c_ || other.val_ != val_; }
  777.  
  778.         iterator & operator++()
  779.         {
  780.             increment_();
  781.             return * this;
  782.         }
  783.  
  784.         iterator operator++( int);
  785.  
  786.         reference_t operator*() const
  787.         {
  788.             if ( ! val_)
  789.                 mars_boost::throw_exception(
  790.                     invalid_result() );
  791.             return * val_;
  792.         }
  793.  
  794.         pointer_t operator->() const
  795.         {
  796.             if ( ! val_)
  797.                 mars_boost::throw_exception(
  798.                     invalid_result() );
  799.             return val_;
  800.         }
  801.     };
  802.  
  803.     class const_iterator : public std::iterator< std::input_iterator_tag, const typename remove_reference< R >::type >
  804.     {
  805.     private:
  806.         pull_coroutine< R > *   c_;
  807.         R                   *   val_;
  808.  
  809.         void fetch_()
  810.         {
  811.             BOOST_ASSERT( c_);
  812.  
  813.             if ( ! ( * c_) )
  814.             {
  815.                 c_ = 0;
  816.                 val_ = 0;
  817.                 return;
  818.             }
  819.             val_ = c_->impl_->get_pointer();
  820.         }
  821.  
  822.         void increment_()
  823.         {
  824.             BOOST_ASSERT( c_);
  825.             BOOST_ASSERT( * c_);
  826.  
  827.             ( * c_)();
  828.             fetch_();
  829.         }
  830.  
  831.     public:
  832.         typedef typename const_iterator::pointer      pointer_t;
  833.         typedef typename const_iterator::reference    reference_t;
  834.  
  835.         const_iterator() :
  836.             c_( 0), val_( 0)
  837.         {}
  838.  
  839.         explicit const_iterator( pull_coroutine< R > const* c) :
  840.             c_( const_cast< pull_coroutine< R > * >( c) ),
  841.             val_( 0)
  842.         { fetch_(); }
  843.  
  844.         const_iterator( const_iterator const& other) :
  845.             c_( other.c_), val_( other.val_)
  846.         {}
  847.  
  848.         const_iterator & operator=( const_iterator const& other)
  849.         {
  850.             if ( this == & other) return * this;
  851.             c_ = other.c_;
  852.             val_ = other.val_;
  853.             return * this;
  854.         }
  855.  
  856.         bool operator==( const_iterator const& other) const
  857.         { return other.c_ == c_ && other.val_ == val_; }
  858.  
  859.         bool operator!=( const_iterator const& other) const
  860.         { return other.c_ != c_ || other.val_ != val_; }
  861.  
  862.         const_iterator & operator++()
  863.         {
  864.             increment_();
  865.             return * this;
  866.         }
  867.  
  868.         const_iterator operator++( int);
  869.  
  870.         reference_t operator*() const
  871.         {
  872.             if ( ! val_)
  873.                 mars_boost::throw_exception(
  874.                     invalid_result() );
  875.             return * val_;
  876.         }
  877.  
  878.         pointer_t operator->() const
  879.         {
  880.             if ( ! val_)
  881.                 mars_boost::throw_exception(
  882.                     invalid_result() );
  883.             return val_;
  884.         }
  885.     };
  886.  
  887.     friend class iterator;
  888.     friend class const_iterator;
  889. };
  890.  
  891. template< typename R >
  892. class pull_coroutine< R & >
  893. {
  894. private:
  895.     template< typename V, typename X, typename Y, typename Z >
  896.     friend class detail::push_coroutine_object;
  897.  
  898.     typedef detail::pull_coroutine_impl< R & >            impl_type;
  899.     typedef detail::pull_coroutine_synthesized< R & >     synth_type;
  900.     typedef detail::parameters< R & >                     param_type;
  901.  
  902.     struct dummy {};
  903.  
  904.     impl_type       *   impl_;
  905.  
  906.     BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine)
  907.  
  908.     explicit pull_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
  909.         impl_( & impl)
  910.     { BOOST_ASSERT( impl_); }
  911.  
  912. public:
  913.     pull_coroutine() BOOST_NOEXCEPT :
  914.         impl_( 0)
  915.     {}
  916.  
  917. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  918. # ifdef BOOST_MSVC
  919.     typedef void ( * coroutine_fn)( push_coroutine< R & > &);
  920.  
  921.     explicit pull_coroutine( coroutine_fn fn,
  922.                              attributes const& attrs = attributes() ) :
  923.         impl_( 0)
  924.     {
  925.         // create a stack-context
  926.         stack_context stack_ctx;
  927.         stack_allocator stack_alloc;
  928.         // allocate the coroutine-stack
  929.         stack_alloc.allocate( stack_ctx, attrs.size);
  930.         BOOST_ASSERT( 0 != stack_ctx.sp);
  931.         // typedef of internal coroutine-type
  932.         typedef detail::pull_coroutine_object<
  933.             push_coroutine< R & >, R &, coroutine_fn, stack_allocator
  934.         >                                                        object_t;
  935.         // reserve space on top of coroutine-stack for internal coroutine-type
  936.         std::size_t size = stack_ctx.size - sizeof( object_t);
  937.         BOOST_ASSERT( 0 != size);
  938.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  939.         BOOST_ASSERT( 0 != sp);
  940.         // placement new for internal coroutine
  941.         impl_ = new ( sp) object_t(
  942.                 mars_boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  943.         BOOST_ASSERT( impl_);
  944.         impl_->pull();
  945.     }
  946.  
  947.     template< typename StackAllocator >
  948.     explicit pull_coroutine( coroutine_fn fn,
  949.                              attributes const& attrs,
  950.                              StackAllocator stack_alloc) :
  951.         impl_( 0)
  952.     {
  953.         // create a stack-context
  954.         stack_context stack_ctx;
  955.         // allocate the coroutine-stack
  956.         stack_alloc.allocate( stack_ctx, attrs.size);
  957.         BOOST_ASSERT( 0 != stack_ctx.sp);
  958.         // typedef of internal coroutine-type
  959.         typedef detail::pull_coroutine_object<
  960.             push_coroutine< R & >, R &, coroutine_fn, StackAllocator
  961.         >                                                        object_t;
  962.         // reserve space on top of coroutine-stack for internal coroutine-type
  963.         std::size_t size = stack_ctx.size - sizeof( object_t);
  964.         BOOST_ASSERT( 0 != size);
  965.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  966.         BOOST_ASSERT( 0 != sp);
  967.         // placement new for internal coroutine
  968.         impl_ = new ( sp) object_t(
  969.                 mars_boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  970.         BOOST_ASSERT( impl_);
  971.         impl_->pull();
  972.     }
  973. # endif
  974.     template< typename Fn >
  975.     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
  976.                              attributes const& attrs = attributes() ) :
  977.         impl_( 0)
  978.     {
  979.         // create a stack-context
  980.         stack_context stack_ctx;
  981.         stack_allocator stack_alloc;
  982.         // allocate the coroutine-stack
  983.         stack_alloc.allocate( stack_ctx, attrs.size);
  984.         BOOST_ASSERT( 0 != stack_ctx.sp);
  985.         // typedef of internal coroutine-type
  986.         typedef detail::pull_coroutine_object<
  987.             push_coroutine< R & >, R &, Fn, stack_allocator
  988.         >                                                        object_t;
  989.         // reserve space on top of coroutine-stack for internal coroutine-type
  990.         std::size_t size = stack_ctx.size - sizeof( object_t);
  991.         BOOST_ASSERT( 0 != size);
  992.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  993.         BOOST_ASSERT( 0 != sp);
  994.         // placement new for internal coroutine
  995.         impl_ = new ( sp) object_t(
  996.                 mars_boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  997.         BOOST_ASSERT( impl_);
  998.         impl_->pull();
  999.     }
  1000.  
  1001.     template< typename Fn, typename StackAllocator >
  1002.     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
  1003.                              attributes const& attrs,
  1004.                              StackAllocator stack_alloc) :
  1005.         impl_( 0)
  1006.     {
  1007.         // create a stack-context
  1008.         stack_context stack_ctx;
  1009.         // allocate the coroutine-stack
  1010.         stack_alloc.allocate( stack_ctx, attrs.size);
  1011.         BOOST_ASSERT( 0 != stack_ctx.sp);
  1012.         // typedef of internal coroutine-type
  1013.         typedef detail::pull_coroutine_object<
  1014.             push_coroutine< R & >, R &, Fn, StackAllocator
  1015.         >                                                        object_t;
  1016.         // reserve space on top of coroutine-stack for internal coroutine-type
  1017.         std::size_t size = stack_ctx.size - sizeof( object_t);
  1018.         BOOST_ASSERT( 0 != size);
  1019.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1020.         BOOST_ASSERT( 0 != sp);
  1021.         // placement new for internal coroutine
  1022.         impl_ = new ( sp) object_t(
  1023.                 mars_boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1024.         BOOST_ASSERT( impl_);
  1025.         impl_->pull();
  1026.     }
  1027. #else
  1028.     template< typename Fn >
  1029.     explicit pull_coroutine( Fn fn,
  1030.                              attributes const& attrs = attributes() ) :
  1031.         impl_( 0)
  1032.     {
  1033.         // create a stack-context
  1034.         stack_context stack_ctx;
  1035.         stack_allocator stack_alloc;
  1036.         // allocate the coroutine-stack
  1037.         stack_alloc.allocate( stack_ctx, attrs.size);
  1038.         BOOST_ASSERT( 0 != stack_ctx.sp);
  1039.         // typedef of internal coroutine-type
  1040.         typedef detail::pull_coroutine_object<
  1041.             push_coroutine< R & >, R &, Fn, stack_allocator
  1042.         >                                                        object_t;
  1043.         // reserve space on top of coroutine-stack for internal coroutine-type
  1044.         std::size_t size = stack_ctx.size - sizeof( object_t);
  1045.         BOOST_ASSERT( 0 != size);
  1046.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1047.         BOOST_ASSERT( 0 != sp);
  1048.         // placement new for internal coroutine
  1049.         impl_ = new ( sp) object_t(
  1050.                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1051.         BOOST_ASSERT( impl_);
  1052.         impl_->pull();
  1053.     }
  1054.  
  1055.     template< typename Fn, typename StackAllocator >
  1056.     explicit pull_coroutine( Fn fn,
  1057.                              attributes const& attrs,
  1058.                              StackAllocator stack_alloc) :
  1059.         impl_( 0)
  1060.     {
  1061.         // create a stack-context
  1062.         stack_context stack_ctx;
  1063.         // allocate the coroutine-stack
  1064.         stack_alloc.allocate( stack_ctx, attrs.size);
  1065.         BOOST_ASSERT( 0 != stack_ctx.sp);
  1066.         // typedef of internal coroutine-type
  1067.         typedef detail::pull_coroutine_object<
  1068.             push_coroutine< R & >, R &, Fn, StackAllocator
  1069.         >                                                        object_t;
  1070.         // reserve space on top of coroutine-stack for internal coroutine-type
  1071.         std::size_t size = stack_ctx.size - sizeof( object_t);
  1072.         BOOST_ASSERT( 0 != size);
  1073.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1074.         BOOST_ASSERT( 0 != sp);
  1075.         // placement new for internal coroutine
  1076.         impl_ = new ( sp) object_t(
  1077.                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1078.         BOOST_ASSERT( impl_);
  1079.         impl_->pull();
  1080.     }
  1081.  
  1082.     template< typename Fn >
  1083.     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
  1084.                              attributes const& attrs = attributes() ) :
  1085.         impl_( 0)
  1086.     {
  1087.         // create a stack-context
  1088.         stack_context stack_ctx;
  1089.         stack_allocator stack_alloc;
  1090.         // allocate the coroutine-stack
  1091.         stack_alloc.allocate( stack_ctx, attrs.size);
  1092.         BOOST_ASSERT( 0 != stack_ctx.sp);
  1093.         // typedef of internal coroutine-type
  1094.         typedef detail::pull_coroutine_object<
  1095.             push_coroutine< R & >, R &, Fn, stack_allocator
  1096.         >                                                        object_t;
  1097.         // reserve space on top of coroutine-stack for internal coroutine-type
  1098.         std::size_t size = stack_ctx.size - sizeof( object_t);
  1099.         BOOST_ASSERT( 0 != size);
  1100.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1101.         BOOST_ASSERT( 0 != sp);
  1102.         // placement new for internal coroutine
  1103.         impl_ = new ( sp) object_t(
  1104.                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1105.         BOOST_ASSERT( impl_);
  1106.         impl_->pull();
  1107.     }
  1108.  
  1109.     template< typename Fn, typename StackAllocator >
  1110.     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
  1111.                              attributes const& attrs,
  1112.                              StackAllocator stack_alloc) :
  1113.         impl_( 0)
  1114.     {
  1115.         // create a stack-context
  1116.         stack_context stack_ctx;
  1117.         // allocate the coroutine-stack
  1118.         stack_alloc.allocate( stack_ctx, attrs.size);
  1119.         BOOST_ASSERT( 0 != stack_ctx.sp);
  1120.         // typedef of internal coroutine-type
  1121.         typedef detail::pull_coroutine_object<
  1122.             push_coroutine< R & >, R &, Fn, StackAllocator
  1123.         >                                                        object_t;
  1124.         // reserve space on top of coroutine-stack for internal coroutine-type
  1125.         std::size_t size = stack_ctx.size - sizeof( object_t);
  1126.         BOOST_ASSERT( 0 != size);
  1127.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1128.         BOOST_ASSERT( 0 != sp);
  1129.         // placement new for internal coroutine
  1130.         impl_ = new ( sp) object_t(
  1131.                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1132.         BOOST_ASSERT( impl_);
  1133.         impl_->pull();
  1134.     }
  1135. #endif
  1136.  
  1137.     ~pull_coroutine()
  1138.     {
  1139.         if ( 0 != impl_)
  1140.         {
  1141.             impl_->destroy();
  1142.             impl_ = 0;
  1143.         }
  1144.     }
  1145.  
  1146.     pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT :
  1147.         impl_( 0)
  1148.     { swap( other); }
  1149.  
  1150.     pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT
  1151.     {
  1152.         pull_coroutine tmp( mars_boost::move( other) );
  1153.         swap( tmp);
  1154.         return * this;
  1155.     }
  1156.  
  1157.     BOOST_EXPLICIT_OPERATOR_BOOL();
  1158.  
  1159.     bool operator!() const BOOST_NOEXCEPT
  1160.     { return 0 == impl_ || impl_->is_complete(); }
  1161.  
  1162.     void swap( pull_coroutine & other) BOOST_NOEXCEPT
  1163.     { std::swap( impl_, other.impl_); }
  1164.  
  1165.     pull_coroutine & operator()()
  1166.     {
  1167.         BOOST_ASSERT( * this);
  1168.  
  1169.         impl_->pull();
  1170.         return * this;
  1171.     }
  1172.  
  1173.     R & get() const
  1174.     { return impl_->get(); }
  1175.  
  1176.     class iterator : public std::iterator< std::input_iterator_tag, typename remove_reference< R >::type >
  1177.     {
  1178.     private:
  1179.         pull_coroutine< R & >   *   c_;
  1180.         R                       *   val_;
  1181.  
  1182.         void fetch_()
  1183.         {
  1184.             BOOST_ASSERT( c_);
  1185.  
  1186.             if ( ! ( * c_) )
  1187.             {
  1188.                 c_ = 0;
  1189.                 val_ = 0;
  1190.                 return;
  1191.             }
  1192.             val_ = c_->impl_->get_pointer();
  1193.         }
  1194.  
  1195.         void increment_()
  1196.         {
  1197.             BOOST_ASSERT( c_);
  1198.             BOOST_ASSERT( * c_);
  1199.  
  1200.             ( * c_)();
  1201.             fetch_();
  1202.         }
  1203.  
  1204.     public:
  1205.         typedef typename iterator::pointer      pointer_t;
  1206.         typedef typename iterator::reference    reference_t;
  1207.  
  1208.         iterator() :
  1209.             c_( 0), val_( 0)
  1210.         {}
  1211.  
  1212.         explicit iterator( pull_coroutine< R & > * c) :
  1213.             c_( c), val_( 0)
  1214.         { fetch_(); }
  1215.  
  1216.         iterator( iterator const& other) :
  1217.             c_( other.c_), val_( other.val_)
  1218.         {}
  1219.  
  1220.         iterator & operator=( iterator const& other)
  1221.         {
  1222.             if ( this == & other) return * this;
  1223.             c_ = other.c_;
  1224.             val_ = other.val_;
  1225.             return * this;
  1226.         }
  1227.  
  1228.         bool operator==( iterator const& other) const
  1229.         { return other.c_ == c_ && other.val_ == val_; }
  1230.  
  1231.         bool operator!=( iterator const& other) const
  1232.         { return other.c_ != c_ || other.val_ != val_; }
  1233.  
  1234.         iterator & operator++()
  1235.         {
  1236.             increment_();
  1237.             return * this;
  1238.         }
  1239.  
  1240.         iterator operator++( int);
  1241.  
  1242.         reference_t operator*() const
  1243.         {
  1244.             if ( ! val_)
  1245.                 mars_boost::throw_exception(
  1246.                     invalid_result() );
  1247.             return * val_;
  1248.         }
  1249.  
  1250.         pointer_t operator->() const
  1251.         {
  1252.             if ( ! val_)
  1253.                 mars_boost::throw_exception(
  1254.                     invalid_result() );
  1255.             return val_;
  1256.         }
  1257.     };
  1258.  
  1259.     class const_iterator : public std::iterator< std::input_iterator_tag, const typename remove_reference< R >::type >
  1260.     {
  1261.     private:
  1262.         pull_coroutine< R & >   *   c_;
  1263.         R                       *   val_;
  1264.  
  1265.         void fetch_()
  1266.         {
  1267.             BOOST_ASSERT( c_);
  1268.  
  1269.             if ( ! ( * c_) )
  1270.             {
  1271.                 c_ = 0;
  1272.                 val_ = 0;
  1273.                 return;
  1274.             }
  1275.             val_ = c_->impl_->get_pointer();
  1276.         }
  1277.  
  1278.         void increment_()
  1279.         {
  1280.             BOOST_ASSERT( c_);
  1281.             BOOST_ASSERT( * c_);
  1282.  
  1283.             ( * c_)();
  1284.             fetch_();
  1285.         }
  1286.  
  1287.     public:
  1288.         typedef typename const_iterator::pointer      pointer_t;
  1289.         typedef typename const_iterator::reference    reference_t;
  1290.  
  1291.         const_iterator() :
  1292.             c_( 0), val_( 0)
  1293.         {}
  1294.  
  1295.         explicit const_iterator( pull_coroutine< R & > const* c) :
  1296.             c_( const_cast< pull_coroutine< R & > * >( c) ),
  1297.             val_( 0)
  1298.         { fetch_(); }
  1299.  
  1300.         const_iterator( const_iterator const& other) :
  1301.             c_( other.c_), val_( other.val_)
  1302.         {}
  1303.  
  1304.         const_iterator & operator=( const_iterator const& other)
  1305.         {
  1306.             if ( this == & other) return * this;
  1307.             c_ = other.c_;
  1308.             val_ = other.val_;
  1309.             return * this;
  1310.         }
  1311.  
  1312.         bool operator==( const_iterator const& other) const
  1313.         { return other.c_ == c_ && other.val_ == val_; }
  1314.  
  1315.         bool operator!=( const_iterator const& other) const
  1316.         { return other.c_ != c_ || other.val_ != val_; }
  1317.  
  1318.         const_iterator & operator++()
  1319.         {
  1320.             increment_();
  1321.             return * this;
  1322.         }
  1323.  
  1324.         const_iterator operator++( int);
  1325.  
  1326.         reference_t operator*() const
  1327.         {
  1328.             if ( ! val_)
  1329.                 mars_boost::throw_exception(
  1330.                     invalid_result() );
  1331.             return * val_;
  1332.         }
  1333.  
  1334.         pointer_t operator->() const
  1335.         {
  1336.             if ( ! val_)
  1337.                 mars_boost::throw_exception(
  1338.                     invalid_result() );
  1339.             return val_;
  1340.         }
  1341.     };
  1342.  
  1343.     friend class iterator;
  1344.     friend class const_iterator;
  1345. };
  1346.  
  1347. template<>
  1348. class pull_coroutine< void >
  1349. {
  1350. private:
  1351.     template< typename V, typename X, typename Y, typename Z >
  1352.     friend class detail::push_coroutine_object;
  1353.  
  1354.     typedef detail::pull_coroutine_impl< void >            impl_type;
  1355.     typedef detail::pull_coroutine_synthesized< void >     synth_type;
  1356.     typedef detail::parameters< void >                     param_type;
  1357.  
  1358.     struct dummy {};
  1359.  
  1360.     impl_type       *   impl_;
  1361.  
  1362.     BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine)
  1363.  
  1364.     explicit pull_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
  1365.         impl_( & impl)
  1366.     { BOOST_ASSERT( impl_); }
  1367.  
  1368. public:
  1369.     pull_coroutine() BOOST_NOEXCEPT :
  1370.         impl_( 0)
  1371.     {}
  1372.  
  1373. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  1374. # ifdef BOOST_MSVC
  1375.     typedef void ( * coroutine_fn)( push_coroutine< void > &);
  1376.  
  1377.     explicit pull_coroutine( coroutine_fn fn,
  1378.                              attributes const& attrs = attributes() ) :
  1379.         impl_( 0)
  1380.     {
  1381.         // create a stack-context
  1382.         stack_context stack_ctx;
  1383.         stack_allocator stack_alloc;
  1384.         // allocate the coroutine-stack
  1385.         stack_alloc.allocate( stack_ctx, attrs.size);
  1386.         BOOST_ASSERT( 0 != stack_ctx.sp);
  1387.         // typedef of internal coroutine-type
  1388.         typedef detail::pull_coroutine_object<
  1389.             push_coroutine< void >, void, coroutine_fn, stack_allocator
  1390.         >                                       object_t;
  1391.         // reserve space on top of coroutine-stack for internal coroutine-type
  1392.         std::size_t size = stack_ctx.size - sizeof( object_t);
  1393.         BOOST_ASSERT( 0 != size);
  1394.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1395.         BOOST_ASSERT( 0 != sp);
  1396.         // placement new for internal coroutine
  1397.         impl_ = new ( sp) object_t(
  1398.                 mars_boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1399.         BOOST_ASSERT( impl_);
  1400.         impl_->pull();
  1401.     }
  1402.  
  1403.     template< typename StackAllocator >
  1404.     explicit pull_coroutine( coroutine_fn fn,
  1405.                              attributes const& attrs,
  1406.                              StackAllocator stack_alloc) :
  1407.         impl_( 0)
  1408.     {
  1409.         // create a stack-context
  1410.         stack_context stack_ctx;
  1411.         // allocate the coroutine-stack
  1412.         stack_alloc.allocate( stack_ctx, attrs.size);
  1413.         BOOST_ASSERT( 0 != stack_ctx.sp);
  1414.         // typedef of internal coroutine-type
  1415.         typedef detail::pull_coroutine_object<
  1416.             push_coroutine< void >, void, coroutine_fn, StackAllocator
  1417.         >                                                                   object_t;
  1418.         // reserve space on top of coroutine-stack for internal coroutine-type
  1419.         std::size_t size = stack_ctx.size - sizeof( object_t);
  1420.         BOOST_ASSERT( 0 != size);
  1421.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1422.         BOOST_ASSERT( 0 != sp);
  1423.         // placement new for internal coroutine
  1424.         impl_ = new ( sp) object_t(
  1425.                 mars_boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1426.         BOOST_ASSERT( impl_);
  1427.         impl_->pull();
  1428.     }
  1429. # endif
  1430.     template< typename Fn >
  1431.     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
  1432.                              attributes const& attrs = attributes() ) :
  1433.         impl_( 0)
  1434.     {
  1435.         // create a stack-context
  1436.         stack_context stack_ctx;
  1437.         stack_allocator stack_alloc;
  1438.         // allocate the coroutine-stack
  1439.         stack_alloc.allocate( stack_ctx, attrs.size);
  1440.         BOOST_ASSERT( 0 != stack_ctx.sp);
  1441.         // typedef of internal coroutine-type
  1442.         typedef detail::pull_coroutine_object<
  1443.             push_coroutine< void >, void, Fn, stack_allocator
  1444.         >                                                       object_t;
  1445.         // reserve space on top of coroutine-stack for internal coroutine-type
  1446.         std::size_t size = stack_ctx.size - sizeof( object_t);
  1447.         BOOST_ASSERT( 0 != size);
  1448.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1449.         BOOST_ASSERT( 0 != sp);
  1450.         // placement new for internal coroutine
  1451.         impl_ = new ( sp) object_t(
  1452.                 mars_boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1453.         BOOST_ASSERT( impl_);
  1454.         impl_->pull();
  1455.     }
  1456.  
  1457.     template< typename Fn, typename StackAllocator >
  1458.     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
  1459.                              attributes const& attrs,
  1460.                              StackAllocator stack_alloc) :
  1461.         impl_( 0)
  1462.     {
  1463.         // create a stack-context
  1464.         stack_context stack_ctx;
  1465.         // allocate the coroutine-stack
  1466.         stack_alloc.allocate( stack_ctx, attrs.size);
  1467.         BOOST_ASSERT( 0 != stack_ctx.sp);
  1468.         // typedef of internal coroutine-type
  1469.         typedef detail::pull_coroutine_object<
  1470.             push_coroutine< void >, void, Fn, StackAllocator
  1471.         >                                                       object_t;
  1472.         // reserve space on top of coroutine-stack for internal coroutine-type
  1473.         std::size_t size = stack_ctx.size - sizeof( object_t);
  1474.         BOOST_ASSERT( 0 != size);
  1475.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1476.         BOOST_ASSERT( 0 != sp);
  1477.         // placement new for internal coroutine
  1478.         impl_ = new ( sp) object_t(
  1479.                 mars_boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1480.         BOOST_ASSERT( impl_);
  1481.         impl_->pull();
  1482.     }
  1483. #else
  1484.     template< typename Fn >
  1485.     explicit pull_coroutine( Fn fn,
  1486.                              attributes const& attrs = attributes() ) :
  1487.         impl_( 0)
  1488.     {
  1489.         // create a stack-context
  1490.         stack_context stack_ctx;
  1491.         stack_allocator stack_alloc;
  1492.         // allocate the coroutine-stack
  1493.         stack_alloc.allocate( stack_ctx, attrs.size);
  1494.         BOOST_ASSERT( 0 != stack_ctx.sp);
  1495.         // typedef of internal coroutine-type
  1496.         typedef detail::pull_coroutine_object<
  1497.             push_coroutine< void >, void, Fn, stack_allocator
  1498.         >                                                       object_t;
  1499.         // reserve space on top of coroutine-stack for internal coroutine-type
  1500.         std::size_t size = stack_ctx.size - sizeof( object_t);
  1501.         BOOST_ASSERT( 0 != size);
  1502.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1503.         BOOST_ASSERT( 0 != sp);
  1504.         // placement new for internal coroutine
  1505.         impl_ = new ( sp) object_t(
  1506.                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1507.         BOOST_ASSERT( impl_);
  1508.         impl_->pull();
  1509.     }
  1510.  
  1511.     template< typename Fn, typename StackAllocator >
  1512.     explicit pull_coroutine( Fn fn,
  1513.                              attributes const& attrs,
  1514.                              StackAllocator stack_alloc) :
  1515.         impl_( 0)
  1516.     {
  1517.         // create a stack-context
  1518.         stack_context stack_ctx;
  1519.         // allocate the coroutine-stack
  1520.         stack_alloc.allocate( stack_ctx, attrs.size);
  1521.         BOOST_ASSERT( 0 != stack_ctx.sp);
  1522.         // typedef of internal coroutine-type
  1523.         typedef detail::pull_coroutine_object<
  1524.             push_coroutine< void >, void, Fn, StackAllocator
  1525.         >                                                       object_t;
  1526.         // reserve space on top of coroutine-stack for internal coroutine-type
  1527.         std::size_t size = stack_ctx.size - sizeof( object_t);
  1528.         BOOST_ASSERT( 0 != size);
  1529.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1530.         BOOST_ASSERT( 0 != sp);
  1531.         // placement new for internal coroutine
  1532.         impl_ = new ( sp) object_t(
  1533.                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1534.         BOOST_ASSERT( impl_);
  1535.         impl_->pull();
  1536.     }
  1537.  
  1538.     template< typename Fn >
  1539.     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
  1540.                              attributes const& attrs = attributes() ) :
  1541.         impl_( 0)
  1542.     {
  1543.         // create a stack-context
  1544.         stack_context stack_ctx;
  1545.         stack_allocator stack_alloc;
  1546.         // allocate the coroutine-stack
  1547.         stack_alloc.allocate( stack_ctx, attrs.size);
  1548.         BOOST_ASSERT( 0 != stack_ctx.sp);
  1549.         // typedef of internal coroutine-type
  1550.         typedef detail::pull_coroutine_object<
  1551.             push_coroutine< void >, void, Fn, stack_allocator
  1552.         >                                           object_t;
  1553.         // reserve space on top of coroutine-stack for internal coroutine-type
  1554.         std::size_t size = stack_ctx.size - sizeof( object_t);
  1555.         BOOST_ASSERT( 0 != size);
  1556.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1557.         BOOST_ASSERT( 0 != sp);
  1558.         // placement new for internal coroutine
  1559.         impl_ = new ( sp) object_t(
  1560.                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1561.         BOOST_ASSERT( impl_);
  1562.         impl_->pull();
  1563.     }
  1564.  
  1565.     template< typename Fn, typename StackAllocator >
  1566.     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
  1567.                              attributes const& attrs,
  1568.                              StackAllocator stack_alloc) :
  1569.         impl_( 0)
  1570.     {
  1571.         // create a stack-context
  1572.         stack_context stack_ctx;
  1573.         // allocate the coroutine-stack
  1574.         stack_alloc.allocate( stack_ctx, attrs.size);
  1575.         BOOST_ASSERT( 0 != stack_ctx.sp);
  1576.         // typedef of internal coroutine-type
  1577.         typedef detail::pull_coroutine_object<
  1578.             push_coroutine< void >, void, Fn, StackAllocator
  1579.         >                                           object_t;
  1580.         // reserve space on top of coroutine-stack for internal coroutine-type
  1581.         std::size_t size = stack_ctx.size - sizeof( object_t);
  1582.         BOOST_ASSERT( 0 != size);
  1583.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1584.         BOOST_ASSERT( 0 != sp);
  1585.         // placement new for internal coroutine
  1586.         impl_ = new ( sp) object_t(
  1587.                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1588.         BOOST_ASSERT( impl_);
  1589.         impl_->pull();
  1590.     }
  1591. #endif
  1592.  
  1593.     ~pull_coroutine()
  1594.     {
  1595.         if ( 0 != impl_)
  1596.         {
  1597.             impl_->destroy();
  1598.             impl_ = 0;
  1599.         }
  1600.     }
  1601.  
  1602.     inline pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT :
  1603.         impl_( 0)
  1604.     { swap( other); }
  1605.  
  1606.     inline pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT
  1607.     {
  1608.         pull_coroutine tmp( mars_boost::move( other) );
  1609.         swap( tmp);
  1610.         return * this;
  1611.     }
  1612.  
  1613.     BOOST_EXPLICIT_OPERATOR_BOOL();
  1614.  
  1615.     inline bool operator!() const BOOST_NOEXCEPT
  1616.     { return 0 == impl_ || impl_->is_complete(); }
  1617.  
  1618.     inline void swap( pull_coroutine & other) BOOST_NOEXCEPT
  1619.     { std::swap( impl_, other.impl_); }
  1620.  
  1621.     inline pull_coroutine & operator()()
  1622.     {
  1623.         BOOST_ASSERT( * this);
  1624.  
  1625.         impl_->pull();
  1626.         return * this;
  1627.     }
  1628.  
  1629.     struct iterator;
  1630.     struct const_iterator;
  1631. };
  1632.  
  1633. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  1634. # ifdef BOOST_MSVC
  1635. template< typename Arg >
  1636. push_coroutine< Arg >::push_coroutine( coroutine_fn fn,
  1637.                                        attributes const& attrs) :
  1638.     impl_( 0)
  1639. {
  1640.     // create a stack-context
  1641.     stack_context stack_ctx;
  1642.     stack_allocator stack_alloc;
  1643.     // allocate the coroutine-stack
  1644.     stack_alloc.allocate( stack_ctx, attrs.size);
  1645.     BOOST_ASSERT( 0 != stack_ctx.sp);
  1646.     // typedef of internal coroutine-type
  1647.     typedef detail::push_coroutine_object<
  1648.         pull_coroutine< Arg >, Arg, coroutine_fn, stack_allocator
  1649.     >                                                            object_t;
  1650.     // reserve space on top of coroutine-stack for internal coroutine-type
  1651.     std::size_t size = stack_ctx.size - sizeof( object_t);
  1652.     BOOST_ASSERT( 0 != size);
  1653.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1654.     BOOST_ASSERT( 0 != sp);
  1655.     // placement new for internal coroutine
  1656.     impl_ = new ( sp) object_t(
  1657.             mars_boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1658.     BOOST_ASSERT( impl_);
  1659. }
  1660.  
  1661. template< typename Arg >
  1662. template< typename StackAllocator >
  1663. push_coroutine< Arg >::push_coroutine( coroutine_fn fn,
  1664.                                        attributes const& attrs,
  1665.                                        StackAllocator stack_alloc) :
  1666.     impl_( 0)
  1667. {
  1668.     // create a stack-context
  1669.     stack_context stack_ctx;
  1670.     // allocate the coroutine-stack
  1671.     stack_alloc.allocate( stack_ctx, attrs.size);
  1672.     BOOST_ASSERT( 0 != stack_ctx.sp);
  1673.     // typedef of internal coroutine-type
  1674.     typedef detail::push_coroutine_object<
  1675.         pull_coroutine< Arg >, Arg, coroutine_fn, StackAllocator
  1676.     >                                                            object_t;
  1677.     // reserve space on top of coroutine-stack for internal coroutine-type
  1678.     std::size_t size = stack_ctx.size - sizeof( object_t);
  1679.     BOOST_ASSERT( 0 != size);
  1680.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1681.     BOOST_ASSERT( 0 != sp);
  1682.     // placement new for internal coroutine
  1683.     impl_ = new ( sp) object_t(
  1684.             mars_boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1685.     BOOST_ASSERT( impl_);
  1686. }
  1687.  
  1688. template< typename Arg >
  1689. push_coroutine< Arg & >::push_coroutine( coroutine_fn fn,
  1690.                                          attributes const& attrs) :
  1691.     impl_( 0)
  1692. {
  1693.     // create a stack-context
  1694.     stack_context stack_ctx;
  1695.     stack_allocator stack_alloc;
  1696.     // allocate the coroutine-stack
  1697.     stack_alloc.allocate( stack_ctx, attrs.size);
  1698.     BOOST_ASSERT( 0 != stack_ctx.sp);
  1699.     // typedef of internal coroutine-type
  1700.     typedef detail::push_coroutine_object<
  1701.         pull_coroutine< Arg & >, Arg &, coroutine_fn, stack_allocator
  1702.     >                                                            object_t;
  1703.     // reserve space on top of coroutine-stack for internal coroutine-type
  1704.     std::size_t size = stack_ctx.size - sizeof( object_t);
  1705.     BOOST_ASSERT( 0 != size);
  1706.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1707.     BOOST_ASSERT( 0 != sp);
  1708.     // placement new for internal coroutine
  1709.     impl_ = new ( sp) object_t(
  1710.             mars_boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1711.     BOOST_ASSERT( impl_);
  1712. }
  1713.  
  1714. template< typename Arg >
  1715. template< typename StackAllocator >
  1716. push_coroutine< Arg & >::push_coroutine( coroutine_fn fn,
  1717.                                          attributes const& attrs,
  1718.                                          StackAllocator stack_alloc) :
  1719.     impl_( 0)
  1720. {
  1721.     // create a stack-context
  1722.     stack_context stack_ctx;
  1723.     // allocate the coroutine-stack
  1724.     stack_alloc.allocate( stack_ctx, attrs.size);
  1725.     BOOST_ASSERT( 0 != stack_ctx.sp);
  1726.     // typedef of internal coroutine-type
  1727.     typedef detail::push_coroutine_object<
  1728.         pull_coroutine< Arg & >, Arg &, coroutine_fn, StackAllocator
  1729.     >                                                            object_t;
  1730.     // reserve space on top of coroutine-stack for internal coroutine-type
  1731.     std::size_t size = stack_ctx.size - sizeof( object_t);
  1732.     BOOST_ASSERT( 0 != size);
  1733.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1734.     BOOST_ASSERT( 0 != sp);
  1735.     // placement new for internal coroutine
  1736.     impl_ = new ( sp) object_t(
  1737.             mars_boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1738.     BOOST_ASSERT( impl_);
  1739. }
  1740.  
  1741. inline push_coroutine< void >::push_coroutine( coroutine_fn fn,
  1742.                                                attributes const& attrs) :
  1743.     impl_( 0)
  1744. {
  1745.     // create a stack-context
  1746.     stack_context stack_ctx;
  1747.     stack_allocator stack_alloc;
  1748.     // allocate the coroutine-stack
  1749.     stack_alloc.allocate( stack_ctx, attrs.size);
  1750.     BOOST_ASSERT( 0 != stack_ctx.sp);
  1751.     // typedef of internal coroutine-type
  1752.     typedef detail::push_coroutine_object<
  1753.         pull_coroutine< void >, void, coroutine_fn, stack_allocator
  1754.     >                                                               object_t;
  1755.     // reserve space on top of coroutine-stack for internal coroutine-type
  1756.     std::size_t size = stack_ctx.size - sizeof( object_t);
  1757.     BOOST_ASSERT( 0 != size);
  1758.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1759.     BOOST_ASSERT( 0 != sp);
  1760.     // placement new for internal coroutine
  1761.     impl_ = new ( sp) object_t(
  1762.             mars_boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1763.     BOOST_ASSERT( impl_);
  1764. }
  1765.  
  1766. template< typename StackAllocator >
  1767. push_coroutine< void >::push_coroutine( coroutine_fn fn,
  1768.                                         attributes const& attrs,
  1769.                                         StackAllocator stack_alloc) :
  1770.     impl_( 0)
  1771. {
  1772.     // create a stack-context
  1773.     stack_context stack_ctx;
  1774.     // allocate the coroutine-stack
  1775.     stack_alloc.allocate( stack_ctx, attrs.size);
  1776.     BOOST_ASSERT( 0 != stack_ctx.sp);
  1777.     // typedef of internal coroutine-type
  1778.     typedef detail::push_coroutine_object<
  1779.         pull_coroutine< void >, void, coroutine_fn, StackAllocator
  1780.     >                                                               object_t;
  1781.     // reserve space on top of coroutine-stack for internal coroutine-type
  1782.     std::size_t size = stack_ctx.size - sizeof( object_t);
  1783.     BOOST_ASSERT( 0 != size);
  1784.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1785.     BOOST_ASSERT( 0 != sp);
  1786.     // placement new for internal coroutine
  1787.     impl_ = new ( sp) object_t(
  1788.             mars_boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1789.     BOOST_ASSERT( impl_);
  1790. }
  1791. # endif
  1792. template< typename Arg >
  1793. template< typename Fn >
  1794. push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
  1795.                                        attributes const& attrs) :
  1796.     impl_( 0)
  1797. {
  1798.     // create a stack-context
  1799.     stack_context stack_ctx;
  1800.     stack_allocator stack_alloc;
  1801.     // allocate the coroutine-stack
  1802.     stack_alloc.allocate( stack_ctx, attrs.size);
  1803.     BOOST_ASSERT( 0 != stack_ctx.sp);
  1804.     // typedef of internal coroutine-type
  1805.     typedef detail::push_coroutine_object<
  1806.         pull_coroutine< Arg >, Arg, Fn, stack_allocator
  1807.     >                                                    object_t;
  1808.     // reserve space on top of coroutine-stack for internal coroutine-type
  1809.     std::size_t size = stack_ctx.size - sizeof( object_t);
  1810.     BOOST_ASSERT( 0 != size);
  1811.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1812.     BOOST_ASSERT( 0 != sp);
  1813.     // placement new for internal coroutine
  1814.     impl_ = new ( sp) object_t(
  1815.             mars_boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1816.     BOOST_ASSERT( impl_);
  1817. }
  1818.  
  1819. template< typename Arg >
  1820. template< typename Fn, typename StackAllocator >
  1821. push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
  1822.                                        attributes const& attrs,
  1823.                                        StackAllocator stack_alloc) :
  1824.     impl_( 0)
  1825. {
  1826.     // create a stack-context
  1827.     stack_context stack_ctx;
  1828.     // allocate the coroutine-stack
  1829.     stack_alloc.allocate( stack_ctx, attrs.size);
  1830.     BOOST_ASSERT( 0 != stack_ctx.sp);
  1831.     // typedef of internal coroutine-type
  1832.     typedef detail::push_coroutine_object<
  1833.         pull_coroutine< Arg >, Arg, Fn, StackAllocator
  1834.     >                                                    object_t;
  1835.     // reserve space on top of coroutine-stack for internal coroutine-type
  1836.     std::size_t size = stack_ctx.size - sizeof( object_t);
  1837.     BOOST_ASSERT( 0 != size);
  1838.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1839.     BOOST_ASSERT( 0 != sp);
  1840.     // placement new for internal coroutine
  1841.     impl_ = new ( sp) object_t(
  1842.             mars_boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1843.     BOOST_ASSERT( impl_);
  1844. }
  1845.  
  1846. template< typename Arg >
  1847. template< typename Fn >
  1848. push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
  1849.                                          attributes const& attrs) :
  1850.     impl_( 0)
  1851. {
  1852.     // create a stack-context
  1853.     stack_context stack_ctx;
  1854.     stack_allocator stack_alloc;
  1855.     // allocate the coroutine-stack
  1856.     stack_alloc.allocate( stack_ctx, attrs.size);
  1857.     BOOST_ASSERT( 0 != stack_ctx.sp);
  1858.     // typedef of internal coroutine-type
  1859.     typedef detail::push_coroutine_object<
  1860.         pull_coroutine< Arg & >, Arg &, Fn, stack_allocator
  1861.     >                                                            object_t;
  1862.     // reserve space on top of coroutine-stack for internal coroutine-type
  1863.     std::size_t size = stack_ctx.size - sizeof( object_t);
  1864.     BOOST_ASSERT( 0 != size);
  1865.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1866.     BOOST_ASSERT( 0 != sp);
  1867.     // placement new for internal coroutine
  1868.     impl_ = new ( sp) object_t(
  1869.             mars_boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1870.     BOOST_ASSERT( impl_);
  1871. }
  1872.  
  1873. template< typename Arg >
  1874. template< typename Fn, typename StackAllocator >
  1875. push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
  1876.                                          attributes const& attrs,
  1877.                                          StackAllocator stack_alloc) :
  1878.     impl_( 0)
  1879. {
  1880.     // create a stack-context
  1881.     stack_context stack_ctx;
  1882.     // allocate the coroutine-stack
  1883.     stack_alloc.allocate( stack_ctx, attrs.size);
  1884.     BOOST_ASSERT( 0 != stack_ctx.sp);
  1885.     // typedef of internal coroutine-type
  1886.     typedef detail::push_coroutine_object<
  1887.         pull_coroutine< Arg & >, Arg &, Fn, StackAllocator
  1888.     >                                                            object_t;
  1889.     // reserve space on top of coroutine-stack for internal coroutine-type
  1890.     std::size_t size = stack_ctx.size - sizeof( object_t);
  1891.     BOOST_ASSERT( 0 != size);
  1892.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1893.     BOOST_ASSERT( 0 != sp);
  1894.     // placement new for internal coroutine
  1895.     impl_ = new ( sp) object_t(
  1896.             mars_boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1897.     BOOST_ASSERT( impl_);
  1898. }
  1899.  
  1900. template< typename Fn >
  1901. push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
  1902.                                         attributes const& attrs) :
  1903.     impl_( 0)
  1904. {
  1905.     // create a stack-context
  1906.     stack_context stack_ctx;
  1907.     stack_allocator stack_alloc;
  1908.     // allocate the coroutine-stack
  1909.     stack_alloc.allocate( stack_ctx, attrs.size);
  1910.     BOOST_ASSERT( 0 != stack_ctx.sp);
  1911.     // typedef of internal coroutine-type
  1912.     typedef detail::push_coroutine_object<
  1913.         pull_coroutine< void >, void, Fn, stack_allocator
  1914.     >                                                            object_t;
  1915.     // reserve space on top of coroutine-stack for internal coroutine-type
  1916.     std::size_t size = stack_ctx.size - sizeof( object_t);
  1917.     BOOST_ASSERT( 0 != size);
  1918.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1919.     BOOST_ASSERT( 0 != sp);
  1920.     // placement new for internal coroutine
  1921.     impl_ = new ( sp) object_t(
  1922.             mars_boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1923.     BOOST_ASSERT( impl_);
  1924. }
  1925.  
  1926. template< typename Fn, typename StackAllocator >
  1927. push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
  1928.                                         attributes const& attrs,
  1929.                                         StackAllocator stack_alloc) :
  1930.     impl_( 0)
  1931. {
  1932.     // create a stack-context
  1933.     stack_context stack_ctx;
  1934.     // allocate the coroutine-stack
  1935.     stack_alloc.allocate( stack_ctx, attrs.size);
  1936.     BOOST_ASSERT( 0 != stack_ctx.sp);
  1937.     // typedef of internal coroutine-type
  1938.     typedef detail::push_coroutine_object<
  1939.         pull_coroutine< void >, void, Fn, StackAllocator
  1940.     >                                                            object_t;
  1941.     // reserve space on top of coroutine-stack for internal coroutine-type
  1942.     std::size_t size = stack_ctx.size - sizeof( object_t);
  1943.     BOOST_ASSERT( 0 != size);
  1944.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1945.     BOOST_ASSERT( 0 != sp);
  1946.     // placement new for internal coroutine
  1947.     impl_ = new ( sp) object_t(
  1948.             mars_boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1949.     BOOST_ASSERT( impl_);
  1950. }
  1951. #else
  1952. template< typename Arg >
  1953. template< typename Fn >
  1954. push_coroutine< Arg >::push_coroutine( Fn fn,
  1955.                                        attributes const& attrs) :
  1956.     impl_( 0)
  1957. {
  1958.     // create a stack-context
  1959.     stack_context stack_ctx;
  1960.     stack_allocator stack_alloc;
  1961.     // allocate the coroutine-stack
  1962.     stack_alloc.allocate( stack_ctx, attrs.size);
  1963.     BOOST_ASSERT( 0 != stack_ctx.sp);
  1964.     // typedef of internal coroutine-type
  1965.     typedef detail::push_coroutine_object<
  1966.         pull_coroutine< Arg >, Arg, Fn, stack_allocator
  1967.     >                                                    object_t;
  1968.     // reserve space on top of coroutine-stack for internal coroutine-type
  1969.     std::size_t size = stack_ctx.size - sizeof( object_t);
  1970.     BOOST_ASSERT( 0 != size);
  1971.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1972.     BOOST_ASSERT( 0 != sp);
  1973.     // placement new for internal coroutine
  1974.     impl_ = new ( sp) object_t(
  1975.             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  1976.     BOOST_ASSERT( impl_);
  1977. }
  1978.  
  1979. template< typename Arg >
  1980. template< typename Fn, typename StackAllocator >
  1981. push_coroutine< Arg >::push_coroutine( Fn fn,
  1982.                                        attributes const& attrs,
  1983.                                        StackAllocator stack_alloc) :
  1984.     impl_( 0)
  1985. {
  1986.     // create a stack-context
  1987.     stack_context stack_ctx;
  1988.     // allocate the coroutine-stack
  1989.     stack_alloc.allocate( stack_ctx, attrs.size);
  1990.     BOOST_ASSERT( 0 != stack_ctx.sp);
  1991.     // typedef of internal coroutine-type
  1992.     typedef detail::push_coroutine_object<
  1993.         pull_coroutine< Arg >, Arg, Fn, StackAllocator
  1994.     >                                                    object_t;
  1995.     // reserve space on top of coroutine-stack for internal coroutine-type
  1996.     std::size_t size = stack_ctx.size - sizeof( object_t);
  1997.     BOOST_ASSERT( 0 != size);
  1998.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  1999.     BOOST_ASSERT( 0 != sp);
  2000.     // placement new for internal coroutine
  2001.     impl_ = new ( sp) object_t(
  2002.             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  2003.     BOOST_ASSERT( impl_);
  2004. }
  2005.  
  2006. template< typename Arg >
  2007. template< typename Fn >
  2008. push_coroutine< Arg & >::push_coroutine( Fn fn,
  2009.                                          attributes const& attrs) :
  2010.     impl_( 0)
  2011. {
  2012.     // create a stack-context
  2013.     stack_context stack_ctx;
  2014.     stack_allocator stack_alloc;
  2015.     // allocate the coroutine-stack
  2016.     stack_alloc.allocate( stack_ctx, attrs.size);
  2017.     BOOST_ASSERT( 0 != stack_ctx.sp);
  2018.     // typedef of internal coroutine-type
  2019.     typedef detail::push_coroutine_object<
  2020.         pull_coroutine< Arg & >, Arg &, Fn, stack_allocator
  2021.     >                                                            object_t;
  2022.     // reserve space on top of coroutine-stack for internal coroutine-type
  2023.     std::size_t size = stack_ctx.size - sizeof( object_t);
  2024.     BOOST_ASSERT( 0 != size);
  2025.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  2026.     BOOST_ASSERT( 0 != sp);
  2027.     // placement new for internal coroutine
  2028.     impl_ = new ( sp) object_t(
  2029.             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  2030.     BOOST_ASSERT( impl_);
  2031. }
  2032.  
  2033. template< typename Arg >
  2034. template< typename Fn, typename StackAllocator >
  2035. push_coroutine< Arg & >::push_coroutine( Fn fn,
  2036.                                          attributes const& attrs,
  2037.                                          StackAllocator stack_alloc) :
  2038.     impl_( 0)
  2039. {
  2040.     // create a stack-context
  2041.     stack_context stack_ctx;
  2042.     // allocate the coroutine-stack
  2043.     stack_alloc.allocate( stack_ctx, attrs.size);
  2044.     BOOST_ASSERT( 0 != stack_ctx.sp);
  2045.     // typedef of internal coroutine-type
  2046.     typedef detail::push_coroutine_object<
  2047.         pull_coroutine< Arg & >, Arg &, Fn, StackAllocator
  2048.     >                                                            object_t;
  2049.     // reserve space on top of coroutine-stack for internal coroutine-type
  2050.     std::size_t size = stack_ctx.size - sizeof( object_t);
  2051.     BOOST_ASSERT( 0 != size);
  2052.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  2053.     BOOST_ASSERT( 0 != sp);
  2054.     // placement new for internal coroutine
  2055.     impl_ = new ( sp) object_t(
  2056.             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  2057.     BOOST_ASSERT( impl_);
  2058. }
  2059.  
  2060. template< typename Fn >
  2061. push_coroutine< void >::push_coroutine( Fn fn,
  2062.                                         attributes const& attrs) :
  2063.     impl_( 0)
  2064. {
  2065.     // create a stack-context
  2066.     stack_context stack_ctx;
  2067.     stack_allocator stack_alloc;
  2068.     // allocate the coroutine-stack
  2069.     stack_alloc.allocate( stack_ctx, attrs.size);
  2070.     BOOST_ASSERT( 0 != stack_ctx.sp);
  2071.     // typedef of internal coroutine-type
  2072.     typedef detail::push_coroutine_object<
  2073.         pull_coroutine< void >, void, Fn, stack_allocator
  2074.     >                                                            object_t;
  2075.     // reserve space on top of coroutine-stack for internal coroutine-type
  2076.     std::size_t size = stack_ctx.size - sizeof( object_t);
  2077.     BOOST_ASSERT( 0 != size);
  2078.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  2079.     BOOST_ASSERT( 0 != sp);
  2080.     // placement new for internal coroutine
  2081.     impl_ = new ( sp) object_t(
  2082.             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  2083.     BOOST_ASSERT( impl_);
  2084. }
  2085.  
  2086. template< typename Fn, typename StackAllocator >
  2087. push_coroutine< void >::push_coroutine( Fn fn,
  2088.                                         attributes const& attrs,
  2089.                                         StackAllocator stack_alloc) :
  2090.     impl_( 0)
  2091. {
  2092.     // create a stack-context
  2093.     stack_context stack_ctx;
  2094.     // allocate the coroutine-stack
  2095.     stack_alloc.allocate( stack_ctx, attrs.size);
  2096.     BOOST_ASSERT( 0 != stack_ctx.sp);
  2097.     // typedef of internal coroutine-type
  2098.     typedef detail::push_coroutine_object<
  2099.         pull_coroutine< void >, void, Fn, StackAllocator
  2100.     >                                                            object_t;
  2101.     // reserve space on top of coroutine-stack for internal coroutine-type
  2102.     std::size_t size = stack_ctx.size - sizeof( object_t);
  2103.     BOOST_ASSERT( 0 != size);
  2104.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  2105.     BOOST_ASSERT( 0 != sp);
  2106.     // placement new for internal coroutine
  2107.     impl_ = new ( sp) object_t(
  2108.             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  2109.     BOOST_ASSERT( impl_);
  2110. }
  2111.  
  2112. template< typename Arg >
  2113. template< typename Fn >
  2114. push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
  2115.                                        attributes const& attrs) :
  2116.     impl_( 0)
  2117. {
  2118.     // create a stack-context
  2119.     stack_context stack_ctx;
  2120.     stack_allocator stack_alloc;
  2121.     // allocate the coroutine-stack
  2122.     stack_alloc.allocate( stack_ctx, attrs.size);
  2123.     BOOST_ASSERT( 0 != stack_ctx.sp);
  2124.     // typedef of internal coroutine-type
  2125.     typedef detail::push_coroutine_object<
  2126.         pull_coroutine< Arg >, Arg, Fn, stack_allocator
  2127.     >                                                    object_t;
  2128.     // reserve space on top of coroutine-stack for internal coroutine-type
  2129.     std::size_t size = stack_ctx.size - sizeof( object_t);
  2130.     BOOST_ASSERT( 0 != size);
  2131.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  2132.     BOOST_ASSERT( 0 != sp);
  2133.     // placement new for internal coroutine
  2134.     impl_ = new ( sp) object_t(
  2135.             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  2136.     BOOST_ASSERT( impl_);
  2137. }
  2138.  
  2139. template< typename Arg >
  2140. template< typename Fn, typename StackAllocator >
  2141. push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
  2142.                                        attributes const& attrs,
  2143.                                        StackAllocator stack_alloc) :
  2144.     impl_( 0)
  2145. {
  2146.     // create a stack-context
  2147.     stack_context stack_ctx;
  2148.     // allocate the coroutine-stack
  2149.     stack_alloc.allocate( stack_ctx, attrs.size);
  2150.     BOOST_ASSERT( 0 != stack_ctx.sp);
  2151.     // typedef of internal coroutine-type
  2152.     typedef detail::push_coroutine_object<
  2153.         pull_coroutine< Arg >, Arg, Fn, StackAllocator
  2154.     >                                                    object_t;
  2155.     // reserve space on top of coroutine-stack for internal coroutine-type
  2156.     std::size_t size = stack_ctx.size - sizeof( object_t);
  2157.     BOOST_ASSERT( 0 != size);
  2158.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  2159.     BOOST_ASSERT( 0 != sp);
  2160.     // placement new for internal coroutine
  2161.     impl_ = new ( sp) object_t(
  2162.             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  2163.     BOOST_ASSERT( impl_);
  2164. }
  2165.  
  2166. template< typename Arg >
  2167. template< typename Fn >
  2168. push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
  2169.                                          attributes const& attrs) :
  2170.     impl_( 0)
  2171. {
  2172.     // create a stack-context
  2173.     stack_context stack_ctx;
  2174.     stack_allocator stack_alloc;
  2175.     // allocate the coroutine-stack
  2176.     stack_alloc.allocate( stack_ctx, attrs.size);
  2177.     BOOST_ASSERT( 0 != stack_ctx.sp);
  2178.     // typedef of internal coroutine-type
  2179.     typedef detail::push_coroutine_object<
  2180.         pull_coroutine< Arg & >, Arg &, Fn, stack_allocator
  2181.     >                                                            object_t;
  2182.     // reserve space on top of coroutine-stack for internal coroutine-type
  2183.     std::size_t size = stack_ctx.size - sizeof( object_t);
  2184.     BOOST_ASSERT( 0 != size);
  2185.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  2186.     BOOST_ASSERT( 0 != sp);
  2187.     // placement new for internal coroutine
  2188.     impl_ = new ( sp) object_t(
  2189.             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  2190.     BOOST_ASSERT( impl_);
  2191. }
  2192.  
  2193. template< typename Arg >
  2194. template< typename Fn, typename StackAllocator >
  2195. push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
  2196.                                          attributes const& attrs,
  2197.                                          StackAllocator stack_alloc) :
  2198.     impl_( 0)
  2199. {
  2200.     // create a stack-context
  2201.     stack_context stack_ctx;
  2202.     // allocate the coroutine-stack
  2203.     stack_alloc.allocate( stack_ctx, attrs.size);
  2204.     BOOST_ASSERT( 0 != stack_ctx.sp);
  2205.     // typedef of internal coroutine-type
  2206.     typedef detail::push_coroutine_object<
  2207.         pull_coroutine< Arg & >, Arg &, Fn, StackAllocator
  2208.     >                                                            object_t;
  2209.     // reserve space on top of coroutine-stack for internal coroutine-type
  2210.     std::size_t size = stack_ctx.size - sizeof( object_t);
  2211.     BOOST_ASSERT( 0 != size);
  2212.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  2213.     BOOST_ASSERT( 0 != sp);
  2214.     // placement new for internal coroutine
  2215.     impl_ = new ( sp) object_t(
  2216.             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  2217.     BOOST_ASSERT( impl_);
  2218. }
  2219.  
  2220. template< typename Fn >
  2221. push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
  2222.                                         attributes const& attrs) :
  2223.     impl_( 0)
  2224. {
  2225.     // create a stack-context
  2226.     stack_context stack_ctx;
  2227.     stack_allocator stack_alloc;
  2228.     // allocate the coroutine-stack
  2229.     stack_alloc.allocate( stack_ctx, attrs.size);
  2230.     BOOST_ASSERT( 0 != stack_ctx.sp);
  2231.     // typedef of internal coroutine-type
  2232.     typedef detail::push_coroutine_object<
  2233.         pull_coroutine< void >, void, Fn, stack_allocator
  2234.     >                                                            object_t;
  2235.     // reserve space on top of coroutine-stack for internal coroutine-type
  2236.     std::size_t size = stack_ctx.size - sizeof( object_t);
  2237.     BOOST_ASSERT( 0 != size);
  2238.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  2239.     BOOST_ASSERT( 0 != sp);
  2240.     // placement new for internal coroutine
  2241.     impl_ = new ( sp) object_t(
  2242.             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  2243.     BOOST_ASSERT( impl_);
  2244. }
  2245.  
  2246. template< typename Fn, typename StackAllocator >
  2247. push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
  2248.                                         attributes const& attrs,
  2249.                                         StackAllocator stack_alloc) :
  2250.     impl_( 0)
  2251. {
  2252.     // create a stack-context
  2253.     stack_context stack_ctx;
  2254.     // allocate the coroutine-stack
  2255.     stack_alloc.allocate( stack_ctx, attrs.size);
  2256.     BOOST_ASSERT( 0 != stack_ctx.sp);
  2257.     // typedef of internal coroutine-type
  2258.     typedef detail::push_coroutine_object<
  2259.         pull_coroutine< void >, void, Fn, StackAllocator
  2260.     >                                                            object_t;
  2261.     // reserve space on top of coroutine-stack for internal coroutine-type
  2262.     std::size_t size = stack_ctx.size - sizeof( object_t);
  2263.     BOOST_ASSERT( 0 != size);
  2264.     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  2265.     BOOST_ASSERT( 0 != sp);
  2266.     // placement new for internal coroutine
  2267.     impl_ = new ( sp) object_t(
  2268.             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
  2269.     BOOST_ASSERT( impl_);
  2270. }
  2271. #endif
  2272.  
  2273. template< typename R >
  2274. void swap( pull_coroutine< R > & l, pull_coroutine< R > & r) BOOST_NOEXCEPT
  2275. { l.swap( r); }
  2276.  
  2277. template< typename Arg >
  2278. void swap( push_coroutine< Arg > & l, push_coroutine< Arg > & r) BOOST_NOEXCEPT
  2279. { l.swap( r); }
  2280.  
  2281. template< typename R >
  2282. typename pull_coroutine< R >::iterator
  2283. range_begin( pull_coroutine< R > & c)
  2284. { return typename pull_coroutine< R >::iterator( & c); }
  2285.  
  2286. template< typename R >
  2287. typename pull_coroutine< R >::const_iterator
  2288. range_begin( pull_coroutine< R > const& c)
  2289. { return typename pull_coroutine< R >::const_iterator( & c); }
  2290.  
  2291. template< typename R >
  2292. typename pull_coroutine< R >::iterator
  2293. range_end( pull_coroutine< R > &)
  2294. { return typename pull_coroutine< R >::iterator(); }
  2295.  
  2296. template< typename R >
  2297. typename pull_coroutine< R >::const_iterator
  2298. range_end( pull_coroutine< R > const&)
  2299. { return typename pull_coroutine< R >::const_iterator(); }
  2300.  
  2301. template< typename Arg >
  2302. typename push_coroutine< Arg >::iterator
  2303. range_begin( push_coroutine< Arg > & c)
  2304. { return typename push_coroutine< Arg >::iterator( & c); }
  2305.  
  2306. template< typename Arg >
  2307. typename push_coroutine< Arg >::iterator
  2308. range_end( push_coroutine< Arg > &)
  2309. { return typename push_coroutine< Arg >::iterator(); }
  2310.  
  2311. template< typename T >
  2312. struct asymmetric_coroutine
  2313. {
  2314.     typedef push_coroutine< T > push_type;
  2315.     typedef pull_coroutine< T > pull_type;
  2316. };
  2317.  
  2318. // deprecated
  2319. template< typename T >
  2320. struct coroutine
  2321. {
  2322.     typedef push_coroutine< T > push_type;
  2323.     typedef pull_coroutine< T > pull_type;
  2324. };
  2325.  
  2326. template< typename R >
  2327. typename pull_coroutine< R >::iterator
  2328. begin( pull_coroutine< R > & c)
  2329. { return mars_boost::begin( c); }
  2330.  
  2331. template< typename R >
  2332. typename pull_coroutine< R >::const_iterator
  2333. begin( pull_coroutine< R > const& c)
  2334. { return mars_boost::begin( c); }
  2335.  
  2336. template< typename R >
  2337. typename pull_coroutine< R >::iterator
  2338. end( pull_coroutine< R > & c)
  2339. { return mars_boost::end( c); }
  2340.  
  2341. template< typename R >
  2342. typename pull_coroutine< R >::const_iterator
  2343. end( pull_coroutine< R > const& c)
  2344. { return mars_boost::end( c); }
  2345.  
  2346. template< typename R >
  2347. typename push_coroutine< R >::iterator
  2348. begin( push_coroutine< R > & c)
  2349. { return mars_boost::begin( c); }
  2350.  
  2351. template< typename R >
  2352. typename push_coroutine< R >::iterator
  2353. end( push_coroutine< R > & c)
  2354. { return mars_boost::end( c); }
  2355.  
  2356. }
  2357.  
  2358. template< typename Arg >
  2359. struct range_mutable_iterator< coroutines::push_coroutine< Arg > >
  2360. { typedef typename coroutines::push_coroutine< Arg >::iterator type; };
  2361.  
  2362. template< typename R >
  2363. struct range_mutable_iterator< coroutines::pull_coroutine< R > >
  2364. { typedef typename coroutines::pull_coroutine< R >::iterator type; };
  2365.  
  2366. }
  2367.  
  2368. #ifdef BOOST_HAS_ABI_HEADERS
  2369. #  include BOOST_ABI_SUFFIX
  2370. #endif
  2371.  
  2372. #endif // BOOST_COROUTINES_ASYMMETRIC_COROUTINE_H
  2373.  
downloadasymmetric_coroutine.hpp Source code - Download mars Source code
Related Source Codes/Software:
Hero - Elegant transition library for iOS & tvOS 2017-06-09
deep-photo-styletransfer - Code and data for paper "Deep Photo Style Transfer... 2017-06-09
mastodon - A GNU Social-compatible microblogging server ... 2017-06-09
plyr - A simple HTML5, YouTube and Vimeo player ... 2017-06-08
prepack - Prepack is a partial evaluator for JavaScript. Pre... 2017-06-08
Public-APIs - 2017-06-09
lottie-ios - An iOS library to natively render After Effects ve... 2017-06-09
Awesome-Hacking - A collection of various awesome lists for hackers,... 2017-06-09
algorithms - Minimal examples of data structures and algorithms... 2017-06-10
lectures - Oxford Deep NLP 2017 course 2017-06-10
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top