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);
155 class iterator : public std::iterator< std::output_iterator_tag, void, void, void, void >
158 push_coroutine< Arg > * c_;
165 explicit iterator( push_coroutine< Arg > * c) :
169 iterator & operator=( Arg a)
172 if ( ! ( * c_)( a) ) c_ = 0;
176 bool operator==( iterator const& other) const
177 { return other.c_ == c_; }
179 bool operator!=( iterator const& other) const
180 { return other.c_ != c_; }
182 iterator & operator*()
185 iterator & operator++()
189 struct const_iterator;
192 template< typename Arg >
193 class push_coroutine< Arg & >
196 template< typename V, typename X, typename Y, typename Z >
197 friend class detail::pull_coroutine_object;
199 typedef detail::push_coroutine_impl< Arg & > impl_type;
200 typedef detail::push_coroutine_synthesized< Arg & > synth_type;
201 typedef detail::parameters< Arg & > param_type;
207 BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine)
209 explicit push_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
211 { BOOST_ASSERT( impl_); }
214 push_coroutine() BOOST_NOEXCEPT :
218 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
220 typedef void ( * coroutine_fn)( pull_coroutine< Arg & > &);
222 explicit push_coroutine( coroutine_fn,
223 attributes const& = attributes() );
225 template< typename StackAllocator >
226 explicit push_coroutine( coroutine_fn,
230 template< typename Fn >
231 explicit push_coroutine( BOOST_RV_REF( Fn),
232 attributes const& = attributes() );
234 template< typename Fn, typename StackAllocator >
235 explicit push_coroutine( BOOST_RV_REF( Fn),
239 template< typename Fn >
240 explicit push_coroutine( Fn,
241 attributes const& = attributes() );
243 template< typename Fn, typename StackAllocator >
244 explicit push_coroutine( Fn,
248 template< typename Fn >
249 explicit push_coroutine( BOOST_RV_REF( Fn),
250 attributes const& = attributes() );
252 template< typename Fn, typename StackAllocator >
253 explicit push_coroutine( BOOST_RV_REF( Fn),
267 push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT :
271 push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT
273 push_coroutine tmp( boost::move( other) );
278 BOOST_EXPLICIT_OPERATOR_BOOL();
280 bool operator!() const BOOST_NOEXCEPT
281 { return 0 == impl_ || impl_->is_complete(); }
283 void swap( push_coroutine & other) BOOST_NOEXCEPT
284 { std::swap( impl_, other.impl_); }
286 push_coroutine & operator()( Arg & arg)
288 BOOST_ASSERT( * this);
294 class iterator : public std::iterator< std::output_iterator_tag, void, void, void, void >
297 push_coroutine< Arg & > * c_;
304 explicit iterator( push_coroutine< Arg & > * c) :
308 iterator & operator=( Arg & a)
311 if ( ! ( * c_)( a) ) c_ = 0;
315 bool operator==( iterator const& other) const
316 { return other.c_ == c_; }
318 bool operator!=( iterator const& other) const
319 { return other.c_ != c_; }
321 iterator & operator*()
324 iterator & operator++()
328 struct const_iterator;
332 class push_coroutine< void >
335 template< typename V, typename X, typename Y, typename Z >
336 friend class detail::pull_coroutine_object;
338 typedef detail::push_coroutine_impl< void > impl_type;
339 typedef detail::push_coroutine_synthesized< void > synth_type;
340 typedef detail::parameters< void > param_type;
346 BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine)
348 explicit push_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
350 { BOOST_ASSERT( impl_); }
353 push_coroutine() BOOST_NOEXCEPT :
357 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
359 typedef void ( * coroutine_fn)( pull_coroutine< void > &);
361 explicit push_coroutine( coroutine_fn,
362 attributes const& = attributes() );
364 template< typename StackAllocator >
365 explicit push_coroutine( coroutine_fn,
369 template< typename Fn >
370 explicit push_coroutine( BOOST_RV_REF( Fn),
371 attributes const& = attributes() );
373 template< typename Fn, typename StackAllocator >
374 explicit push_coroutine( BOOST_RV_REF( Fn),
378 template< typename Fn >
379 explicit push_coroutine( Fn,
380 attributes const& = attributes() );
382 template< typename Fn, typename StackAllocator >
383 explicit push_coroutine( Fn,
387 template< typename Fn >
388 explicit push_coroutine( BOOST_RV_REF( Fn),
389 attributes const& = attributes() );
391 template< typename Fn, typename StackAllocator >
392 explicit push_coroutine( BOOST_RV_REF( Fn),
406 inline push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT :
410 inline push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT
412 push_coroutine tmp( boost::move( other) );
417 BOOST_EXPLICIT_OPERATOR_BOOL();
419 inline bool operator!() const BOOST_NOEXCEPT
420 { return 0 == impl_ || impl_->is_complete(); }
422 inline void swap( push_coroutine & other) BOOST_NOEXCEPT
423 { std::swap( impl_, other.impl_); }
425 inline push_coroutine & operator()()
427 BOOST_ASSERT( * this);
434 struct const_iterator;
439 template< typename R >
443 template< typename V, typename X, typename Y, typename Z >
444 friend class detail::push_coroutine_object;
446 typedef detail::pull_coroutine_impl< R > impl_type;
447 typedef detail::pull_coroutine_synthesized< R > synth_type;
448 typedef detail::parameters< R > param_type;
454 BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine)
456 explicit pull_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
458 { BOOST_ASSERT( impl_); }
461 pull_coroutine() BOOST_NOEXCEPT :
465 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
467 typedef void ( * coroutine_fn)( push_coroutine< R > &);
469 explicit pull_coroutine( coroutine_fn fn,
470 attributes const& attrs = attributes() ) :
473 // create a stack-context
474 stack_context stack_ctx;
475 stack_allocator stack_alloc;
476 // allocate the coroutine-stack
477 stack_alloc.allocate( stack_ctx, attrs.size);
478 BOOST_ASSERT( 0 != stack_ctx.sp);
479 // typedef of internal coroutine-type
480 typedef detail::pull_coroutine_object<
481 push_coroutine< R >, R, coroutine_fn, stack_allocator
483 // reserve space on top of coroutine-stack for internal coroutine-type
484 std::size_t size = stack_ctx.size - sizeof( object_t);
485 BOOST_ASSERT( 0 != size);
486 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
487 BOOST_ASSERT( 0 != sp);
488 // placement new for internal coroutine
489 impl_ = new ( sp) object_t(
490 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
491 BOOST_ASSERT( impl_);
495 template< typename StackAllocator >
496 explicit pull_coroutine( coroutine_fn fn,
497 attributes const& attrs,
498 StackAllocator stack_alloc) :
501 // create a stack-context
502 stack_context stack_ctx;
503 // allocate the coroutine-stack
504 stack_alloc.allocate( stack_ctx, attrs.size);
505 BOOST_ASSERT( 0 != stack_ctx.sp);
506 // typedef of internal coroutine-type
507 typedef detail::pull_coroutine_object<
508 push_coroutine< R >, R, coroutine_fn, StackAllocator
510 // reserve space on top of coroutine-stack for internal coroutine-type
511 std::size_t size = stack_ctx.size - sizeof( object_t);
512 BOOST_ASSERT( 0 != size);
513 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
514 BOOST_ASSERT( 0 != sp);
515 // placement new for internal coroutine
516 impl_ = new ( sp) object_t(
517 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
518 BOOST_ASSERT( impl_);
522 template< typename Fn >
523 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
524 attributes const& attrs = attributes() ) :
527 // create a stack-context
528 stack_context stack_ctx;
529 stack_allocator stack_alloc;
530 // allocate the coroutine-stack
531 stack_alloc.allocate( stack_ctx, attrs.size);
532 BOOST_ASSERT( 0 != stack_ctx.sp);
533 // typedef of internal coroutine-type
534 typedef detail::pull_coroutine_object<
535 push_coroutine< R >, R, Fn, stack_allocator
537 // reserve space on top of coroutine-stack for internal coroutine-type
538 std::size_t size = stack_ctx.size - sizeof( object_t);
539 BOOST_ASSERT( 0 != size);
540 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
541 BOOST_ASSERT( 0 != sp);
542 // placement new for internal coroutine
543 impl_ = new ( sp) object_t(
544 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
545 BOOST_ASSERT( impl_);
549 template< typename Fn, typename StackAllocator >
550 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
551 attributes const& attrs,
552 StackAllocator stack_alloc) :
555 // create a stack-context
556 stack_context stack_ctx;
557 // allocate the coroutine-stack
558 stack_alloc.allocate( stack_ctx, attrs.size);
559 BOOST_ASSERT( 0 != stack_ctx.sp);
560 // typedef of internal coroutine-type
561 typedef detail::pull_coroutine_object<
562 push_coroutine< R >, R, Fn, StackAllocator
564 // reserve space on top of coroutine-stack for internal coroutine-type
565 std::size_t size = stack_ctx.size - sizeof( object_t);
566 BOOST_ASSERT( 0 != size);
567 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
568 BOOST_ASSERT( 0 != sp);
569 // placement new for internal coroutine
570 impl_ = new ( sp) object_t(
571 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
572 BOOST_ASSERT( impl_);
576 template< typename Fn >
577 explicit pull_coroutine( Fn fn,
578 attributes const& attrs = attributes() ) :
581 // create a stack-context
582 stack_context stack_ctx;
583 stack_allocator stack_alloc;
584 // allocate the coroutine-stack
585 stack_alloc.allocate( stack_ctx, attrs.size);
586 BOOST_ASSERT( 0 != stack_ctx.sp);
587 // typedef of internal coroutine-type
588 typedef detail::pull_coroutine_object<
589 push_coroutine< R >, R, Fn, stack_allocator
591 // reserve space on top of coroutine-stack for internal coroutine-type
592 std::size_t size = stack_ctx.size - sizeof( object_t);
593 BOOST_ASSERT( 0 != size);
594 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
595 BOOST_ASSERT( 0 != sp);
596 // placement new for internal coroutine
597 impl_ = new ( sp) object_t(
598 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
599 BOOST_ASSERT( impl_);
603 template< typename Fn, typename StackAllocator >
604 explicit pull_coroutine( Fn fn,
605 attributes const& attrs,
606 StackAllocator stack_alloc) :
609 // create a stack-context
610 stack_context stack_ctx;
611 // allocate the coroutine-stack
612 stack_alloc.allocate( stack_ctx, attrs.size);
613 BOOST_ASSERT( 0 != stack_ctx.sp);
614 // typedef of internal coroutine-type
615 typedef detail::pull_coroutine_object<
616 push_coroutine< R >, R, Fn, StackAllocator
618 // reserve space on top of coroutine-stack for internal coroutine-type
619 std::size_t size = stack_ctx.size - sizeof( object_t);
620 BOOST_ASSERT( 0 != size);
621 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
622 BOOST_ASSERT( 0 != sp);
623 // placement new for internal coroutine
624 impl_ = new ( sp) object_t(
625 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
626 BOOST_ASSERT( impl_);
630 template< typename Fn >
631 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
632 attributes const& attrs = attributes() ) :
635 // create a stack-context
636 stack_context stack_ctx;
637 stack_allocator stack_alloc;
638 // allocate the coroutine-stack
639 stack_alloc.allocate( stack_ctx, attrs.size);
640 BOOST_ASSERT( 0 != stack_ctx.sp);
641 // typedef of internal coroutine-type
642 typedef detail::pull_coroutine_object<
643 push_coroutine< R >, R, Fn, stack_allocator
645 // reserve space on top of coroutine-stack for internal coroutine-type
646 std::size_t size = stack_ctx.size - sizeof( object_t);
647 BOOST_ASSERT( 0 != size);
648 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
649 BOOST_ASSERT( 0 != sp);
650 // placement new for internal coroutine
651 impl_ = new ( sp) object_t(
652 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
653 BOOST_ASSERT( impl_);
657 template< typename Fn, typename StackAllocator >
658 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
659 attributes const& attrs,
660 StackAllocator stack_alloc) :
663 // create a stack-context
664 stack_context stack_ctx;
665 // allocate the coroutine-stack
666 stack_alloc.allocate( stack_ctx, attrs.size);
667 BOOST_ASSERT( 0 != stack_ctx.sp);
668 // typedef of internal coroutine-type
669 typedef detail::pull_coroutine_object<
670 push_coroutine< R >, R, Fn, StackAllocator
672 // reserve space on top of coroutine-stack for internal coroutine-type
673 std::size_t size = stack_ctx.size - sizeof( object_t);
674 BOOST_ASSERT( 0 != size);
675 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
676 BOOST_ASSERT( 0 != sp);
677 // placement new for internal coroutine
678 impl_ = new ( sp) object_t(
679 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
680 BOOST_ASSERT( impl_);
694 pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT :
698 pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT
700 pull_coroutine tmp( boost::move( other) );
705 BOOST_EXPLICIT_OPERATOR_BOOL();
707 bool operator!() const BOOST_NOEXCEPT
708 { return 0 == impl_ || impl_->is_complete(); }
710 void swap( pull_coroutine & other) BOOST_NOEXCEPT
711 { std::swap( impl_, other.impl_); }
713 pull_coroutine & operator()()
715 BOOST_ASSERT( * this);
723 BOOST_ASSERT( 0 != impl_);
728 class iterator : public std::iterator< std::input_iterator_tag, typename remove_reference< R >::type >
731 pull_coroutine< R > * c_;
744 val_ = c_->impl_->get_pointer();
757 typedef typename iterator::pointer pointer_t;
758 typedef typename iterator::reference reference_t;
764 explicit iterator( pull_coroutine< R > * c) :
768 iterator( iterator const& other) :
769 c_( other.c_), val_( other.val_)
772 iterator & operator=( iterator const& other)
774 if ( this == & other) return * this;
780 bool operator==( iterator const& other) const
781 { return other.c_ == c_ && other.val_ == val_; }
783 bool operator!=( iterator const& other) const
784 { return other.c_ != c_ || other.val_ != val_; }
786 iterator & operator++()
792 iterator operator++( int);
794 reference_t operator*() const
797 boost::throw_exception(
802 pointer_t operator->() const
805 boost::throw_exception(
811 class const_iterator : public std::iterator< std::input_iterator_tag, const typename remove_reference< R >::type >
814 pull_coroutine< R > * c_;
827 val_ = c_->impl_->get_pointer();
840 typedef typename const_iterator::pointer pointer_t;
841 typedef typename const_iterator::reference reference_t;
847 explicit const_iterator( pull_coroutine< R > const* c) :
848 c_( const_cast< pull_coroutine< R > * >( c) ),
852 const_iterator( const_iterator const& other) :
853 c_( other.c_), val_( other.val_)
856 const_iterator & operator=( const_iterator const& other)
858 if ( this == & other) return * this;
864 bool operator==( const_iterator const& other) const
865 { return other.c_ == c_ && other.val_ == val_; }
867 bool operator!=( const_iterator const& other) const
868 { return other.c_ != c_ || other.val_ != val_; }
870 const_iterator & operator++()
876 const_iterator operator++( int);
878 reference_t operator*() const
881 boost::throw_exception(
886 pointer_t operator->() const
889 boost::throw_exception(
895 friend class iterator;
896 friend class const_iterator;
899 template< typename R >
900 class pull_coroutine< R & >
903 template< typename V, typename X, typename Y, typename Z >
904 friend class detail::push_coroutine_object;
906 typedef detail::pull_coroutine_impl< R & > impl_type;
907 typedef detail::pull_coroutine_synthesized< R & > synth_type;
908 typedef detail::parameters< R & > param_type;
914 BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine)
916 explicit pull_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
918 { BOOST_ASSERT( impl_); }
921 pull_coroutine() BOOST_NOEXCEPT :
925 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
927 typedef void ( * coroutine_fn)( push_coroutine< R & > &);
929 explicit pull_coroutine( coroutine_fn fn,
930 attributes const& attrs = attributes() ) :
933 // create a stack-context
934 stack_context stack_ctx;
935 stack_allocator stack_alloc;
936 // allocate the coroutine-stack
937 stack_alloc.allocate( stack_ctx, attrs.size);
938 BOOST_ASSERT( 0 != stack_ctx.sp);
939 // typedef of internal coroutine-type
940 typedef detail::pull_coroutine_object<
941 push_coroutine< R & >, R &, coroutine_fn, stack_allocator
943 // reserve space on top of coroutine-stack for internal coroutine-type
944 std::size_t size = stack_ctx.size - sizeof( object_t);
945 BOOST_ASSERT( 0 != size);
946 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
947 BOOST_ASSERT( 0 != sp);
948 // placement new for internal coroutine
949 impl_ = new ( sp) object_t(
950 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
951 BOOST_ASSERT( impl_);
955 template< typename StackAllocator >
956 explicit pull_coroutine( coroutine_fn fn,
957 attributes const& attrs,
958 StackAllocator stack_alloc) :
961 // create a stack-context
962 stack_context stack_ctx;
963 // allocate the coroutine-stack
964 stack_alloc.allocate( stack_ctx, attrs.size);
965 BOOST_ASSERT( 0 != stack_ctx.sp);
966 // typedef of internal coroutine-type
967 typedef detail::pull_coroutine_object<
968 push_coroutine< R & >, R &, coroutine_fn, StackAllocator
970 // reserve space on top of coroutine-stack for internal coroutine-type
971 std::size_t size = stack_ctx.size - sizeof( object_t);
972 BOOST_ASSERT( 0 != size);
973 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
974 BOOST_ASSERT( 0 != sp);
975 // placement new for internal coroutine
976 impl_ = new ( sp) object_t(
977 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
978 BOOST_ASSERT( impl_);
982 template< typename Fn >
983 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
984 attributes const& attrs = attributes() ) :
987 // create a stack-context
988 stack_context stack_ctx;
989 stack_allocator stack_alloc;
990 // allocate the coroutine-stack
991 stack_alloc.allocate( stack_ctx, attrs.size);
992 BOOST_ASSERT( 0 != stack_ctx.sp);
993 // typedef of internal coroutine-type
994 typedef detail::pull_coroutine_object<
995 push_coroutine< R & >, R &, Fn, stack_allocator
997 // reserve space on top of coroutine-stack for internal coroutine-type
998 std::size_t size = stack_ctx.size - sizeof( object_t);
999 BOOST_ASSERT( 0 != size);
1000 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1001 BOOST_ASSERT( 0 != sp);
1002 // placement new for internal coroutine
1003 impl_ = new ( sp) object_t(
1004 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1005 BOOST_ASSERT( impl_);
1009 template< typename Fn, typename StackAllocator >
1010 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1011 attributes const& attrs,
1012 StackAllocator stack_alloc) :
1015 // create a stack-context
1016 stack_context stack_ctx;
1017 // allocate the coroutine-stack
1018 stack_alloc.allocate( stack_ctx, attrs.size);
1019 BOOST_ASSERT( 0 != stack_ctx.sp);
1020 // typedef of internal coroutine-type
1021 typedef detail::pull_coroutine_object<
1022 push_coroutine< R & >, R &, Fn, StackAllocator
1024 // reserve space on top of coroutine-stack for internal coroutine-type
1025 std::size_t size = stack_ctx.size - sizeof( object_t);
1026 BOOST_ASSERT( 0 != size);
1027 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1028 BOOST_ASSERT( 0 != sp);
1029 // placement new for internal coroutine
1030 impl_ = new ( sp) object_t(
1031 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1032 BOOST_ASSERT( impl_);
1036 template< typename Fn >
1037 explicit pull_coroutine( Fn fn,
1038 attributes const& attrs = attributes() ) :
1041 // create a stack-context
1042 stack_context stack_ctx;
1043 stack_allocator stack_alloc;
1044 // allocate the coroutine-stack
1045 stack_alloc.allocate( stack_ctx, attrs.size);
1046 BOOST_ASSERT( 0 != stack_ctx.sp);
1047 // typedef of internal coroutine-type
1048 typedef detail::pull_coroutine_object<
1049 push_coroutine< R & >, R &, Fn, stack_allocator
1051 // reserve space on top of coroutine-stack for internal coroutine-type
1052 std::size_t size = stack_ctx.size - sizeof( object_t);
1053 BOOST_ASSERT( 0 != size);
1054 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1055 BOOST_ASSERT( 0 != sp);
1056 // placement new for internal coroutine
1057 impl_ = new ( sp) object_t(
1058 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1059 BOOST_ASSERT( impl_);
1063 template< typename Fn, typename StackAllocator >
1064 explicit pull_coroutine( Fn fn,
1065 attributes const& attrs,
1066 StackAllocator stack_alloc) :
1069 // create a stack-context
1070 stack_context stack_ctx;
1071 // allocate the coroutine-stack
1072 stack_alloc.allocate( stack_ctx, attrs.size);
1073 BOOST_ASSERT( 0 != stack_ctx.sp);
1074 // typedef of internal coroutine-type
1075 typedef detail::pull_coroutine_object<
1076 push_coroutine< R & >, R &, Fn, StackAllocator
1078 // reserve space on top of coroutine-stack for internal coroutine-type
1079 std::size_t size = stack_ctx.size - sizeof( object_t);
1080 BOOST_ASSERT( 0 != size);
1081 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1082 BOOST_ASSERT( 0 != sp);
1083 // placement new for internal coroutine
1084 impl_ = new ( sp) object_t(
1085 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1086 BOOST_ASSERT( impl_);
1090 template< typename Fn >
1091 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1092 attributes const& attrs = attributes() ) :
1095 // create a stack-context
1096 stack_context stack_ctx;
1097 stack_allocator stack_alloc;
1098 // allocate the coroutine-stack
1099 stack_alloc.allocate( stack_ctx, attrs.size);
1100 BOOST_ASSERT( 0 != stack_ctx.sp);
1101 // typedef of internal coroutine-type
1102 typedef detail::pull_coroutine_object<
1103 push_coroutine< R & >, R &, Fn, stack_allocator
1105 // reserve space on top of coroutine-stack for internal coroutine-type
1106 std::size_t size = stack_ctx.size - sizeof( object_t);
1107 BOOST_ASSERT( 0 != size);
1108 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1109 BOOST_ASSERT( 0 != sp);
1110 // placement new for internal coroutine
1111 impl_ = new ( sp) object_t(
1112 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1113 BOOST_ASSERT( impl_);
1117 template< typename Fn, typename StackAllocator >
1118 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1119 attributes const& attrs,
1120 StackAllocator stack_alloc) :
1123 // create a stack-context
1124 stack_context stack_ctx;
1125 // allocate the coroutine-stack
1126 stack_alloc.allocate( stack_ctx, attrs.size);
1127 BOOST_ASSERT( 0 != stack_ctx.sp);
1128 // typedef of internal coroutine-type
1129 typedef detail::pull_coroutine_object<
1130 push_coroutine< R & >, R &, Fn, StackAllocator
1132 // reserve space on top of coroutine-stack for internal coroutine-type
1133 std::size_t size = stack_ctx.size - sizeof( object_t);
1134 BOOST_ASSERT( 0 != size);
1135 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1136 BOOST_ASSERT( 0 != sp);
1137 // placement new for internal coroutine
1138 impl_ = new ( sp) object_t(
1139 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1140 BOOST_ASSERT( impl_);
1154 pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT :
1158 pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT
1160 pull_coroutine tmp( boost::move( other) );
1165 BOOST_EXPLICIT_OPERATOR_BOOL();
1167 bool operator!() const BOOST_NOEXCEPT
1168 { return 0 == impl_ || impl_->is_complete(); }
1170 void swap( pull_coroutine & other) BOOST_NOEXCEPT
1171 { std::swap( impl_, other.impl_); }
1173 pull_coroutine & operator()()
1175 BOOST_ASSERT( * this);
1182 { return impl_->get(); }
1184 class iterator : public std::iterator< std::input_iterator_tag, typename remove_reference< R >::type >
1187 pull_coroutine< R & > * c_;
1200 val_ = c_->impl_->get_pointer();
1206 BOOST_ASSERT( * c_);
1213 typedef typename iterator::pointer pointer_t;
1214 typedef typename iterator::reference reference_t;
1220 explicit iterator( pull_coroutine< R & > * c) :
1224 iterator( iterator const& other) :
1225 c_( other.c_), val_( other.val_)
1228 iterator & operator=( iterator const& other)
1230 if ( this == & other) return * this;
1236 bool operator==( iterator const& other) const
1237 { return other.c_ == c_ && other.val_ == val_; }
1239 bool operator!=( iterator const& other) const
1240 { return other.c_ != c_ || other.val_ != val_; }
1242 iterator & operator++()
1248 iterator operator++( int);
1250 reference_t operator*() const
1253 boost::throw_exception(
1258 pointer_t operator->() const
1261 boost::throw_exception(
1267 class const_iterator : public std::iterator< std::input_iterator_tag, const typename remove_reference< R >::type >
1270 pull_coroutine< R & > * c_;
1283 val_ = c_->impl_->get_pointer();
1289 BOOST_ASSERT( * c_);
1296 typedef typename const_iterator::pointer pointer_t;
1297 typedef typename const_iterator::reference reference_t;
1303 explicit const_iterator( pull_coroutine< R & > const* c) :
1304 c_( const_cast< pull_coroutine< R & > * >( c) ),
1308 const_iterator( const_iterator const& other) :
1309 c_( other.c_), val_( other.val_)
1312 const_iterator & operator=( const_iterator const& other)
1314 if ( this == & other) return * this;
1320 bool operator==( const_iterator const& other) const
1321 { return other.c_ == c_ && other.val_ == val_; }
1323 bool operator!=( const_iterator const& other) const
1324 { return other.c_ != c_ || other.val_ != val_; }
1326 const_iterator & operator++()
1332 const_iterator operator++( int);
1334 reference_t operator*() const
1337 boost::throw_exception(
1342 pointer_t operator->() const
1345 boost::throw_exception(
1351 friend class iterator;
1352 friend class const_iterator;
1356 class pull_coroutine< void >
1359 template< typename V, typename X, typename Y, typename Z >
1360 friend class detail::push_coroutine_object;
1362 typedef detail::pull_coroutine_impl< void > impl_type;
1363 typedef detail::pull_coroutine_synthesized< void > synth_type;
1364 typedef detail::parameters< void > param_type;
1370 BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine)
1372 explicit pull_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
1374 { BOOST_ASSERT( impl_); }
1377 pull_coroutine() BOOST_NOEXCEPT :
1381 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1383 typedef void ( * coroutine_fn)( push_coroutine< void > &);
1385 explicit pull_coroutine( coroutine_fn fn,
1386 attributes const& attrs = attributes() ) :
1389 // create a stack-context
1390 stack_context stack_ctx;
1391 stack_allocator stack_alloc;
1392 // allocate the coroutine-stack
1393 stack_alloc.allocate( stack_ctx, attrs.size);
1394 BOOST_ASSERT( 0 != stack_ctx.sp);
1395 // typedef of internal coroutine-type
1396 typedef detail::pull_coroutine_object<
1397 push_coroutine< void >, void, coroutine_fn, stack_allocator
1399 // reserve space on top of coroutine-stack for internal coroutine-type
1400 std::size_t size = stack_ctx.size - sizeof( object_t);
1401 BOOST_ASSERT( 0 != size);
1402 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1403 BOOST_ASSERT( 0 != sp);
1404 // placement new for internal coroutine
1405 impl_ = new ( sp) object_t(
1406 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1407 BOOST_ASSERT( impl_);
1411 template< typename StackAllocator >
1412 explicit pull_coroutine( coroutine_fn fn,
1413 attributes const& attrs,
1414 StackAllocator stack_alloc) :
1417 // create a stack-context
1418 stack_context stack_ctx;
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, StackAllocator
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_);
1438 template< typename Fn >
1439 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1440 attributes const& attrs = attributes() ) :
1443 // create a stack-context
1444 stack_context stack_ctx;
1445 stack_allocator stack_alloc;
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, Fn, stack_allocator
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< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1461 BOOST_ASSERT( impl_);
1465 template< typename Fn, typename StackAllocator >
1466 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1467 attributes const& attrs,
1468 StackAllocator stack_alloc) :
1471 // create a stack-context
1472 stack_context stack_ctx;
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, StackAllocator
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_);
1492 template< typename Fn >
1493 explicit pull_coroutine( Fn fn,
1494 attributes const& attrs = attributes() ) :
1497 // create a stack-context
1498 stack_context stack_ctx;
1499 stack_allocator stack_alloc;
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, stack_allocator
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 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1515 BOOST_ASSERT( impl_);
1519 template< typename Fn, typename StackAllocator >
1520 explicit pull_coroutine( Fn fn,
1521 attributes const& attrs,
1522 StackAllocator stack_alloc) :
1525 // create a stack-context
1526 stack_context stack_ctx;
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, StackAllocator
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_);
1546 template< typename Fn >
1547 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1548 attributes const& attrs = attributes() ) :
1551 // create a stack-context
1552 stack_context stack_ctx;
1553 stack_allocator stack_alloc;
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, stack_allocator
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_);
1573 template< typename Fn, typename StackAllocator >
1574 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1575 attributes const& attrs,
1576 StackAllocator stack_alloc) :
1579 // create a stack-context
1580 stack_context stack_ctx;
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, StackAllocator
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_);
1610 inline pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT :
1614 inline pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT
1616 pull_coroutine tmp( boost::move( other) );
1621 BOOST_EXPLICIT_OPERATOR_BOOL();
1623 inline bool operator!() const BOOST_NOEXCEPT
1624 { return 0 == impl_ || impl_->is_complete(); }
1626 inline void swap( pull_coroutine & other) BOOST_NOEXCEPT
1627 { std::swap( impl_, other.impl_); }
1629 inline pull_coroutine & operator()()
1631 BOOST_ASSERT( * this);
1638 struct const_iterator;
1641 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1643 template< typename Arg >
1644 push_coroutine< Arg >::push_coroutine( coroutine_fn fn,
1645 attributes const& attrs) :
1648 // create a stack-context
1649 stack_context stack_ctx;
1650 stack_allocator stack_alloc;
1651 // allocate the coroutine-stack
1652 stack_alloc.allocate( stack_ctx, attrs.size);
1653 BOOST_ASSERT( 0 != stack_ctx.sp);
1654 // typedef of internal coroutine-type
1655 typedef detail::push_coroutine_object<
1656 pull_coroutine< Arg >, Arg, coroutine_fn, stack_allocator
1658 // reserve space on top of coroutine-stack for internal coroutine-type
1659 std::size_t size = stack_ctx.size - sizeof( object_t);
1660 BOOST_ASSERT( 0 != size);
1661 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1662 BOOST_ASSERT( 0 != sp);
1663 // placement new for internal coroutine
1664 impl_ = new ( sp) object_t(
1665 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1666 BOOST_ASSERT( impl_);
1669 template< typename Arg >
1670 template< typename StackAllocator >
1671 push_coroutine< Arg >::push_coroutine( coroutine_fn fn,
1672 attributes const& attrs,
1673 StackAllocator stack_alloc) :
1676 // create a stack-context
1677 stack_context stack_ctx;
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, StackAllocator
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_);
1696 template< typename Arg >
1697 push_coroutine< Arg & >::push_coroutine( coroutine_fn fn,
1698 attributes const& attrs) :
1701 // create a stack-context
1702 stack_context stack_ctx;
1703 stack_allocator stack_alloc;
1704 // allocate the coroutine-stack
1705 stack_alloc.allocate( stack_ctx, attrs.size);
1706 BOOST_ASSERT( 0 != stack_ctx.sp);
1707 // typedef of internal coroutine-type
1708 typedef detail::push_coroutine_object<
1709 pull_coroutine< Arg & >, Arg &, coroutine_fn, stack_allocator
1711 // reserve space on top of coroutine-stack for internal coroutine-type
1712 std::size_t size = stack_ctx.size - sizeof( object_t);
1713 BOOST_ASSERT( 0 != size);
1714 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1715 BOOST_ASSERT( 0 != sp);
1716 // placement new for internal coroutine
1717 impl_ = new ( sp) object_t(
1718 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1719 BOOST_ASSERT( impl_);
1722 template< typename Arg >
1723 template< typename StackAllocator >
1724 push_coroutine< Arg & >::push_coroutine( coroutine_fn fn,
1725 attributes const& attrs,
1726 StackAllocator stack_alloc) :
1729 // create a stack-context
1730 stack_context stack_ctx;
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, StackAllocator
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_);
1749 inline push_coroutine< void >::push_coroutine( coroutine_fn fn,
1750 attributes const& attrs) :
1753 // create a stack-context
1754 stack_context stack_ctx;
1755 stack_allocator stack_alloc;
1756 // allocate the coroutine-stack
1757 stack_alloc.allocate( stack_ctx, attrs.size);
1758 BOOST_ASSERT( 0 != stack_ctx.sp);
1759 // typedef of internal coroutine-type
1760 typedef detail::push_coroutine_object<
1761 pull_coroutine< void >, void, coroutine_fn, stack_allocator
1763 // reserve space on top of coroutine-stack for internal coroutine-type
1764 std::size_t size = stack_ctx.size - sizeof( object_t);
1765 BOOST_ASSERT( 0 != size);
1766 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1767 BOOST_ASSERT( 0 != sp);
1768 // placement new for internal coroutine
1769 impl_ = new ( sp) object_t(
1770 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1771 BOOST_ASSERT( impl_);
1774 template< typename StackAllocator >
1775 push_coroutine< void >::push_coroutine( coroutine_fn fn,
1776 attributes const& attrs,
1777 StackAllocator stack_alloc) :
1780 // create a stack-context
1781 stack_context stack_ctx;
1782 // allocate the coroutine-stack
1783 stack_alloc.allocate( stack_ctx, attrs.size);
1784 BOOST_ASSERT( 0 != stack_ctx.sp);
1785 // typedef of internal coroutine-type
1786 typedef detail::push_coroutine_object<
1787 pull_coroutine< void >, void, coroutine_fn, StackAllocator
1789 // reserve space on top of coroutine-stack for internal coroutine-type
1790 std::size_t size = stack_ctx.size - sizeof( object_t);
1791 BOOST_ASSERT( 0 != size);
1792 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1793 BOOST_ASSERT( 0 != sp);
1794 // placement new for internal coroutine
1795 impl_ = new ( sp) object_t(
1796 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1797 BOOST_ASSERT( impl_);
1800 template< typename Arg >
1801 template< typename Fn >
1802 push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
1803 attributes const& attrs) :
1806 // create a stack-context
1807 stack_context stack_ctx;
1808 stack_allocator stack_alloc;
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< Arg >, Arg, Fn, stack_allocator
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< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1824 BOOST_ASSERT( impl_);
1827 template< typename Arg >
1828 template< typename Fn, typename StackAllocator >
1829 push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
1830 attributes const& attrs,
1831 StackAllocator stack_alloc) :
1834 // create a stack-context
1835 stack_context stack_ctx;
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, StackAllocator
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_);
1854 template< typename Arg >
1855 template< typename Fn >
1856 push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
1857 attributes const& attrs) :
1860 // create a stack-context
1861 stack_context stack_ctx;
1862 stack_allocator stack_alloc;
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, stack_allocator
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_);
1881 template< typename Arg >
1882 template< typename Fn, typename StackAllocator >
1883 push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
1884 attributes const& attrs,
1885 StackAllocator stack_alloc) :
1888 // create a stack-context
1889 stack_context stack_ctx;
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, StackAllocator
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_);
1908 template< typename Fn >
1909 push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
1910 attributes const& attrs) :
1913 // create a stack-context
1914 stack_context stack_ctx;
1915 stack_allocator stack_alloc;
1916 // allocate the coroutine-stack
1917 stack_alloc.allocate( stack_ctx, attrs.size);
1918 BOOST_ASSERT( 0 != stack_ctx.sp);
1919 // typedef of internal coroutine-type
1920 typedef detail::push_coroutine_object<
1921 pull_coroutine< void >, void, Fn, stack_allocator
1923 // reserve space on top of coroutine-stack for internal coroutine-type
1924 std::size_t size = stack_ctx.size - sizeof( object_t);
1925 BOOST_ASSERT( 0 != size);
1926 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1927 BOOST_ASSERT( 0 != sp);
1928 // placement new for internal coroutine
1929 impl_ = new ( sp) object_t(
1930 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1931 BOOST_ASSERT( impl_);
1934 template< typename Fn, typename StackAllocator >
1935 push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
1936 attributes const& attrs,
1937 StackAllocator stack_alloc) :
1940 // create a stack-context
1941 stack_context stack_ctx;
1942 // allocate the coroutine-stack
1943 stack_alloc.allocate( stack_ctx, attrs.size);
1944 BOOST_ASSERT( 0 != stack_ctx.sp);
1945 // typedef of internal coroutine-type
1946 typedef detail::push_coroutine_object<
1947 pull_coroutine< void >, void, Fn, StackAllocator
1949 // reserve space on top of coroutine-stack for internal coroutine-type
1950 std::size_t size = stack_ctx.size - sizeof( object_t);
1951 BOOST_ASSERT( 0 != size);
1952 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1953 BOOST_ASSERT( 0 != sp);
1954 // placement new for internal coroutine
1955 impl_ = new ( sp) object_t(
1956 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1957 BOOST_ASSERT( impl_);
1960 template< typename Arg >
1961 template< typename Fn >
1962 push_coroutine< Arg >::push_coroutine( Fn fn,
1963 attributes const& attrs) :
1966 // create a stack-context
1967 stack_context stack_ctx;
1968 stack_allocator stack_alloc;
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< Arg >, Arg, Fn, stack_allocator
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 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1984 BOOST_ASSERT( impl_);
1987 template< typename Arg >
1988 template< typename Fn, typename StackAllocator >
1989 push_coroutine< Arg >::push_coroutine( Fn fn,
1990 attributes const& attrs,
1991 StackAllocator stack_alloc) :
1994 // create a stack-context
1995 stack_context stack_ctx;
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, StackAllocator
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_);
2014 template< typename Arg >
2015 template< typename Fn >
2016 push_coroutine< Arg & >::push_coroutine( Fn fn,
2017 attributes const& attrs) :
2020 // create a stack-context
2021 stack_context stack_ctx;
2022 stack_allocator stack_alloc;
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, stack_allocator
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_);
2041 template< typename Arg >
2042 template< typename Fn, typename StackAllocator >
2043 push_coroutine< Arg & >::push_coroutine( Fn fn,
2044 attributes const& attrs,
2045 StackAllocator stack_alloc) :
2048 // create a stack-context
2049 stack_context stack_ctx;
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, StackAllocator
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_);
2068 template< typename Fn >
2069 push_coroutine< void >::push_coroutine( Fn fn,
2070 attributes const& attrs) :
2073 // create a stack-context
2074 stack_context stack_ctx;
2075 stack_allocator stack_alloc;
2076 // allocate the coroutine-stack
2077 stack_alloc.allocate( stack_ctx, attrs.size);
2078 BOOST_ASSERT( 0 != stack_ctx.sp);
2079 // typedef of internal coroutine-type
2080 typedef detail::push_coroutine_object<
2081 pull_coroutine< void >, void, Fn, stack_allocator
2083 // reserve space on top of coroutine-stack for internal coroutine-type
2084 std::size_t size = stack_ctx.size - sizeof( object_t);
2085 BOOST_ASSERT( 0 != size);
2086 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2087 BOOST_ASSERT( 0 != sp);
2088 // placement new for internal coroutine
2089 impl_ = new ( sp) object_t(
2090 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2091 BOOST_ASSERT( impl_);
2094 template< typename Fn, typename StackAllocator >
2095 push_coroutine< void >::push_coroutine( Fn fn,
2096 attributes const& attrs,
2097 StackAllocator stack_alloc) :
2100 // create a stack-context
2101 stack_context stack_ctx;
2102 // allocate the coroutine-stack
2103 stack_alloc.allocate( stack_ctx, attrs.size);
2104 BOOST_ASSERT( 0 != stack_ctx.sp);
2105 // typedef of internal coroutine-type
2106 typedef detail::push_coroutine_object<
2107 pull_coroutine< void >, void, Fn, StackAllocator
2109 // reserve space on top of coroutine-stack for internal coroutine-type
2110 std::size_t size = stack_ctx.size - sizeof( object_t);
2111 BOOST_ASSERT( 0 != size);
2112 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2113 BOOST_ASSERT( 0 != sp);
2114 // placement new for internal coroutine
2115 impl_ = new ( sp) object_t(
2116 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2117 BOOST_ASSERT( impl_);
2120 template< typename Arg >
2121 template< typename Fn >
2122 push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
2123 attributes const& attrs) :
2126 // create a stack-context
2127 stack_context stack_ctx;
2128 stack_allocator stack_alloc;
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< Arg >, Arg, Fn, stack_allocator
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_);
2147 template< typename Arg >
2148 template< typename Fn, typename StackAllocator >
2149 push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
2150 attributes const& attrs,
2151 StackAllocator stack_alloc) :
2154 // create a stack-context
2155 stack_context stack_ctx;
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, StackAllocator
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_);
2174 template< typename Arg >
2175 template< typename Fn >
2176 push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
2177 attributes const& attrs) :
2180 // create a stack-context
2181 stack_context stack_ctx;
2182 stack_allocator stack_alloc;
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, stack_allocator
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_);
2201 template< typename Arg >
2202 template< typename Fn, typename StackAllocator >
2203 push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
2204 attributes const& attrs,
2205 StackAllocator stack_alloc) :
2208 // create a stack-context
2209 stack_context stack_ctx;
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, StackAllocator
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_);
2228 template< typename Fn >
2229 push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
2230 attributes const& attrs) :
2233 // create a stack-context
2234 stack_context stack_ctx;
2235 stack_allocator stack_alloc;
2236 // allocate the coroutine-stack
2237 stack_alloc.allocate( stack_ctx, attrs.size);
2238 BOOST_ASSERT( 0 != stack_ctx.sp);
2239 // typedef of internal coroutine-type
2240 typedef detail::push_coroutine_object<
2241 pull_coroutine< void >, void, Fn, stack_allocator
2243 // reserve space on top of coroutine-stack for internal coroutine-type
2244 std::size_t size = stack_ctx.size - sizeof( object_t);
2245 BOOST_ASSERT( 0 != size);
2246 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2247 BOOST_ASSERT( 0 != sp);
2248 // placement new for internal coroutine
2249 impl_ = new ( sp) object_t(
2250 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2251 BOOST_ASSERT( impl_);
2254 template< typename Fn, typename StackAllocator >
2255 push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
2256 attributes const& attrs,
2257 StackAllocator stack_alloc) :
2260 // create a stack-context
2261 stack_context stack_ctx;
2262 // allocate the coroutine-stack
2263 stack_alloc.allocate( stack_ctx, attrs.size);
2264 BOOST_ASSERT( 0 != stack_ctx.sp);
2265 // typedef of internal coroutine-type
2266 typedef detail::push_coroutine_object<
2267 pull_coroutine< void >, void, Fn, StackAllocator
2269 // reserve space on top of coroutine-stack for internal coroutine-type
2270 std::size_t size = stack_ctx.size - sizeof( object_t);
2271 BOOST_ASSERT( 0 != size);
2272 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2273 BOOST_ASSERT( 0 != sp);
2274 // placement new for internal coroutine
2275 impl_ = new ( sp) object_t(
2276 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2277 BOOST_ASSERT( impl_);
2281 template< typename R >
2282 void swap( pull_coroutine< R > & l, pull_coroutine< R > & r) BOOST_NOEXCEPT
2285 template< typename Arg >
2286 void swap( push_coroutine< Arg > & l, push_coroutine< Arg > & r) BOOST_NOEXCEPT
2289 template< typename R >
2290 typename pull_coroutine< R >::iterator
2291 range_begin( pull_coroutine< R > & c)
2292 { return typename pull_coroutine< R >::iterator( & c); }
2294 template< typename R >
2295 typename pull_coroutine< R >::const_iterator
2296 range_begin( pull_coroutine< R > const& c)
2297 { return typename pull_coroutine< R >::const_iterator( & c); }
2299 template< typename R >
2300 typename pull_coroutine< R >::iterator
2301 range_end( pull_coroutine< R > &)
2302 { return typename pull_coroutine< R >::iterator(); }
2304 template< typename R >
2305 typename pull_coroutine< R >::const_iterator
2306 range_end( pull_coroutine< R > const&)
2307 { return typename pull_coroutine< R >::const_iterator(); }
2309 template< typename Arg >
2310 typename push_coroutine< Arg >::iterator
2311 range_begin( push_coroutine< Arg > & c)
2312 { return typename push_coroutine< Arg >::iterator( & c); }
2314 template< typename Arg >
2315 typename push_coroutine< Arg >::iterator
2316 range_end( push_coroutine< Arg > &)
2317 { return typename push_coroutine< Arg >::iterator(); }
2319 template< typename T >
2320 struct asymmetric_coroutine
2322 typedef push_coroutine< T > push_type;
2323 typedef pull_coroutine< T > pull_type;
2327 template< typename T >
2330 typedef push_coroutine< T > push_type;
2331 typedef pull_coroutine< T > pull_type;
2334 template< typename R >
2335 typename pull_coroutine< R >::iterator
2336 begin( pull_coroutine< R > & c)
2337 { return boost::begin( c); }
2339 template< typename R >
2340 typename pull_coroutine< R >::const_iterator
2341 begin( pull_coroutine< R > const& c)
2342 { return boost::begin( c); }
2344 template< typename R >
2345 typename pull_coroutine< R >::iterator
2346 end( pull_coroutine< R > & c)
2347 { return boost::end( c); }
2349 template< typename R >
2350 typename pull_coroutine< R >::const_iterator
2351 end( pull_coroutine< R > const& c)
2352 { return boost::end( c); }
2354 template< typename R >
2355 typename push_coroutine< R >::iterator
2356 begin( push_coroutine< R > & c)
2357 { return boost::begin( c); }
2359 template< typename R >
2360 typename push_coroutine< R >::iterator
2361 end( push_coroutine< R > & c)
2362 { return boost::end( c); }
2366 template< typename Arg >
2367 struct range_mutable_iterator< coroutines::push_coroutine< Arg > >
2368 { typedef typename coroutines::push_coroutine< Arg >::iterator type; };
2370 template< typename R >
2371 struct range_mutable_iterator< coroutines::pull_coroutine< R > >
2372 { typedef typename coroutines::pull_coroutine< R >::iterator type; };
2376 #ifdef BOOST_HAS_ABI_HEADERS
2377 # include BOOST_ABI_SUFFIX
2380 #endif // BOOST_COROUTINES_ASYMMETRIC_COROUTINE_H