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)
7 #ifndef BOOST_COROUTINES_ASYMMETRIC_COROUTINE_H
8 #define BOOST_COROUTINES_ASYMMETRIC_COROUTINE_H
10 #ifndef BOOST_COROUTINES_NO_DEPRECATION_WARNING
11 # if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
12 # pragma message ("Warning: Boost.Coroutine is now deprecated. Please switch to Boost.Coroutine2. To disable this warning message, define BOOST_COROUTINES_NO_DEPRECATION_WARNING.")
13 # elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
14 # warning "Boost.Coroutine is now deprecated. Please switch to Boost.Coroutine2. To disable this warning message, define BOOST_COROUTINES_NO_DEPRECATION_WARNING."
22 #include <boost/assert.hpp>
23 #include <boost/config.hpp>
24 #include <boost/move/move.hpp>
25 #include <boost/range.hpp>
26 #include <boost/throw_exception.hpp>
27 #include <boost/utility/explicit_operator_bool.hpp>
29 #include <boost/coroutine/attributes.hpp>
30 #include <boost/coroutine/detail/config.hpp>
31 #include <boost/coroutine/detail/coroutine_context.hpp>
32 #include <boost/coroutine/detail/parameters.hpp>
33 #include <boost/coroutine/exceptions.hpp>
34 #include <boost/coroutine/stack_allocator.hpp>
35 #include <boost/coroutine/detail/pull_coroutine_impl.hpp>
36 #include <boost/coroutine/detail/pull_coroutine_object.hpp>
37 #include <boost/coroutine/detail/pull_coroutine_synthesized.hpp>
38 #include <boost/coroutine/detail/push_coroutine_impl.hpp>
39 #include <boost/coroutine/detail/push_coroutine_object.hpp>
40 #include <boost/coroutine/detail/push_coroutine_synthesized.hpp>
41 #include <boost/coroutine/stack_context.hpp>
43 #ifdef BOOST_HAS_ABI_HEADERS
44 # include BOOST_ABI_PREFIX
48 namespace coroutines {
50 template< typename R >
53 template< typename Arg >
57 template< typename V, typename X, typename Y, typename Z >
58 friend class detail::pull_coroutine_object;
60 typedef detail::push_coroutine_impl< Arg > impl_type;
61 typedef detail::push_coroutine_synthesized< Arg > synth_type;
62 typedef detail::parameters< Arg > param_type;
68 BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine)
70 explicit push_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
72 { BOOST_ASSERT( impl_); }
75 push_coroutine() BOOST_NOEXCEPT :
79 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
81 typedef void ( * coroutine_fn)( pull_coroutine< Arg > &);
83 explicit push_coroutine( coroutine_fn,
84 attributes const& = attributes() );
86 template< typename StackAllocator >
87 explicit push_coroutine( coroutine_fn,
91 template< typename Fn >
92 explicit push_coroutine( BOOST_RV_REF( Fn),
93 attributes const& = attributes() );
95 template< typename Fn, typename StackAllocator >
96 explicit push_coroutine( BOOST_RV_REF( Fn),
100 template< typename Fn >
101 explicit push_coroutine( Fn fn,
102 attributes const& = attributes() );
104 template< typename Fn, typename StackAllocator >
105 explicit push_coroutine( Fn fn,
109 template< typename Fn >
110 explicit push_coroutine( BOOST_RV_REF( Fn),
111 attributes const& = attributes() );
113 template< typename Fn, typename StackAllocator >
114 explicit push_coroutine( BOOST_RV_REF( Fn),
128 push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT :
132 push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT
134 push_coroutine tmp( boost::move( other) );
139 BOOST_EXPLICIT_OPERATOR_BOOL();
141 bool operator!() const BOOST_NOEXCEPT
142 { return 0 == impl_ || impl_->is_complete(); }
144 void swap( push_coroutine & other) BOOST_NOEXCEPT
145 { std::swap( impl_, other.impl_); }
147 push_coroutine & operator()( Arg arg)
149 BOOST_ASSERT( * this);
158 push_coroutine< Arg > * c_;
161 typedef std::output_iterator_tag iterator_category;
162 typedef void value_type;
163 typedef void difference_type;
164 typedef void pointer;
165 typedef void reference;
171 explicit iterator( push_coroutine< Arg > * c) :
175 iterator & operator=( Arg a)
178 if ( ! ( * c_)( a) ) c_ = 0;
182 bool operator==( iterator const& other) const
183 { return other.c_ == c_; }
185 bool operator!=( iterator const& other) const
186 { return other.c_ != c_; }
188 iterator & operator*()
191 iterator & operator++()
195 struct const_iterator;
198 template< typename Arg >
199 class push_coroutine< Arg & >
202 template< typename V, typename X, typename Y, typename Z >
203 friend class detail::pull_coroutine_object;
205 typedef detail::push_coroutine_impl< Arg & > impl_type;
206 typedef detail::push_coroutine_synthesized< Arg & > synth_type;
207 typedef detail::parameters< Arg & > param_type;
213 BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine)
215 explicit push_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
217 { BOOST_ASSERT( impl_); }
220 push_coroutine() BOOST_NOEXCEPT :
224 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
226 typedef void ( * coroutine_fn)( pull_coroutine< Arg & > &);
228 explicit push_coroutine( coroutine_fn,
229 attributes const& = attributes() );
231 template< typename StackAllocator >
232 explicit push_coroutine( coroutine_fn,
236 template< typename Fn >
237 explicit push_coroutine( BOOST_RV_REF( Fn),
238 attributes const& = attributes() );
240 template< typename Fn, typename StackAllocator >
241 explicit push_coroutine( BOOST_RV_REF( Fn),
245 template< typename Fn >
246 explicit push_coroutine( Fn,
247 attributes const& = attributes() );
249 template< typename Fn, typename StackAllocator >
250 explicit push_coroutine( Fn,
254 template< typename Fn >
255 explicit push_coroutine( BOOST_RV_REF( Fn),
256 attributes const& = attributes() );
258 template< typename Fn, typename StackAllocator >
259 explicit push_coroutine( BOOST_RV_REF( Fn),
273 push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT :
277 push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT
279 push_coroutine tmp( boost::move( other) );
284 BOOST_EXPLICIT_OPERATOR_BOOL();
286 bool operator!() const BOOST_NOEXCEPT
287 { return 0 == impl_ || impl_->is_complete(); }
289 void swap( push_coroutine & other) BOOST_NOEXCEPT
290 { std::swap( impl_, other.impl_); }
292 push_coroutine & operator()( Arg & arg)
294 BOOST_ASSERT( * this);
303 push_coroutine< Arg & > * c_;
306 typedef std::output_iterator_tag iterator_category;
307 typedef void value_type;
308 typedef void difference_type;
309 typedef void pointer;
310 typedef void reference;
316 explicit iterator( push_coroutine< Arg & > * c) :
320 iterator & operator=( Arg & a)
323 if ( ! ( * c_)( a) ) c_ = 0;
327 bool operator==( iterator const& other) const
328 { return other.c_ == c_; }
330 bool operator!=( iterator const& other) const
331 { return other.c_ != c_; }
333 iterator & operator*()
336 iterator & operator++()
340 struct const_iterator;
344 class push_coroutine< void >
347 template< typename V, typename X, typename Y, typename Z >
348 friend class detail::pull_coroutine_object;
350 typedef detail::push_coroutine_impl< void > impl_type;
351 typedef detail::push_coroutine_synthesized< void > synth_type;
352 typedef detail::parameters< void > param_type;
358 BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine)
360 explicit push_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
362 { BOOST_ASSERT( impl_); }
365 push_coroutine() BOOST_NOEXCEPT :
369 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
371 typedef void ( * coroutine_fn)( pull_coroutine< void > &);
373 explicit push_coroutine( coroutine_fn,
374 attributes const& = attributes() );
376 template< typename StackAllocator >
377 explicit push_coroutine( coroutine_fn,
381 template< typename Fn >
382 explicit push_coroutine( BOOST_RV_REF( Fn),
383 attributes const& = attributes() );
385 template< typename Fn, typename StackAllocator >
386 explicit push_coroutine( BOOST_RV_REF( Fn),
390 template< typename Fn >
391 explicit push_coroutine( Fn,
392 attributes const& = attributes() );
394 template< typename Fn, typename StackAllocator >
395 explicit push_coroutine( Fn,
399 template< typename Fn >
400 explicit push_coroutine( BOOST_RV_REF( Fn),
401 attributes const& = attributes() );
403 template< typename Fn, typename StackAllocator >
404 explicit push_coroutine( BOOST_RV_REF( Fn),
418 inline push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT :
422 inline push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT
424 push_coroutine tmp( boost::move( other) );
429 BOOST_EXPLICIT_OPERATOR_BOOL();
431 inline bool operator!() const BOOST_NOEXCEPT
432 { return 0 == impl_ || impl_->is_complete(); }
434 inline void swap( push_coroutine & other) BOOST_NOEXCEPT
435 { std::swap( impl_, other.impl_); }
437 inline push_coroutine & operator()()
439 BOOST_ASSERT( * this);
446 struct const_iterator;
451 template< typename R >
455 template< typename V, typename X, typename Y, typename Z >
456 friend class detail::push_coroutine_object;
458 typedef detail::pull_coroutine_impl< R > impl_type;
459 typedef detail::pull_coroutine_synthesized< R > synth_type;
460 typedef detail::parameters< R > param_type;
466 BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine)
468 explicit pull_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
470 { BOOST_ASSERT( impl_); }
473 pull_coroutine() BOOST_NOEXCEPT :
477 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
479 typedef void ( * coroutine_fn)( push_coroutine< R > &);
481 explicit pull_coroutine( coroutine_fn fn,
482 attributes const& attrs = attributes() ) :
485 // create a stack-context
486 stack_context stack_ctx;
487 stack_allocator stack_alloc;
488 // allocate the coroutine-stack
489 stack_alloc.allocate( stack_ctx, attrs.size);
490 BOOST_ASSERT( 0 != stack_ctx.sp);
491 // typedef of internal coroutine-type
492 typedef detail::pull_coroutine_object<
493 push_coroutine< R >, R, coroutine_fn, stack_allocator
495 // reserve space on top of coroutine-stack for internal coroutine-type
496 std::size_t size = stack_ctx.size - sizeof( object_t);
497 BOOST_ASSERT( 0 != size);
498 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
499 BOOST_ASSERT( 0 != sp);
500 // placement new for internal coroutine
501 impl_ = new ( sp) object_t(
502 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
503 BOOST_ASSERT( impl_);
507 template< typename StackAllocator >
508 explicit pull_coroutine( coroutine_fn fn,
509 attributes const& attrs,
510 StackAllocator stack_alloc) :
513 // create a stack-context
514 stack_context stack_ctx;
515 // allocate the coroutine-stack
516 stack_alloc.allocate( stack_ctx, attrs.size);
517 BOOST_ASSERT( 0 != stack_ctx.sp);
518 // typedef of internal coroutine-type
519 typedef detail::pull_coroutine_object<
520 push_coroutine< R >, R, coroutine_fn, StackAllocator
522 // reserve space on top of coroutine-stack for internal coroutine-type
523 std::size_t size = stack_ctx.size - sizeof( object_t);
524 BOOST_ASSERT( 0 != size);
525 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
526 BOOST_ASSERT( 0 != sp);
527 // placement new for internal coroutine
528 impl_ = new ( sp) object_t(
529 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
530 BOOST_ASSERT( impl_);
534 template< typename Fn >
535 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
536 attributes const& attrs = attributes() ) :
539 // create a stack-context
540 stack_context stack_ctx;
541 stack_allocator stack_alloc;
542 // allocate the coroutine-stack
543 stack_alloc.allocate( stack_ctx, attrs.size);
544 BOOST_ASSERT( 0 != stack_ctx.sp);
545 // typedef of internal coroutine-type
546 typedef detail::pull_coroutine_object<
547 push_coroutine< R >, R, Fn, stack_allocator
549 // reserve space on top of coroutine-stack for internal coroutine-type
550 std::size_t size = stack_ctx.size - sizeof( object_t);
551 BOOST_ASSERT( 0 != size);
552 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
553 BOOST_ASSERT( 0 != sp);
554 // placement new for internal coroutine
555 impl_ = new ( sp) object_t(
556 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
557 BOOST_ASSERT( impl_);
561 template< typename Fn, typename StackAllocator >
562 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
563 attributes const& attrs,
564 StackAllocator stack_alloc) :
567 // create a stack-context
568 stack_context stack_ctx;
569 // allocate the coroutine-stack
570 stack_alloc.allocate( stack_ctx, attrs.size);
571 BOOST_ASSERT( 0 != stack_ctx.sp);
572 // typedef of internal coroutine-type
573 typedef detail::pull_coroutine_object<
574 push_coroutine< R >, R, Fn, StackAllocator
576 // reserve space on top of coroutine-stack for internal coroutine-type
577 std::size_t size = stack_ctx.size - sizeof( object_t);
578 BOOST_ASSERT( 0 != size);
579 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
580 BOOST_ASSERT( 0 != sp);
581 // placement new for internal coroutine
582 impl_ = new ( sp) object_t(
583 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
584 BOOST_ASSERT( impl_);
588 template< typename Fn >
589 explicit pull_coroutine( Fn fn,
590 attributes const& attrs = attributes() ) :
593 // create a stack-context
594 stack_context stack_ctx;
595 stack_allocator stack_alloc;
596 // allocate the coroutine-stack
597 stack_alloc.allocate( stack_ctx, attrs.size);
598 BOOST_ASSERT( 0 != stack_ctx.sp);
599 // typedef of internal coroutine-type
600 typedef detail::pull_coroutine_object<
601 push_coroutine< R >, R, Fn, stack_allocator
603 // reserve space on top of coroutine-stack for internal coroutine-type
604 std::size_t size = stack_ctx.size - sizeof( object_t);
605 BOOST_ASSERT( 0 != size);
606 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
607 BOOST_ASSERT( 0 != sp);
608 // placement new for internal coroutine
609 impl_ = new ( sp) object_t(
610 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
611 BOOST_ASSERT( impl_);
615 template< typename Fn, typename StackAllocator >
616 explicit pull_coroutine( Fn fn,
617 attributes const& attrs,
618 StackAllocator stack_alloc) :
621 // create a stack-context
622 stack_context stack_ctx;
623 // allocate the coroutine-stack
624 stack_alloc.allocate( stack_ctx, attrs.size);
625 BOOST_ASSERT( 0 != stack_ctx.sp);
626 // typedef of internal coroutine-type
627 typedef detail::pull_coroutine_object<
628 push_coroutine< R >, R, Fn, StackAllocator
630 // reserve space on top of coroutine-stack for internal coroutine-type
631 std::size_t size = stack_ctx.size - sizeof( object_t);
632 BOOST_ASSERT( 0 != size);
633 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
634 BOOST_ASSERT( 0 != sp);
635 // placement new for internal coroutine
636 impl_ = new ( sp) object_t(
637 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
638 BOOST_ASSERT( impl_);
642 template< typename Fn >
643 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
644 attributes const& attrs = attributes() ) :
647 // create a stack-context
648 stack_context stack_ctx;
649 stack_allocator stack_alloc;
650 // allocate the coroutine-stack
651 stack_alloc.allocate( stack_ctx, attrs.size);
652 BOOST_ASSERT( 0 != stack_ctx.sp);
653 // typedef of internal coroutine-type
654 typedef detail::pull_coroutine_object<
655 push_coroutine< R >, R, Fn, stack_allocator
657 // reserve space on top of coroutine-stack for internal coroutine-type
658 std::size_t size = stack_ctx.size - sizeof( object_t);
659 BOOST_ASSERT( 0 != size);
660 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
661 BOOST_ASSERT( 0 != sp);
662 // placement new for internal coroutine
663 impl_ = new ( sp) object_t(
664 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
665 BOOST_ASSERT( impl_);
669 template< typename Fn, typename StackAllocator >
670 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
671 attributes const& attrs,
672 StackAllocator stack_alloc) :
675 // create a stack-context
676 stack_context stack_ctx;
677 // allocate the coroutine-stack
678 stack_alloc.allocate( stack_ctx, attrs.size);
679 BOOST_ASSERT( 0 != stack_ctx.sp);
680 // typedef of internal coroutine-type
681 typedef detail::pull_coroutine_object<
682 push_coroutine< R >, R, Fn, StackAllocator
684 // reserve space on top of coroutine-stack for internal coroutine-type
685 std::size_t size = stack_ctx.size - sizeof( object_t);
686 BOOST_ASSERT( 0 != size);
687 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
688 BOOST_ASSERT( 0 != sp);
689 // placement new for internal coroutine
690 impl_ = new ( sp) object_t(
691 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
692 BOOST_ASSERT( impl_);
706 pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT :
710 pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT
712 pull_coroutine tmp( boost::move( other) );
717 BOOST_EXPLICIT_OPERATOR_BOOL();
719 bool operator!() const BOOST_NOEXCEPT
720 { return 0 == impl_ || impl_->is_complete(); }
722 void swap( pull_coroutine & other) BOOST_NOEXCEPT
723 { std::swap( impl_, other.impl_); }
725 pull_coroutine & operator()()
727 BOOST_ASSERT( * this);
735 BOOST_ASSERT( 0 != impl_);
743 pull_coroutine< R > * c_;
756 val_ = c_->impl_->get_pointer();
769 typedef std::input_iterator_tag iterator_category;
770 typedef typename remove_reference< R >::type value_type;
771 typedef std::ptrdiff_t difference_type;
772 typedef value_type * pointer;
773 typedef value_type & reference;
775 typedef pointer pointer_t;
776 typedef reference reference_t;
782 explicit iterator( pull_coroutine< R > * c) :
786 iterator( iterator const& other) :
787 c_( other.c_), val_( other.val_)
790 iterator & operator=( iterator const& other)
792 if ( this == & other) return * this;
798 bool operator==( iterator const& other) const
799 { return other.c_ == c_ && other.val_ == val_; }
801 bool operator!=( iterator const& other) const
802 { return other.c_ != c_ || other.val_ != val_; }
804 iterator & operator++()
810 iterator operator++( int);
812 reference_t operator*() const
815 boost::throw_exception(
820 pointer_t operator->() const
823 boost::throw_exception(
832 pull_coroutine< R > * c_;
845 val_ = c_->impl_->get_pointer();
858 typedef std::input_iterator_tag iterator_category;
859 typedef const typename remove_reference< R >::type value_type;
860 typedef std::ptrdiff_t difference_type;
861 typedef value_type * pointer;
862 typedef value_type & reference;
864 typedef pointer pointer_t;
865 typedef reference reference_t;
871 explicit const_iterator( pull_coroutine< R > const* c) :
872 c_( const_cast< pull_coroutine< R > * >( c) ),
876 const_iterator( const_iterator const& other) :
877 c_( other.c_), val_( other.val_)
880 const_iterator & operator=( const_iterator const& other)
882 if ( this == & other) return * this;
888 bool operator==( const_iterator const& other) const
889 { return other.c_ == c_ && other.val_ == val_; }
891 bool operator!=( const_iterator const& other) const
892 { return other.c_ != c_ || other.val_ != val_; }
894 const_iterator & operator++()
900 const_iterator operator++( int);
902 reference_t operator*() const
905 boost::throw_exception(
910 pointer_t operator->() const
913 boost::throw_exception(
919 friend class iterator;
920 friend class const_iterator;
923 template< typename R >
924 class pull_coroutine< R & >
927 template< typename V, typename X, typename Y, typename Z >
928 friend class detail::push_coroutine_object;
930 typedef detail::pull_coroutine_impl< R & > impl_type;
931 typedef detail::pull_coroutine_synthesized< R & > synth_type;
932 typedef detail::parameters< R & > param_type;
938 BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine)
940 explicit pull_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
942 { BOOST_ASSERT( impl_); }
945 pull_coroutine() BOOST_NOEXCEPT :
949 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
951 typedef void ( * coroutine_fn)( push_coroutine< R & > &);
953 explicit pull_coroutine( coroutine_fn fn,
954 attributes const& attrs = attributes() ) :
957 // create a stack-context
958 stack_context stack_ctx;
959 stack_allocator stack_alloc;
960 // allocate the coroutine-stack
961 stack_alloc.allocate( stack_ctx, attrs.size);
962 BOOST_ASSERT( 0 != stack_ctx.sp);
963 // typedef of internal coroutine-type
964 typedef detail::pull_coroutine_object<
965 push_coroutine< R & >, R &, coroutine_fn, stack_allocator
967 // reserve space on top of coroutine-stack for internal coroutine-type
968 std::size_t size = stack_ctx.size - sizeof( object_t);
969 BOOST_ASSERT( 0 != size);
970 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
971 BOOST_ASSERT( 0 != sp);
972 // placement new for internal coroutine
973 impl_ = new ( sp) object_t(
974 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
975 BOOST_ASSERT( impl_);
979 template< typename StackAllocator >
980 explicit pull_coroutine( coroutine_fn fn,
981 attributes const& attrs,
982 StackAllocator stack_alloc) :
985 // create a stack-context
986 stack_context stack_ctx;
987 // allocate the coroutine-stack
988 stack_alloc.allocate( stack_ctx, attrs.size);
989 BOOST_ASSERT( 0 != stack_ctx.sp);
990 // typedef of internal coroutine-type
991 typedef detail::pull_coroutine_object<
992 push_coroutine< R & >, R &, coroutine_fn, StackAllocator
994 // reserve space on top of coroutine-stack for internal coroutine-type
995 std::size_t size = stack_ctx.size - sizeof( object_t);
996 BOOST_ASSERT( 0 != size);
997 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
998 BOOST_ASSERT( 0 != sp);
999 // placement new for internal coroutine
1000 impl_ = new ( sp) object_t(
1001 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1002 BOOST_ASSERT( impl_);
1006 template< typename Fn >
1007 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1008 attributes const& attrs = attributes() ) :
1011 // create a stack-context
1012 stack_context stack_ctx;
1013 stack_allocator stack_alloc;
1014 // allocate the coroutine-stack
1015 stack_alloc.allocate( stack_ctx, attrs.size);
1016 BOOST_ASSERT( 0 != stack_ctx.sp);
1017 // typedef of internal coroutine-type
1018 typedef detail::pull_coroutine_object<
1019 push_coroutine< R & >, R &, Fn, stack_allocator
1021 // reserve space on top of coroutine-stack for internal coroutine-type
1022 std::size_t size = stack_ctx.size - sizeof( object_t);
1023 BOOST_ASSERT( 0 != size);
1024 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1025 BOOST_ASSERT( 0 != sp);
1026 // placement new for internal coroutine
1027 impl_ = new ( sp) object_t(
1028 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1029 BOOST_ASSERT( impl_);
1033 template< typename Fn, typename StackAllocator >
1034 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1035 attributes const& attrs,
1036 StackAllocator stack_alloc) :
1039 // create a stack-context
1040 stack_context stack_ctx;
1041 // allocate the coroutine-stack
1042 stack_alloc.allocate( stack_ctx, attrs.size);
1043 BOOST_ASSERT( 0 != stack_ctx.sp);
1044 // typedef of internal coroutine-type
1045 typedef detail::pull_coroutine_object<
1046 push_coroutine< R & >, R &, Fn, StackAllocator
1048 // reserve space on top of coroutine-stack for internal coroutine-type
1049 std::size_t size = stack_ctx.size - sizeof( object_t);
1050 BOOST_ASSERT( 0 != size);
1051 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1052 BOOST_ASSERT( 0 != sp);
1053 // placement new for internal coroutine
1054 impl_ = new ( sp) object_t(
1055 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1056 BOOST_ASSERT( impl_);
1060 template< typename Fn >
1061 explicit pull_coroutine( Fn fn,
1062 attributes const& attrs = attributes() ) :
1065 // create a stack-context
1066 stack_context stack_ctx;
1067 stack_allocator stack_alloc;
1068 // allocate the coroutine-stack
1069 stack_alloc.allocate( stack_ctx, attrs.size);
1070 BOOST_ASSERT( 0 != stack_ctx.sp);
1071 // typedef of internal coroutine-type
1072 typedef detail::pull_coroutine_object<
1073 push_coroutine< R & >, R &, Fn, stack_allocator
1075 // reserve space on top of coroutine-stack for internal coroutine-type
1076 std::size_t size = stack_ctx.size - sizeof( object_t);
1077 BOOST_ASSERT( 0 != size);
1078 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1079 BOOST_ASSERT( 0 != sp);
1080 // placement new for internal coroutine
1081 impl_ = new ( sp) object_t(
1082 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1083 BOOST_ASSERT( impl_);
1087 template< typename Fn, typename StackAllocator >
1088 explicit pull_coroutine( Fn fn,
1089 attributes const& attrs,
1090 StackAllocator stack_alloc) :
1093 // create a stack-context
1094 stack_context stack_ctx;
1095 // allocate the coroutine-stack
1096 stack_alloc.allocate( stack_ctx, attrs.size);
1097 BOOST_ASSERT( 0 != stack_ctx.sp);
1098 // typedef of internal coroutine-type
1099 typedef detail::pull_coroutine_object<
1100 push_coroutine< R & >, R &, Fn, StackAllocator
1102 // reserve space on top of coroutine-stack for internal coroutine-type
1103 std::size_t size = stack_ctx.size - sizeof( object_t);
1104 BOOST_ASSERT( 0 != size);
1105 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1106 BOOST_ASSERT( 0 != sp);
1107 // placement new for internal coroutine
1108 impl_ = new ( sp) object_t(
1109 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1110 BOOST_ASSERT( impl_);
1114 template< typename Fn >
1115 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1116 attributes const& attrs = attributes() ) :
1119 // create a stack-context
1120 stack_context stack_ctx;
1121 stack_allocator stack_alloc;
1122 // allocate the coroutine-stack
1123 stack_alloc.allocate( stack_ctx, attrs.size);
1124 BOOST_ASSERT( 0 != stack_ctx.sp);
1125 // typedef of internal coroutine-type
1126 typedef detail::pull_coroutine_object<
1127 push_coroutine< R & >, R &, Fn, stack_allocator
1129 // reserve space on top of coroutine-stack for internal coroutine-type
1130 std::size_t size = stack_ctx.size - sizeof( object_t);
1131 BOOST_ASSERT( 0 != size);
1132 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1133 BOOST_ASSERT( 0 != sp);
1134 // placement new for internal coroutine
1135 impl_ = new ( sp) object_t(
1136 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1137 BOOST_ASSERT( impl_);
1141 template< typename Fn, typename StackAllocator >
1142 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1143 attributes const& attrs,
1144 StackAllocator stack_alloc) :
1147 // create a stack-context
1148 stack_context stack_ctx;
1149 // allocate the coroutine-stack
1150 stack_alloc.allocate( stack_ctx, attrs.size);
1151 BOOST_ASSERT( 0 != stack_ctx.sp);
1152 // typedef of internal coroutine-type
1153 typedef detail::pull_coroutine_object<
1154 push_coroutine< R & >, R &, Fn, StackAllocator
1156 // reserve space on top of coroutine-stack for internal coroutine-type
1157 std::size_t size = stack_ctx.size - sizeof( object_t);
1158 BOOST_ASSERT( 0 != size);
1159 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1160 BOOST_ASSERT( 0 != sp);
1161 // placement new for internal coroutine
1162 impl_ = new ( sp) object_t(
1163 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1164 BOOST_ASSERT( impl_);
1178 pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT :
1182 pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT
1184 pull_coroutine tmp( boost::move( other) );
1189 BOOST_EXPLICIT_OPERATOR_BOOL();
1191 bool operator!() const BOOST_NOEXCEPT
1192 { return 0 == impl_ || impl_->is_complete(); }
1194 void swap( pull_coroutine & other) BOOST_NOEXCEPT
1195 { std::swap( impl_, other.impl_); }
1197 pull_coroutine & operator()()
1199 BOOST_ASSERT( * this);
1206 { return impl_->get(); }
1211 pull_coroutine< R & > * c_;
1224 val_ = c_->impl_->get_pointer();
1230 BOOST_ASSERT( * c_);
1237 typedef std::input_iterator_tag iterator_category;
1238 typedef typename remove_reference< R >::type value_type;
1239 typedef std::ptrdiff_t difference_type;
1240 typedef value_type * pointer;
1241 typedef value_type & reference;
1243 typedef pointer pointer_t;
1244 typedef reference reference_t;
1250 explicit iterator( pull_coroutine< R & > * c) :
1254 iterator( iterator const& other) :
1255 c_( other.c_), val_( other.val_)
1258 iterator & operator=( iterator const& other)
1260 if ( this == & other) return * this;
1266 bool operator==( iterator const& other) const
1267 { return other.c_ == c_ && other.val_ == val_; }
1269 bool operator!=( iterator const& other) const
1270 { return other.c_ != c_ || other.val_ != val_; }
1272 iterator & operator++()
1278 iterator operator++( int);
1280 reference_t operator*() const
1283 boost::throw_exception(
1288 pointer_t operator->() const
1291 boost::throw_exception(
1297 class const_iterator
1300 pull_coroutine< R & > * c_;
1313 val_ = c_->impl_->get_pointer();
1319 BOOST_ASSERT( * c_);
1326 typedef std::input_iterator_tag iterator_category;
1327 typedef const typename remove_reference< R >::type value_type;
1328 typedef std::ptrdiff_t difference_type;
1329 typedef value_type * pointer;
1330 typedef value_type & reference;
1332 typedef pointer pointer_t;
1333 typedef reference reference_t;
1339 explicit const_iterator( pull_coroutine< R & > const* c) :
1340 c_( const_cast< pull_coroutine< R & > * >( c) ),
1344 const_iterator( const_iterator const& other) :
1345 c_( other.c_), val_( other.val_)
1348 const_iterator & operator=( const_iterator const& other)
1350 if ( this == & other) return * this;
1356 bool operator==( const_iterator const& other) const
1357 { return other.c_ == c_ && other.val_ == val_; }
1359 bool operator!=( const_iterator const& other) const
1360 { return other.c_ != c_ || other.val_ != val_; }
1362 const_iterator & operator++()
1368 const_iterator operator++( int);
1370 reference_t operator*() const
1373 boost::throw_exception(
1378 pointer_t operator->() const
1381 boost::throw_exception(
1387 friend class iterator;
1388 friend class const_iterator;
1392 class pull_coroutine< void >
1395 template< typename V, typename X, typename Y, typename Z >
1396 friend class detail::push_coroutine_object;
1398 typedef detail::pull_coroutine_impl< void > impl_type;
1399 typedef detail::pull_coroutine_synthesized< void > synth_type;
1400 typedef detail::parameters< void > param_type;
1406 BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine)
1408 explicit pull_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
1410 { BOOST_ASSERT( impl_); }
1413 pull_coroutine() BOOST_NOEXCEPT :
1417 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1419 typedef void ( * coroutine_fn)( push_coroutine< void > &);
1421 explicit pull_coroutine( coroutine_fn fn,
1422 attributes const& attrs = attributes() ) :
1425 // create a stack-context
1426 stack_context stack_ctx;
1427 stack_allocator stack_alloc;
1428 // allocate the coroutine-stack
1429 stack_alloc.allocate( stack_ctx, attrs.size);
1430 BOOST_ASSERT( 0 != stack_ctx.sp);
1431 // typedef of internal coroutine-type
1432 typedef detail::pull_coroutine_object<
1433 push_coroutine< void >, void, coroutine_fn, stack_allocator
1435 // reserve space on top of coroutine-stack for internal coroutine-type
1436 std::size_t size = stack_ctx.size - sizeof( object_t);
1437 BOOST_ASSERT( 0 != size);
1438 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1439 BOOST_ASSERT( 0 != sp);
1440 // placement new for internal coroutine
1441 impl_ = new ( sp) object_t(
1442 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1443 BOOST_ASSERT( impl_);
1447 template< typename StackAllocator >
1448 explicit pull_coroutine( coroutine_fn fn,
1449 attributes const& attrs,
1450 StackAllocator stack_alloc) :
1453 // create a stack-context
1454 stack_context stack_ctx;
1455 // allocate the coroutine-stack
1456 stack_alloc.allocate( stack_ctx, attrs.size);
1457 BOOST_ASSERT( 0 != stack_ctx.sp);
1458 // typedef of internal coroutine-type
1459 typedef detail::pull_coroutine_object<
1460 push_coroutine< void >, void, coroutine_fn, StackAllocator
1462 // reserve space on top of coroutine-stack for internal coroutine-type
1463 std::size_t size = stack_ctx.size - sizeof( object_t);
1464 BOOST_ASSERT( 0 != size);
1465 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1466 BOOST_ASSERT( 0 != sp);
1467 // placement new for internal coroutine
1468 impl_ = new ( sp) object_t(
1469 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1470 BOOST_ASSERT( impl_);
1474 template< typename Fn >
1475 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1476 attributes const& attrs = attributes() ) :
1479 // create a stack-context
1480 stack_context stack_ctx;
1481 stack_allocator stack_alloc;
1482 // allocate the coroutine-stack
1483 stack_alloc.allocate( stack_ctx, attrs.size);
1484 BOOST_ASSERT( 0 != stack_ctx.sp);
1485 // typedef of internal coroutine-type
1486 typedef detail::pull_coroutine_object<
1487 push_coroutine< void >, void, Fn, stack_allocator
1489 // reserve space on top of coroutine-stack for internal coroutine-type
1490 std::size_t size = stack_ctx.size - sizeof( object_t);
1491 BOOST_ASSERT( 0 != size);
1492 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1493 BOOST_ASSERT( 0 != sp);
1494 // placement new for internal coroutine
1495 impl_ = new ( sp) object_t(
1496 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1497 BOOST_ASSERT( impl_);
1501 template< typename Fn, typename StackAllocator >
1502 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1503 attributes const& attrs,
1504 StackAllocator stack_alloc) :
1507 // create a stack-context
1508 stack_context stack_ctx;
1509 // allocate the coroutine-stack
1510 stack_alloc.allocate( stack_ctx, attrs.size);
1511 BOOST_ASSERT( 0 != stack_ctx.sp);
1512 // typedef of internal coroutine-type
1513 typedef detail::pull_coroutine_object<
1514 push_coroutine< void >, void, Fn, StackAllocator
1516 // reserve space on top of coroutine-stack for internal coroutine-type
1517 std::size_t size = stack_ctx.size - sizeof( object_t);
1518 BOOST_ASSERT( 0 != size);
1519 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1520 BOOST_ASSERT( 0 != sp);
1521 // placement new for internal coroutine
1522 impl_ = new ( sp) object_t(
1523 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1524 BOOST_ASSERT( impl_);
1528 template< typename Fn >
1529 explicit pull_coroutine( Fn fn,
1530 attributes const& attrs = attributes() ) :
1533 // create a stack-context
1534 stack_context stack_ctx;
1535 stack_allocator stack_alloc;
1536 // allocate the coroutine-stack
1537 stack_alloc.allocate( stack_ctx, attrs.size);
1538 BOOST_ASSERT( 0 != stack_ctx.sp);
1539 // typedef of internal coroutine-type
1540 typedef detail::pull_coroutine_object<
1541 push_coroutine< void >, void, Fn, stack_allocator
1543 // reserve space on top of coroutine-stack for internal coroutine-type
1544 std::size_t size = stack_ctx.size - sizeof( object_t);
1545 BOOST_ASSERT( 0 != size);
1546 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1547 BOOST_ASSERT( 0 != sp);
1548 // placement new for internal coroutine
1549 impl_ = new ( sp) object_t(
1550 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1551 BOOST_ASSERT( impl_);
1555 template< typename Fn, typename StackAllocator >
1556 explicit pull_coroutine( Fn fn,
1557 attributes const& attrs,
1558 StackAllocator stack_alloc) :
1561 // create a stack-context
1562 stack_context stack_ctx;
1563 // allocate the coroutine-stack
1564 stack_alloc.allocate( stack_ctx, attrs.size);
1565 BOOST_ASSERT( 0 != stack_ctx.sp);
1566 // typedef of internal coroutine-type
1567 typedef detail::pull_coroutine_object<
1568 push_coroutine< void >, void, Fn, StackAllocator
1570 // reserve space on top of coroutine-stack for internal coroutine-type
1571 std::size_t size = stack_ctx.size - sizeof( object_t);
1572 BOOST_ASSERT( 0 != size);
1573 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1574 BOOST_ASSERT( 0 != sp);
1575 // placement new for internal coroutine
1576 impl_ = new ( sp) object_t(
1577 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1578 BOOST_ASSERT( impl_);
1582 template< typename Fn >
1583 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1584 attributes const& attrs = attributes() ) :
1587 // create a stack-context
1588 stack_context stack_ctx;
1589 stack_allocator stack_alloc;
1590 // allocate the coroutine-stack
1591 stack_alloc.allocate( stack_ctx, attrs.size);
1592 BOOST_ASSERT( 0 != stack_ctx.sp);
1593 // typedef of internal coroutine-type
1594 typedef detail::pull_coroutine_object<
1595 push_coroutine< void >, void, Fn, stack_allocator
1597 // reserve space on top of coroutine-stack for internal coroutine-type
1598 std::size_t size = stack_ctx.size - sizeof( object_t);
1599 BOOST_ASSERT( 0 != size);
1600 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1601 BOOST_ASSERT( 0 != sp);
1602 // placement new for internal coroutine
1603 impl_ = new ( sp) object_t(
1604 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1605 BOOST_ASSERT( impl_);
1609 template< typename Fn, typename StackAllocator >
1610 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1611 attributes const& attrs,
1612 StackAllocator stack_alloc) :
1615 // create a stack-context
1616 stack_context stack_ctx;
1617 // allocate the coroutine-stack
1618 stack_alloc.allocate( stack_ctx, attrs.size);
1619 BOOST_ASSERT( 0 != stack_ctx.sp);
1620 // typedef of internal coroutine-type
1621 typedef detail::pull_coroutine_object<
1622 push_coroutine< void >, void, Fn, StackAllocator
1624 // reserve space on top of coroutine-stack for internal coroutine-type
1625 std::size_t size = stack_ctx.size - sizeof( object_t);
1626 BOOST_ASSERT( 0 != size);
1627 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1628 BOOST_ASSERT( 0 != sp);
1629 // placement new for internal coroutine
1630 impl_ = new ( sp) object_t(
1631 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1632 BOOST_ASSERT( impl_);
1646 inline pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT :
1650 inline pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT
1652 pull_coroutine tmp( boost::move( other) );
1657 BOOST_EXPLICIT_OPERATOR_BOOL();
1659 inline bool operator!() const BOOST_NOEXCEPT
1660 { return 0 == impl_ || impl_->is_complete(); }
1662 inline void swap( pull_coroutine & other) BOOST_NOEXCEPT
1663 { std::swap( impl_, other.impl_); }
1665 inline pull_coroutine & operator()()
1667 BOOST_ASSERT( * this);
1674 struct const_iterator;
1677 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1679 template< typename Arg >
1680 push_coroutine< Arg >::push_coroutine( coroutine_fn fn,
1681 attributes const& attrs) :
1684 // create a stack-context
1685 stack_context stack_ctx;
1686 stack_allocator stack_alloc;
1687 // allocate the coroutine-stack
1688 stack_alloc.allocate( stack_ctx, attrs.size);
1689 BOOST_ASSERT( 0 != stack_ctx.sp);
1690 // typedef of internal coroutine-type
1691 typedef detail::push_coroutine_object<
1692 pull_coroutine< Arg >, Arg, coroutine_fn, stack_allocator
1694 // reserve space on top of coroutine-stack for internal coroutine-type
1695 std::size_t size = stack_ctx.size - sizeof( object_t);
1696 BOOST_ASSERT( 0 != size);
1697 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1698 BOOST_ASSERT( 0 != sp);
1699 // placement new for internal coroutine
1700 impl_ = new ( sp) object_t(
1701 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1702 BOOST_ASSERT( impl_);
1705 template< typename Arg >
1706 template< typename StackAllocator >
1707 push_coroutine< Arg >::push_coroutine( coroutine_fn fn,
1708 attributes const& attrs,
1709 StackAllocator stack_alloc) :
1712 // create a stack-context
1713 stack_context stack_ctx;
1714 // allocate the coroutine-stack
1715 stack_alloc.allocate( stack_ctx, attrs.size);
1716 BOOST_ASSERT( 0 != stack_ctx.sp);
1717 // typedef of internal coroutine-type
1718 typedef detail::push_coroutine_object<
1719 pull_coroutine< Arg >, Arg, coroutine_fn, StackAllocator
1721 // reserve space on top of coroutine-stack for internal coroutine-type
1722 std::size_t size = stack_ctx.size - sizeof( object_t);
1723 BOOST_ASSERT( 0 != size);
1724 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1725 BOOST_ASSERT( 0 != sp);
1726 // placement new for internal coroutine
1727 impl_ = new ( sp) object_t(
1728 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1729 BOOST_ASSERT( impl_);
1732 template< typename Arg >
1733 push_coroutine< Arg & >::push_coroutine( coroutine_fn fn,
1734 attributes const& attrs) :
1737 // create a stack-context
1738 stack_context stack_ctx;
1739 stack_allocator stack_alloc;
1740 // allocate the coroutine-stack
1741 stack_alloc.allocate( stack_ctx, attrs.size);
1742 BOOST_ASSERT( 0 != stack_ctx.sp);
1743 // typedef of internal coroutine-type
1744 typedef detail::push_coroutine_object<
1745 pull_coroutine< Arg & >, Arg &, coroutine_fn, stack_allocator
1747 // reserve space on top of coroutine-stack for internal coroutine-type
1748 std::size_t size = stack_ctx.size - sizeof( object_t);
1749 BOOST_ASSERT( 0 != size);
1750 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1751 BOOST_ASSERT( 0 != sp);
1752 // placement new for internal coroutine
1753 impl_ = new ( sp) object_t(
1754 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1755 BOOST_ASSERT( impl_);
1758 template< typename Arg >
1759 template< typename StackAllocator >
1760 push_coroutine< Arg & >::push_coroutine( coroutine_fn fn,
1761 attributes const& attrs,
1762 StackAllocator stack_alloc) :
1765 // create a stack-context
1766 stack_context stack_ctx;
1767 // allocate the coroutine-stack
1768 stack_alloc.allocate( stack_ctx, attrs.size);
1769 BOOST_ASSERT( 0 != stack_ctx.sp);
1770 // typedef of internal coroutine-type
1771 typedef detail::push_coroutine_object<
1772 pull_coroutine< Arg & >, Arg &, coroutine_fn, StackAllocator
1774 // reserve space on top of coroutine-stack for internal coroutine-type
1775 std::size_t size = stack_ctx.size - sizeof( object_t);
1776 BOOST_ASSERT( 0 != size);
1777 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1778 BOOST_ASSERT( 0 != sp);
1779 // placement new for internal coroutine
1780 impl_ = new ( sp) object_t(
1781 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1782 BOOST_ASSERT( impl_);
1785 inline push_coroutine< void >::push_coroutine( coroutine_fn fn,
1786 attributes const& attrs) :
1789 // create a stack-context
1790 stack_context stack_ctx;
1791 stack_allocator stack_alloc;
1792 // allocate the coroutine-stack
1793 stack_alloc.allocate( stack_ctx, attrs.size);
1794 BOOST_ASSERT( 0 != stack_ctx.sp);
1795 // typedef of internal coroutine-type
1796 typedef detail::push_coroutine_object<
1797 pull_coroutine< void >, void, coroutine_fn, stack_allocator
1799 // reserve space on top of coroutine-stack for internal coroutine-type
1800 std::size_t size = stack_ctx.size - sizeof( object_t);
1801 BOOST_ASSERT( 0 != size);
1802 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1803 BOOST_ASSERT( 0 != sp);
1804 // placement new for internal coroutine
1805 impl_ = new ( sp) object_t(
1806 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1807 BOOST_ASSERT( impl_);
1810 template< typename StackAllocator >
1811 push_coroutine< void >::push_coroutine( coroutine_fn fn,
1812 attributes const& attrs,
1813 StackAllocator stack_alloc) :
1816 // create a stack-context
1817 stack_context stack_ctx;
1818 // allocate the coroutine-stack
1819 stack_alloc.allocate( stack_ctx, attrs.size);
1820 BOOST_ASSERT( 0 != stack_ctx.sp);
1821 // typedef of internal coroutine-type
1822 typedef detail::push_coroutine_object<
1823 pull_coroutine< void >, void, coroutine_fn, StackAllocator
1825 // reserve space on top of coroutine-stack for internal coroutine-type
1826 std::size_t size = stack_ctx.size - sizeof( object_t);
1827 BOOST_ASSERT( 0 != size);
1828 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1829 BOOST_ASSERT( 0 != sp);
1830 // placement new for internal coroutine
1831 impl_ = new ( sp) object_t(
1832 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1833 BOOST_ASSERT( impl_);
1836 template< typename Arg >
1837 template< typename Fn >
1838 push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
1839 attributes const& attrs) :
1842 // create a stack-context
1843 stack_context stack_ctx;
1844 stack_allocator stack_alloc;
1845 // allocate the coroutine-stack
1846 stack_alloc.allocate( stack_ctx, attrs.size);
1847 BOOST_ASSERT( 0 != stack_ctx.sp);
1848 // typedef of internal coroutine-type
1849 typedef detail::push_coroutine_object<
1850 pull_coroutine< Arg >, Arg, Fn, stack_allocator
1852 // reserve space on top of coroutine-stack for internal coroutine-type
1853 std::size_t size = stack_ctx.size - sizeof( object_t);
1854 BOOST_ASSERT( 0 != size);
1855 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1856 BOOST_ASSERT( 0 != sp);
1857 // placement new for internal coroutine
1858 impl_ = new ( sp) object_t(
1859 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1860 BOOST_ASSERT( impl_);
1863 template< typename Arg >
1864 template< typename Fn, typename StackAllocator >
1865 push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
1866 attributes const& attrs,
1867 StackAllocator stack_alloc) :
1870 // create a stack-context
1871 stack_context stack_ctx;
1872 // allocate the coroutine-stack
1873 stack_alloc.allocate( stack_ctx, attrs.size);
1874 BOOST_ASSERT( 0 != stack_ctx.sp);
1875 // typedef of internal coroutine-type
1876 typedef detail::push_coroutine_object<
1877 pull_coroutine< Arg >, Arg, Fn, StackAllocator
1879 // reserve space on top of coroutine-stack for internal coroutine-type
1880 std::size_t size = stack_ctx.size - sizeof( object_t);
1881 BOOST_ASSERT( 0 != size);
1882 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1883 BOOST_ASSERT( 0 != sp);
1884 // placement new for internal coroutine
1885 impl_ = new ( sp) object_t(
1886 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1887 BOOST_ASSERT( impl_);
1890 template< typename Arg >
1891 template< typename Fn >
1892 push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
1893 attributes const& attrs) :
1896 // create a stack-context
1897 stack_context stack_ctx;
1898 stack_allocator stack_alloc;
1899 // allocate the coroutine-stack
1900 stack_alloc.allocate( stack_ctx, attrs.size);
1901 BOOST_ASSERT( 0 != stack_ctx.sp);
1902 // typedef of internal coroutine-type
1903 typedef detail::push_coroutine_object<
1904 pull_coroutine< Arg & >, Arg &, Fn, stack_allocator
1906 // reserve space on top of coroutine-stack for internal coroutine-type
1907 std::size_t size = stack_ctx.size - sizeof( object_t);
1908 BOOST_ASSERT( 0 != size);
1909 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1910 BOOST_ASSERT( 0 != sp);
1911 // placement new for internal coroutine
1912 impl_ = new ( sp) object_t(
1913 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1914 BOOST_ASSERT( impl_);
1917 template< typename Arg >
1918 template< typename Fn, typename StackAllocator >
1919 push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
1920 attributes const& attrs,
1921 StackAllocator stack_alloc) :
1924 // create a stack-context
1925 stack_context stack_ctx;
1926 // allocate the coroutine-stack
1927 stack_alloc.allocate( stack_ctx, attrs.size);
1928 BOOST_ASSERT( 0 != stack_ctx.sp);
1929 // typedef of internal coroutine-type
1930 typedef detail::push_coroutine_object<
1931 pull_coroutine< Arg & >, Arg &, Fn, StackAllocator
1933 // reserve space on top of coroutine-stack for internal coroutine-type
1934 std::size_t size = stack_ctx.size - sizeof( object_t);
1935 BOOST_ASSERT( 0 != size);
1936 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1937 BOOST_ASSERT( 0 != sp);
1938 // placement new for internal coroutine
1939 impl_ = new ( sp) object_t(
1940 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1941 BOOST_ASSERT( impl_);
1944 template< typename Fn >
1945 push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
1946 attributes const& attrs) :
1949 // create a stack-context
1950 stack_context stack_ctx;
1951 stack_allocator stack_alloc;
1952 // allocate the coroutine-stack
1953 stack_alloc.allocate( stack_ctx, attrs.size);
1954 BOOST_ASSERT( 0 != stack_ctx.sp);
1955 // typedef of internal coroutine-type
1956 typedef detail::push_coroutine_object<
1957 pull_coroutine< void >, void, Fn, stack_allocator
1959 // reserve space on top of coroutine-stack for internal coroutine-type
1960 std::size_t size = stack_ctx.size - sizeof( object_t);
1961 BOOST_ASSERT( 0 != size);
1962 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1963 BOOST_ASSERT( 0 != sp);
1964 // placement new for internal coroutine
1965 impl_ = new ( sp) object_t(
1966 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1967 BOOST_ASSERT( impl_);
1970 template< typename Fn, typename StackAllocator >
1971 push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
1972 attributes const& attrs,
1973 StackAllocator stack_alloc) :
1976 // create a stack-context
1977 stack_context stack_ctx;
1978 // allocate the coroutine-stack
1979 stack_alloc.allocate( stack_ctx, attrs.size);
1980 BOOST_ASSERT( 0 != stack_ctx.sp);
1981 // typedef of internal coroutine-type
1982 typedef detail::push_coroutine_object<
1983 pull_coroutine< void >, void, Fn, StackAllocator
1985 // reserve space on top of coroutine-stack for internal coroutine-type
1986 std::size_t size = stack_ctx.size - sizeof( object_t);
1987 BOOST_ASSERT( 0 != size);
1988 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1989 BOOST_ASSERT( 0 != sp);
1990 // placement new for internal coroutine
1991 impl_ = new ( sp) object_t(
1992 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1993 BOOST_ASSERT( impl_);
1996 template< typename Arg >
1997 template< typename Fn >
1998 push_coroutine< Arg >::push_coroutine( Fn fn,
1999 attributes const& attrs) :
2002 // create a stack-context
2003 stack_context stack_ctx;
2004 stack_allocator stack_alloc;
2005 // allocate the coroutine-stack
2006 stack_alloc.allocate( stack_ctx, attrs.size);
2007 BOOST_ASSERT( 0 != stack_ctx.sp);
2008 // typedef of internal coroutine-type
2009 typedef detail::push_coroutine_object<
2010 pull_coroutine< Arg >, Arg, Fn, stack_allocator
2012 // reserve space on top of coroutine-stack for internal coroutine-type
2013 std::size_t size = stack_ctx.size - sizeof( object_t);
2014 BOOST_ASSERT( 0 != size);
2015 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2016 BOOST_ASSERT( 0 != sp);
2017 // placement new for internal coroutine
2018 impl_ = new ( sp) object_t(
2019 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2020 BOOST_ASSERT( impl_);
2023 template< typename Arg >
2024 template< typename Fn, typename StackAllocator >
2025 push_coroutine< Arg >::push_coroutine( Fn fn,
2026 attributes const& attrs,
2027 StackAllocator stack_alloc) :
2030 // create a stack-context
2031 stack_context stack_ctx;
2032 // allocate the coroutine-stack
2033 stack_alloc.allocate( stack_ctx, attrs.size);
2034 BOOST_ASSERT( 0 != stack_ctx.sp);
2035 // typedef of internal coroutine-type
2036 typedef detail::push_coroutine_object<
2037 pull_coroutine< Arg >, Arg, Fn, StackAllocator
2039 // reserve space on top of coroutine-stack for internal coroutine-type
2040 std::size_t size = stack_ctx.size - sizeof( object_t);
2041 BOOST_ASSERT( 0 != size);
2042 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2043 BOOST_ASSERT( 0 != sp);
2044 // placement new for internal coroutine
2045 impl_ = new ( sp) object_t(
2046 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2047 BOOST_ASSERT( impl_);
2050 template< typename Arg >
2051 template< typename Fn >
2052 push_coroutine< Arg & >::push_coroutine( Fn fn,
2053 attributes const& attrs) :
2056 // create a stack-context
2057 stack_context stack_ctx;
2058 stack_allocator stack_alloc;
2059 // allocate the coroutine-stack
2060 stack_alloc.allocate( stack_ctx, attrs.size);
2061 BOOST_ASSERT( 0 != stack_ctx.sp);
2062 // typedef of internal coroutine-type
2063 typedef detail::push_coroutine_object<
2064 pull_coroutine< Arg & >, Arg &, Fn, stack_allocator
2066 // reserve space on top of coroutine-stack for internal coroutine-type
2067 std::size_t size = stack_ctx.size - sizeof( object_t);
2068 BOOST_ASSERT( 0 != size);
2069 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2070 BOOST_ASSERT( 0 != sp);
2071 // placement new for internal coroutine
2072 impl_ = new ( sp) object_t(
2073 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2074 BOOST_ASSERT( impl_);
2077 template< typename Arg >
2078 template< typename Fn, typename StackAllocator >
2079 push_coroutine< Arg & >::push_coroutine( Fn fn,
2080 attributes const& attrs,
2081 StackAllocator stack_alloc) :
2084 // create a stack-context
2085 stack_context stack_ctx;
2086 // allocate the coroutine-stack
2087 stack_alloc.allocate( stack_ctx, attrs.size);
2088 BOOST_ASSERT( 0 != stack_ctx.sp);
2089 // typedef of internal coroutine-type
2090 typedef detail::push_coroutine_object<
2091 pull_coroutine< Arg & >, Arg &, Fn, StackAllocator
2093 // reserve space on top of coroutine-stack for internal coroutine-type
2094 std::size_t size = stack_ctx.size - sizeof( object_t);
2095 BOOST_ASSERT( 0 != size);
2096 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2097 BOOST_ASSERT( 0 != sp);
2098 // placement new for internal coroutine
2099 impl_ = new ( sp) object_t(
2100 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2101 BOOST_ASSERT( impl_);
2104 template< typename Fn >
2105 push_coroutine< void >::push_coroutine( Fn fn,
2106 attributes const& attrs) :
2109 // create a stack-context
2110 stack_context stack_ctx;
2111 stack_allocator stack_alloc;
2112 // allocate the coroutine-stack
2113 stack_alloc.allocate( stack_ctx, attrs.size);
2114 BOOST_ASSERT( 0 != stack_ctx.sp);
2115 // typedef of internal coroutine-type
2116 typedef detail::push_coroutine_object<
2117 pull_coroutine< void >, void, Fn, stack_allocator
2119 // reserve space on top of coroutine-stack for internal coroutine-type
2120 std::size_t size = stack_ctx.size - sizeof( object_t);
2121 BOOST_ASSERT( 0 != size);
2122 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2123 BOOST_ASSERT( 0 != sp);
2124 // placement new for internal coroutine
2125 impl_ = new ( sp) object_t(
2126 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2127 BOOST_ASSERT( impl_);
2130 template< typename Fn, typename StackAllocator >
2131 push_coroutine< void >::push_coroutine( Fn fn,
2132 attributes const& attrs,
2133 StackAllocator stack_alloc) :
2136 // create a stack-context
2137 stack_context stack_ctx;
2138 // allocate the coroutine-stack
2139 stack_alloc.allocate( stack_ctx, attrs.size);
2140 BOOST_ASSERT( 0 != stack_ctx.sp);
2141 // typedef of internal coroutine-type
2142 typedef detail::push_coroutine_object<
2143 pull_coroutine< void >, void, Fn, StackAllocator
2145 // reserve space on top of coroutine-stack for internal coroutine-type
2146 std::size_t size = stack_ctx.size - sizeof( object_t);
2147 BOOST_ASSERT( 0 != size);
2148 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2149 BOOST_ASSERT( 0 != sp);
2150 // placement new for internal coroutine
2151 impl_ = new ( sp) object_t(
2152 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2153 BOOST_ASSERT( impl_);
2156 template< typename Arg >
2157 template< typename Fn >
2158 push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
2159 attributes const& attrs) :
2162 // create a stack-context
2163 stack_context stack_ctx;
2164 stack_allocator stack_alloc;
2165 // allocate the coroutine-stack
2166 stack_alloc.allocate( stack_ctx, attrs.size);
2167 BOOST_ASSERT( 0 != stack_ctx.sp);
2168 // typedef of internal coroutine-type
2169 typedef detail::push_coroutine_object<
2170 pull_coroutine< Arg >, Arg, Fn, stack_allocator
2172 // reserve space on top of coroutine-stack for internal coroutine-type
2173 std::size_t size = stack_ctx.size - sizeof( object_t);
2174 BOOST_ASSERT( 0 != size);
2175 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2176 BOOST_ASSERT( 0 != sp);
2177 // placement new for internal coroutine
2178 impl_ = new ( sp) object_t(
2179 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2180 BOOST_ASSERT( impl_);
2183 template< typename Arg >
2184 template< typename Fn, typename StackAllocator >
2185 push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
2186 attributes const& attrs,
2187 StackAllocator stack_alloc) :
2190 // create a stack-context
2191 stack_context stack_ctx;
2192 // allocate the coroutine-stack
2193 stack_alloc.allocate( stack_ctx, attrs.size);
2194 BOOST_ASSERT( 0 != stack_ctx.sp);
2195 // typedef of internal coroutine-type
2196 typedef detail::push_coroutine_object<
2197 pull_coroutine< Arg >, Arg, Fn, StackAllocator
2199 // reserve space on top of coroutine-stack for internal coroutine-type
2200 std::size_t size = stack_ctx.size - sizeof( object_t);
2201 BOOST_ASSERT( 0 != size);
2202 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2203 BOOST_ASSERT( 0 != sp);
2204 // placement new for internal coroutine
2205 impl_ = new ( sp) object_t(
2206 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2207 BOOST_ASSERT( impl_);
2210 template< typename Arg >
2211 template< typename Fn >
2212 push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
2213 attributes const& attrs) :
2216 // create a stack-context
2217 stack_context stack_ctx;
2218 stack_allocator stack_alloc;
2219 // allocate the coroutine-stack
2220 stack_alloc.allocate( stack_ctx, attrs.size);
2221 BOOST_ASSERT( 0 != stack_ctx.sp);
2222 // typedef of internal coroutine-type
2223 typedef detail::push_coroutine_object<
2224 pull_coroutine< Arg & >, Arg &, Fn, stack_allocator
2226 // reserve space on top of coroutine-stack for internal coroutine-type
2227 std::size_t size = stack_ctx.size - sizeof( object_t);
2228 BOOST_ASSERT( 0 != size);
2229 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2230 BOOST_ASSERT( 0 != sp);
2231 // placement new for internal coroutine
2232 impl_ = new ( sp) object_t(
2233 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2234 BOOST_ASSERT( impl_);
2237 template< typename Arg >
2238 template< typename Fn, typename StackAllocator >
2239 push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
2240 attributes const& attrs,
2241 StackAllocator stack_alloc) :
2244 // create a stack-context
2245 stack_context stack_ctx;
2246 // allocate the coroutine-stack
2247 stack_alloc.allocate( stack_ctx, attrs.size);
2248 BOOST_ASSERT( 0 != stack_ctx.sp);
2249 // typedef of internal coroutine-type
2250 typedef detail::push_coroutine_object<
2251 pull_coroutine< Arg & >, Arg &, Fn, StackAllocator
2253 // reserve space on top of coroutine-stack for internal coroutine-type
2254 std::size_t size = stack_ctx.size - sizeof( object_t);
2255 BOOST_ASSERT( 0 != size);
2256 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2257 BOOST_ASSERT( 0 != sp);
2258 // placement new for internal coroutine
2259 impl_ = new ( sp) object_t(
2260 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2261 BOOST_ASSERT( impl_);
2264 template< typename Fn >
2265 push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
2266 attributes const& attrs) :
2269 // create a stack-context
2270 stack_context stack_ctx;
2271 stack_allocator stack_alloc;
2272 // allocate the coroutine-stack
2273 stack_alloc.allocate( stack_ctx, attrs.size);
2274 BOOST_ASSERT( 0 != stack_ctx.sp);
2275 // typedef of internal coroutine-type
2276 typedef detail::push_coroutine_object<
2277 pull_coroutine< void >, void, Fn, stack_allocator
2279 // reserve space on top of coroutine-stack for internal coroutine-type
2280 std::size_t size = stack_ctx.size - sizeof( object_t);
2281 BOOST_ASSERT( 0 != size);
2282 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2283 BOOST_ASSERT( 0 != sp);
2284 // placement new for internal coroutine
2285 impl_ = new ( sp) object_t(
2286 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2287 BOOST_ASSERT( impl_);
2290 template< typename Fn, typename StackAllocator >
2291 push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
2292 attributes const& attrs,
2293 StackAllocator stack_alloc) :
2296 // create a stack-context
2297 stack_context stack_ctx;
2298 // allocate the coroutine-stack
2299 stack_alloc.allocate( stack_ctx, attrs.size);
2300 BOOST_ASSERT( 0 != stack_ctx.sp);
2301 // typedef of internal coroutine-type
2302 typedef detail::push_coroutine_object<
2303 pull_coroutine< void >, void, Fn, StackAllocator
2305 // reserve space on top of coroutine-stack for internal coroutine-type
2306 std::size_t size = stack_ctx.size - sizeof( object_t);
2307 BOOST_ASSERT( 0 != size);
2308 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2309 BOOST_ASSERT( 0 != sp);
2310 // placement new for internal coroutine
2311 impl_ = new ( sp) object_t(
2312 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2313 BOOST_ASSERT( impl_);
2317 template< typename R >
2318 void swap( pull_coroutine< R > & l, pull_coroutine< R > & r) BOOST_NOEXCEPT
2321 template< typename Arg >
2322 void swap( push_coroutine< Arg > & l, push_coroutine< Arg > & r) BOOST_NOEXCEPT
2325 template< typename R >
2326 typename pull_coroutine< R >::iterator
2327 range_begin( pull_coroutine< R > & c)
2328 { return typename pull_coroutine< R >::iterator( & c); }
2330 template< typename R >
2331 typename pull_coroutine< R >::const_iterator
2332 range_begin( pull_coroutine< R > const& c)
2333 { return typename pull_coroutine< R >::const_iterator( & c); }
2335 template< typename R >
2336 typename pull_coroutine< R >::iterator
2337 range_end( pull_coroutine< R > &)
2338 { return typename pull_coroutine< R >::iterator(); }
2340 template< typename R >
2341 typename pull_coroutine< R >::const_iterator
2342 range_end( pull_coroutine< R > const&)
2343 { return typename pull_coroutine< R >::const_iterator(); }
2345 template< typename Arg >
2346 typename push_coroutine< Arg >::iterator
2347 range_begin( push_coroutine< Arg > & c)
2348 { return typename push_coroutine< Arg >::iterator( & c); }
2350 template< typename Arg >
2351 typename push_coroutine< Arg >::iterator
2352 range_end( push_coroutine< Arg > &)
2353 { return typename push_coroutine< Arg >::iterator(); }
2355 template< typename T >
2356 struct asymmetric_coroutine
2358 typedef push_coroutine< T > push_type;
2359 typedef pull_coroutine< T > pull_type;
2363 template< typename T >
2366 typedef push_coroutine< T > push_type;
2367 typedef pull_coroutine< T > pull_type;
2370 template< typename R >
2371 typename pull_coroutine< R >::iterator
2372 begin( pull_coroutine< R > & c)
2373 { return boost::begin( c); }
2375 template< typename R >
2376 typename pull_coroutine< R >::const_iterator
2377 begin( pull_coroutine< R > const& c)
2378 { return boost::begin( c); }
2380 template< typename R >
2381 typename pull_coroutine< R >::iterator
2382 end( pull_coroutine< R > & c)
2383 { return boost::end( c); }
2385 template< typename R >
2386 typename pull_coroutine< R >::const_iterator
2387 end( pull_coroutine< R > const& c)
2388 { return boost::end( c); }
2390 template< typename R >
2391 typename push_coroutine< R >::iterator
2392 begin( push_coroutine< R > & c)
2393 { return boost::begin( c); }
2395 template< typename R >
2396 typename push_coroutine< R >::iterator
2397 end( push_coroutine< R > & c)
2398 { return boost::end( c); }
2402 template< typename Arg >
2403 struct range_mutable_iterator< coroutines::push_coroutine< Arg > >
2404 { typedef typename coroutines::push_coroutine< Arg >::iterator type; };
2406 template< typename R >
2407 struct range_mutable_iterator< coroutines::pull_coroutine< R > >
2408 { typedef typename coroutines::pull_coroutine< R >::iterator type; };
2412 #ifdef BOOST_HAS_ABI_HEADERS
2413 # include BOOST_ABI_SUFFIX
2416 #endif // BOOST_COROUTINES_ASYMMETRIC_COROUTINE_H