100#include <boost/preprocessor.hpp>
118#define _coroutine_ENUMDEF(lblseq) \
119 BOOST_PP_SEQ_FOR_EACH(_coroutine_ENUMDEF_1, , lblseq)
120#define _coroutine_ENUMDEF_1(r,data,label) \
121 BOOST_PP_CAT(BOOST_PP_CAT(_coroutine_, label), _enum),
142#define COROUTINES_SECTION \
143 do {{ if (1) {{{ do {
161#define COROUTINE_LABELS(locations) \
162 enum class _coroutine_labels { \
163 _coroutine_1_BEGIN_enum_, \
164 _coroutine_ENUMDEF(locations) \
165 ONLY_IF_DEBUG( _coroutine_ILLEGAL_enum_, ) \
166 _coroutine_2_BEGIN_enum_ \
167 } _coroutine_location[2] = \
168 { _coroutine_labels::_coroutine_2_BEGIN_enum_, \
169 _coroutine_labels::_coroutine_1_BEGIN_enum_ };\
170 std::size_t _coroutine_allowance = 1; \
171 _coroutine_label_switch: \
172 _coroutine_labels _coroutine_temp_location=_coroutine_location[1];\
173 _coroutine_location[1] = _coroutine_location[0]; \
174 ONLY_IF_DEBUG( _coroutine_location[0] = \
175 _coroutine_labels::_coroutine_ILLEGAL_enum_; )\
176 switch (_coroutine_temp_location) \
178 case _coroutine_labels::_coroutine_1_BEGIN_enum_: \
180 switch (_coroutine_labels::_coroutine_2_BEGIN_enum_) {
193 case _coroutine_labels::_coroutine_2_BEGIN_enum_: ; \
194 }} while (0); } while (0); \
200#define END_COROUTINE \
201 TERMINATE_COROUTINE_SUCCESSFULLY(); \
202 } else assert(0 && "mismatched END_COROUTINE"); }} \
203 }} while (0); } while (0); \
208#define END_COROUTINES_SECTION \
209 ONLY_IF_DEBUG( default: ; ) \
210 }} while (0); } while (0); \
212 assert(0 && "corrupted coroutine state"); \
213 _coroutine_label_terminate: ; \
214 } while(0); }}} else assert(0 && "mismatched END_COROUTINES_SECTION");\
227#define COROUTINE_WHILE(location, condition) \
234 goto _coroutine_ ## location ## _label; \
237 assert(_coroutine_labels::_coroutine_ILLEGAL_enum_ == \
238 _coroutine_location[0]);\
239 if (0 == --_coroutine_allowance) \
241 _coroutine_location[0] = _coroutine_labels:: \
242 _coroutine_ ## location ## _enum;\
243 _coroutine_allowance = 2; \
244 goto _coroutine_label_switch; \
245 case _coroutine_labels::_coroutine_ ## location ## _enum: ; \
247 _coroutine_ ## location ## _label: \
248 if (!(condition)) break;
252#define END_COROUTINE_WHILE \
255 else assert(0 && "mismatched END_COROUTINE_WHILE"); \
257 else assert(0 && "mismatched END_COROUTINE_WHILE"); \
271#define COROUTINE_FOR(location, init, condition, update) \
278 goto _coroutine_ ## location ## _label; \
282 assert(_coroutine_labels::_coroutine_ILLEGAL_enum_ == \
283 _coroutine_location[0]);\
284 if (0 == --_coroutine_allowance) \
286 _coroutine_location[0] = _coroutine_labels:: \
287 _coroutine_ ## location ## _enum;\
288 _coroutine_allowance = 2; \
289 goto _coroutine_label_switch; \
290 case _coroutine_labels::_coroutine_ ## location ## _enum: ; \
292 _coroutine_ ## location ## _label: \
293 if (!(condition)) break;
297#define END_COROUTINE_FOR \
301 else assert(0 && "mismatched END_COROUTINE_FOR"); \
314#define COROUTINE_DO_WHILE(location,condition) \
318 goto _coroutine_ ## location ## _do_while_begin; \
321 assert(_coroutine_labels::_coroutine_ILLEGAL_enum_ == \
322 _coroutine_location[0]);\
323 if (0 == --_coroutine_allowance) \
325 _coroutine_location[0] = _coroutine_labels:: \
326 _coroutine_ ## location ## _enum;\
327 _coroutine_allowance = 2; \
328 goto _coroutine_label_switch; \
329 case _coroutine_labels::_coroutine_ ## location ## _enum: ; \
331 if (!(condition)) break; \
332 _coroutine_ ## location ## _do_while_begin:
336#define END_COROUTINE_DO_WHILE \
340 else assert(0 && "mismatched END_COROUTINE_DO_WHILE"); \
348#define TERMINATE_COROUTINE_SUCCESSFULLY() \
351 assert(_coroutine_labels::_coroutine_ILLEGAL_enum_\
352 == _coroutine_location[0]);\
353 goto _coroutine_label_terminate; \
354 (void) _coroutine_allowance; \
355 (void) _coroutine_location[1]; \
363#define ABORT_THIS_COROUTINE() \
366 assert(_coroutine_labels::_coroutine_ILLEGAL_enum_\
367 == _coroutine_location[0]);\
368 _coroutine_allowance = 0; \
369 goto _coroutine_label_switch; \
370 (void) _coroutine_location[1]; \
378#define ABORT_OTHER_COROUTINE() \
381 assert(_coroutine_labels::_coroutine_ILLEGAL_enum_\
382 == _coroutine_location[0]);\
383 ONLY_IF_DEBUG( _coroutine_location[1] = \
384 _coroutine_labels::_coroutine_ILLEGAL_enum_; )\
385 _coroutine_allowance = 0; \