1
2// Copyright Oliver Kowalke 2014.
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_COROUTINES2_DETAIL_PULL_COROUTINE_IPP
8#define BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_IPP
9
10#include <algorithm>
11#include <utility>
12
13#include <boost/assert.hpp>
14#include <boost/config.hpp>
15
16#include <boost/coroutine2/detail/config.hpp>
17#include <boost/coroutine2/detail/create_control_block.ipp>
18#include <boost/coroutine2/detail/disable_overload.hpp>
19#include <boost/coroutine2/fixedsize_stack.hpp>
20#include <boost/coroutine2/segmented_stack.hpp>
21
22#ifdef BOOST_HAS_ABI_HEADERS
23# include BOOST_ABI_PREFIX
24#endif
25
26namespace boost {
27namespace coroutines2 {
28namespace detail {
29
30// pull_coroutine< T >
31
32template< typename T >
33pull_coroutine< T >::pull_coroutine( control_block * cb) noexcept :
34 cb_{ cb } {
35}
36
37template< typename T >
38bool
39pull_coroutine< T >::has_result_() const noexcept {
40 return nullptr != cb_->other->t;
41}
42
43template< typename T >
44template< typename Fn,
45 typename
46>
47pull_coroutine< T >::pull_coroutine( Fn && fn) :
48 pull_coroutine{ default_stack(), std::forward< Fn >( fn) } {
49}
50
51template< typename T >
52template< typename StackAllocator, typename Fn >
53pull_coroutine< T >::pull_coroutine( StackAllocator && salloc, Fn && fn) :
54 cb_{ create_control_block< control_block >( std::forward< StackAllocator >( salloc), std::forward< Fn >( fn) ) } {
55 if ( ! cb_->valid() ) {
56 cb_->deallocate();
57 cb_ = nullptr;
58 }
59}
60
61template< typename T >
62pull_coroutine< T >::~pull_coroutine() {
63 if ( nullptr != cb_) {
64 cb_->deallocate();
65 }
66}
67
68template< typename T >
69pull_coroutine< T >::pull_coroutine( pull_coroutine && other) noexcept :
70 cb_{ nullptr } {
71 std::swap( cb_, other.cb_);
72}
73
74template< typename T >
75pull_coroutine< T > &
76pull_coroutine< T >::operator()() {
77 cb_->resume();
78 return * this;
79}
80
81template< typename T >
82pull_coroutine< T >::operator bool() const noexcept {
83 return nullptr != cb_ && cb_->valid();
84}
85
86template< typename T >
87bool
88pull_coroutine< T >::operator!() const noexcept {
89 return nullptr == cb_ || ! cb_->valid();
90}
91
92template< typename T >
93T
94pull_coroutine< T >::get() noexcept {
95 return std::move( cb_->get() );
96}
97
98
99// pull_coroutine< T & >
100
101template< typename T >
102pull_coroutine< T & >::pull_coroutine( control_block * cb) noexcept :
103 cb_{ cb } {
104}
105
106template< typename T >
107bool
108pull_coroutine< T & >::has_result_() const noexcept {
109 return nullptr != cb_->other->t;
110}
111
112template< typename T >
113template< typename Fn,
114 typename
115>
116pull_coroutine< T & >::pull_coroutine( Fn && fn) :
117 pull_coroutine{ default_stack(), std::forward< Fn >( fn) } {
118}
119
120template< typename T >
121template< typename StackAllocator, typename Fn >
122pull_coroutine< T & >::pull_coroutine( StackAllocator && salloc, Fn && fn) :
123 cb_{ create_control_block< control_block >( std::forward< StackAllocator >( salloc), std::forward< Fn >( fn) ) } {
124 if ( ! cb_->valid() ) {
125 cb_->deallocate();
126 cb_ = nullptr;
127 }
128}
129
130template< typename T >
131pull_coroutine< T & >::~pull_coroutine() {
132 if ( nullptr != cb_) {
133 cb_->deallocate();
134 }
135}
136
137template< typename T >
138pull_coroutine< T & >::pull_coroutine( pull_coroutine && other) noexcept :
139 cb_{ nullptr } {
140 std::swap( cb_, other.cb_);
141}
142
143template< typename T >
144pull_coroutine< T & > &
145pull_coroutine< T & >::operator()() {
146 cb_->resume();
147 return * this;
148}
149
150template< typename T >
151pull_coroutine< T & >::operator bool() const noexcept {
152 return nullptr != cb_ && cb_->valid();
153}
154
155template< typename T >
156bool
157pull_coroutine< T & >::operator!() const noexcept {
158 return nullptr == cb_ || ! cb_->valid();
159}
160
161template< typename T >
162T &
163pull_coroutine< T & >::get() noexcept {
164 return cb_->get();
165}
166
167
168// pull_coroutine< void >
169
170inline
171pull_coroutine< void >::pull_coroutine( control_block * cb) noexcept :
172 cb_{ cb } {
173}
174
175template< typename Fn,
176 typename
177>
178pull_coroutine< void >::pull_coroutine( Fn && fn) :
179 pull_coroutine{ default_stack(), std::forward< Fn >( fn) } {
180}
181
182template< typename StackAllocator, typename Fn >
183pull_coroutine< void >::pull_coroutine( StackAllocator && salloc, Fn && fn) :
184 cb_{ create_control_block< control_block >( std::forward< StackAllocator >( salloc), std::forward< Fn >( fn) ) } {
185 if ( ! cb_->valid() ) {
186 cb_->deallocate();
187 cb_ = nullptr;
188 }
189}
190
191inline
192pull_coroutine< void >::~pull_coroutine() {
193 if ( nullptr != cb_) {
194 cb_->deallocate();
195 }
196}
197
198inline
199pull_coroutine< void >::pull_coroutine( pull_coroutine && other) noexcept :
200 cb_{ nullptr } {
201 std::swap( a&: cb_, b&: other.cb_);
202}
203
204inline
205pull_coroutine< void > &
206pull_coroutine< void >::operator()() {
207 cb_->resume();
208 return * this;
209}
210
211inline
212pull_coroutine< void >::operator bool() const noexcept {
213 return nullptr != cb_ && cb_->valid();
214}
215
216inline
217bool
218pull_coroutine< void >::operator!() const noexcept {
219 return nullptr == cb_ || ! cb_->valid();
220}
221
222}}}
223
224#ifdef BOOST_HAS_ABI_HEADERS
225# include BOOST_ABI_SUFFIX
226#endif
227
228#endif // BOOST_COROUTINES2_DETAIL_PULL_COROUTINE_IPP
229

source code of boost/libs/coroutine2/include/boost/coroutine2/detail/pull_coroutine.ipp