push_coroutine.ipp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // Copyright Oliver Kowalke 2014.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_COROUTINES2_DETAIL_PUSH_COROUTINE_IPP
  6. #define BOOST_COROUTINES2_DETAIL_PUSH_COROUTINE_IPP
  7. #include <utility>
  8. #include <boost/assert.hpp>
  9. #include <boost/config.hpp>
  10. #include <boost/coroutine2/detail/config.hpp>
  11. #include <boost/coroutine2/detail/create_control_block.ipp>
  12. #include <boost/coroutine2/detail/disable_overload.hpp>
  13. #include <boost/coroutine2/fixedsize_stack.hpp>
  14. #include <boost/coroutine2/segmented_stack.hpp>
  15. #ifdef BOOST_HAS_ABI_HEADERS
  16. # include BOOST_ABI_PREFIX
  17. #endif
  18. namespace boost {
  19. namespace coroutines2 {
  20. namespace detail {
  21. // push_coroutine< T >
  22. template< typename T >
  23. push_coroutine< T >::push_coroutine( control_block * cb) noexcept :
  24. cb_{ cb } {
  25. }
  26. template< typename T >
  27. template< typename Fn,
  28. typename
  29. >
  30. push_coroutine< T >::push_coroutine( Fn && fn) :
  31. push_coroutine{ default_stack(), std::forward< Fn >( fn) } {
  32. }
  33. template< typename T >
  34. template< typename StackAllocator, typename Fn >
  35. push_coroutine< T >::push_coroutine( StackAllocator && salloc, Fn && fn) :
  36. cb_{ create_control_block< control_block >( std::forward< StackAllocator >( salloc), std::forward< Fn >( fn) ) } {
  37. }
  38. template< typename T >
  39. push_coroutine< T >::~push_coroutine() {
  40. if ( nullptr != cb_) {
  41. cb_->deallocate();
  42. }
  43. }
  44. template< typename T >
  45. push_coroutine< T >::push_coroutine( push_coroutine && other) noexcept :
  46. cb_{ nullptr } {
  47. std::swap( cb_, other.cb_);
  48. }
  49. template< typename T >
  50. push_coroutine< T > &
  51. push_coroutine< T >::operator()( T const& t) {
  52. cb_->resume( t);
  53. return * this;
  54. }
  55. template< typename T >
  56. push_coroutine< T > &
  57. push_coroutine< T >::operator()( T && t) {
  58. cb_->resume( std::forward< T >( t) );
  59. return * this;
  60. }
  61. template< typename T >
  62. push_coroutine< T >::operator bool() const noexcept {
  63. return nullptr != cb_ && cb_->valid();
  64. }
  65. template< typename T >
  66. bool
  67. push_coroutine< T >::operator!() const noexcept {
  68. return nullptr == cb_ || ! cb_->valid();
  69. }
  70. // push_coroutine< T & >
  71. template< typename T >
  72. push_coroutine< T & >::push_coroutine( control_block * cb) noexcept :
  73. cb_{ cb } {
  74. }
  75. template< typename T >
  76. template< typename Fn,
  77. typename
  78. >
  79. push_coroutine< T & >::push_coroutine( Fn && fn) :
  80. push_coroutine{ default_stack(), std::forward< Fn >( fn) } {
  81. }
  82. template< typename T >
  83. template< typename StackAllocator, typename Fn >
  84. push_coroutine< T & >::push_coroutine( StackAllocator && salloc, Fn && fn) :
  85. cb_{ create_control_block< control_block >( std::forward< StackAllocator >( salloc), std::forward< Fn >( fn) ) } {
  86. }
  87. template< typename T >
  88. push_coroutine< T & >::~push_coroutine() {
  89. if ( nullptr != cb_) {
  90. cb_->deallocate();
  91. }
  92. }
  93. template< typename T >
  94. push_coroutine< T & >::push_coroutine( push_coroutine && other) noexcept :
  95. cb_{ nullptr } {
  96. std::swap( cb_, other.cb_);
  97. }
  98. template< typename T >
  99. push_coroutine< T & > &
  100. push_coroutine< T & >::operator()( T & t) {
  101. cb_->resume( t);
  102. return * this;
  103. }
  104. template< typename T >
  105. push_coroutine< T & >::operator bool() const noexcept {
  106. return nullptr != cb_ && cb_->valid();
  107. }
  108. template< typename T >
  109. bool
  110. push_coroutine< T & >::operator!() const noexcept {
  111. return nullptr == cb_ || ! cb_->valid();
  112. }
  113. // push_coroutine< void >
  114. inline
  115. push_coroutine< void >::push_coroutine( control_block * cb) noexcept :
  116. cb_{ cb } {
  117. }
  118. template< typename Fn,
  119. typename
  120. >
  121. push_coroutine< void >::push_coroutine( Fn && fn) :
  122. push_coroutine{ default_stack(), std::forward< Fn >( fn) } {
  123. }
  124. template< typename StackAllocator, typename Fn >
  125. push_coroutine< void >::push_coroutine( StackAllocator && salloc, Fn && fn) :
  126. cb_{ create_control_block< control_block >( std::forward< StackAllocator >( salloc), std::forward< Fn >( fn) ) } {
  127. }
  128. inline
  129. push_coroutine< void >::~push_coroutine() {
  130. if ( nullptr != cb_) {
  131. cb_->deallocate();
  132. }
  133. }
  134. inline
  135. push_coroutine< void >::push_coroutine( push_coroutine && other) noexcept :
  136. cb_{ nullptr } {
  137. std::swap( cb_, other.cb_);
  138. }
  139. inline
  140. push_coroutine< void > &
  141. push_coroutine< void >::operator()() {
  142. cb_->resume();
  143. return * this;
  144. }
  145. inline
  146. push_coroutine< void >::operator bool() const noexcept {
  147. return nullptr != cb_ && cb_->valid();
  148. }
  149. inline
  150. bool
  151. push_coroutine< void >::operator!() const noexcept {
  152. return nullptr == cb_ || ! cb_->valid();
  153. }
  154. }}}
  155. #ifdef BOOST_HAS_ABI_HEADERS
  156. # include BOOST_ABI_SUFFIX
  157. #endif
  158. #endif // BOOST_COROUTINES2_DETAIL_PUSH_COROUTINE_IPP