BVB Source Codes

mars Show symmetric_coroutine_impl.hpp Source code

Return Download mars: download symmetric_coroutine_impl.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_IMPL_H
  8. #define BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_IMPL_H
  9.  
  10. #include <boost/assert.hpp>
  11. #include <boost/config.hpp>
  12. #include <boost/cstdint.hpp>
  13. #include <boost/utility.hpp>
  14.  
  15. #include <boost/coroutine/detail/config.hpp>
  16. #include <boost/coroutine/detail/coroutine_context.hpp>
  17. #include <boost/coroutine/detail/flags.hpp>
  18. #include <boost/coroutine/detail/parameters.hpp>
  19. #include <boost/coroutine/detail/preallocated.hpp>
  20. #include <boost/coroutine/detail/trampoline.hpp>
  21. #include <boost/coroutine/exceptions.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 R >
  33. class symmetric_coroutine_impl : private noncopyable
  34. {
  35. public:
  36.     typedef parameters< R >                           param_type;
  37.  
  38.     symmetric_coroutine_impl( preallocated const& palloc,
  39.                               bool unwind) BOOST_NOEXCEPT :
  40.         flags_( 0),
  41.         caller_(),
  42.         callee_( trampoline< symmetric_coroutine_impl< R > >, palloc)
  43.     {
  44.         if ( unwind) flags_ |= flag_force_unwind;
  45.     }
  46.  
  47.     virtual ~symmetric_coroutine_impl() {}
  48.  
  49.     bool force_unwind() const BOOST_NOEXCEPT
  50.     { return 0 != ( flags_ & flag_force_unwind); }
  51.  
  52.     bool unwind_requested() const BOOST_NOEXCEPT
  53.     { return 0 != ( flags_ & flag_unwind_stack); }
  54.  
  55.     bool is_started() const BOOST_NOEXCEPT
  56.     { return 0 != ( flags_ & flag_started); }
  57.  
  58.     bool is_running() const BOOST_NOEXCEPT
  59.     { return 0 != ( flags_ & flag_running); }
  60.  
  61.     bool is_complete() const BOOST_NOEXCEPT
  62.     { return 0 != ( flags_ & flag_complete); }
  63.  
  64.     void unwind_stack() BOOST_NOEXCEPT
  65.     {
  66.         if ( is_started() && ! is_complete() && force_unwind() )
  67.         {
  68.             flags_ |= flag_unwind_stack;
  69.             flags_ |= flag_running;
  70.             param_type to( unwind_t::force_unwind);
  71.             caller_.jump(
  72.                 callee_,
  73.                 & to);
  74.             flags_ &= ~flag_running;
  75.             flags_ &= ~flag_unwind_stack;
  76.  
  77.             BOOST_ASSERT( is_complete() );
  78.         }
  79.     }
  80.  
  81.     void resume( R r) BOOST_NOEXCEPT
  82.     {
  83.         param_type to( const_cast< R * >( & r), this);
  84.         resume_( & to);
  85.     }
  86.  
  87.     R * yield()
  88.     {
  89.         BOOST_ASSERT( is_running() );
  90.         BOOST_ASSERT( ! is_complete() );
  91.  
  92.         flags_ &= ~flag_running;
  93.         param_type to;
  94.         param_type * from(
  95.             static_cast< param_type * >(
  96.                 callee_.jump(
  97.                     caller_,
  98.                     & to) ) );
  99.         flags_ |= flag_running;
  100.         if ( from->do_unwind) mars_boost::throw_exception(forced_unwind());
  101.         BOOST_ASSERT( from->data);
  102.         return from->data;
  103.     }
  104.  
  105.     template< typename X >
  106.     R * yield_to( symmetric_coroutine_impl< X > * other, X x)
  107.     {
  108.         typename symmetric_coroutine_impl< X >::param_type to( & x, other);
  109.         return yield_to_( other, & to);
  110.     }
  111.  
  112.     template< typename X >
  113.     R * yield_to( symmetric_coroutine_impl< X & > * other, X & x)
  114.     {
  115.         typename symmetric_coroutine_impl< X & >::param_type to( & x, other);
  116.         return yield_to_( other, & to);
  117.     }
  118.  
  119.     template< typename X >
  120.     R * yield_to( symmetric_coroutine_impl< X > * other)
  121.     {
  122.         typename symmetric_coroutine_impl< X >::param_type to( other);
  123.         return yield_to_( other, & to);
  124.     }
  125.  
  126.     virtual void run( R *) BOOST_NOEXCEPT = 0;
  127.  
  128.     virtual void destroy() = 0;
  129.  
  130. protected:
  131.     template< typename X >
  132.     friend class symmetric_coroutine_impl;
  133.  
  134.     int                 flags_;
  135.     coroutine_context   caller_;
  136.     coroutine_context   callee_;
  137.  
  138.     void resume_( param_type * to) BOOST_NOEXCEPT
  139.     {
  140.         BOOST_ASSERT( ! is_running() );
  141.         BOOST_ASSERT( ! is_complete() );
  142.  
  143.         flags_ |= flag_running;
  144.         caller_.jump(
  145.             callee_,
  146.             to);
  147.         flags_ &= ~flag_running;
  148.     }
  149.  
  150.     template< typename Other >
  151.     R * yield_to_( Other * other, typename Other::param_type * to)
  152.     {
  153.         BOOST_ASSERT( is_running() );
  154.         BOOST_ASSERT( ! is_complete() );
  155.         BOOST_ASSERT( ! other->is_running() );
  156.         BOOST_ASSERT( ! other->is_complete() );
  157.  
  158.         other->caller_ = caller_;
  159.         flags_ &= ~flag_running;
  160.         param_type * from(
  161.             static_cast< param_type * >(
  162.                 callee_.jump(
  163.                     other->callee_,
  164.                     to) ) );
  165.         flags_ |= flag_running;
  166.         if ( from->do_unwind) mars_boost::throw_exception(forced_unwind());
  167.         BOOST_ASSERT( from->data);
  168.         return from->data;
  169.     }
  170. };
  171.  
  172. template< typename R >
  173. class symmetric_coroutine_impl< R & > : private noncopyable
  174. {
  175. public:
  176.     typedef parameters< R & >                         param_type;
  177.  
  178.     symmetric_coroutine_impl( preallocated const& palloc,
  179.                               bool unwind) BOOST_NOEXCEPT :
  180.         flags_( 0),
  181.         caller_(),
  182.         callee_( trampoline< symmetric_coroutine_impl< R > >, palloc)
  183.     {
  184.         if ( unwind) flags_ |= flag_force_unwind;
  185.     }
  186.  
  187.     virtual ~symmetric_coroutine_impl() {}
  188.  
  189.     bool force_unwind() const BOOST_NOEXCEPT
  190.     { return 0 != ( flags_ & flag_force_unwind); }
  191.  
  192.     bool unwind_requested() const BOOST_NOEXCEPT
  193.     { return 0 != ( flags_ & flag_unwind_stack); }
  194.  
  195.     bool is_started() const BOOST_NOEXCEPT
  196.     { return 0 != ( flags_ & flag_started); }
  197.  
  198.     bool is_running() const BOOST_NOEXCEPT
  199.     { return 0 != ( flags_ & flag_running); }
  200.  
  201.     bool is_complete() const BOOST_NOEXCEPT
  202.     { return 0 != ( flags_ & flag_complete); }
  203.  
  204.     void unwind_stack() BOOST_NOEXCEPT
  205.     {
  206.         if ( is_started() && ! is_complete() && force_unwind() )
  207.         {
  208.             flags_ |= flag_unwind_stack;
  209.             flags_ |= flag_running;
  210.             param_type to( unwind_t::force_unwind);
  211.             caller_.jump(
  212.                 callee_,
  213.                 & to);
  214.             flags_ &= ~flag_running;
  215.             flags_ &= ~flag_unwind_stack;
  216.  
  217.             BOOST_ASSERT( is_complete() );
  218.         }
  219.     }
  220.  
  221.     void resume( R & arg) BOOST_NOEXCEPT
  222.     {
  223.         param_type to( & arg, this);
  224.         resume_( & to);
  225.     }
  226.  
  227.     R * yield()
  228.     {
  229.         BOOST_ASSERT( is_running() );
  230.         BOOST_ASSERT( ! is_complete() );
  231.  
  232.         flags_ &= ~flag_running;
  233.         param_type to;
  234.         param_type * from(
  235.             static_cast< param_type * >(
  236.                 callee_.jump(
  237.                     caller_,
  238.                     & to) ) );
  239.         flags_ |= flag_running;
  240.         if ( from->do_unwind) mars_boost::throw_exception(forced_unwind());
  241.         BOOST_ASSERT( from->data);
  242.         return from->data;
  243.     }
  244.  
  245.     template< typename X >
  246.     R * yield_to( symmetric_coroutine_impl< X > * other, X x)
  247.     {
  248.         typename symmetric_coroutine_impl< X >::param_type to( & x, other);
  249.         return yield_to_( other, & to);
  250.     }
  251.  
  252.     template< typename X >
  253.     R * yield_to( symmetric_coroutine_impl< X & > * other, X & x)
  254.     {
  255.         typename symmetric_coroutine_impl< X & >::param_type to( & x, other);
  256.         return yield_to_( other, & to);
  257.     }
  258.  
  259.     template< typename X >
  260.     R * yield_to( symmetric_coroutine_impl< X > * other)
  261.     {
  262.         typename symmetric_coroutine_impl< X >::param_type to( other);
  263.         return yield_to_( other, & to);
  264.     }
  265.  
  266.     virtual void run( R *) BOOST_NOEXCEPT = 0;
  267.  
  268.     virtual void destroy() = 0;
  269.  
  270. protected:
  271.     template< typename X >
  272.     friend class symmetric_coroutine_impl;
  273.  
  274.     int                 flags_;
  275.     coroutine_context   caller_;
  276.     coroutine_context   callee_;
  277.  
  278.     void resume_( param_type * to) BOOST_NOEXCEPT
  279.     {
  280.         BOOST_ASSERT( ! is_running() );
  281.         BOOST_ASSERT( ! is_complete() );
  282.  
  283.         flags_ |= flag_running;
  284.         caller_.jump(
  285.             callee_,
  286.             to);
  287.         flags_ &= ~flag_running;
  288.     }
  289.  
  290.     template< typename Other >
  291.     R * yield_to_( Other * other, typename Other::param_type * to)
  292.     {
  293.         BOOST_ASSERT( is_running() );
  294.         BOOST_ASSERT( ! is_complete() );
  295.         BOOST_ASSERT( ! other->is_running() );
  296.         BOOST_ASSERT( ! other->is_complete() );
  297.  
  298.         other->caller_ = caller_;
  299.         flags_ &= ~flag_running;
  300.         param_type * from(
  301.             static_cast< param_type * >(
  302.                 callee_.jump(
  303.                     other->callee_,
  304.                     to) ) );
  305.         flags_ |= flag_running;
  306.         if ( from->do_unwind) mars_boost::throw_exception(forced_unwind());
  307.         BOOST_ASSERT( from->data);
  308.         return from->data;
  309.     }
  310. };
  311.  
  312. template<>
  313. class symmetric_coroutine_impl< void > : private noncopyable
  314. {
  315. public:
  316.     typedef parameters< void >                          param_type;
  317.  
  318.     symmetric_coroutine_impl( preallocated const& palloc,
  319.                               bool unwind) BOOST_NOEXCEPT :
  320.         flags_( 0),
  321.         caller_(),
  322.         callee_( trampoline_void< symmetric_coroutine_impl< void > >, palloc)
  323.     {
  324.         if ( unwind) flags_ |= flag_force_unwind;
  325.     }
  326.  
  327.     virtual ~symmetric_coroutine_impl() {}
  328.  
  329.     inline bool force_unwind() const BOOST_NOEXCEPT
  330.     { return 0 != ( flags_ & flag_force_unwind); }
  331.  
  332.     inline bool unwind_requested() const BOOST_NOEXCEPT
  333.     { return 0 != ( flags_ & flag_unwind_stack); }
  334.  
  335.     inline bool is_started() const BOOST_NOEXCEPT
  336.     { return 0 != ( flags_ & flag_started); }
  337.  
  338.     inline bool is_running() const BOOST_NOEXCEPT
  339.     { return 0 != ( flags_ & flag_running); }
  340.  
  341.     inline bool is_complete() const BOOST_NOEXCEPT
  342.     { return 0 != ( flags_ & flag_complete); }
  343.  
  344.     inline void unwind_stack() BOOST_NOEXCEPT
  345.     {
  346.         if ( is_started() && ! is_complete() && force_unwind() )
  347.         {
  348.             flags_ |= flag_unwind_stack;
  349.             flags_ |= flag_running;
  350.             param_type to( unwind_t::force_unwind);
  351.             caller_.jump(
  352.                 callee_,
  353.                 & to);
  354.             flags_ &= ~flag_running;
  355.             flags_ &= ~flag_unwind_stack;
  356.  
  357.             BOOST_ASSERT( is_complete() );
  358.         }
  359.     }
  360.  
  361.     inline void resume() BOOST_NOEXCEPT
  362.     {
  363.         BOOST_ASSERT( ! is_running() );
  364.         BOOST_ASSERT( ! is_complete() );
  365.  
  366.         param_type to( this);
  367.         flags_ |= flag_running;
  368.         caller_.jump(
  369.             callee_,
  370.             & to);
  371.         flags_ &= ~flag_running;
  372.     }
  373.  
  374.     inline void yield()
  375.     {
  376.         BOOST_ASSERT( is_running() );
  377.         BOOST_ASSERT( ! is_complete() );
  378.  
  379.         flags_ &= ~flag_running;
  380.         param_type to;
  381.         param_type * from(
  382.             static_cast< param_type * >(
  383.                 callee_.jump(
  384.                      caller_,
  385.                     & to) ) );
  386.         flags_ |= flag_running;
  387.         if ( from->do_unwind) mars_boost::throw_exception(forced_unwind());
  388.     }
  389.  
  390.     template< typename X >
  391.     void yield_to( symmetric_coroutine_impl< X > * other, X x)
  392.     {
  393.         typename symmetric_coroutine_impl< X >::param_type to( & x, other);
  394.         yield_to_( other, & to);
  395.     }
  396.  
  397.     template< typename X >
  398.     void yield_to( symmetric_coroutine_impl< X & > * other, X & x)
  399.     {
  400.         typename symmetric_coroutine_impl< X & >::param_type to( & x, other);
  401.         yield_to_( other, & to);
  402.     }
  403.  
  404.     template< typename X >
  405.     void yield_to( symmetric_coroutine_impl< X > * other)
  406.     {
  407.         typename symmetric_coroutine_impl< X >::param_type to( other);
  408.         yield_to_( other, & to);
  409.     }
  410.  
  411.     virtual void run() BOOST_NOEXCEPT = 0;
  412.  
  413.     virtual void destroy() = 0;
  414.  
  415. protected:
  416.     template< typename X >
  417.     friend class symmetric_coroutine_impl;
  418.  
  419.     int                 flags_;
  420.     coroutine_context   caller_;
  421.     coroutine_context   callee_;
  422.  
  423.     template< typename Other >
  424.     void yield_to_( Other * other, typename Other::param_type * to)
  425.     {
  426.         BOOST_ASSERT( is_running() );
  427.         BOOST_ASSERT( ! is_complete() );
  428.         BOOST_ASSERT( ! other->is_running() );
  429.         BOOST_ASSERT( ! other->is_complete() );
  430.  
  431.         other->caller_ = caller_;
  432.         flags_ &= ~flag_running;
  433.         param_type * from(
  434.             static_cast< param_type * >(
  435.                 callee_.jump(
  436.                     other->callee_,
  437.                     to) ) );
  438.         flags_ |= flag_running;
  439.         if ( from->do_unwind) mars_boost::throw_exception(forced_unwind());
  440.     }
  441. };
  442.  
  443. }}}
  444.  
  445. #ifdef BOOST_HAS_ABI_HEADERS
  446. #  include BOOST_ABI_SUFFIX
  447. #endif
  448.  
  449. #endif // BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_IMPL_H
  450.  
downloadsymmetric_coroutine_impl.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