BVB Source Codes

mars Show symmetric_coroutine_call.hpp Source code

Return Download mars: download symmetric_coroutine_call.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_DETAIL_SYMMETRIC_COROUTINE_CALL_H
  8. #define BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_CALL_H
  9.  
  10. #include <boost/assert.hpp>
  11. #include <boost/config.hpp>
  12. #include <boost/move/move.hpp>
  13. #include <boost/utility/explicit_operator_bool.hpp>
  14.  
  15. #include <boost/coroutine/attributes.hpp>
  16. #include <boost/coroutine/detail/config.hpp>
  17. #include <boost/coroutine/detail/preallocated.hpp>
  18. #include <boost/coroutine/detail/symmetric_coroutine_impl.hpp>
  19. #include <boost/coroutine/detail/symmetric_coroutine_object.hpp>
  20. #include <boost/coroutine/detail/symmetric_coroutine_yield.hpp>
  21. #include <boost/coroutine/stack_allocator.hpp>
  22. #include <boost/coroutine/stack_context.hpp>
  23.  
  24. #ifdef BOOST_HAS_ABI_HEADERS
  25. #  include BOOST_ABI_PREFIX
  26. #endif
  27.  
  28. namespace mars_boost {} namespace boost = mars_boost; namespace mars_boost {
  29. namespace coroutines {
  30. namespace detail {
  31.  
  32. template< typename Arg >
  33. class symmetric_coroutine_call
  34. {
  35. private:
  36.     template< typename X >
  37.     friend class symmetric_coroutine_yield;
  38.  
  39.     typedef symmetric_coroutine_impl< Arg >   impl_type;
  40.  
  41.     BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_call)
  42.  
  43.     struct dummy {};
  44.  
  45.     impl_type       *   impl_;
  46.  
  47. public:
  48.     typedef Arg                                value_type;
  49.     typedef symmetric_coroutine_yield< Arg >   yield_type;
  50.  
  51.     symmetric_coroutine_call() BOOST_NOEXCEPT :
  52.         impl_( 0)
  53.     {}
  54.  
  55. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  56. # ifdef BOOST_MSVC
  57.     typedef void ( * coroutine_fn)( yield_type &);
  58.  
  59.     explicit symmetric_coroutine_call( coroutine_fn fn,
  60.                                        attributes const& attrs = attributes(),
  61.                                        stack_allocator stack_alloc = stack_allocator() ) :
  62.         impl_( 0)
  63.     {
  64.         // create a stack-context
  65.         stack_context stack_ctx;
  66.         // allocate the coroutine-stack
  67.         stack_alloc.allocate( stack_ctx, attrs.size);
  68.         BOOST_ASSERT( 0 != stack_ctx.sp);
  69.         // typedef of internal coroutine-type
  70.         typedef symmetric_coroutine_object< Arg, coroutine_fn, stack_allocator > object_t;
  71.         // reserve space on top of coroutine-stack for internal coroutine-type
  72.         std::size_t size = stack_ctx.size - sizeof( object_t);
  73.         BOOST_ASSERT( 0 != size);
  74.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  75.         BOOST_ASSERT( 0 != sp);
  76.         // placement new for internal coroutine
  77.         impl_ = new ( sp) object_t(
  78.                     mars_boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  79.         BOOST_ASSERT( impl_);
  80.     }
  81.  
  82.     template< typename StackAllocator >
  83.     explicit symmetric_coroutine_call( coroutine_fn fn,
  84.                                        attributes const& attrs,
  85.                                        StackAllocator stack_alloc) :
  86.         impl_( 0)
  87.     {
  88.         // create a stack-context
  89.         stack_context stack_ctx;
  90.         // allocate the coroutine-stack
  91.         stack_alloc.allocate( stack_ctx, attrs.size);
  92.         BOOST_ASSERT( 0 != stack_ctx.sp);
  93.         // typedef of internal coroutine-type
  94.         typedef symmetric_coroutine_object< Arg, coroutine_fn, StackAllocator > object_t;
  95.         // reserve space on top of coroutine-stack for internal coroutine-type
  96.         std::size_t size = stack_ctx.size - sizeof( object_t);
  97.         BOOST_ASSERT( 0 != size);
  98.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  99.         BOOST_ASSERT( 0 != sp);
  100.         // placement new for internal coroutine
  101.         impl_ = new ( sp) object_t(
  102.                     mars_boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  103.         BOOST_ASSERT( impl_);
  104.     }
  105. # endif
  106.     template< typename Fn >
  107.     explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
  108.                                        attributes const& attrs = attributes(),
  109.                                        stack_allocator stack_alloc = stack_allocator() ) :
  110.         impl_( 0)
  111.     {
  112.         // create a stack-context
  113.         stack_context stack_ctx;
  114.         // allocate the coroutine-stack
  115.         stack_alloc.allocate( stack_ctx, attrs.size);
  116.         BOOST_ASSERT( 0 != stack_ctx.sp);
  117.         // typedef of internal coroutine-type
  118.         typedef symmetric_coroutine_object< Arg, Fn, stack_allocator > object_t;
  119.         // reserve space on top of coroutine-stack for internal coroutine-type
  120.         std::size_t size = stack_ctx.size - sizeof( object_t);
  121.         BOOST_ASSERT( 0 != size);
  122.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  123.         BOOST_ASSERT( 0 != sp);
  124.         // placement new for internal coroutine
  125.         impl_ = new ( sp) object_t(
  126.                     mars_boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  127.         BOOST_ASSERT( impl_);
  128.     }
  129.  
  130.     template< typename Fn, typename StackAllocator >
  131.     explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
  132.                                        attributes const& attrs,
  133.                                        StackAllocator stack_alloc) :
  134.         impl_( 0)
  135.     {
  136.         // create a stack-context
  137.         stack_context stack_ctx;
  138.         // allocate the coroutine-stack
  139.         stack_alloc.allocate( stack_ctx, attrs.size);
  140.         BOOST_ASSERT( 0 != stack_ctx.sp);
  141.         // typedef of internal coroutine-type
  142.         typedef symmetric_coroutine_object< Arg, Fn, StackAllocator > object_t;
  143.         // reserve space on top of coroutine-stack for internal coroutine-type
  144.         std::size_t size = stack_ctx.size - sizeof( object_t);
  145.         BOOST_ASSERT( 0 != size);
  146.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  147.         BOOST_ASSERT( 0 != sp);
  148.         // placement new for internal coroutine
  149.         impl_ = new ( sp) object_t(
  150.                     mars_boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  151.         BOOST_ASSERT( impl_);
  152.     }
  153. #else
  154.     template< typename Fn >
  155.     explicit symmetric_coroutine_call( Fn fn,
  156.                                        attributes const& attrs = attributes(),
  157.                                        stack_allocator stack_alloc = stack_allocator() ) :
  158.         impl_( 0)
  159.     {
  160.         // create a stack-context
  161.         stack_context stack_ctx;
  162.         // allocate the coroutine-stack
  163.         stack_alloc.allocate( stack_ctx, attrs.size);
  164.         BOOST_ASSERT( 0 != stack_ctx.sp);
  165.         // typedef of internal coroutine-type
  166.         typedef symmetric_coroutine_object< Arg, Fn, stack_allocator > object_t;
  167.         // reserve space on top of coroutine-stack for internal coroutine-type
  168.         std::size_t size = stack_ctx.size - sizeof( object_t);
  169.         BOOST_ASSERT( 0 != size);
  170.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  171.         BOOST_ASSERT( 0 != sp);
  172.         // placement new for internal coroutine
  173.         impl_ = new ( sp) object_t(
  174.                     fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  175.         BOOST_ASSERT( impl_);
  176.     }
  177.  
  178.     template< typename Fn, typename StackAllocator >
  179.     explicit symmetric_coroutine_call( Fn fn,
  180.                                        attributes const& attrs,
  181.                                        StackAllocator stack_alloc) :
  182.         impl_( 0)
  183.     {
  184.         // create a stack-context
  185.         stack_context stack_ctx;
  186.         // allocate the coroutine-stack
  187.         stack_alloc.allocate( stack_ctx, attrs.size);
  188.         BOOST_ASSERT( 0 != stack_ctx.sp);
  189.         // typedef of internal coroutine-type
  190.         typedef symmetric_coroutine_object< Arg, Fn, StackAllocator > object_t;
  191.         // reserve space on top of coroutine-stack for internal coroutine-type
  192.         std::size_t size = stack_ctx.size - sizeof( object_t);
  193.         BOOST_ASSERT( 0 != size);
  194.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  195.         BOOST_ASSERT( 0 != sp);
  196.         // placement new for internal coroutine
  197.         impl_ = new ( sp) object_t(
  198.                     fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  199.         BOOST_ASSERT( impl_);
  200.     }
  201.  
  202.     template< typename Fn >
  203.     explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
  204.                                        attributes const& attrs = attributes(),
  205.                                        stack_allocator stack_alloc = stack_allocator() ) :
  206.         impl_( 0)
  207.     {
  208.         // create a stack-context
  209.         stack_context stack_ctx;
  210.         // allocate the coroutine-stack
  211.         stack_alloc.allocate( stack_ctx, attrs.size);
  212.         BOOST_ASSERT( 0 != stack_ctx.sp);
  213.         // typedef of internal coroutine-type
  214.         typedef symmetric_coroutine_object< Arg, Fn, stack_allocator > object_t;
  215.         // reserve space on top of coroutine-stack for internal coroutine-type
  216.         std::size_t size = stack_ctx.size - sizeof( object_t);
  217.         BOOST_ASSERT( 0 != size);
  218.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  219.         BOOST_ASSERT( 0 != sp);
  220.         // placement new for internal coroutine
  221.         impl_ = new ( sp) object_t(
  222.                     fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  223.         BOOST_ASSERT( impl_);
  224.     }
  225.  
  226.     template< typename Fn, typename StackAllocator >
  227.     explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
  228.                                        attributes const& attrs,
  229.                                        StackAllocator stack_alloc) :
  230.         impl_( 0)
  231.     {
  232.         // create a stack-context
  233.         stack_context stack_ctx;
  234.         // allocate the coroutine-stack
  235.         stack_alloc.allocate( stack_ctx, attrs.size);
  236.         BOOST_ASSERT( 0 != stack_ctx.sp);
  237.         // typedef of internal coroutine-type
  238.         typedef symmetric_coroutine_object< Arg, Fn, StackAllocator > object_t;
  239.         // reserve space on top of coroutine-stack for internal coroutine-type
  240.         std::size_t size = stack_ctx.size - sizeof( object_t);
  241.         BOOST_ASSERT( 0 != size);
  242.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  243.         BOOST_ASSERT( 0 != sp);
  244.         // placement new for internal coroutine
  245.         impl_ = new ( sp) object_t(
  246.                     fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  247.         BOOST_ASSERT( impl_);
  248.     }
  249. #endif
  250.  
  251.     ~symmetric_coroutine_call()
  252.     {
  253.         if ( 0 != impl_)
  254.         {
  255.             impl_->destroy();
  256.             impl_ = 0;
  257.         }
  258.     }
  259.  
  260.     symmetric_coroutine_call( BOOST_RV_REF( symmetric_coroutine_call) other) BOOST_NOEXCEPT :
  261.         impl_( 0)
  262.     { swap( other); }
  263.  
  264.     symmetric_coroutine_call & operator=( BOOST_RV_REF( symmetric_coroutine_call) other) BOOST_NOEXCEPT
  265.     {
  266.         symmetric_coroutine_call tmp( mars_boost::move( other) );
  267.         swap( tmp);
  268.         return * this;
  269.     }
  270.  
  271.     BOOST_EXPLICIT_OPERATOR_BOOL();
  272.  
  273.     bool operator!() const BOOST_NOEXCEPT
  274.     { return 0 == impl_ || impl_->is_complete() || impl_->is_running(); }
  275.  
  276.     void swap( symmetric_coroutine_call & other) BOOST_NOEXCEPT
  277.     { std::swap( impl_, other.impl_); }
  278.  
  279.     symmetric_coroutine_call & operator()( Arg arg) BOOST_NOEXCEPT
  280.     {
  281.         BOOST_ASSERT( * this);
  282.  
  283.         impl_->resume( arg);
  284.         return * this;
  285.     }
  286. };
  287.  
  288. template< typename Arg >
  289. class symmetric_coroutine_call< Arg & >
  290. {
  291. private:
  292.     template< typename X >
  293.     friend class symmetric_coroutine_yield;
  294.  
  295.     typedef symmetric_coroutine_impl< Arg & >     impl_type;
  296.  
  297.     BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_call)
  298.  
  299.     struct dummy {};
  300.  
  301.     impl_type       *   impl_;
  302.  
  303. public:
  304.     typedef Arg                                    value_type;
  305.     typedef symmetric_coroutine_yield< Arg & >     yield_type;
  306.  
  307.     symmetric_coroutine_call() BOOST_NOEXCEPT :
  308.         impl_( 0)
  309.     {}
  310.  
  311. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  312. # ifdef BOOST_MSVC
  313.     typedef void ( * coroutine_fn)( yield_type &);
  314.  
  315.     explicit symmetric_coroutine_call( coroutine_fn fn,
  316.                                        attributes const& attrs = attributes(),
  317.                                        stack_allocator stack_alloc = stack_allocator() ) :
  318.         impl_( 0)
  319.     {
  320.         // create a stack-context
  321.         stack_context stack_ctx;
  322.         // allocate the coroutine-stack
  323.         stack_alloc.allocate( stack_ctx, attrs.size);
  324.         BOOST_ASSERT( 0 != stack_ctx.sp);
  325.         // typedef of internal coroutine-type
  326.         typedef symmetric_coroutine_object< Arg &, coroutine_fn, stack_allocator > object_t;
  327.         // reserve space on top of coroutine-stack for internal coroutine-type
  328.         std::size_t size = stack_ctx.size - sizeof( object_t);
  329.         BOOST_ASSERT( 0 != size);
  330.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  331.         BOOST_ASSERT( 0 != sp);
  332.         // placement new for internal coroutine
  333.         impl_ = new ( sp) object_t(
  334.                     mars_boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  335.         BOOST_ASSERT( impl_);
  336.     }
  337.  
  338.     template< typename StackAllocator >
  339.     explicit symmetric_coroutine_call( coroutine_fn fn,
  340.                                        attributes const& attrs,
  341.                                        StackAllocator stack_alloc) :
  342.         impl_( 0)
  343.     {
  344.         // create a stack-context
  345.         stack_context stack_ctx;
  346.         // allocate the coroutine-stack
  347.         stack_alloc.allocate( stack_ctx, attrs.size);
  348.         BOOST_ASSERT( 0 != stack_ctx.sp);
  349.         // typedef of internal coroutine-type
  350.         typedef symmetric_coroutine_object< Arg &, coroutine_fn, StackAllocator > object_t;
  351.         // reserve space on top of coroutine-stack for internal coroutine-type
  352.         std::size_t size = stack_ctx.size - sizeof( object_t);
  353.         BOOST_ASSERT( 0 != size);
  354.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  355.         BOOST_ASSERT( 0 != sp);
  356.         // placement new for internal coroutine
  357.         impl_ = new ( sp) object_t(
  358.                     mars_boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  359.         BOOST_ASSERT( impl_);
  360.     }
  361. # endif
  362.     template< typename Fn >
  363.     explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
  364.                                        attributes const& attrs = attributes(),
  365.                                        stack_allocator stack_alloc = stack_allocator() ) :
  366.         impl_( 0)
  367.     {
  368.         // create a stack-context
  369.         stack_context stack_ctx;
  370.         // allocate the coroutine-stack
  371.         stack_alloc.allocate( stack_ctx, attrs.size);
  372.         BOOST_ASSERT( 0 != stack_ctx.sp);
  373.         // typedef of internal coroutine-type
  374.         typedef symmetric_coroutine_object< Arg &, Fn, stack_allocator > object_t;
  375.         // reserve space on top of coroutine-stack for internal coroutine-type
  376.         std::size_t size = stack_ctx.size - sizeof( object_t);
  377.         BOOST_ASSERT( 0 != size);
  378.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  379.         BOOST_ASSERT( 0 != sp);
  380.         // placement new for internal coroutine
  381.         impl_ = new ( sp) object_t(
  382.                     mars_boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  383.         BOOST_ASSERT( impl_);
  384.     }
  385.  
  386.     template< typename Fn, typename StackAllocator >
  387.     explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
  388.                                        attributes const& attrs,
  389.                                        StackAllocator stack_alloc) :
  390.         impl_( 0)
  391.     {
  392.         // create a stack-context
  393.         stack_context stack_ctx;
  394.         // allocate the coroutine-stack
  395.         stack_alloc.allocate( stack_ctx, attrs.size);
  396.         BOOST_ASSERT( 0 != stack_ctx.sp);
  397.         // typedef of internal coroutine-type
  398.         typedef symmetric_coroutine_object< Arg &, Fn, StackAllocator > object_t;
  399.         // reserve space on top of coroutine-stack for internal coroutine-type
  400.         std::size_t size = stack_ctx.size - sizeof( object_t);
  401.         BOOST_ASSERT( 0 != size);
  402.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  403.         BOOST_ASSERT( 0 != sp);
  404.         // placement new for internal coroutine
  405.         impl_ = new ( sp) object_t(
  406.                     mars_boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  407.         BOOST_ASSERT( impl_);
  408.     }
  409. #else
  410.     template< typename Fn >
  411.     explicit symmetric_coroutine_call( Fn fn,
  412.                                        attributes const& attrs = attributes(),
  413.                                        stack_allocator stack_alloc = stack_allocator() ) :
  414.         impl_( 0)
  415.     {
  416.         // create a stack-context
  417.         stack_context stack_ctx;
  418.         // allocate the coroutine-stack
  419.         stack_alloc.allocate( stack_ctx, attrs.size);
  420.         BOOST_ASSERT( 0 != stack_ctx.sp);
  421.         // typedef of internal coroutine-type
  422.         typedef symmetric_coroutine_object< Arg &, Fn, stack_allocator > object_t;
  423.         // reserve space on top of coroutine-stack for internal coroutine-type
  424.         std::size_t size = stack_ctx.size - sizeof( object_t);
  425.         BOOST_ASSERT( 0 != size);
  426.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  427.         BOOST_ASSERT( 0 != sp);
  428.         // placement new for internal coroutine
  429.         impl_ = new ( sp) object_t(
  430.                     fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  431.         BOOST_ASSERT( impl_);
  432.     }
  433.  
  434.     template< typename Fn, typename StackAllocator >
  435.     explicit symmetric_coroutine_call( Fn fn,
  436.                                        attributes const& attrs,
  437.                                        StackAllocator stack_alloc) :
  438.         impl_( 0)
  439.     {
  440.         // create a stack-context
  441.         stack_context stack_ctx;
  442.         // allocate the coroutine-stack
  443.         stack_alloc.allocate( stack_ctx, attrs.size);
  444.         BOOST_ASSERT( 0 != stack_ctx.sp);
  445.         // typedef of internal coroutine-type
  446.         typedef symmetric_coroutine_object< Arg &, Fn, StackAllocator > object_t;
  447.         // reserve space on top of coroutine-stack for internal coroutine-type
  448.         std::size_t size = stack_ctx.size - sizeof( object_t);
  449.         BOOST_ASSERT( 0 != size);
  450.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  451.         BOOST_ASSERT( 0 != sp);
  452.         // placement new for internal coroutine
  453.         impl_ = new ( sp) object_t(
  454.                     fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  455.         BOOST_ASSERT( impl_);
  456.     }
  457.  
  458.     template< typename Fn >
  459.     explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
  460.                                        attributes const& attrs = attributes(),
  461.                                        stack_allocator stack_alloc = stack_allocator() ) :
  462.         impl_( 0)
  463.     {
  464.         // create a stack-context
  465.         stack_context stack_ctx;
  466.         // allocate the coroutine-stack
  467.         stack_alloc.allocate( stack_ctx, attrs.size);
  468.         BOOST_ASSERT( 0 != stack_ctx.sp);
  469.         // typedef of internal coroutine-type
  470.         typedef symmetric_coroutine_object< Arg &, Fn, stack_allocator > object_t;
  471.         // reserve space on top of coroutine-stack for internal coroutine-type
  472.         std::size_t size = stack_ctx.size - sizeof( object_t);
  473.         BOOST_ASSERT( 0 != size);
  474.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  475.         BOOST_ASSERT( 0 != sp);
  476.         // placement new for internal coroutine
  477.         impl_ = new ( sp) object_t(
  478.                     fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  479.         BOOST_ASSERT( impl_);
  480.     }
  481.  
  482.     template< typename Fn, typename StackAllocator >
  483.     explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
  484.                                        attributes const& attrs,
  485.                                        StackAllocator stack_alloc) :
  486.         impl_( 0)
  487.     {
  488.         // create a stack-context
  489.         stack_context stack_ctx;
  490.         // allocate the coroutine-stack
  491.         stack_alloc.allocate( stack_ctx, attrs.size);
  492.         BOOST_ASSERT( 0 != stack_ctx.sp);
  493.         // typedef of internal coroutine-type
  494.         typedef symmetric_coroutine_object< Arg &, Fn, StackAllocator > object_t;
  495.         // reserve space on top of coroutine-stack for internal coroutine-type
  496.         std::size_t size = stack_ctx.size - sizeof( object_t);
  497.         BOOST_ASSERT( 0 != size);
  498.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  499.         BOOST_ASSERT( 0 != sp);
  500.         // placement new for internal coroutine
  501.         impl_ = new ( sp) object_t(
  502.                     fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  503.         BOOST_ASSERT( impl_);
  504.     }
  505. #endif
  506.  
  507.     ~symmetric_coroutine_call()
  508.     {
  509.         if ( 0 != impl_)
  510.         {
  511.             impl_->destroy();
  512.             impl_ = 0;
  513.         }
  514.     }
  515.  
  516.     symmetric_coroutine_call( BOOST_RV_REF( symmetric_coroutine_call) other) BOOST_NOEXCEPT :
  517.         impl_( 0)
  518.     { swap( other); }
  519.  
  520.     symmetric_coroutine_call & operator=( BOOST_RV_REF( symmetric_coroutine_call) other) BOOST_NOEXCEPT
  521.     {
  522.         symmetric_coroutine_call tmp( mars_boost::move( other) );
  523.         swap( tmp);
  524.         return * this;
  525.     }
  526.  
  527.     BOOST_EXPLICIT_OPERATOR_BOOL();
  528.  
  529.     bool operator!() const BOOST_NOEXCEPT
  530.     { return 0 == impl_ || impl_->is_complete() || impl_->is_running(); }
  531.  
  532.     void swap( symmetric_coroutine_call & other) BOOST_NOEXCEPT
  533.     { std::swap( impl_, other.impl_); }
  534.  
  535.     symmetric_coroutine_call & operator()( Arg & arg) BOOST_NOEXCEPT
  536.     {
  537.         BOOST_ASSERT( * this);
  538.  
  539.         impl_->resume( arg);
  540.         return * this;
  541.     }
  542. };
  543.  
  544. template<>
  545. class symmetric_coroutine_call< void >
  546. {
  547. private:
  548.     template< typename X >
  549.     friend class symmetric_coroutine_yield;
  550.  
  551.     typedef symmetric_coroutine_impl< void >        impl_type;
  552.  
  553.     BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_call)
  554.  
  555.     struct dummy {};
  556.  
  557.     impl_type       *   impl_;
  558.  
  559. public:
  560.     typedef void                                     value_type;
  561.     typedef symmetric_coroutine_yield< void >        yield_type;
  562.  
  563.     symmetric_coroutine_call() BOOST_NOEXCEPT :
  564.         impl_( 0)
  565.     {}
  566.  
  567. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  568. # ifdef BOOST_MSVC
  569.     typedef void ( * coroutine_fn)( yield_type &);
  570.  
  571.     explicit symmetric_coroutine_call( coroutine_fn fn,
  572.                                        attributes const& attrs = attributes(),
  573.                                        stack_allocator stack_alloc = stack_allocator() ) :
  574.         impl_( 0)
  575.     {
  576.         // create a stack-context
  577.         stack_context stack_ctx;
  578.         // allocate the coroutine-stack
  579.         stack_alloc.allocate( stack_ctx, attrs.size);
  580.         BOOST_ASSERT( 0 != stack_ctx.sp);
  581.         // typedef of internal coroutine-type
  582.         typedef symmetric_coroutine_object< void, coroutine_fn, stack_allocator > 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.                     mars_boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  591.         BOOST_ASSERT( impl_);
  592.     }
  593.  
  594.     template< typename StackAllocator >
  595.     explicit symmetric_coroutine_call( coroutine_fn fn,
  596.                                        attributes const& attrs,
  597.                                        StackAllocator stack_alloc) :
  598.         impl_( 0)
  599.     {
  600.         // create a stack-context
  601.         stack_context stack_ctx;
  602.         // allocate the coroutine-stack
  603.         stack_alloc.allocate( stack_ctx, attrs.size);
  604.         BOOST_ASSERT( 0 != stack_ctx.sp);
  605.         // typedef of internal coroutine-type
  606.         typedef symmetric_coroutine_object< void, coroutine_fn, StackAllocator > object_t;
  607.         // reserve space on top of coroutine-stack for internal coroutine-type
  608.         std::size_t size = stack_ctx.size - sizeof( object_t);
  609.         BOOST_ASSERT( 0 != size);
  610.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  611.         BOOST_ASSERT( 0 != sp);
  612.         // placement new for internal coroutine
  613.         impl_ = new ( sp) object_t(
  614.                     mars_boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  615.         BOOST_ASSERT( impl_);
  616.     }
  617. # endif
  618.     template< typename Fn >
  619.     explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
  620.                                        attributes const& attrs = attributes(),
  621.                                        stack_allocator stack_alloc = stack_allocator() ) :
  622.         impl_( 0)
  623.     {
  624.         // create a stack-context
  625.         stack_context stack_ctx;
  626.         // allocate the coroutine-stack
  627.         stack_alloc.allocate( stack_ctx, attrs.size);
  628.         BOOST_ASSERT( 0 != stack_ctx.sp);
  629.         // typedef of internal coroutine-type
  630.         typedef symmetric_coroutine_object< void, Fn, stack_allocator > object_t;
  631.         // reserve space on top of coroutine-stack for internal coroutine-type
  632.         std::size_t size = stack_ctx.size - sizeof( object_t);
  633.         BOOST_ASSERT( 0 != size);
  634.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  635.         BOOST_ASSERT( 0 != sp);
  636.         // placement new for internal coroutine
  637.         impl_ = new ( sp) object_t(
  638.                     mars_boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  639.         BOOST_ASSERT( impl_);
  640.     }
  641.  
  642.     template< typename Fn, typename StackAllocator >
  643.     explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
  644.                                        attributes const& attrs,
  645.                                        StackAllocator stack_alloc) :
  646.         impl_( 0)
  647.     {
  648.         // create a stack-context
  649.         stack_context stack_ctx;
  650.         // allocate the coroutine-stack
  651.         stack_alloc.allocate( stack_ctx, attrs.size);
  652.         BOOST_ASSERT( 0 != stack_ctx.sp);
  653.         // typedef of internal coroutine-type
  654.         typedef symmetric_coroutine_object< void, Fn, StackAllocator > object_t;
  655.         // reserve space on top of coroutine-stack for internal coroutine-type
  656.         std::size_t size = stack_ctx.size - sizeof( object_t);
  657.         BOOST_ASSERT( 0 != size);
  658.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  659.         BOOST_ASSERT( 0 != sp);
  660.         // placement new for internal coroutine
  661.         impl_ = new ( sp) object_t(
  662.                     mars_boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  663.         BOOST_ASSERT( impl_);
  664.     }
  665. #else
  666.     template< typename Fn >
  667.     explicit symmetric_coroutine_call( Fn fn,
  668.                                        attributes const& attrs = attributes(),
  669.                                        stack_allocator stack_alloc = stack_allocator() ) :
  670.         impl_( 0)
  671.     {
  672.         // create a stack-context
  673.         stack_context stack_ctx;
  674.         // allocate the coroutine-stack
  675.         stack_alloc.allocate( stack_ctx, attrs.size);
  676.         BOOST_ASSERT( 0 != stack_ctx.sp);
  677.         // typedef of internal coroutine-type
  678.         typedef symmetric_coroutine_object< void, Fn, stack_allocator > object_t;
  679.         // reserve space on top of coroutine-stack for internal coroutine-type
  680.         std::size_t size = stack_ctx.size - sizeof( object_t);
  681.         BOOST_ASSERT( 0 != size);
  682.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  683.         BOOST_ASSERT( 0 != sp);
  684.         // placement new for internal coroutine
  685.         impl_ = new ( sp) object_t(
  686.                     fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  687.         BOOST_ASSERT( impl_);
  688.     }
  689.  
  690.     template< typename Fn, typename StackAllocator >
  691.     explicit symmetric_coroutine_call( Fn fn,
  692.                                        attributes const& attrs,
  693.                                        StackAllocator stack_alloc) :
  694.         impl_( 0)
  695.     {
  696.         // create a stack-context
  697.         stack_context stack_ctx;
  698.         // allocate the coroutine-stack
  699.         stack_alloc.allocate( stack_ctx, attrs.size);
  700.         BOOST_ASSERT( 0 != stack_ctx.sp);
  701.         // typedef of internal coroutine-type
  702.         typedef symmetric_coroutine_object< void, Fn, StackAllocator > object_t;
  703.         // reserve space on top of coroutine-stack for internal coroutine-type
  704.         std::size_t size = stack_ctx.size - sizeof( object_t);
  705.         BOOST_ASSERT( 0 != size);
  706.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  707.         BOOST_ASSERT( 0 != sp);
  708.         // placement new for internal coroutine
  709.         impl_ = new ( sp) object_t(
  710.                     fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  711.         BOOST_ASSERT( impl_);
  712.     }
  713.  
  714.     template< typename Fn >
  715.     explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
  716.                                        attributes const& attrs = attributes(),
  717.                                        stack_allocator stack_alloc = stack_allocator() ) :
  718.         impl_( 0)
  719.     {
  720.         // create a stack-context
  721.         stack_context stack_ctx;
  722.         // allocate the coroutine-stack
  723.         stack_alloc.allocate( stack_ctx, attrs.size);
  724.         BOOST_ASSERT( 0 != stack_ctx.sp);
  725.         // typedef of internal coroutine-type
  726.         typedef symmetric_coroutine_object< void, Fn, stack_allocator > object_t;
  727.         // reserve space on top of coroutine-stack for internal coroutine-type
  728.         std::size_t size = stack_ctx.size - sizeof( object_t);
  729.         BOOST_ASSERT( 0 != size);
  730.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  731.         BOOST_ASSERT( 0 != sp);
  732.         // placement new for internal coroutine
  733.         impl_ = new ( sp) object_t(
  734.                     fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  735.         BOOST_ASSERT( impl_);
  736.     }
  737.  
  738.     template< typename Fn, typename StackAllocator >
  739.     explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
  740.                                        attributes const& attrs,
  741.                                        StackAllocator stack_alloc) :
  742.         impl_( 0)
  743.     {
  744.         // create a stack-context
  745.         stack_context stack_ctx;
  746.         // allocate the coroutine-stack
  747.         stack_alloc.allocate( stack_ctx, attrs.size);
  748.         BOOST_ASSERT( 0 != stack_ctx.sp);
  749.         // typedef of internal coroutine-type
  750.         typedef symmetric_coroutine_object< void, Fn, StackAllocator > object_t;
  751.         // reserve space on top of coroutine-stack for internal coroutine-type
  752.         std::size_t size = stack_ctx.size - sizeof( object_t);
  753.         BOOST_ASSERT( 0 != size);
  754.         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
  755.         BOOST_ASSERT( 0 != sp);
  756.         // placement new for internal coroutine
  757.         impl_ = new ( sp) object_t(
  758.                     fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
  759.         BOOST_ASSERT( impl_);
  760.     }
  761. #endif
  762.  
  763.     ~symmetric_coroutine_call()
  764.     {
  765.         if ( 0 != impl_)
  766.         {
  767.             impl_->destroy();
  768.             impl_ = 0;
  769.         }
  770.     }
  771.  
  772.     inline symmetric_coroutine_call( BOOST_RV_REF( symmetric_coroutine_call) other) BOOST_NOEXCEPT :
  773.         impl_( 0)
  774.     { swap( other); }
  775.  
  776.     inline symmetric_coroutine_call & operator=( BOOST_RV_REF( symmetric_coroutine_call) other) BOOST_NOEXCEPT
  777.     {
  778.         symmetric_coroutine_call tmp( mars_boost::move( other) );
  779.         swap( tmp);
  780.         return * this;
  781.     }
  782.  
  783.     BOOST_EXPLICIT_OPERATOR_BOOL();
  784.  
  785.     inline bool operator!() const BOOST_NOEXCEPT
  786.     { return 0 == impl_ || impl_->is_complete() || impl_->is_running(); }
  787.  
  788.     inline void swap( symmetric_coroutine_call & other) BOOST_NOEXCEPT
  789.     { std::swap( impl_, other.impl_); }
  790.  
  791.     inline symmetric_coroutine_call & operator()() BOOST_NOEXCEPT
  792.     {
  793.         BOOST_ASSERT( * this);
  794.  
  795.         impl_->resume();
  796.         return * this;
  797.     }
  798. };
  799.  
  800. template< typename Arg >
  801. void swap( symmetric_coroutine_call< Arg > & l,
  802.            symmetric_coroutine_call< Arg > & r)
  803. { l.swap( r); }
  804.  
  805. }}}
  806.  
  807. #ifdef BOOST_HAS_ABI_HEADERS
  808. #  include BOOST_ABI_SUFFIX
  809. #endif
  810.  
  811. #endif // BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_CALL_H
  812.  
downloadsymmetric_coroutine_call.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