Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / coroutine / asymmetric_coroutine.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_ASYMMETRIC_COROUTINE_H
8 #define BOOST_COROUTINES_ASYMMETRIC_COROUTINE_H
9
10 #include <cstddef>
11 #include <iterator>
12 #include <memory>
13
14 #include <boost/assert.hpp>
15 #include <boost/config.hpp>
16 #include <boost/move/move.hpp>
17 #include <boost/throw_exception.hpp>
18 #include <boost/utility/explicit_operator_bool.hpp>
19
20 #include <boost/coroutine/attributes.hpp>
21 #include <boost/coroutine/detail/config.hpp>
22 #include <boost/coroutine/detail/coroutine_context.hpp>
23 #include <boost/coroutine/detail/parameters.hpp>
24 #include <boost/coroutine/exceptions.hpp>
25 #include <boost/coroutine/stack_allocator.hpp>
26 #include <boost/coroutine/detail/pull_coroutine_impl.hpp>
27 #include <boost/coroutine/detail/pull_coroutine_object.hpp>
28 #include <boost/coroutine/detail/pull_coroutine_synthesized.hpp>
29 #include <boost/coroutine/detail/push_coroutine_impl.hpp>
30 #include <boost/coroutine/detail/push_coroutine_object.hpp>
31 #include <boost/coroutine/detail/push_coroutine_synthesized.hpp>
32 #include <boost/coroutine/stack_context.hpp>
33
34 #ifdef BOOST_HAS_ABI_HEADERS
35 #  include BOOST_ABI_PREFIX
36 #endif
37
38 namespace boost {
39 namespace coroutines {
40
41 template< typename R >
42 class pull_coroutine;
43
44 template< typename Arg >
45 class push_coroutine
46 {
47 private:
48     template< typename V, typename X, typename Y, typename Z >
49     friend class detail::pull_coroutine_object;
50
51     typedef detail::push_coroutine_impl< Arg >          impl_type;
52     typedef detail::push_coroutine_synthesized< Arg >   synth_type;
53     typedef detail::parameters< Arg >                   param_type;
54
55     struct dummy {};
56
57     impl_type       *   impl_;
58
59     BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine)
60
61     explicit push_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
62         impl_( & impl)
63     { BOOST_ASSERT( impl_); }
64
65 public:
66     push_coroutine() BOOST_NOEXCEPT :
67         impl_( 0)
68     {}
69
70 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
71 # ifdef BOOST_MSVC
72     typedef void ( * coroutine_fn)( pull_coroutine< Arg > &);
73
74     explicit push_coroutine( coroutine_fn,
75                              attributes const& = attributes() );
76
77     template< typename StackAllocator >
78     explicit push_coroutine( coroutine_fn,
79                              attributes const&,
80                              StackAllocator);
81 # endif
82     template< typename Fn >
83     explicit push_coroutine( BOOST_RV_REF( Fn),
84                              attributes const& = attributes() );
85
86     template< typename Fn, typename StackAllocator >
87     explicit push_coroutine( BOOST_RV_REF( Fn),
88                              attributes const&,
89                              StackAllocator);
90 #else
91     template< typename Fn >
92     explicit push_coroutine( Fn fn,
93                              attributes const& = attributes() );
94
95     template< typename Fn, typename StackAllocator >
96     explicit push_coroutine( Fn fn,
97                              attributes const&,
98                              StackAllocator);
99
100     template< typename Fn >
101     explicit push_coroutine( BOOST_RV_REF( Fn),
102                              attributes const& = attributes() );
103
104     template< typename Fn, typename StackAllocator >
105     explicit push_coroutine( BOOST_RV_REF( Fn),
106                              attributes const&,
107                              StackAllocator);
108 #endif
109
110     ~push_coroutine()
111     {
112         if ( 0 != impl_)
113         {
114             impl_->destroy();
115             impl_ = 0;
116         }
117     }
118
119     push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT :
120         impl_( 0)
121     { swap( other); }
122
123     push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT
124     {
125         push_coroutine tmp( boost::move( other) );
126         swap( tmp);
127         return * this;
128     }
129
130     BOOST_EXPLICIT_OPERATOR_BOOL();
131
132     bool operator!() const BOOST_NOEXCEPT
133     { return 0 == impl_ || impl_->is_complete(); }
134
135     void swap( push_coroutine & other) BOOST_NOEXCEPT
136     { std::swap( impl_, other.impl_); }
137
138     push_coroutine & operator()( Arg arg)
139     {
140         BOOST_ASSERT( * this);
141
142         impl_->push( arg);
143         return * this;
144     }
145
146     class iterator
147     {
148     private:
149        push_coroutine< Arg >    *   c_;
150
151     public:
152         typedef std::output_iterator_tag iterator_category;
153         typedef void value_type;
154         typedef void difference_type;
155         typedef void pointer;
156         typedef void reference;
157
158         iterator() :
159            c_( 0)
160         {}
161
162         explicit iterator( push_coroutine< Arg > * c) :
163             c_( c)
164         {}
165
166         iterator & operator=( Arg a)
167         {
168             BOOST_ASSERT( c_);
169             if ( ! ( * c_)( a) ) c_ = 0;
170             return * this;
171         }
172
173         bool operator==( iterator const& other) const
174         { return other.c_ == c_; }
175
176         bool operator!=( iterator const& other) const
177         { return other.c_ != c_; }
178
179         iterator & operator*()
180         { return * this; }
181
182         iterator & operator++()
183         { return * this; }
184     };
185
186     struct const_iterator;
187 };
188
189 template< typename Arg >
190 class push_coroutine< Arg & >
191 {
192 private:
193     template< typename V, typename X, typename Y, typename Z >
194     friend class detail::pull_coroutine_object;
195
196     typedef detail::push_coroutine_impl< Arg & >          impl_type;
197     typedef detail::push_coroutine_synthesized< Arg & >   synth_type;
198     typedef detail::parameters< Arg & >                   param_type;
199
200     struct dummy {};
201
202     impl_type       *   impl_;
203
204     BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine)
205
206     explicit push_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
207         impl_( & impl)
208     { BOOST_ASSERT( impl_); }
209
210 public:
211     push_coroutine() BOOST_NOEXCEPT :
212         impl_( 0)
213     {}
214
215 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
216 # ifdef BOOST_MSVC
217     typedef void ( * coroutine_fn)( pull_coroutine< Arg & > &);
218
219     explicit push_coroutine( coroutine_fn,
220                              attributes const& = attributes() );
221
222     template< typename StackAllocator >
223     explicit push_coroutine( coroutine_fn,
224                              attributes const&,
225                              StackAllocator);
226 # endif
227     template< typename Fn >
228     explicit push_coroutine( BOOST_RV_REF( Fn),
229                              attributes const& = attributes() );
230
231     template< typename Fn, typename StackAllocator >
232     explicit push_coroutine( BOOST_RV_REF( Fn),
233                              attributes const&,
234                              StackAllocator);
235 #else
236     template< typename Fn >
237     explicit push_coroutine( Fn,
238                              attributes const& = attributes() );
239
240     template< typename Fn, typename StackAllocator >
241     explicit push_coroutine( Fn,
242                              attributes const&,
243                              StackAllocator);
244
245     template< typename Fn >
246     explicit push_coroutine( BOOST_RV_REF( Fn),
247                              attributes const& = attributes() );
248
249     template< typename Fn, typename StackAllocator >
250     explicit push_coroutine( BOOST_RV_REF( Fn),
251                              attributes const&,
252                              StackAllocator);
253 #endif
254
255     ~push_coroutine()
256     {
257         if ( 0 != impl_)
258         {
259             impl_->destroy();
260             impl_ = 0;
261         }
262     }
263
264     push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT :
265         impl_( 0)
266     { swap( other); }
267
268     push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT
269     {
270         push_coroutine tmp( boost::move( other) );
271         swap( tmp);
272         return * this;
273     }
274
275     BOOST_EXPLICIT_OPERATOR_BOOL();
276
277     bool operator!() const BOOST_NOEXCEPT
278     { return 0 == impl_ || impl_->is_complete(); }
279
280     void swap( push_coroutine & other) BOOST_NOEXCEPT
281     { std::swap( impl_, other.impl_); }
282
283     push_coroutine & operator()( Arg & arg)
284     {
285         BOOST_ASSERT( * this);
286
287         impl_->push( arg);
288         return * this;
289     }
290
291     class iterator
292     {
293     private:
294        push_coroutine< Arg & >  *   c_;
295
296     public:
297         typedef std::output_iterator_tag iterator_category;
298         typedef void value_type;
299         typedef void difference_type;
300         typedef void pointer;
301         typedef void reference;
302
303         iterator() :
304            c_( 0)
305         {}
306
307         explicit iterator( push_coroutine< Arg & > * c) :
308             c_( c)
309         {}
310
311         iterator & operator=( Arg & a)
312         {
313             BOOST_ASSERT( c_);
314             if ( ! ( * c_)( a) ) c_ = 0;
315             return * this;
316         }
317
318         bool operator==( iterator const& other) const
319         { return other.c_ == c_; }
320
321         bool operator!=( iterator const& other) const
322         { return other.c_ != c_; }
323
324         iterator & operator*()
325         { return * this; }
326
327         iterator & operator++()
328         { return * this; }
329     };
330
331     struct const_iterator;
332 };
333
334 template<>
335 class push_coroutine< void >
336 {
337 private:
338     template< typename V, typename X, typename Y, typename Z >
339     friend class detail::pull_coroutine_object;
340
341     typedef detail::push_coroutine_impl< void >          impl_type;
342     typedef detail::push_coroutine_synthesized< void >   synth_type;
343     typedef detail::parameters< void >                   param_type;
344
345     struct dummy {};
346
347     impl_type       *   impl_;
348
349     BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine)
350
351     explicit push_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
352         impl_( & impl)
353     { BOOST_ASSERT( impl_); }
354
355 public:
356     push_coroutine() BOOST_NOEXCEPT :
357         impl_( 0)
358     {}
359
360 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
361 # ifdef BOOST_MSVC
362     typedef void ( * coroutine_fn)( pull_coroutine< void > &);
363
364     explicit push_coroutine( coroutine_fn,
365                              attributes const& = attributes() );
366
367     template< typename StackAllocator >
368     explicit push_coroutine( coroutine_fn,
369                              attributes const&,
370                              StackAllocator);
371 # endif
372     template< typename Fn >
373     explicit push_coroutine( BOOST_RV_REF( Fn),
374                              attributes const& = attributes() );
375
376     template< typename Fn, typename StackAllocator >
377     explicit push_coroutine( BOOST_RV_REF( Fn),
378                              attributes const&,
379                              StackAllocator);
380 #else
381     template< typename Fn >
382     explicit push_coroutine( Fn,
383                              attributes const& = attributes() );
384
385     template< typename Fn, typename StackAllocator >
386     explicit push_coroutine( Fn,
387                              attributes const&,
388                              StackAllocator);
389
390     template< typename Fn >
391     explicit push_coroutine( BOOST_RV_REF( Fn),
392                              attributes const& = attributes() );
393
394     template< typename Fn, typename StackAllocator >
395     explicit push_coroutine( BOOST_RV_REF( Fn),
396                              attributes const&,
397                              StackAllocator);
398 #endif
399
400     ~push_coroutine()
401     {
402         if ( 0 != impl_)
403         {
404             impl_->destroy();
405             impl_ = 0;
406         }
407     }
408
409     inline push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT :
410         impl_( 0)
411     { swap( other); }
412
413     inline push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT
414     {
415         push_coroutine tmp( boost::move( other) );
416         swap( tmp);
417         return * this;
418     }
419
420     BOOST_EXPLICIT_OPERATOR_BOOL();
421
422     inline bool operator!() const BOOST_NOEXCEPT
423     { return 0 == impl_ || impl_->is_complete(); }
424
425     inline void swap( push_coroutine & other) BOOST_NOEXCEPT
426     { std::swap( impl_, other.impl_); }
427
428     inline push_coroutine & operator()()
429     {
430         BOOST_ASSERT( * this);
431
432         impl_->push();
433         return * this;
434     }
435
436     struct iterator;
437     struct const_iterator;
438 };
439
440
441
442 template< typename R >
443 class pull_coroutine
444 {
445 private:
446     template< typename V, typename X, typename Y, typename Z >
447     friend class detail::push_coroutine_object;
448
449     typedef detail::pull_coroutine_impl< R >            impl_type;
450     typedef detail::pull_coroutine_synthesized< R >     synth_type;
451     typedef detail::parameters< R >                     param_type;
452
453     struct dummy {};
454
455     impl_type       *   impl_;
456
457     BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine)
458
459     explicit pull_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
460         impl_( & impl)
461     { BOOST_ASSERT( impl_); }
462
463 public:
464     pull_coroutine() BOOST_NOEXCEPT :
465         impl_( 0)
466     {}
467
468 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
469 # ifdef BOOST_MSVC
470     typedef void ( * coroutine_fn)( push_coroutine< R > &);
471
472     explicit pull_coroutine( coroutine_fn fn,
473                              attributes const& attrs = attributes() ) :
474         impl_( 0)
475     {
476         // create a stack-context
477         stack_context stack_ctx;
478         stack_allocator stack_alloc;
479         // allocate the coroutine-stack
480         stack_alloc.allocate( stack_ctx, attrs.size);
481         BOOST_ASSERT( 0 != stack_ctx.sp);
482         // typedef of internal coroutine-type
483         typedef detail::pull_coroutine_object<
484             push_coroutine< R >, R, coroutine_fn, stack_allocator
485         >                                                        object_t;
486         // reserve space on top of coroutine-stack for internal coroutine-type
487         std::size_t size = stack_ctx.size - sizeof( object_t);
488         BOOST_ASSERT( 0 != size);
489         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
490         BOOST_ASSERT( 0 != sp);
491         // placement new for internal coroutine
492         impl_ = new ( sp) object_t(
493                 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
494         BOOST_ASSERT( impl_);
495         impl_->pull();
496     }
497
498     template< typename StackAllocator >
499     explicit pull_coroutine( coroutine_fn fn,
500                              attributes const& attrs,
501                              StackAllocator stack_alloc) :
502         impl_( 0)
503     {
504         // create a stack-context
505         stack_context stack_ctx;
506         // allocate the coroutine-stack
507         stack_alloc.allocate( stack_ctx, attrs.size);
508         BOOST_ASSERT( 0 != stack_ctx.sp);
509         // typedef of internal coroutine-type
510         typedef detail::pull_coroutine_object<
511             push_coroutine< R >, R, coroutine_fn, StackAllocator
512         >                                                        object_t;
513         // reserve space on top of coroutine-stack for internal coroutine-type
514         std::size_t size = stack_ctx.size - sizeof( object_t);
515         BOOST_ASSERT( 0 != size);
516         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
517         BOOST_ASSERT( 0 != sp);
518         // placement new for internal coroutine
519         impl_ = new ( sp) object_t(
520                 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
521         BOOST_ASSERT( impl_);
522         impl_->pull();
523     }
524 # endif
525     template< typename Fn >
526     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
527                              attributes const& attrs = attributes() ) :
528         impl_( 0)
529     {
530         // create a stack-context
531         stack_context stack_ctx;
532         stack_allocator stack_alloc;
533         // allocate the coroutine-stack
534         stack_alloc.allocate( stack_ctx, attrs.size);
535         BOOST_ASSERT( 0 != stack_ctx.sp);
536         // typedef of internal coroutine-type
537         typedef detail::pull_coroutine_object<
538             push_coroutine< R >, R, Fn, stack_allocator
539         >                                                        object_t;
540         // reserve space on top of coroutine-stack for internal coroutine-type
541         std::size_t size = stack_ctx.size - sizeof( object_t);
542         BOOST_ASSERT( 0 != size);
543         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
544         BOOST_ASSERT( 0 != sp);
545         // placement new for internal coroutine
546         impl_ = new ( sp) object_t(
547                 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
548         BOOST_ASSERT( impl_);
549         impl_->pull();
550     }
551
552     template< typename Fn, typename StackAllocator >
553     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
554                              attributes const& attrs,
555                              StackAllocator stack_alloc) :
556         impl_( 0)
557     {
558         // create a stack-context
559         stack_context stack_ctx;
560         // allocate the coroutine-stack
561         stack_alloc.allocate( stack_ctx, attrs.size);
562         BOOST_ASSERT( 0 != stack_ctx.sp);
563         // typedef of internal coroutine-type
564         typedef detail::pull_coroutine_object<
565             push_coroutine< R >, R, Fn, StackAllocator
566         >                                                        object_t;
567         // reserve space on top of coroutine-stack for internal coroutine-type
568         std::size_t size = stack_ctx.size - sizeof( object_t);
569         BOOST_ASSERT( 0 != size);
570         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
571         BOOST_ASSERT( 0 != sp);
572         // placement new for internal coroutine
573         impl_ = new ( sp) object_t(
574                 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
575         BOOST_ASSERT( impl_);
576         impl_->pull();
577     }
578 #else
579     template< typename Fn >
580     explicit pull_coroutine( Fn fn,
581                              attributes const& attrs = attributes() ) :
582         impl_( 0)
583     {
584         // create a stack-context
585         stack_context stack_ctx;
586         stack_allocator stack_alloc;
587         // allocate the coroutine-stack
588         stack_alloc.allocate( stack_ctx, attrs.size);
589         BOOST_ASSERT( 0 != stack_ctx.sp);
590         // typedef of internal coroutine-type
591         typedef detail::pull_coroutine_object<
592             push_coroutine< R >, R, Fn, stack_allocator
593         >                                                        object_t;
594         // reserve space on top of coroutine-stack for internal coroutine-type
595         std::size_t size = stack_ctx.size - sizeof( object_t);
596         BOOST_ASSERT( 0 != size);
597         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
598         BOOST_ASSERT( 0 != sp);
599         // placement new for internal coroutine
600         impl_ = new ( sp) object_t(
601                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
602         BOOST_ASSERT( impl_);
603         impl_->pull();
604     }
605
606     template< typename Fn, typename StackAllocator >
607     explicit pull_coroutine( Fn fn,
608                              attributes const& attrs,
609                              StackAllocator stack_alloc) :
610         impl_( 0)
611     {
612         // create a stack-context
613         stack_context stack_ctx;
614         // allocate the coroutine-stack
615         stack_alloc.allocate( stack_ctx, attrs.size);
616         BOOST_ASSERT( 0 != stack_ctx.sp);
617         // typedef of internal coroutine-type
618         typedef detail::pull_coroutine_object<
619             push_coroutine< R >, R, Fn, StackAllocator
620         >                                                        object_t;
621         // reserve space on top of coroutine-stack for internal coroutine-type
622         std::size_t size = stack_ctx.size - sizeof( object_t);
623         BOOST_ASSERT( 0 != size);
624         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
625         BOOST_ASSERT( 0 != sp);
626         // placement new for internal coroutine
627         impl_ = new ( sp) object_t(
628                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
629         BOOST_ASSERT( impl_);
630         impl_->pull();
631     }
632
633     template< typename Fn >
634     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
635                              attributes const& attrs = attributes() ) :
636         impl_( 0)
637     {
638         // create a stack-context
639         stack_context stack_ctx;
640         stack_allocator stack_alloc;
641         // allocate the coroutine-stack
642         stack_alloc.allocate( stack_ctx, attrs.size);
643         BOOST_ASSERT( 0 != stack_ctx.sp);
644         // typedef of internal coroutine-type
645         typedef detail::pull_coroutine_object<
646             push_coroutine< R >, R, Fn, stack_allocator
647         >                                                        object_t;
648         // reserve space on top of coroutine-stack for internal coroutine-type
649         std::size_t size = stack_ctx.size - sizeof( object_t);
650         BOOST_ASSERT( 0 != size);
651         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
652         BOOST_ASSERT( 0 != sp);
653         // placement new for internal coroutine
654         impl_ = new ( sp) object_t(
655                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
656         BOOST_ASSERT( impl_);
657         impl_->pull();
658     }
659
660     template< typename Fn, typename StackAllocator >
661     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
662                              attributes const& attrs,
663                              StackAllocator stack_alloc) :
664         impl_( 0)
665     {
666         // create a stack-context
667         stack_context stack_ctx;
668         // allocate the coroutine-stack
669         stack_alloc.allocate( stack_ctx, attrs.size);
670         BOOST_ASSERT( 0 != stack_ctx.sp);
671         // typedef of internal coroutine-type
672         typedef detail::pull_coroutine_object<
673             push_coroutine< R >, R, Fn, StackAllocator
674         >                                                        object_t;
675         // reserve space on top of coroutine-stack for internal coroutine-type
676         std::size_t size = stack_ctx.size - sizeof( object_t);
677         BOOST_ASSERT( 0 != size);
678         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
679         BOOST_ASSERT( 0 != sp);
680         // placement new for internal coroutine
681         impl_ = new ( sp) object_t(
682                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
683         BOOST_ASSERT( impl_);
684         impl_->pull();
685     }
686 #endif
687
688     ~pull_coroutine()
689     {
690         if ( 0 != impl_)
691         {
692             impl_->destroy();
693             impl_ = 0;
694         }
695     }
696
697     pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT :
698         impl_( 0)
699     { swap( other); }
700
701     pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT
702     {
703         pull_coroutine tmp( boost::move( other) );
704         swap( tmp);
705         return * this;
706     }
707
708     BOOST_EXPLICIT_OPERATOR_BOOL();
709
710     bool operator!() const BOOST_NOEXCEPT
711     { return 0 == impl_ || impl_->is_complete(); }
712
713     void swap( pull_coroutine & other) BOOST_NOEXCEPT
714     { std::swap( impl_, other.impl_); }
715
716     pull_coroutine & operator()()
717     {
718         BOOST_ASSERT( * this);
719
720         impl_->pull();
721         return * this;
722     }
723
724     R get() const
725     {
726         BOOST_ASSERT( 0 != impl_);
727
728         return impl_->get();
729     }
730
731     class iterator
732     {
733     private:
734         pull_coroutine< R > *   c_;
735         R                   *   val_;
736
737         void fetch_()
738         {
739             BOOST_ASSERT( c_);
740
741             if ( ! ( * c_) )
742             {
743                 c_ = 0;
744                 val_ = 0;
745                 return;
746             }
747             val_ = c_->impl_->get_pointer();
748         }
749
750         void increment_()
751         {
752             BOOST_ASSERT( c_);
753             BOOST_ASSERT( * c_);
754
755             ( * c_)();
756             fetch_();
757         }
758
759     public:
760         typedef std::input_iterator_tag iterator_category;
761         typedef typename remove_reference< R >::type value_type;
762         typedef std::ptrdiff_t difference_type;
763         typedef value_type * pointer;
764         typedef value_type & reference;
765
766         typedef pointer   pointer_t;
767         typedef reference reference_t;
768
769         iterator() :
770             c_( 0), val_( 0)
771         {}
772
773         explicit iterator( pull_coroutine< R > * c) :
774             c_( c), val_( 0)
775         { fetch_(); }
776
777         iterator( iterator const& other) :
778             c_( other.c_), val_( other.val_)
779         {}
780
781         iterator & operator=( iterator const& other)
782         {
783             if ( this == & other) return * this;
784             c_ = other.c_;
785             val_ = other.val_;
786             return * this;
787         }
788
789         bool operator==( iterator const& other) const
790         { return other.c_ == c_ && other.val_ == val_; }
791
792         bool operator!=( iterator const& other) const
793         { return other.c_ != c_ || other.val_ != val_; }
794
795         iterator & operator++()
796         {
797             increment_();
798             return * this;
799         }
800
801         iterator operator++( int);
802
803         reference_t operator*() const
804         {
805             if ( ! val_)
806                 boost::throw_exception(
807                     invalid_result() );
808             return * val_;
809         }
810
811         pointer_t operator->() const
812         {
813             if ( ! val_)
814                 boost::throw_exception(
815                     invalid_result() );
816             return val_;
817         }
818     };
819
820     class const_iterator
821     {
822     private:
823         pull_coroutine< R > *   c_;
824         R                   *   val_;
825
826         void fetch_()
827         {
828             BOOST_ASSERT( c_);
829
830             if ( ! ( * c_) )
831             {
832                 c_ = 0;
833                 val_ = 0;
834                 return;
835             }
836             val_ = c_->impl_->get_pointer();
837         }
838
839         void increment_()
840         {
841             BOOST_ASSERT( c_);
842             BOOST_ASSERT( * c_);
843
844             ( * c_)();
845             fetch_();
846         }
847
848     public:
849         typedef std::input_iterator_tag iterator_category;
850         typedef const typename remove_reference< R >::type value_type;
851         typedef std::ptrdiff_t difference_type;
852         typedef value_type * pointer;
853         typedef value_type & reference;
854
855         typedef pointer   pointer_t;
856         typedef reference reference_t;
857
858         const_iterator() :
859             c_( 0), val_( 0)
860         {}
861
862         explicit const_iterator( pull_coroutine< R > const* c) :
863             c_( const_cast< pull_coroutine< R > * >( c) ),
864             val_( 0)
865         { fetch_(); }
866
867         const_iterator( const_iterator const& other) :
868             c_( other.c_), val_( other.val_)
869         {}
870
871         const_iterator & operator=( const_iterator const& other)
872         {
873             if ( this == & other) return * this;
874             c_ = other.c_;
875             val_ = other.val_;
876             return * this;
877         }
878
879         bool operator==( const_iterator const& other) const
880         { return other.c_ == c_ && other.val_ == val_; }
881
882         bool operator!=( const_iterator const& other) const
883         { return other.c_ != c_ || other.val_ != val_; }
884
885         const_iterator & operator++()
886         {
887             increment_();
888             return * this;
889         }
890
891         const_iterator operator++( int);
892
893         reference_t operator*() const
894         {
895             if ( ! val_)
896                 boost::throw_exception(
897                     invalid_result() );
898             return * val_;
899         }
900
901         pointer_t operator->() const
902         {
903             if ( ! val_)
904                 boost::throw_exception(
905                     invalid_result() );
906             return val_;
907         }
908     };
909
910     friend class iterator;
911     friend class const_iterator;
912 };
913
914 template< typename R >
915 class pull_coroutine< R & >
916 {
917 private:
918     template< typename V, typename X, typename Y, typename Z >
919     friend class detail::push_coroutine_object;
920
921     typedef detail::pull_coroutine_impl< R & >            impl_type;
922     typedef detail::pull_coroutine_synthesized< R & >     synth_type;
923     typedef detail::parameters< R & >                     param_type;
924
925     struct dummy {};
926
927     impl_type       *   impl_;
928
929     BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine)
930
931     explicit pull_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
932         impl_( & impl)
933     { BOOST_ASSERT( impl_); }
934
935 public:
936     pull_coroutine() BOOST_NOEXCEPT :
937         impl_( 0)
938     {}
939
940 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
941 # ifdef BOOST_MSVC
942     typedef void ( * coroutine_fn)( push_coroutine< R & > &);
943
944     explicit pull_coroutine( coroutine_fn fn,
945                              attributes const& attrs = attributes() ) :
946         impl_( 0)
947     {
948         // create a stack-context
949         stack_context stack_ctx;
950         stack_allocator stack_alloc;
951         // allocate the coroutine-stack
952         stack_alloc.allocate( stack_ctx, attrs.size);
953         BOOST_ASSERT( 0 != stack_ctx.sp);
954         // typedef of internal coroutine-type
955         typedef detail::pull_coroutine_object<
956             push_coroutine< R & >, R &, coroutine_fn, stack_allocator
957         >                                                        object_t;
958         // reserve space on top of coroutine-stack for internal coroutine-type
959         std::size_t size = stack_ctx.size - sizeof( object_t);
960         BOOST_ASSERT( 0 != size);
961         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
962         BOOST_ASSERT( 0 != sp);
963         // placement new for internal coroutine
964         impl_ = new ( sp) object_t(
965                 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
966         BOOST_ASSERT( impl_);
967         impl_->pull();
968     }
969
970     template< typename StackAllocator >
971     explicit pull_coroutine( coroutine_fn fn,
972                              attributes const& attrs,
973                              StackAllocator stack_alloc) :
974         impl_( 0)
975     {
976         // create a stack-context
977         stack_context stack_ctx;
978         // allocate the coroutine-stack
979         stack_alloc.allocate( stack_ctx, attrs.size);
980         BOOST_ASSERT( 0 != stack_ctx.sp);
981         // typedef of internal coroutine-type
982         typedef detail::pull_coroutine_object<
983             push_coroutine< R & >, R &, coroutine_fn, StackAllocator
984         >                                                        object_t;
985         // reserve space on top of coroutine-stack for internal coroutine-type
986         std::size_t size = stack_ctx.size - sizeof( object_t);
987         BOOST_ASSERT( 0 != size);
988         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
989         BOOST_ASSERT( 0 != sp);
990         // placement new for internal coroutine
991         impl_ = new ( sp) object_t(
992                 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
993         BOOST_ASSERT( impl_);
994         impl_->pull();
995     }
996 # endif
997     template< typename Fn >
998     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
999                              attributes const& attrs = attributes() ) :
1000         impl_( 0)
1001     {
1002         // create a stack-context
1003         stack_context stack_ctx;
1004         stack_allocator stack_alloc;
1005         // allocate the coroutine-stack
1006         stack_alloc.allocate( stack_ctx, attrs.size);
1007         BOOST_ASSERT( 0 != stack_ctx.sp);
1008         // typedef of internal coroutine-type
1009         typedef detail::pull_coroutine_object<
1010             push_coroutine< R & >, R &, Fn, stack_allocator
1011         >                                                        object_t;
1012         // reserve space on top of coroutine-stack for internal coroutine-type
1013         std::size_t size = stack_ctx.size - sizeof( object_t);
1014         BOOST_ASSERT( 0 != size);
1015         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1016         BOOST_ASSERT( 0 != sp);
1017         // placement new for internal coroutine
1018         impl_ = new ( sp) object_t(
1019                 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1020         BOOST_ASSERT( impl_);
1021         impl_->pull();
1022     }
1023
1024     template< typename Fn, typename StackAllocator >
1025     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1026                              attributes const& attrs,
1027                              StackAllocator stack_alloc) :
1028         impl_( 0)
1029     {
1030         // create a stack-context
1031         stack_context stack_ctx;
1032         // allocate the coroutine-stack
1033         stack_alloc.allocate( stack_ctx, attrs.size);
1034         BOOST_ASSERT( 0 != stack_ctx.sp);
1035         // typedef of internal coroutine-type
1036         typedef detail::pull_coroutine_object<
1037             push_coroutine< R & >, R &, Fn, StackAllocator
1038         >                                                        object_t;
1039         // reserve space on top of coroutine-stack for internal coroutine-type
1040         std::size_t size = stack_ctx.size - sizeof( object_t);
1041         BOOST_ASSERT( 0 != size);
1042         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1043         BOOST_ASSERT( 0 != sp);
1044         // placement new for internal coroutine
1045         impl_ = new ( sp) object_t(
1046                 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1047         BOOST_ASSERT( impl_);
1048         impl_->pull();
1049     }
1050 #else
1051     template< typename Fn >
1052     explicit pull_coroutine( Fn fn,
1053                              attributes const& attrs = attributes() ) :
1054         impl_( 0)
1055     {
1056         // create a stack-context
1057         stack_context stack_ctx;
1058         stack_allocator stack_alloc;
1059         // allocate the coroutine-stack
1060         stack_alloc.allocate( stack_ctx, attrs.size);
1061         BOOST_ASSERT( 0 != stack_ctx.sp);
1062         // typedef of internal coroutine-type
1063         typedef detail::pull_coroutine_object<
1064             push_coroutine< R & >, R &, Fn, stack_allocator
1065         >                                                        object_t;
1066         // reserve space on top of coroutine-stack for internal coroutine-type
1067         std::size_t size = stack_ctx.size - sizeof( object_t);
1068         BOOST_ASSERT( 0 != size);
1069         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1070         BOOST_ASSERT( 0 != sp);
1071         // placement new for internal coroutine
1072         impl_ = new ( sp) object_t(
1073                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1074         BOOST_ASSERT( impl_);
1075         impl_->pull();
1076     }
1077
1078     template< typename Fn, typename StackAllocator >
1079     explicit pull_coroutine( Fn fn,
1080                              attributes const& attrs,
1081                              StackAllocator stack_alloc) :
1082         impl_( 0)
1083     {
1084         // create a stack-context
1085         stack_context stack_ctx;
1086         // allocate the coroutine-stack
1087         stack_alloc.allocate( stack_ctx, attrs.size);
1088         BOOST_ASSERT( 0 != stack_ctx.sp);
1089         // typedef of internal coroutine-type
1090         typedef detail::pull_coroutine_object<
1091             push_coroutine< R & >, R &, Fn, StackAllocator
1092         >                                                        object_t;
1093         // reserve space on top of coroutine-stack for internal coroutine-type
1094         std::size_t size = stack_ctx.size - sizeof( object_t);
1095         BOOST_ASSERT( 0 != size);
1096         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1097         BOOST_ASSERT( 0 != sp);
1098         // placement new for internal coroutine
1099         impl_ = new ( sp) object_t(
1100                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1101         BOOST_ASSERT( impl_);
1102         impl_->pull();
1103     }
1104
1105     template< typename Fn >
1106     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1107                              attributes const& attrs = attributes() ) :
1108         impl_( 0)
1109     {
1110         // create a stack-context
1111         stack_context stack_ctx;
1112         stack_allocator stack_alloc;
1113         // allocate the coroutine-stack
1114         stack_alloc.allocate( stack_ctx, attrs.size);
1115         BOOST_ASSERT( 0 != stack_ctx.sp);
1116         // typedef of internal coroutine-type
1117         typedef detail::pull_coroutine_object<
1118             push_coroutine< R & >, R &, Fn, stack_allocator
1119         >                                                        object_t;
1120         // reserve space on top of coroutine-stack for internal coroutine-type
1121         std::size_t size = stack_ctx.size - sizeof( object_t);
1122         BOOST_ASSERT( 0 != size);
1123         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1124         BOOST_ASSERT( 0 != sp);
1125         // placement new for internal coroutine
1126         impl_ = new ( sp) object_t(
1127                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1128         BOOST_ASSERT( impl_);
1129         impl_->pull();
1130     }
1131
1132     template< typename Fn, typename StackAllocator >
1133     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1134                              attributes const& attrs,
1135                              StackAllocator stack_alloc) :
1136         impl_( 0)
1137     {
1138         // create a stack-context
1139         stack_context stack_ctx;
1140         // allocate the coroutine-stack
1141         stack_alloc.allocate( stack_ctx, attrs.size);
1142         BOOST_ASSERT( 0 != stack_ctx.sp);
1143         // typedef of internal coroutine-type
1144         typedef detail::pull_coroutine_object<
1145             push_coroutine< R & >, R &, Fn, StackAllocator
1146         >                                                        object_t;
1147         // reserve space on top of coroutine-stack for internal coroutine-type
1148         std::size_t size = stack_ctx.size - sizeof( object_t);
1149         BOOST_ASSERT( 0 != size);
1150         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1151         BOOST_ASSERT( 0 != sp);
1152         // placement new for internal coroutine
1153         impl_ = new ( sp) object_t(
1154                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1155         BOOST_ASSERT( impl_);
1156         impl_->pull();
1157     }
1158 #endif
1159
1160     ~pull_coroutine()
1161     {
1162         if ( 0 != impl_)
1163         {
1164             impl_->destroy();
1165             impl_ = 0;
1166         }
1167     }
1168
1169     pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT :
1170         impl_( 0)
1171     { swap( other); }
1172
1173     pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT
1174     {
1175         pull_coroutine tmp( boost::move( other) );
1176         swap( tmp);
1177         return * this;
1178     }
1179
1180     BOOST_EXPLICIT_OPERATOR_BOOL();
1181
1182     bool operator!() const BOOST_NOEXCEPT
1183     { return 0 == impl_ || impl_->is_complete(); }
1184
1185     void swap( pull_coroutine & other) BOOST_NOEXCEPT
1186     { std::swap( impl_, other.impl_); }
1187
1188     pull_coroutine & operator()()
1189     {
1190         BOOST_ASSERT( * this);
1191
1192         impl_->pull();
1193         return * this;
1194     }
1195
1196     R & get() const
1197     { return impl_->get(); }
1198
1199     class iterator
1200     {
1201     private:
1202         pull_coroutine< R & >   *   c_;
1203         R                       *   val_;
1204
1205         void fetch_()
1206         {
1207             BOOST_ASSERT( c_);
1208
1209             if ( ! ( * c_) )
1210             {
1211                 c_ = 0;
1212                 val_ = 0;
1213                 return;
1214             }
1215             val_ = c_->impl_->get_pointer();
1216         }
1217
1218         void increment_()
1219         {
1220             BOOST_ASSERT( c_);
1221             BOOST_ASSERT( * c_);
1222
1223             ( * c_)();
1224             fetch_();
1225         }
1226
1227     public:
1228         typedef std::input_iterator_tag iterator_category;
1229         typedef typename remove_reference< R >::type value_type;
1230         typedef std::ptrdiff_t difference_type;
1231         typedef value_type * pointer;
1232         typedef value_type & reference;
1233
1234         typedef pointer   pointer_t;
1235         typedef reference reference_t;
1236
1237         iterator() :
1238             c_( 0), val_( 0)
1239         {}
1240
1241         explicit iterator( pull_coroutine< R & > * c) :
1242             c_( c), val_( 0)
1243         { fetch_(); }
1244
1245         iterator( iterator const& other) :
1246             c_( other.c_), val_( other.val_)
1247         {}
1248
1249         iterator & operator=( iterator const& other)
1250         {
1251             if ( this == & other) return * this;
1252             c_ = other.c_;
1253             val_ = other.val_;
1254             return * this;
1255         }
1256
1257         bool operator==( iterator const& other) const
1258         { return other.c_ == c_ && other.val_ == val_; }
1259
1260         bool operator!=( iterator const& other) const
1261         { return other.c_ != c_ || other.val_ != val_; }
1262
1263         iterator & operator++()
1264         {
1265             increment_();
1266             return * this;
1267         }
1268
1269         iterator operator++( int);
1270
1271         reference_t operator*() const
1272         {
1273             if ( ! val_)
1274                 boost::throw_exception(
1275                     invalid_result() );
1276             return * val_;
1277         }
1278
1279         pointer_t operator->() const
1280         {
1281             if ( ! val_)
1282                 boost::throw_exception(
1283                     invalid_result() );
1284             return val_;
1285         }
1286     };
1287
1288     class const_iterator
1289     {
1290     private:
1291         pull_coroutine< R & >   *   c_;
1292         R                       *   val_;
1293
1294         void fetch_()
1295         {
1296             BOOST_ASSERT( c_);
1297
1298             if ( ! ( * c_) )
1299             {
1300                 c_ = 0;
1301                 val_ = 0;
1302                 return;
1303             }
1304             val_ = c_->impl_->get_pointer();
1305         }
1306
1307         void increment_()
1308         {
1309             BOOST_ASSERT( c_);
1310             BOOST_ASSERT( * c_);
1311
1312             ( * c_)();
1313             fetch_();
1314         }
1315
1316     public:
1317         typedef std::input_iterator_tag iterator_category;
1318         typedef const typename remove_reference< R >::type value_type;
1319         typedef std::ptrdiff_t difference_type;
1320         typedef value_type * pointer;
1321         typedef value_type & reference;
1322
1323         typedef pointer   pointer_t;
1324         typedef reference reference_t;
1325
1326         const_iterator() :
1327             c_( 0), val_( 0)
1328         {}
1329
1330         explicit const_iterator( pull_coroutine< R & > const* c) :
1331             c_( const_cast< pull_coroutine< R & > * >( c) ),
1332             val_( 0)
1333         { fetch_(); }
1334
1335         const_iterator( const_iterator const& other) :
1336             c_( other.c_), val_( other.val_)
1337         {}
1338
1339         const_iterator & operator=( const_iterator const& other)
1340         {
1341             if ( this == & other) return * this;
1342             c_ = other.c_;
1343             val_ = other.val_;
1344             return * this;
1345         }
1346
1347         bool operator==( const_iterator const& other) const
1348         { return other.c_ == c_ && other.val_ == val_; }
1349
1350         bool operator!=( const_iterator const& other) const
1351         { return other.c_ != c_ || other.val_ != val_; }
1352
1353         const_iterator & operator++()
1354         {
1355             increment_();
1356             return * this;
1357         }
1358
1359         const_iterator operator++( int);
1360
1361         reference_t operator*() const
1362         {
1363             if ( ! val_)
1364                 boost::throw_exception(
1365                     invalid_result() );
1366             return * val_;
1367         }
1368
1369         pointer_t operator->() const
1370         {
1371             if ( ! val_)
1372                 boost::throw_exception(
1373                     invalid_result() );
1374             return val_;
1375         }
1376     };
1377
1378     friend class iterator;
1379     friend class const_iterator;
1380 };
1381
1382 template<>
1383 class pull_coroutine< void >
1384 {
1385 private:
1386     template< typename V, typename X, typename Y, typename Z >
1387     friend class detail::push_coroutine_object;
1388
1389     typedef detail::pull_coroutine_impl< void >            impl_type;
1390     typedef detail::pull_coroutine_synthesized< void >     synth_type;
1391     typedef detail::parameters< void >                     param_type;
1392
1393     struct dummy {};
1394
1395     impl_type       *   impl_;
1396
1397     BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine)
1398
1399     explicit pull_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
1400         impl_( & impl)
1401     { BOOST_ASSERT( impl_); }
1402
1403 public:
1404     pull_coroutine() BOOST_NOEXCEPT :
1405         impl_( 0)
1406     {}
1407
1408 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1409 # ifdef BOOST_MSVC
1410     typedef void ( * coroutine_fn)( push_coroutine< void > &);
1411
1412     explicit pull_coroutine( coroutine_fn fn,
1413                              attributes const& attrs = attributes() ) :
1414         impl_( 0)
1415     {
1416         // create a stack-context
1417         stack_context stack_ctx;
1418         stack_allocator stack_alloc;
1419         // allocate the coroutine-stack
1420         stack_alloc.allocate( stack_ctx, attrs.size);
1421         BOOST_ASSERT( 0 != stack_ctx.sp);
1422         // typedef of internal coroutine-type
1423         typedef detail::pull_coroutine_object<
1424             push_coroutine< void >, void, coroutine_fn, stack_allocator
1425         >                                       object_t;
1426         // reserve space on top of coroutine-stack for internal coroutine-type
1427         std::size_t size = stack_ctx.size - sizeof( object_t);
1428         BOOST_ASSERT( 0 != size);
1429         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1430         BOOST_ASSERT( 0 != sp);
1431         // placement new for internal coroutine
1432         impl_ = new ( sp) object_t(
1433                 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1434         BOOST_ASSERT( impl_);
1435         impl_->pull();
1436     }
1437
1438     template< typename StackAllocator >
1439     explicit pull_coroutine( coroutine_fn fn,
1440                              attributes const& attrs,
1441                              StackAllocator stack_alloc) :
1442         impl_( 0)
1443     {
1444         // create a stack-context
1445         stack_context stack_ctx;
1446         // allocate the coroutine-stack
1447         stack_alloc.allocate( stack_ctx, attrs.size);
1448         BOOST_ASSERT( 0 != stack_ctx.sp);
1449         // typedef of internal coroutine-type
1450         typedef detail::pull_coroutine_object<
1451             push_coroutine< void >, void, coroutine_fn, StackAllocator
1452         >                                                                   object_t;
1453         // reserve space on top of coroutine-stack for internal coroutine-type
1454         std::size_t size = stack_ctx.size - sizeof( object_t);
1455         BOOST_ASSERT( 0 != size);
1456         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1457         BOOST_ASSERT( 0 != sp);
1458         // placement new for internal coroutine
1459         impl_ = new ( sp) object_t(
1460                 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1461         BOOST_ASSERT( impl_);
1462         impl_->pull();
1463     }
1464 # endif
1465     template< typename Fn >
1466     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1467                              attributes const& attrs = attributes() ) :
1468         impl_( 0)
1469     {
1470         // create a stack-context
1471         stack_context stack_ctx;
1472         stack_allocator stack_alloc;
1473         // allocate the coroutine-stack
1474         stack_alloc.allocate( stack_ctx, attrs.size);
1475         BOOST_ASSERT( 0 != stack_ctx.sp);
1476         // typedef of internal coroutine-type
1477         typedef detail::pull_coroutine_object<
1478             push_coroutine< void >, void, Fn, stack_allocator
1479         >                                                       object_t;
1480         // reserve space on top of coroutine-stack for internal coroutine-type
1481         std::size_t size = stack_ctx.size - sizeof( object_t);
1482         BOOST_ASSERT( 0 != size);
1483         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1484         BOOST_ASSERT( 0 != sp);
1485         // placement new for internal coroutine
1486         impl_ = new ( sp) object_t(
1487                 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1488         BOOST_ASSERT( impl_);
1489         impl_->pull();
1490     }
1491
1492     template< typename Fn, typename StackAllocator >
1493     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1494                              attributes const& attrs,
1495                              StackAllocator stack_alloc) :
1496         impl_( 0)
1497     {
1498         // create a stack-context
1499         stack_context stack_ctx;
1500         // allocate the coroutine-stack
1501         stack_alloc.allocate( stack_ctx, attrs.size);
1502         BOOST_ASSERT( 0 != stack_ctx.sp);
1503         // typedef of internal coroutine-type
1504         typedef detail::pull_coroutine_object<
1505             push_coroutine< void >, void, Fn, StackAllocator
1506         >                                                       object_t;
1507         // reserve space on top of coroutine-stack for internal coroutine-type
1508         std::size_t size = stack_ctx.size - sizeof( object_t);
1509         BOOST_ASSERT( 0 != size);
1510         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1511         BOOST_ASSERT( 0 != sp);
1512         // placement new for internal coroutine
1513         impl_ = new ( sp) object_t(
1514                 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1515         BOOST_ASSERT( impl_);
1516         impl_->pull();
1517     }
1518 #else
1519     template< typename Fn >
1520     explicit pull_coroutine( Fn fn,
1521                              attributes const& attrs = attributes() ) :
1522         impl_( 0)
1523     {
1524         // create a stack-context
1525         stack_context stack_ctx;
1526         stack_allocator stack_alloc;
1527         // allocate the coroutine-stack
1528         stack_alloc.allocate( stack_ctx, attrs.size);
1529         BOOST_ASSERT( 0 != stack_ctx.sp);
1530         // typedef of internal coroutine-type
1531         typedef detail::pull_coroutine_object<
1532             push_coroutine< void >, void, Fn, stack_allocator
1533         >                                                       object_t;
1534         // reserve space on top of coroutine-stack for internal coroutine-type
1535         std::size_t size = stack_ctx.size - sizeof( object_t);
1536         BOOST_ASSERT( 0 != size);
1537         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1538         BOOST_ASSERT( 0 != sp);
1539         // placement new for internal coroutine
1540         impl_ = new ( sp) object_t(
1541                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1542         BOOST_ASSERT( impl_);
1543         impl_->pull();
1544     }
1545
1546     template< typename Fn, typename StackAllocator >
1547     explicit pull_coroutine( Fn fn,
1548                              attributes const& attrs,
1549                              StackAllocator stack_alloc) :
1550         impl_( 0)
1551     {
1552         // create a stack-context
1553         stack_context stack_ctx;
1554         // allocate the coroutine-stack
1555         stack_alloc.allocate( stack_ctx, attrs.size);
1556         BOOST_ASSERT( 0 != stack_ctx.sp);
1557         // typedef of internal coroutine-type
1558         typedef detail::pull_coroutine_object<
1559             push_coroutine< void >, void, Fn, StackAllocator
1560         >                                                       object_t;
1561         // reserve space on top of coroutine-stack for internal coroutine-type
1562         std::size_t size = stack_ctx.size - sizeof( object_t);
1563         BOOST_ASSERT( 0 != size);
1564         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1565         BOOST_ASSERT( 0 != sp);
1566         // placement new for internal coroutine
1567         impl_ = new ( sp) object_t(
1568                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1569         BOOST_ASSERT( impl_);
1570         impl_->pull();
1571     }
1572
1573     template< typename Fn >
1574     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1575                              attributes const& attrs = attributes() ) :
1576         impl_( 0)
1577     {
1578         // create a stack-context
1579         stack_context stack_ctx;
1580         stack_allocator stack_alloc;
1581         // allocate the coroutine-stack
1582         stack_alloc.allocate( stack_ctx, attrs.size);
1583         BOOST_ASSERT( 0 != stack_ctx.sp);
1584         // typedef of internal coroutine-type
1585         typedef detail::pull_coroutine_object<
1586             push_coroutine< void >, void, Fn, stack_allocator
1587         >                                           object_t;
1588         // reserve space on top of coroutine-stack for internal coroutine-type
1589         std::size_t size = stack_ctx.size - sizeof( object_t);
1590         BOOST_ASSERT( 0 != size);
1591         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1592         BOOST_ASSERT( 0 != sp);
1593         // placement new for internal coroutine
1594         impl_ = new ( sp) object_t(
1595                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1596         BOOST_ASSERT( impl_);
1597         impl_->pull();
1598     }
1599
1600     template< typename Fn, typename StackAllocator >
1601     explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1602                              attributes const& attrs,
1603                              StackAllocator stack_alloc) :
1604         impl_( 0)
1605     {
1606         // create a stack-context
1607         stack_context stack_ctx;
1608         // allocate the coroutine-stack
1609         stack_alloc.allocate( stack_ctx, attrs.size);
1610         BOOST_ASSERT( 0 != stack_ctx.sp);
1611         // typedef of internal coroutine-type
1612         typedef detail::pull_coroutine_object<
1613             push_coroutine< void >, void, Fn, StackAllocator
1614         >                                           object_t;
1615         // reserve space on top of coroutine-stack for internal coroutine-type
1616         std::size_t size = stack_ctx.size - sizeof( object_t);
1617         BOOST_ASSERT( 0 != size);
1618         void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1619         BOOST_ASSERT( 0 != sp);
1620         // placement new for internal coroutine
1621         impl_ = new ( sp) object_t(
1622                 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1623         BOOST_ASSERT( impl_);
1624         impl_->pull();
1625     }
1626 #endif
1627
1628     ~pull_coroutine()
1629     {
1630         if ( 0 != impl_)
1631         {
1632             impl_->destroy();
1633             impl_ = 0;
1634         }
1635     }
1636
1637     inline pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT :
1638         impl_( 0)
1639     { swap( other); }
1640
1641     inline pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT
1642     {
1643         pull_coroutine tmp( boost::move( other) );
1644         swap( tmp);
1645         return * this;
1646     }
1647
1648     BOOST_EXPLICIT_OPERATOR_BOOL();
1649
1650     inline bool operator!() const BOOST_NOEXCEPT
1651     { return 0 == impl_ || impl_->is_complete(); }
1652
1653     inline void swap( pull_coroutine & other) BOOST_NOEXCEPT
1654     { std::swap( impl_, other.impl_); }
1655
1656     inline pull_coroutine & operator()()
1657     {
1658         BOOST_ASSERT( * this);
1659
1660         impl_->pull();
1661         return * this;
1662     }
1663
1664     struct iterator;
1665     struct const_iterator;
1666 };
1667
1668 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1669 # ifdef BOOST_MSVC
1670 template< typename Arg >
1671 push_coroutine< Arg >::push_coroutine( coroutine_fn fn,
1672                                        attributes const& attrs) :
1673     impl_( 0)
1674 {
1675     // create a stack-context
1676     stack_context stack_ctx;
1677     stack_allocator stack_alloc;
1678     // allocate the coroutine-stack
1679     stack_alloc.allocate( stack_ctx, attrs.size);
1680     BOOST_ASSERT( 0 != stack_ctx.sp);
1681     // typedef of internal coroutine-type
1682     typedef detail::push_coroutine_object<
1683         pull_coroutine< Arg >, Arg, coroutine_fn, stack_allocator
1684     >                                                            object_t;
1685     // reserve space on top of coroutine-stack for internal coroutine-type
1686     std::size_t size = stack_ctx.size - sizeof( object_t);
1687     BOOST_ASSERT( 0 != size);
1688     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1689     BOOST_ASSERT( 0 != sp);
1690     // placement new for internal coroutine
1691     impl_ = new ( sp) object_t(
1692             boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1693     BOOST_ASSERT( impl_);
1694 }
1695
1696 template< typename Arg >
1697 template< typename StackAllocator >
1698 push_coroutine< Arg >::push_coroutine( coroutine_fn fn,
1699                                        attributes const& attrs,
1700                                        StackAllocator stack_alloc) :
1701     impl_( 0)
1702 {
1703     // create a stack-context
1704     stack_context stack_ctx;
1705     // allocate the coroutine-stack
1706     stack_alloc.allocate( stack_ctx, attrs.size);
1707     BOOST_ASSERT( 0 != stack_ctx.sp);
1708     // typedef of internal coroutine-type
1709     typedef detail::push_coroutine_object<
1710         pull_coroutine< Arg >, Arg, coroutine_fn, StackAllocator
1711     >                                                            object_t;
1712     // reserve space on top of coroutine-stack for internal coroutine-type
1713     std::size_t size = stack_ctx.size - sizeof( object_t);
1714     BOOST_ASSERT( 0 != size);
1715     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1716     BOOST_ASSERT( 0 != sp);
1717     // placement new for internal coroutine
1718     impl_ = new ( sp) object_t(
1719             boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1720     BOOST_ASSERT( impl_);
1721 }
1722
1723 template< typename Arg >
1724 push_coroutine< Arg & >::push_coroutine( coroutine_fn fn,
1725                                          attributes const& attrs) :
1726     impl_( 0)
1727 {
1728     // create a stack-context
1729     stack_context stack_ctx;
1730     stack_allocator stack_alloc;
1731     // allocate the coroutine-stack
1732     stack_alloc.allocate( stack_ctx, attrs.size);
1733     BOOST_ASSERT( 0 != stack_ctx.sp);
1734     // typedef of internal coroutine-type
1735     typedef detail::push_coroutine_object<
1736         pull_coroutine< Arg & >, Arg &, coroutine_fn, stack_allocator
1737     >                                                            object_t;
1738     // reserve space on top of coroutine-stack for internal coroutine-type
1739     std::size_t size = stack_ctx.size - sizeof( object_t);
1740     BOOST_ASSERT( 0 != size);
1741     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1742     BOOST_ASSERT( 0 != sp);
1743     // placement new for internal coroutine
1744     impl_ = new ( sp) object_t(
1745             boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1746     BOOST_ASSERT( impl_);
1747 }
1748
1749 template< typename Arg >
1750 template< typename StackAllocator >
1751 push_coroutine< Arg & >::push_coroutine( coroutine_fn fn,
1752                                          attributes const& attrs,
1753                                          StackAllocator stack_alloc) :
1754     impl_( 0)
1755 {
1756     // create a stack-context
1757     stack_context stack_ctx;
1758     // allocate the coroutine-stack
1759     stack_alloc.allocate( stack_ctx, attrs.size);
1760     BOOST_ASSERT( 0 != stack_ctx.sp);
1761     // typedef of internal coroutine-type
1762     typedef detail::push_coroutine_object<
1763         pull_coroutine< Arg & >, Arg &, coroutine_fn, StackAllocator
1764     >                                                            object_t;
1765     // reserve space on top of coroutine-stack for internal coroutine-type
1766     std::size_t size = stack_ctx.size - sizeof( object_t);
1767     BOOST_ASSERT( 0 != size);
1768     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1769     BOOST_ASSERT( 0 != sp);
1770     // placement new for internal coroutine
1771     impl_ = new ( sp) object_t(
1772             boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1773     BOOST_ASSERT( impl_);
1774 }
1775
1776 inline push_coroutine< void >::push_coroutine( coroutine_fn fn,
1777                                                attributes const& attrs) :
1778     impl_( 0)
1779 {
1780     // create a stack-context
1781     stack_context stack_ctx;
1782     stack_allocator stack_alloc;
1783     // allocate the coroutine-stack
1784     stack_alloc.allocate( stack_ctx, attrs.size);
1785     BOOST_ASSERT( 0 != stack_ctx.sp);
1786     // typedef of internal coroutine-type
1787     typedef detail::push_coroutine_object<
1788         pull_coroutine< void >, void, coroutine_fn, stack_allocator
1789     >                                                               object_t;
1790     // reserve space on top of coroutine-stack for internal coroutine-type
1791     std::size_t size = stack_ctx.size - sizeof( object_t);
1792     BOOST_ASSERT( 0 != size);
1793     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1794     BOOST_ASSERT( 0 != sp);
1795     // placement new for internal coroutine
1796     impl_ = new ( sp) object_t(
1797             boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1798     BOOST_ASSERT( impl_);
1799 }
1800
1801 template< typename StackAllocator >
1802 push_coroutine< void >::push_coroutine( coroutine_fn fn,
1803                                         attributes const& attrs,
1804                                         StackAllocator stack_alloc) :
1805     impl_( 0)
1806 {
1807     // create a stack-context
1808     stack_context stack_ctx;
1809     // allocate the coroutine-stack
1810     stack_alloc.allocate( stack_ctx, attrs.size);
1811     BOOST_ASSERT( 0 != stack_ctx.sp);
1812     // typedef of internal coroutine-type
1813     typedef detail::push_coroutine_object<
1814         pull_coroutine< void >, void, coroutine_fn, StackAllocator
1815     >                                                               object_t;
1816     // reserve space on top of coroutine-stack for internal coroutine-type
1817     std::size_t size = stack_ctx.size - sizeof( object_t);
1818     BOOST_ASSERT( 0 != size);
1819     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1820     BOOST_ASSERT( 0 != sp);
1821     // placement new for internal coroutine
1822     impl_ = new ( sp) object_t(
1823             boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1824     BOOST_ASSERT( impl_);
1825 }
1826 # endif
1827 template< typename Arg >
1828 template< typename Fn >
1829 push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
1830                                        attributes const& attrs) :
1831     impl_( 0)
1832 {
1833     // create a stack-context
1834     stack_context stack_ctx;
1835     stack_allocator stack_alloc;
1836     // allocate the coroutine-stack
1837     stack_alloc.allocate( stack_ctx, attrs.size);
1838     BOOST_ASSERT( 0 != stack_ctx.sp);
1839     // typedef of internal coroutine-type
1840     typedef detail::push_coroutine_object<
1841         pull_coroutine< Arg >, Arg, Fn, stack_allocator
1842     >                                                    object_t;
1843     // reserve space on top of coroutine-stack for internal coroutine-type
1844     std::size_t size = stack_ctx.size - sizeof( object_t);
1845     BOOST_ASSERT( 0 != size);
1846     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1847     BOOST_ASSERT( 0 != sp);
1848     // placement new for internal coroutine
1849     impl_ = new ( sp) object_t(
1850             boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1851     BOOST_ASSERT( impl_);
1852 }
1853
1854 template< typename Arg >
1855 template< typename Fn, typename StackAllocator >
1856 push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
1857                                        attributes const& attrs,
1858                                        StackAllocator stack_alloc) :
1859     impl_( 0)
1860 {
1861     // create a stack-context
1862     stack_context stack_ctx;
1863     // allocate the coroutine-stack
1864     stack_alloc.allocate( stack_ctx, attrs.size);
1865     BOOST_ASSERT( 0 != stack_ctx.sp);
1866     // typedef of internal coroutine-type
1867     typedef detail::push_coroutine_object<
1868         pull_coroutine< Arg >, Arg, Fn, StackAllocator
1869     >                                                    object_t;
1870     // reserve space on top of coroutine-stack for internal coroutine-type
1871     std::size_t size = stack_ctx.size - sizeof( object_t);
1872     BOOST_ASSERT( 0 != size);
1873     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1874     BOOST_ASSERT( 0 != sp);
1875     // placement new for internal coroutine
1876     impl_ = new ( sp) object_t(
1877             boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1878     BOOST_ASSERT( impl_);
1879 }
1880
1881 template< typename Arg >
1882 template< typename Fn >
1883 push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
1884                                          attributes const& attrs) :
1885     impl_( 0)
1886 {
1887     // create a stack-context
1888     stack_context stack_ctx;
1889     stack_allocator stack_alloc;
1890     // allocate the coroutine-stack
1891     stack_alloc.allocate( stack_ctx, attrs.size);
1892     BOOST_ASSERT( 0 != stack_ctx.sp);
1893     // typedef of internal coroutine-type
1894     typedef detail::push_coroutine_object<
1895         pull_coroutine< Arg & >, Arg &, Fn, stack_allocator
1896     >                                                            object_t;
1897     // reserve space on top of coroutine-stack for internal coroutine-type
1898     std::size_t size = stack_ctx.size - sizeof( object_t);
1899     BOOST_ASSERT( 0 != size);
1900     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1901     BOOST_ASSERT( 0 != sp);
1902     // placement new for internal coroutine
1903     impl_ = new ( sp) object_t(
1904             boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1905     BOOST_ASSERT( impl_);
1906 }
1907
1908 template< typename Arg >
1909 template< typename Fn, typename StackAllocator >
1910 push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
1911                                          attributes const& attrs,
1912                                          StackAllocator stack_alloc) :
1913     impl_( 0)
1914 {
1915     // create a stack-context
1916     stack_context stack_ctx;
1917     // allocate the coroutine-stack
1918     stack_alloc.allocate( stack_ctx, attrs.size);
1919     BOOST_ASSERT( 0 != stack_ctx.sp);
1920     // typedef of internal coroutine-type
1921     typedef detail::push_coroutine_object<
1922         pull_coroutine< Arg & >, Arg &, Fn, StackAllocator
1923     >                                                            object_t;
1924     // reserve space on top of coroutine-stack for internal coroutine-type
1925     std::size_t size = stack_ctx.size - sizeof( object_t);
1926     BOOST_ASSERT( 0 != size);
1927     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1928     BOOST_ASSERT( 0 != sp);
1929     // placement new for internal coroutine
1930     impl_ = new ( sp) object_t(
1931             boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1932     BOOST_ASSERT( impl_);
1933 }
1934
1935 template< typename Fn >
1936 push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
1937                                         attributes const& attrs) :
1938     impl_( 0)
1939 {
1940     // create a stack-context
1941     stack_context stack_ctx;
1942     stack_allocator stack_alloc;
1943     // allocate the coroutine-stack
1944     stack_alloc.allocate( stack_ctx, attrs.size);
1945     BOOST_ASSERT( 0 != stack_ctx.sp);
1946     // typedef of internal coroutine-type
1947     typedef detail::push_coroutine_object<
1948         pull_coroutine< void >, void, Fn, stack_allocator
1949     >                                                            object_t;
1950     // reserve space on top of coroutine-stack for internal coroutine-type
1951     std::size_t size = stack_ctx.size - sizeof( object_t);
1952     BOOST_ASSERT( 0 != size);
1953     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1954     BOOST_ASSERT( 0 != sp);
1955     // placement new for internal coroutine
1956     impl_ = new ( sp) object_t(
1957             boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1958     BOOST_ASSERT( impl_);
1959 }
1960
1961 template< typename Fn, typename StackAllocator >
1962 push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
1963                                         attributes const& attrs,
1964                                         StackAllocator stack_alloc) :
1965     impl_( 0)
1966 {
1967     // create a stack-context
1968     stack_context stack_ctx;
1969     // allocate the coroutine-stack
1970     stack_alloc.allocate( stack_ctx, attrs.size);
1971     BOOST_ASSERT( 0 != stack_ctx.sp);
1972     // typedef of internal coroutine-type
1973     typedef detail::push_coroutine_object<
1974         pull_coroutine< void >, void, Fn, StackAllocator
1975     >                                                            object_t;
1976     // reserve space on top of coroutine-stack for internal coroutine-type
1977     std::size_t size = stack_ctx.size - sizeof( object_t);
1978     BOOST_ASSERT( 0 != size);
1979     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1980     BOOST_ASSERT( 0 != sp);
1981     // placement new for internal coroutine
1982     impl_ = new ( sp) object_t(
1983             boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
1984     BOOST_ASSERT( impl_);
1985 }
1986 #else
1987 template< typename Arg >
1988 template< typename Fn >
1989 push_coroutine< Arg >::push_coroutine( Fn fn,
1990                                        attributes const& attrs) :
1991     impl_( 0)
1992 {
1993     // create a stack-context
1994     stack_context stack_ctx;
1995     stack_allocator stack_alloc;
1996     // allocate the coroutine-stack
1997     stack_alloc.allocate( stack_ctx, attrs.size);
1998     BOOST_ASSERT( 0 != stack_ctx.sp);
1999     // typedef of internal coroutine-type
2000     typedef detail::push_coroutine_object<
2001         pull_coroutine< Arg >, Arg, Fn, stack_allocator
2002     >                                                    object_t;
2003     // reserve space on top of coroutine-stack for internal coroutine-type
2004     std::size_t size = stack_ctx.size - sizeof( object_t);
2005     BOOST_ASSERT( 0 != size);
2006     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2007     BOOST_ASSERT( 0 != sp);
2008     // placement new for internal coroutine
2009     impl_ = new ( sp) object_t(
2010             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
2011     BOOST_ASSERT( impl_);
2012 }
2013
2014 template< typename Arg >
2015 template< typename Fn, typename StackAllocator >
2016 push_coroutine< Arg >::push_coroutine( Fn fn,
2017                                        attributes const& attrs,
2018                                        StackAllocator stack_alloc) :
2019     impl_( 0)
2020 {
2021     // create a stack-context
2022     stack_context stack_ctx;
2023     // allocate the coroutine-stack
2024     stack_alloc.allocate( stack_ctx, attrs.size);
2025     BOOST_ASSERT( 0 != stack_ctx.sp);
2026     // typedef of internal coroutine-type
2027     typedef detail::push_coroutine_object<
2028         pull_coroutine< Arg >, Arg, Fn, StackAllocator
2029     >                                                    object_t;
2030     // reserve space on top of coroutine-stack for internal coroutine-type
2031     std::size_t size = stack_ctx.size - sizeof( object_t);
2032     BOOST_ASSERT( 0 != size);
2033     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2034     BOOST_ASSERT( 0 != sp);
2035     // placement new for internal coroutine
2036     impl_ = new ( sp) object_t(
2037             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
2038     BOOST_ASSERT( impl_);
2039 }
2040
2041 template< typename Arg >
2042 template< typename Fn >
2043 push_coroutine< Arg & >::push_coroutine( Fn fn,
2044                                          attributes const& attrs) :
2045     impl_( 0)
2046 {
2047     // create a stack-context
2048     stack_context stack_ctx;
2049     stack_allocator stack_alloc;
2050     // allocate the coroutine-stack
2051     stack_alloc.allocate( stack_ctx, attrs.size);
2052     BOOST_ASSERT( 0 != stack_ctx.sp);
2053     // typedef of internal coroutine-type
2054     typedef detail::push_coroutine_object<
2055         pull_coroutine< Arg & >, Arg &, Fn, stack_allocator
2056     >                                                            object_t;
2057     // reserve space on top of coroutine-stack for internal coroutine-type
2058     std::size_t size = stack_ctx.size - sizeof( object_t);
2059     BOOST_ASSERT( 0 != size);
2060     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2061     BOOST_ASSERT( 0 != sp);
2062     // placement new for internal coroutine
2063     impl_ = new ( sp) object_t(
2064             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
2065     BOOST_ASSERT( impl_);
2066 }
2067
2068 template< typename Arg >
2069 template< typename Fn, typename StackAllocator >
2070 push_coroutine< Arg & >::push_coroutine( Fn fn,
2071                                          attributes const& attrs,
2072                                          StackAllocator stack_alloc) :
2073     impl_( 0)
2074 {
2075     // create a stack-context
2076     stack_context stack_ctx;
2077     // allocate the coroutine-stack
2078     stack_alloc.allocate( stack_ctx, attrs.size);
2079     BOOST_ASSERT( 0 != stack_ctx.sp);
2080     // typedef of internal coroutine-type
2081     typedef detail::push_coroutine_object<
2082         pull_coroutine< Arg & >, Arg &, Fn, StackAllocator
2083     >                                                            object_t;
2084     // reserve space on top of coroutine-stack for internal coroutine-type
2085     std::size_t size = stack_ctx.size - sizeof( object_t);
2086     BOOST_ASSERT( 0 != size);
2087     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2088     BOOST_ASSERT( 0 != sp);
2089     // placement new for internal coroutine
2090     impl_ = new ( sp) object_t(
2091             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
2092     BOOST_ASSERT( impl_);
2093 }
2094
2095 template< typename Fn >
2096 push_coroutine< void >::push_coroutine( Fn fn,
2097                                         attributes const& attrs) :
2098     impl_( 0)
2099 {
2100     // create a stack-context
2101     stack_context stack_ctx;
2102     stack_allocator stack_alloc;
2103     // allocate the coroutine-stack
2104     stack_alloc.allocate( stack_ctx, attrs.size);
2105     BOOST_ASSERT( 0 != stack_ctx.sp);
2106     // typedef of internal coroutine-type
2107     typedef detail::push_coroutine_object<
2108         pull_coroutine< void >, void, Fn, stack_allocator
2109     >                                                            object_t;
2110     // reserve space on top of coroutine-stack for internal coroutine-type
2111     std::size_t size = stack_ctx.size - sizeof( object_t);
2112     BOOST_ASSERT( 0 != size);
2113     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2114     BOOST_ASSERT( 0 != sp);
2115     // placement new for internal coroutine
2116     impl_ = new ( sp) object_t(
2117             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
2118     BOOST_ASSERT( impl_);
2119 }
2120
2121 template< typename Fn, typename StackAllocator >
2122 push_coroutine< void >::push_coroutine( Fn fn,
2123                                         attributes const& attrs,
2124                                         StackAllocator stack_alloc) :
2125     impl_( 0)
2126 {
2127     // create a stack-context
2128     stack_context stack_ctx;
2129     // allocate the coroutine-stack
2130     stack_alloc.allocate( stack_ctx, attrs.size);
2131     BOOST_ASSERT( 0 != stack_ctx.sp);
2132     // typedef of internal coroutine-type
2133     typedef detail::push_coroutine_object<
2134         pull_coroutine< void >, void, Fn, StackAllocator
2135     >                                                            object_t;
2136     // reserve space on top of coroutine-stack for internal coroutine-type
2137     std::size_t size = stack_ctx.size - sizeof( object_t);
2138     BOOST_ASSERT( 0 != size);
2139     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2140     BOOST_ASSERT( 0 != sp);
2141     // placement new for internal coroutine
2142     impl_ = new ( sp) object_t(
2143             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
2144     BOOST_ASSERT( impl_);
2145 }
2146
2147 template< typename Arg >
2148 template< typename Fn >
2149 push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
2150                                        attributes const& attrs) :
2151     impl_( 0)
2152 {
2153     // create a stack-context
2154     stack_context stack_ctx;
2155     stack_allocator stack_alloc;
2156     // allocate the coroutine-stack
2157     stack_alloc.allocate( stack_ctx, attrs.size);
2158     BOOST_ASSERT( 0 != stack_ctx.sp);
2159     // typedef of internal coroutine-type
2160     typedef detail::push_coroutine_object<
2161         pull_coroutine< Arg >, Arg, Fn, stack_allocator
2162     >                                                    object_t;
2163     // reserve space on top of coroutine-stack for internal coroutine-type
2164     std::size_t size = stack_ctx.size - sizeof( object_t);
2165     BOOST_ASSERT( 0 != size);
2166     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2167     BOOST_ASSERT( 0 != sp);
2168     // placement new for internal coroutine
2169     impl_ = new ( sp) object_t(
2170             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
2171     BOOST_ASSERT( impl_);
2172 }
2173
2174 template< typename Arg >
2175 template< typename Fn, typename StackAllocator >
2176 push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
2177                                        attributes const& attrs,
2178                                        StackAllocator stack_alloc) :
2179     impl_( 0)
2180 {
2181     // create a stack-context
2182     stack_context stack_ctx;
2183     // allocate the coroutine-stack
2184     stack_alloc.allocate( stack_ctx, attrs.size);
2185     BOOST_ASSERT( 0 != stack_ctx.sp);
2186     // typedef of internal coroutine-type
2187     typedef detail::push_coroutine_object<
2188         pull_coroutine< Arg >, Arg, Fn, StackAllocator
2189     >                                                    object_t;
2190     // reserve space on top of coroutine-stack for internal coroutine-type
2191     std::size_t size = stack_ctx.size - sizeof( object_t);
2192     BOOST_ASSERT( 0 != size);
2193     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2194     BOOST_ASSERT( 0 != sp);
2195     // placement new for internal coroutine
2196     impl_ = new ( sp) object_t(
2197             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
2198     BOOST_ASSERT( impl_);
2199 }
2200
2201 template< typename Arg >
2202 template< typename Fn >
2203 push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
2204                                          attributes const& attrs) :
2205     impl_( 0)
2206 {
2207     // create a stack-context
2208     stack_context stack_ctx;
2209     stack_allocator stack_alloc;
2210     // allocate the coroutine-stack
2211     stack_alloc.allocate( stack_ctx, attrs.size);
2212     BOOST_ASSERT( 0 != stack_ctx.sp);
2213     // typedef of internal coroutine-type
2214     typedef detail::push_coroutine_object<
2215         pull_coroutine< Arg & >, Arg &, Fn, stack_allocator
2216     >                                                            object_t;
2217     // reserve space on top of coroutine-stack for internal coroutine-type
2218     std::size_t size = stack_ctx.size - sizeof( object_t);
2219     BOOST_ASSERT( 0 != size);
2220     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2221     BOOST_ASSERT( 0 != sp);
2222     // placement new for internal coroutine
2223     impl_ = new ( sp) object_t(
2224             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
2225     BOOST_ASSERT( impl_);
2226 }
2227
2228 template< typename Arg >
2229 template< typename Fn, typename StackAllocator >
2230 push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
2231                                          attributes const& attrs,
2232                                          StackAllocator stack_alloc) :
2233     impl_( 0)
2234 {
2235     // create a stack-context
2236     stack_context stack_ctx;
2237     // allocate the coroutine-stack
2238     stack_alloc.allocate( stack_ctx, attrs.size);
2239     BOOST_ASSERT( 0 != stack_ctx.sp);
2240     // typedef of internal coroutine-type
2241     typedef detail::push_coroutine_object<
2242         pull_coroutine< Arg & >, Arg &, Fn, StackAllocator
2243     >                                                            object_t;
2244     // reserve space on top of coroutine-stack for internal coroutine-type
2245     std::size_t size = stack_ctx.size - sizeof( object_t);
2246     BOOST_ASSERT( 0 != size);
2247     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2248     BOOST_ASSERT( 0 != sp);
2249     // placement new for internal coroutine
2250     impl_ = new ( sp) object_t(
2251             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
2252     BOOST_ASSERT( impl_);
2253 }
2254
2255 template< typename Fn >
2256 push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
2257                                         attributes const& attrs) :
2258     impl_( 0)
2259 {
2260     // create a stack-context
2261     stack_context stack_ctx;
2262     stack_allocator stack_alloc;
2263     // allocate the coroutine-stack
2264     stack_alloc.allocate( stack_ctx, attrs.size);
2265     BOOST_ASSERT( 0 != stack_ctx.sp);
2266     // typedef of internal coroutine-type
2267     typedef detail::push_coroutine_object<
2268         pull_coroutine< void >, void, Fn, stack_allocator
2269     >                                                            object_t;
2270     // reserve space on top of coroutine-stack for internal coroutine-type
2271     std::size_t size = stack_ctx.size - sizeof( object_t);
2272     BOOST_ASSERT( 0 != size);
2273     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2274     BOOST_ASSERT( 0 != sp);
2275     // placement new for internal coroutine
2276     impl_ = new ( sp) object_t(
2277             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
2278     BOOST_ASSERT( impl_);
2279 }
2280
2281 template< typename Fn, typename StackAllocator >
2282 push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
2283                                         attributes const& attrs,
2284                                         StackAllocator stack_alloc) :
2285     impl_( 0)
2286 {
2287     // create a stack-context
2288     stack_context stack_ctx;
2289     // allocate the coroutine-stack
2290     stack_alloc.allocate( stack_ctx, attrs.size);
2291     BOOST_ASSERT( 0 != stack_ctx.sp);
2292     // typedef of internal coroutine-type
2293     typedef detail::push_coroutine_object<
2294         pull_coroutine< void >, void, Fn, StackAllocator
2295     >                                                            object_t;
2296     // reserve space on top of coroutine-stack for internal coroutine-type
2297     std::size_t size = stack_ctx.size - sizeof( object_t);
2298     BOOST_ASSERT( 0 != size);
2299     void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2300     BOOST_ASSERT( 0 != sp);
2301     // placement new for internal coroutine
2302     impl_ = new ( sp) object_t(
2303             fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc); 
2304     BOOST_ASSERT( impl_);
2305 }
2306 #endif
2307
2308 template< typename R >
2309 void swap( pull_coroutine< R > & l, pull_coroutine< R > & r) BOOST_NOEXCEPT
2310 { l.swap( r); }
2311
2312 template< typename Arg >
2313 void swap( push_coroutine< Arg > & l, push_coroutine< Arg > & r) BOOST_NOEXCEPT
2314 { l.swap( r); }
2315
2316 template< typename R >
2317 typename pull_coroutine< R >::iterator
2318 range_begin( pull_coroutine< R > & c)
2319 { return typename pull_coroutine< R >::iterator( & c); }
2320
2321 template< typename R >
2322 typename pull_coroutine< R >::const_iterator
2323 range_begin( pull_coroutine< R > const& c)
2324 { return typename pull_coroutine< R >::const_iterator( & c); }
2325
2326 template< typename R >
2327 typename pull_coroutine< R >::iterator
2328 range_end( pull_coroutine< R > &)
2329 { return typename pull_coroutine< R >::iterator(); }
2330
2331 template< typename R >
2332 typename pull_coroutine< R >::const_iterator
2333 range_end( pull_coroutine< R > const&)
2334 { return typename pull_coroutine< R >::const_iterator(); }
2335
2336 template< typename Arg >
2337 typename push_coroutine< Arg >::iterator
2338 range_begin( push_coroutine< Arg > & c)
2339 { return typename push_coroutine< Arg >::iterator( & c); }
2340
2341 template< typename Arg >
2342 typename push_coroutine< Arg >::iterator
2343 range_end( push_coroutine< Arg > &)
2344 { return typename push_coroutine< Arg >::iterator(); }
2345
2346 template< typename T >
2347 struct asymmetric_coroutine
2348 {
2349     typedef push_coroutine< T > push_type;
2350     typedef pull_coroutine< T > pull_type;
2351 };
2352
2353 // deprecated
2354 template< typename T >
2355 struct coroutine
2356 {
2357     typedef push_coroutine< T > push_type;
2358     typedef pull_coroutine< T > pull_type;
2359 };
2360
2361 template< typename R >
2362 typename pull_coroutine< R >::iterator
2363 begin( pull_coroutine< R > & c)
2364 { return boost::begin( c); }
2365
2366 template< typename R >
2367 typename pull_coroutine< R >::const_iterator
2368 begin( pull_coroutine< R > const& c)
2369 { return boost::begin( c); }
2370
2371 template< typename R >
2372 typename pull_coroutine< R >::iterator
2373 end( pull_coroutine< R > & c)
2374 { return boost::end( c); }
2375
2376 template< typename R >
2377 typename pull_coroutine< R >::const_iterator
2378 end( pull_coroutine< R > const& c)
2379 { return boost::end( c); }
2380
2381 template< typename R >
2382 typename push_coroutine< R >::iterator
2383 begin( push_coroutine< R > & c)
2384 { return boost::begin( c); }
2385
2386 template< typename R >
2387 typename push_coroutine< R >::iterator
2388 end( push_coroutine< R > & c)
2389 { return boost::end( c); }
2390
2391 }
2392
2393 // forward declaration of Boost.Range traits to break dependency on it
2394 template<typename C, typename Enabler>
2395 struct range_mutable_iterator;
2396
2397 template<typename C, typename Enabler>
2398 struct range_const_iterator;
2399
2400 template< typename Arg >
2401 struct range_mutable_iterator< coroutines::push_coroutine< Arg >, void >
2402 { typedef typename coroutines::push_coroutine< Arg >::iterator type; };
2403
2404 template< typename R >
2405 struct range_mutable_iterator< coroutines::pull_coroutine< R >, void >
2406 { typedef typename coroutines::pull_coroutine< R >::iterator type; };
2407
2408 }
2409
2410 #ifdef BOOST_HAS_ABI_HEADERS
2411 #  include BOOST_ABI_SUFFIX
2412 #endif
2413
2414 #endif // BOOST_COROUTINES_ASYMMETRIC_COROUTINE_H