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
14 #include <boost/assert.hpp>
15 #include <boost/config.hpp>
16 #include <boost/move/move.hpp>
17 #include <boost/throw_exception.hpp>
18 #include <boost/utility/explicit_operator_bool.hpp>
20 #include <boost/coroutine/attributes.hpp>
21 #include <boost/coroutine/detail/config.hpp>
22 #include <boost/coroutine/detail/coroutine_context.hpp>
23 #include <boost/coroutine/detail/parameters.hpp>
24 #include <boost/coroutine/exceptions.hpp>
25 #include <boost/coroutine/stack_allocator.hpp>
26 #include <boost/coroutine/detail/pull_coroutine_impl.hpp>
27 #include <boost/coroutine/detail/pull_coroutine_object.hpp>
28 #include <boost/coroutine/detail/pull_coroutine_synthesized.hpp>
29 #include <boost/coroutine/detail/push_coroutine_impl.hpp>
30 #include <boost/coroutine/detail/push_coroutine_object.hpp>
31 #include <boost/coroutine/detail/push_coroutine_synthesized.hpp>
32 #include <boost/coroutine/stack_context.hpp>
34 #ifdef BOOST_HAS_ABI_HEADERS
35 # include BOOST_ABI_PREFIX
39 namespace coroutines {
41 template< typename R >
44 template< typename Arg >
48 template< typename V, typename X, typename Y, typename Z >
49 friend class detail::pull_coroutine_object;
51 typedef detail::push_coroutine_impl< Arg > impl_type;
52 typedef detail::push_coroutine_synthesized< Arg > synth_type;
53 typedef detail::parameters< Arg > param_type;
59 BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine)
61 explicit push_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
63 { BOOST_ASSERT( impl_); }
66 push_coroutine() BOOST_NOEXCEPT :
70 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
72 typedef void ( * coroutine_fn)( pull_coroutine< Arg > &);
74 explicit push_coroutine( coroutine_fn,
75 attributes const& = attributes() );
77 template< typename StackAllocator >
78 explicit push_coroutine( coroutine_fn,
82 template< typename Fn >
83 explicit push_coroutine( BOOST_RV_REF( Fn),
84 attributes const& = attributes() );
86 template< typename Fn, typename StackAllocator >
87 explicit push_coroutine( BOOST_RV_REF( Fn),
91 template< typename Fn >
92 explicit push_coroutine( Fn fn,
93 attributes const& = attributes() );
95 template< typename Fn, typename StackAllocator >
96 explicit push_coroutine( Fn fn,
100 template< typename Fn >
101 explicit push_coroutine( BOOST_RV_REF( Fn),
102 attributes const& = attributes() );
104 template< typename Fn, typename StackAllocator >
105 explicit push_coroutine( BOOST_RV_REF( Fn),
119 push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT :
123 push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT
125 push_coroutine tmp( boost::move( other) );
130 BOOST_EXPLICIT_OPERATOR_BOOL();
132 bool operator!() const BOOST_NOEXCEPT
133 { return 0 == impl_ || impl_->is_complete(); }
135 void swap( push_coroutine & other) BOOST_NOEXCEPT
136 { std::swap( impl_, other.impl_); }
138 push_coroutine & operator()( Arg arg)
140 BOOST_ASSERT( * this);
149 push_coroutine< Arg > * c_;
152 typedef std::output_iterator_tag iterator_category;
153 typedef void value_type;
154 typedef void difference_type;
155 typedef void pointer;
156 typedef void reference;
162 explicit iterator( push_coroutine< Arg > * c) :
166 iterator & operator=( Arg a)
169 if ( ! ( * c_)( a) ) c_ = 0;
173 bool operator==( iterator const& other) const
174 { return other.c_ == c_; }
176 bool operator!=( iterator const& other) const
177 { return other.c_ != c_; }
179 iterator & operator*()
182 iterator & operator++()
186 struct const_iterator;
189 template< typename Arg >
190 class push_coroutine< Arg & >
193 template< typename V, typename X, typename Y, typename Z >
194 friend class detail::pull_coroutine_object;
196 typedef detail::push_coroutine_impl< Arg & > impl_type;
197 typedef detail::push_coroutine_synthesized< Arg & > synth_type;
198 typedef detail::parameters< Arg & > param_type;
204 BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine)
206 explicit push_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
208 { BOOST_ASSERT( impl_); }
211 push_coroutine() BOOST_NOEXCEPT :
215 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
217 typedef void ( * coroutine_fn)( pull_coroutine< Arg & > &);
219 explicit push_coroutine( coroutine_fn,
220 attributes const& = attributes() );
222 template< typename StackAllocator >
223 explicit push_coroutine( coroutine_fn,
227 template< typename Fn >
228 explicit push_coroutine( BOOST_RV_REF( Fn),
229 attributes const& = attributes() );
231 template< typename Fn, typename StackAllocator >
232 explicit push_coroutine( BOOST_RV_REF( Fn),
236 template< typename Fn >
237 explicit push_coroutine( Fn,
238 attributes const& = attributes() );
240 template< typename Fn, typename StackAllocator >
241 explicit push_coroutine( Fn,
245 template< typename Fn >
246 explicit push_coroutine( BOOST_RV_REF( Fn),
247 attributes const& = attributes() );
249 template< typename Fn, typename StackAllocator >
250 explicit push_coroutine( BOOST_RV_REF( Fn),
264 push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT :
268 push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT
270 push_coroutine tmp( boost::move( other) );
275 BOOST_EXPLICIT_OPERATOR_BOOL();
277 bool operator!() const BOOST_NOEXCEPT
278 { return 0 == impl_ || impl_->is_complete(); }
280 void swap( push_coroutine & other) BOOST_NOEXCEPT
281 { std::swap( impl_, other.impl_); }
283 push_coroutine & operator()( Arg & arg)
285 BOOST_ASSERT( * this);
294 push_coroutine< Arg & > * c_;
297 typedef std::output_iterator_tag iterator_category;
298 typedef void value_type;
299 typedef void difference_type;
300 typedef void pointer;
301 typedef void reference;
307 explicit iterator( push_coroutine< Arg & > * c) :
311 iterator & operator=( Arg & a)
314 if ( ! ( * c_)( a) ) c_ = 0;
318 bool operator==( iterator const& other) const
319 { return other.c_ == c_; }
321 bool operator!=( iterator const& other) const
322 { return other.c_ != c_; }
324 iterator & operator*()
327 iterator & operator++()
331 struct const_iterator;
335 class push_coroutine< void >
338 template< typename V, typename X, typename Y, typename Z >
339 friend class detail::pull_coroutine_object;
341 typedef detail::push_coroutine_impl< void > impl_type;
342 typedef detail::push_coroutine_synthesized< void > synth_type;
343 typedef detail::parameters< void > param_type;
349 BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine)
351 explicit push_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
353 { BOOST_ASSERT( impl_); }
356 push_coroutine() BOOST_NOEXCEPT :
360 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
362 typedef void ( * coroutine_fn)( pull_coroutine< void > &);
364 explicit push_coroutine( coroutine_fn,
365 attributes const& = attributes() );
367 template< typename StackAllocator >
368 explicit push_coroutine( coroutine_fn,
372 template< typename Fn >
373 explicit push_coroutine( BOOST_RV_REF( Fn),
374 attributes const& = attributes() );
376 template< typename Fn, typename StackAllocator >
377 explicit push_coroutine( BOOST_RV_REF( Fn),
381 template< typename Fn >
382 explicit push_coroutine( Fn,
383 attributes const& = attributes() );
385 template< typename Fn, typename StackAllocator >
386 explicit push_coroutine( Fn,
390 template< typename Fn >
391 explicit push_coroutine( BOOST_RV_REF( Fn),
392 attributes const& = attributes() );
394 template< typename Fn, typename StackAllocator >
395 explicit push_coroutine( BOOST_RV_REF( Fn),
409 inline push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT :
413 inline push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT
415 push_coroutine tmp( boost::move( other) );
420 BOOST_EXPLICIT_OPERATOR_BOOL();
422 inline bool operator!() const BOOST_NOEXCEPT
423 { return 0 == impl_ || impl_->is_complete(); }
425 inline void swap( push_coroutine & other) BOOST_NOEXCEPT
426 { std::swap( impl_, other.impl_); }
428 inline push_coroutine & operator()()
430 BOOST_ASSERT( * this);
437 struct const_iterator;
442 template< typename R >
446 template< typename V, typename X, typename Y, typename Z >
447 friend class detail::push_coroutine_object;
449 typedef detail::pull_coroutine_impl< R > impl_type;
450 typedef detail::pull_coroutine_synthesized< R > synth_type;
451 typedef detail::parameters< R > param_type;
457 BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine)
459 explicit pull_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
461 { BOOST_ASSERT( impl_); }
464 pull_coroutine() BOOST_NOEXCEPT :
468 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
470 typedef void ( * coroutine_fn)( push_coroutine< R > &);
472 explicit pull_coroutine( coroutine_fn fn,
473 attributes const& attrs = attributes() ) :
476 // create a stack-context
477 stack_context stack_ctx;
478 stack_allocator stack_alloc;
479 // allocate the coroutine-stack
480 stack_alloc.allocate( stack_ctx, attrs.size);
481 BOOST_ASSERT( 0 != stack_ctx.sp);
482 // typedef of internal coroutine-type
483 typedef detail::pull_coroutine_object<
484 push_coroutine< R >, R, coroutine_fn, stack_allocator
486 // reserve space on top of coroutine-stack for internal coroutine-type
487 std::size_t size = stack_ctx.size - sizeof( object_t);
488 BOOST_ASSERT( 0 != size);
489 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
490 BOOST_ASSERT( 0 != sp);
491 // placement new for internal coroutine
492 impl_ = new ( sp) object_t(
493 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
494 BOOST_ASSERT( impl_);
498 template< typename StackAllocator >
499 explicit pull_coroutine( coroutine_fn fn,
500 attributes const& attrs,
501 StackAllocator stack_alloc) :
504 // create a stack-context
505 stack_context stack_ctx;
506 // allocate the coroutine-stack
507 stack_alloc.allocate( stack_ctx, attrs.size);
508 BOOST_ASSERT( 0 != stack_ctx.sp);
509 // typedef of internal coroutine-type
510 typedef detail::pull_coroutine_object<
511 push_coroutine< R >, R, coroutine_fn, StackAllocator
513 // reserve space on top of coroutine-stack for internal coroutine-type
514 std::size_t size = stack_ctx.size - sizeof( object_t);
515 BOOST_ASSERT( 0 != size);
516 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
517 BOOST_ASSERT( 0 != sp);
518 // placement new for internal coroutine
519 impl_ = new ( sp) object_t(
520 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
521 BOOST_ASSERT( impl_);
525 template< typename Fn >
526 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
527 attributes const& attrs = attributes() ) :
530 // create a stack-context
531 stack_context stack_ctx;
532 stack_allocator stack_alloc;
533 // allocate the coroutine-stack
534 stack_alloc.allocate( stack_ctx, attrs.size);
535 BOOST_ASSERT( 0 != stack_ctx.sp);
536 // typedef of internal coroutine-type
537 typedef detail::pull_coroutine_object<
538 push_coroutine< R >, R, Fn, stack_allocator
540 // reserve space on top of coroutine-stack for internal coroutine-type
541 std::size_t size = stack_ctx.size - sizeof( object_t);
542 BOOST_ASSERT( 0 != size);
543 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
544 BOOST_ASSERT( 0 != sp);
545 // placement new for internal coroutine
546 impl_ = new ( sp) object_t(
547 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
548 BOOST_ASSERT( impl_);
552 template< typename Fn, typename StackAllocator >
553 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
554 attributes const& attrs,
555 StackAllocator stack_alloc) :
558 // create a stack-context
559 stack_context stack_ctx;
560 // allocate the coroutine-stack
561 stack_alloc.allocate( stack_ctx, attrs.size);
562 BOOST_ASSERT( 0 != stack_ctx.sp);
563 // typedef of internal coroutine-type
564 typedef detail::pull_coroutine_object<
565 push_coroutine< R >, R, Fn, StackAllocator
567 // reserve space on top of coroutine-stack for internal coroutine-type
568 std::size_t size = stack_ctx.size - sizeof( object_t);
569 BOOST_ASSERT( 0 != size);
570 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
571 BOOST_ASSERT( 0 != sp);
572 // placement new for internal coroutine
573 impl_ = new ( sp) object_t(
574 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
575 BOOST_ASSERT( impl_);
579 template< typename Fn >
580 explicit pull_coroutine( Fn fn,
581 attributes const& attrs = attributes() ) :
584 // create a stack-context
585 stack_context stack_ctx;
586 stack_allocator stack_alloc;
587 // allocate the coroutine-stack
588 stack_alloc.allocate( stack_ctx, attrs.size);
589 BOOST_ASSERT( 0 != stack_ctx.sp);
590 // typedef of internal coroutine-type
591 typedef detail::pull_coroutine_object<
592 push_coroutine< R >, R, Fn, stack_allocator
594 // reserve space on top of coroutine-stack for internal coroutine-type
595 std::size_t size = stack_ctx.size - sizeof( object_t);
596 BOOST_ASSERT( 0 != size);
597 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
598 BOOST_ASSERT( 0 != sp);
599 // placement new for internal coroutine
600 impl_ = new ( sp) object_t(
601 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
602 BOOST_ASSERT( impl_);
606 template< typename Fn, typename StackAllocator >
607 explicit pull_coroutine( Fn fn,
608 attributes const& attrs,
609 StackAllocator stack_alloc) :
612 // create a stack-context
613 stack_context stack_ctx;
614 // allocate the coroutine-stack
615 stack_alloc.allocate( stack_ctx, attrs.size);
616 BOOST_ASSERT( 0 != stack_ctx.sp);
617 // typedef of internal coroutine-type
618 typedef detail::pull_coroutine_object<
619 push_coroutine< R >, R, Fn, StackAllocator
621 // reserve space on top of coroutine-stack for internal coroutine-type
622 std::size_t size = stack_ctx.size - sizeof( object_t);
623 BOOST_ASSERT( 0 != size);
624 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
625 BOOST_ASSERT( 0 != sp);
626 // placement new for internal coroutine
627 impl_ = new ( sp) object_t(
628 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
629 BOOST_ASSERT( impl_);
633 template< typename Fn >
634 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
635 attributes const& attrs = attributes() ) :
638 // create a stack-context
639 stack_context stack_ctx;
640 stack_allocator stack_alloc;
641 // allocate the coroutine-stack
642 stack_alloc.allocate( stack_ctx, attrs.size);
643 BOOST_ASSERT( 0 != stack_ctx.sp);
644 // typedef of internal coroutine-type
645 typedef detail::pull_coroutine_object<
646 push_coroutine< R >, R, Fn, stack_allocator
648 // reserve space on top of coroutine-stack for internal coroutine-type
649 std::size_t size = stack_ctx.size - sizeof( object_t);
650 BOOST_ASSERT( 0 != size);
651 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
652 BOOST_ASSERT( 0 != sp);
653 // placement new for internal coroutine
654 impl_ = new ( sp) object_t(
655 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
656 BOOST_ASSERT( impl_);
660 template< typename Fn, typename StackAllocator >
661 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
662 attributes const& attrs,
663 StackAllocator stack_alloc) :
666 // create a stack-context
667 stack_context stack_ctx;
668 // allocate the coroutine-stack
669 stack_alloc.allocate( stack_ctx, attrs.size);
670 BOOST_ASSERT( 0 != stack_ctx.sp);
671 // typedef of internal coroutine-type
672 typedef detail::pull_coroutine_object<
673 push_coroutine< R >, R, Fn, StackAllocator
675 // reserve space on top of coroutine-stack for internal coroutine-type
676 std::size_t size = stack_ctx.size - sizeof( object_t);
677 BOOST_ASSERT( 0 != size);
678 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
679 BOOST_ASSERT( 0 != sp);
680 // placement new for internal coroutine
681 impl_ = new ( sp) object_t(
682 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
683 BOOST_ASSERT( impl_);
697 pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT :
701 pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT
703 pull_coroutine tmp( boost::move( other) );
708 BOOST_EXPLICIT_OPERATOR_BOOL();
710 bool operator!() const BOOST_NOEXCEPT
711 { return 0 == impl_ || impl_->is_complete(); }
713 void swap( pull_coroutine & other) BOOST_NOEXCEPT
714 { std::swap( impl_, other.impl_); }
716 pull_coroutine & operator()()
718 BOOST_ASSERT( * this);
726 BOOST_ASSERT( 0 != impl_);
734 pull_coroutine< R > * c_;
747 val_ = c_->impl_->get_pointer();
760 typedef std::input_iterator_tag iterator_category;
761 typedef typename remove_reference< R >::type value_type;
762 typedef std::ptrdiff_t difference_type;
763 typedef value_type * pointer;
764 typedef value_type & reference;
766 typedef pointer pointer_t;
767 typedef reference reference_t;
773 explicit iterator( pull_coroutine< R > * c) :
777 iterator( iterator const& other) :
778 c_( other.c_), val_( other.val_)
781 iterator & operator=( iterator const& other)
783 if ( this == & other) return * this;
789 bool operator==( iterator const& other) const
790 { return other.c_ == c_ && other.val_ == val_; }
792 bool operator!=( iterator const& other) const
793 { return other.c_ != c_ || other.val_ != val_; }
795 iterator & operator++()
801 iterator operator++( int);
803 reference_t operator*() const
806 boost::throw_exception(
811 pointer_t operator->() const
814 boost::throw_exception(
823 pull_coroutine< R > * c_;
836 val_ = c_->impl_->get_pointer();
849 typedef std::input_iterator_tag iterator_category;
850 typedef const typename remove_reference< R >::type value_type;
851 typedef std::ptrdiff_t difference_type;
852 typedef value_type * pointer;
853 typedef value_type & reference;
855 typedef pointer pointer_t;
856 typedef reference reference_t;
862 explicit const_iterator( pull_coroutine< R > const* c) :
863 c_( const_cast< pull_coroutine< R > * >( c) ),
867 const_iterator( const_iterator const& other) :
868 c_( other.c_), val_( other.val_)
871 const_iterator & operator=( const_iterator const& other)
873 if ( this == & other) return * this;
879 bool operator==( const_iterator const& other) const
880 { return other.c_ == c_ && other.val_ == val_; }
882 bool operator!=( const_iterator const& other) const
883 { return other.c_ != c_ || other.val_ != val_; }
885 const_iterator & operator++()
891 const_iterator operator++( int);
893 reference_t operator*() const
896 boost::throw_exception(
901 pointer_t operator->() const
904 boost::throw_exception(
910 friend class iterator;
911 friend class const_iterator;
914 template< typename R >
915 class pull_coroutine< R & >
918 template< typename V, typename X, typename Y, typename Z >
919 friend class detail::push_coroutine_object;
921 typedef detail::pull_coroutine_impl< R & > impl_type;
922 typedef detail::pull_coroutine_synthesized< R & > synth_type;
923 typedef detail::parameters< R & > param_type;
929 BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine)
931 explicit pull_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
933 { BOOST_ASSERT( impl_); }
936 pull_coroutine() BOOST_NOEXCEPT :
940 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
942 typedef void ( * coroutine_fn)( push_coroutine< R & > &);
944 explicit pull_coroutine( coroutine_fn fn,
945 attributes const& attrs = attributes() ) :
948 // create a stack-context
949 stack_context stack_ctx;
950 stack_allocator stack_alloc;
951 // allocate the coroutine-stack
952 stack_alloc.allocate( stack_ctx, attrs.size);
953 BOOST_ASSERT( 0 != stack_ctx.sp);
954 // typedef of internal coroutine-type
955 typedef detail::pull_coroutine_object<
956 push_coroutine< R & >, R &, coroutine_fn, stack_allocator
958 // reserve space on top of coroutine-stack for internal coroutine-type
959 std::size_t size = stack_ctx.size - sizeof( object_t);
960 BOOST_ASSERT( 0 != size);
961 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
962 BOOST_ASSERT( 0 != sp);
963 // placement new for internal coroutine
964 impl_ = new ( sp) object_t(
965 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
966 BOOST_ASSERT( impl_);
970 template< typename StackAllocator >
971 explicit pull_coroutine( coroutine_fn fn,
972 attributes const& attrs,
973 StackAllocator stack_alloc) :
976 // create a stack-context
977 stack_context stack_ctx;
978 // allocate the coroutine-stack
979 stack_alloc.allocate( stack_ctx, attrs.size);
980 BOOST_ASSERT( 0 != stack_ctx.sp);
981 // typedef of internal coroutine-type
982 typedef detail::pull_coroutine_object<
983 push_coroutine< R & >, R &, coroutine_fn, StackAllocator
985 // reserve space on top of coroutine-stack for internal coroutine-type
986 std::size_t size = stack_ctx.size - sizeof( object_t);
987 BOOST_ASSERT( 0 != size);
988 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
989 BOOST_ASSERT( 0 != sp);
990 // placement new for internal coroutine
991 impl_ = new ( sp) object_t(
992 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
993 BOOST_ASSERT( impl_);
997 template< typename Fn >
998 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
999 attributes const& attrs = attributes() ) :
1002 // create a stack-context
1003 stack_context stack_ctx;
1004 stack_allocator stack_alloc;
1005 // allocate the coroutine-stack
1006 stack_alloc.allocate( stack_ctx, attrs.size);
1007 BOOST_ASSERT( 0 != stack_ctx.sp);
1008 // typedef of internal coroutine-type
1009 typedef detail::pull_coroutine_object<
1010 push_coroutine< R & >, R &, Fn, stack_allocator
1012 // reserve space on top of coroutine-stack for internal coroutine-type
1013 std::size_t size = stack_ctx.size - sizeof( object_t);
1014 BOOST_ASSERT( 0 != size);
1015 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1016 BOOST_ASSERT( 0 != sp);
1017 // placement new for internal coroutine
1018 impl_ = new ( sp) object_t(
1019 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1020 BOOST_ASSERT( impl_);
1024 template< typename Fn, typename StackAllocator >
1025 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1026 attributes const& attrs,
1027 StackAllocator stack_alloc) :
1030 // create a stack-context
1031 stack_context stack_ctx;
1032 // allocate the coroutine-stack
1033 stack_alloc.allocate( stack_ctx, attrs.size);
1034 BOOST_ASSERT( 0 != stack_ctx.sp);
1035 // typedef of internal coroutine-type
1036 typedef detail::pull_coroutine_object<
1037 push_coroutine< R & >, R &, Fn, StackAllocator
1039 // reserve space on top of coroutine-stack for internal coroutine-type
1040 std::size_t size = stack_ctx.size - sizeof( object_t);
1041 BOOST_ASSERT( 0 != size);
1042 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1043 BOOST_ASSERT( 0 != sp);
1044 // placement new for internal coroutine
1045 impl_ = new ( sp) object_t(
1046 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1047 BOOST_ASSERT( impl_);
1051 template< typename Fn >
1052 explicit pull_coroutine( Fn fn,
1053 attributes const& attrs = attributes() ) :
1056 // create a stack-context
1057 stack_context stack_ctx;
1058 stack_allocator stack_alloc;
1059 // allocate the coroutine-stack
1060 stack_alloc.allocate( stack_ctx, attrs.size);
1061 BOOST_ASSERT( 0 != stack_ctx.sp);
1062 // typedef of internal coroutine-type
1063 typedef detail::pull_coroutine_object<
1064 push_coroutine< R & >, R &, Fn, stack_allocator
1066 // reserve space on top of coroutine-stack for internal coroutine-type
1067 std::size_t size = stack_ctx.size - sizeof( object_t);
1068 BOOST_ASSERT( 0 != size);
1069 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1070 BOOST_ASSERT( 0 != sp);
1071 // placement new for internal coroutine
1072 impl_ = new ( sp) object_t(
1073 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1074 BOOST_ASSERT( impl_);
1078 template< typename Fn, typename StackAllocator >
1079 explicit pull_coroutine( Fn fn,
1080 attributes const& attrs,
1081 StackAllocator stack_alloc) :
1084 // create a stack-context
1085 stack_context stack_ctx;
1086 // allocate the coroutine-stack
1087 stack_alloc.allocate( stack_ctx, attrs.size);
1088 BOOST_ASSERT( 0 != stack_ctx.sp);
1089 // typedef of internal coroutine-type
1090 typedef detail::pull_coroutine_object<
1091 push_coroutine< R & >, R &, Fn, StackAllocator
1093 // reserve space on top of coroutine-stack for internal coroutine-type
1094 std::size_t size = stack_ctx.size - sizeof( object_t);
1095 BOOST_ASSERT( 0 != size);
1096 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1097 BOOST_ASSERT( 0 != sp);
1098 // placement new for internal coroutine
1099 impl_ = new ( sp) object_t(
1100 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1101 BOOST_ASSERT( impl_);
1105 template< typename Fn >
1106 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1107 attributes const& attrs = attributes() ) :
1110 // create a stack-context
1111 stack_context stack_ctx;
1112 stack_allocator stack_alloc;
1113 // allocate the coroutine-stack
1114 stack_alloc.allocate( stack_ctx, attrs.size);
1115 BOOST_ASSERT( 0 != stack_ctx.sp);
1116 // typedef of internal coroutine-type
1117 typedef detail::pull_coroutine_object<
1118 push_coroutine< R & >, R &, Fn, stack_allocator
1120 // reserve space on top of coroutine-stack for internal coroutine-type
1121 std::size_t size = stack_ctx.size - sizeof( object_t);
1122 BOOST_ASSERT( 0 != size);
1123 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1124 BOOST_ASSERT( 0 != sp);
1125 // placement new for internal coroutine
1126 impl_ = new ( sp) object_t(
1127 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1128 BOOST_ASSERT( impl_);
1132 template< typename Fn, typename StackAllocator >
1133 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1134 attributes const& attrs,
1135 StackAllocator stack_alloc) :
1138 // create a stack-context
1139 stack_context stack_ctx;
1140 // allocate the coroutine-stack
1141 stack_alloc.allocate( stack_ctx, attrs.size);
1142 BOOST_ASSERT( 0 != stack_ctx.sp);
1143 // typedef of internal coroutine-type
1144 typedef detail::pull_coroutine_object<
1145 push_coroutine< R & >, R &, Fn, StackAllocator
1147 // reserve space on top of coroutine-stack for internal coroutine-type
1148 std::size_t size = stack_ctx.size - sizeof( object_t);
1149 BOOST_ASSERT( 0 != size);
1150 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1151 BOOST_ASSERT( 0 != sp);
1152 // placement new for internal coroutine
1153 impl_ = new ( sp) object_t(
1154 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1155 BOOST_ASSERT( impl_);
1169 pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT :
1173 pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT
1175 pull_coroutine tmp( boost::move( other) );
1180 BOOST_EXPLICIT_OPERATOR_BOOL();
1182 bool operator!() const BOOST_NOEXCEPT
1183 { return 0 == impl_ || impl_->is_complete(); }
1185 void swap( pull_coroutine & other) BOOST_NOEXCEPT
1186 { std::swap( impl_, other.impl_); }
1188 pull_coroutine & operator()()
1190 BOOST_ASSERT( * this);
1197 { return impl_->get(); }
1202 pull_coroutine< R & > * c_;
1215 val_ = c_->impl_->get_pointer();
1221 BOOST_ASSERT( * c_);
1228 typedef std::input_iterator_tag iterator_category;
1229 typedef typename remove_reference< R >::type value_type;
1230 typedef std::ptrdiff_t difference_type;
1231 typedef value_type * pointer;
1232 typedef value_type & reference;
1234 typedef pointer pointer_t;
1235 typedef reference reference_t;
1241 explicit iterator( pull_coroutine< R & > * c) :
1245 iterator( iterator const& other) :
1246 c_( other.c_), val_( other.val_)
1249 iterator & operator=( iterator const& other)
1251 if ( this == & other) return * this;
1257 bool operator==( iterator const& other) const
1258 { return other.c_ == c_ && other.val_ == val_; }
1260 bool operator!=( iterator const& other) const
1261 { return other.c_ != c_ || other.val_ != val_; }
1263 iterator & operator++()
1269 iterator operator++( int);
1271 reference_t operator*() const
1274 boost::throw_exception(
1279 pointer_t operator->() const
1282 boost::throw_exception(
1288 class const_iterator
1291 pull_coroutine< R & > * c_;
1304 val_ = c_->impl_->get_pointer();
1310 BOOST_ASSERT( * c_);
1317 typedef std::input_iterator_tag iterator_category;
1318 typedef const typename remove_reference< R >::type value_type;
1319 typedef std::ptrdiff_t difference_type;
1320 typedef value_type * pointer;
1321 typedef value_type & reference;
1323 typedef pointer pointer_t;
1324 typedef reference reference_t;
1330 explicit const_iterator( pull_coroutine< R & > const* c) :
1331 c_( const_cast< pull_coroutine< R & > * >( c) ),
1335 const_iterator( const_iterator const& other) :
1336 c_( other.c_), val_( other.val_)
1339 const_iterator & operator=( const_iterator const& other)
1341 if ( this == & other) return * this;
1347 bool operator==( const_iterator const& other) const
1348 { return other.c_ == c_ && other.val_ == val_; }
1350 bool operator!=( const_iterator const& other) const
1351 { return other.c_ != c_ || other.val_ != val_; }
1353 const_iterator & operator++()
1359 const_iterator operator++( int);
1361 reference_t operator*() const
1364 boost::throw_exception(
1369 pointer_t operator->() const
1372 boost::throw_exception(
1378 friend class iterator;
1379 friend class const_iterator;
1383 class pull_coroutine< void >
1386 template< typename V, typename X, typename Y, typename Z >
1387 friend class detail::push_coroutine_object;
1389 typedef detail::pull_coroutine_impl< void > impl_type;
1390 typedef detail::pull_coroutine_synthesized< void > synth_type;
1391 typedef detail::parameters< void > param_type;
1397 BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine)
1399 explicit pull_coroutine( detail::synthesized_t::flag_t, impl_type & impl) :
1401 { BOOST_ASSERT( impl_); }
1404 pull_coroutine() BOOST_NOEXCEPT :
1408 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1410 typedef void ( * coroutine_fn)( push_coroutine< void > &);
1412 explicit pull_coroutine( coroutine_fn fn,
1413 attributes const& attrs = attributes() ) :
1416 // create a stack-context
1417 stack_context stack_ctx;
1418 stack_allocator stack_alloc;
1419 // allocate the coroutine-stack
1420 stack_alloc.allocate( stack_ctx, attrs.size);
1421 BOOST_ASSERT( 0 != stack_ctx.sp);
1422 // typedef of internal coroutine-type
1423 typedef detail::pull_coroutine_object<
1424 push_coroutine< void >, void, coroutine_fn, stack_allocator
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 StackAllocator >
1439 explicit pull_coroutine( coroutine_fn fn,
1440 attributes const& attrs,
1441 StackAllocator stack_alloc) :
1444 // create a stack-context
1445 stack_context stack_ctx;
1446 // allocate the coroutine-stack
1447 stack_alloc.allocate( stack_ctx, attrs.size);
1448 BOOST_ASSERT( 0 != stack_ctx.sp);
1449 // typedef of internal coroutine-type
1450 typedef detail::pull_coroutine_object<
1451 push_coroutine< void >, void, coroutine_fn, StackAllocator
1453 // reserve space on top of coroutine-stack for internal coroutine-type
1454 std::size_t size = stack_ctx.size - sizeof( object_t);
1455 BOOST_ASSERT( 0 != size);
1456 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1457 BOOST_ASSERT( 0 != sp);
1458 // placement new for internal coroutine
1459 impl_ = new ( sp) object_t(
1460 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1461 BOOST_ASSERT( impl_);
1465 template< typename Fn >
1466 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1467 attributes const& attrs = attributes() ) :
1470 // create a stack-context
1471 stack_context stack_ctx;
1472 stack_allocator stack_alloc;
1473 // allocate the coroutine-stack
1474 stack_alloc.allocate( stack_ctx, attrs.size);
1475 BOOST_ASSERT( 0 != stack_ctx.sp);
1476 // typedef of internal coroutine-type
1477 typedef detail::pull_coroutine_object<
1478 push_coroutine< void >, void, Fn, stack_allocator
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, typename StackAllocator >
1493 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1494 attributes const& attrs,
1495 StackAllocator stack_alloc) :
1498 // create a stack-context
1499 stack_context stack_ctx;
1500 // allocate the coroutine-stack
1501 stack_alloc.allocate( stack_ctx, attrs.size);
1502 BOOST_ASSERT( 0 != stack_ctx.sp);
1503 // typedef of internal coroutine-type
1504 typedef detail::pull_coroutine_object<
1505 push_coroutine< void >, void, Fn, StackAllocator
1507 // reserve space on top of coroutine-stack for internal coroutine-type
1508 std::size_t size = stack_ctx.size - sizeof( object_t);
1509 BOOST_ASSERT( 0 != size);
1510 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1511 BOOST_ASSERT( 0 != sp);
1512 // placement new for internal coroutine
1513 impl_ = new ( sp) object_t(
1514 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1515 BOOST_ASSERT( impl_);
1519 template< typename Fn >
1520 explicit pull_coroutine( Fn fn,
1521 attributes const& attrs = attributes() ) :
1524 // create a stack-context
1525 stack_context stack_ctx;
1526 stack_allocator stack_alloc;
1527 // allocate the coroutine-stack
1528 stack_alloc.allocate( stack_ctx, attrs.size);
1529 BOOST_ASSERT( 0 != stack_ctx.sp);
1530 // typedef of internal coroutine-type
1531 typedef detail::pull_coroutine_object<
1532 push_coroutine< void >, void, Fn, stack_allocator
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, typename StackAllocator >
1547 explicit pull_coroutine( Fn fn,
1548 attributes const& attrs,
1549 StackAllocator stack_alloc) :
1552 // create a stack-context
1553 stack_context stack_ctx;
1554 // allocate the coroutine-stack
1555 stack_alloc.allocate( stack_ctx, attrs.size);
1556 BOOST_ASSERT( 0 != stack_ctx.sp);
1557 // typedef of internal coroutine-type
1558 typedef detail::pull_coroutine_object<
1559 push_coroutine< void >, void, Fn, StackAllocator
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 >
1574 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1575 attributes const& attrs = attributes() ) :
1578 // create a stack-context
1579 stack_context stack_ctx;
1580 stack_allocator stack_alloc;
1581 // allocate the coroutine-stack
1582 stack_alloc.allocate( stack_ctx, attrs.size);
1583 BOOST_ASSERT( 0 != stack_ctx.sp);
1584 // typedef of internal coroutine-type
1585 typedef detail::pull_coroutine_object<
1586 push_coroutine< void >, void, Fn, stack_allocator
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_);
1600 template< typename Fn, typename StackAllocator >
1601 explicit pull_coroutine( BOOST_RV_REF( Fn) fn,
1602 attributes const& attrs,
1603 StackAllocator stack_alloc) :
1606 // create a stack-context
1607 stack_context stack_ctx;
1608 // allocate the coroutine-stack
1609 stack_alloc.allocate( stack_ctx, attrs.size);
1610 BOOST_ASSERT( 0 != stack_ctx.sp);
1611 // typedef of internal coroutine-type
1612 typedef detail::pull_coroutine_object<
1613 push_coroutine< void >, void, Fn, StackAllocator
1615 // reserve space on top of coroutine-stack for internal coroutine-type
1616 std::size_t size = stack_ctx.size - sizeof( object_t);
1617 BOOST_ASSERT( 0 != size);
1618 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1619 BOOST_ASSERT( 0 != sp);
1620 // placement new for internal coroutine
1621 impl_ = new ( sp) object_t(
1622 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1623 BOOST_ASSERT( impl_);
1637 inline pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT :
1641 inline pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT
1643 pull_coroutine tmp( boost::move( other) );
1648 BOOST_EXPLICIT_OPERATOR_BOOL();
1650 inline bool operator!() const BOOST_NOEXCEPT
1651 { return 0 == impl_ || impl_->is_complete(); }
1653 inline void swap( pull_coroutine & other) BOOST_NOEXCEPT
1654 { std::swap( impl_, other.impl_); }
1656 inline pull_coroutine & operator()()
1658 BOOST_ASSERT( * this);
1665 struct const_iterator;
1668 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
1670 template< typename Arg >
1671 push_coroutine< Arg >::push_coroutine( coroutine_fn fn,
1672 attributes const& attrs) :
1675 // create a stack-context
1676 stack_context stack_ctx;
1677 stack_allocator stack_alloc;
1678 // allocate the coroutine-stack
1679 stack_alloc.allocate( stack_ctx, attrs.size);
1680 BOOST_ASSERT( 0 != stack_ctx.sp);
1681 // typedef of internal coroutine-type
1682 typedef detail::push_coroutine_object<
1683 pull_coroutine< Arg >, Arg, coroutine_fn, stack_allocator
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 template< typename StackAllocator >
1698 push_coroutine< Arg >::push_coroutine( coroutine_fn fn,
1699 attributes const& attrs,
1700 StackAllocator stack_alloc) :
1703 // create a stack-context
1704 stack_context stack_ctx;
1705 // allocate the coroutine-stack
1706 stack_alloc.allocate( stack_ctx, attrs.size);
1707 BOOST_ASSERT( 0 != stack_ctx.sp);
1708 // typedef of internal coroutine-type
1709 typedef detail::push_coroutine_object<
1710 pull_coroutine< Arg >, Arg, coroutine_fn, StackAllocator
1712 // reserve space on top of coroutine-stack for internal coroutine-type
1713 std::size_t size = stack_ctx.size - sizeof( object_t);
1714 BOOST_ASSERT( 0 != size);
1715 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1716 BOOST_ASSERT( 0 != sp);
1717 // placement new for internal coroutine
1718 impl_ = new ( sp) object_t(
1719 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1720 BOOST_ASSERT( impl_);
1723 template< typename Arg >
1724 push_coroutine< Arg & >::push_coroutine( coroutine_fn fn,
1725 attributes const& attrs) :
1728 // create a stack-context
1729 stack_context stack_ctx;
1730 stack_allocator stack_alloc;
1731 // allocate the coroutine-stack
1732 stack_alloc.allocate( stack_ctx, attrs.size);
1733 BOOST_ASSERT( 0 != stack_ctx.sp);
1734 // typedef of internal coroutine-type
1735 typedef detail::push_coroutine_object<
1736 pull_coroutine< Arg & >, Arg &, coroutine_fn, stack_allocator
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 template< typename Arg >
1750 template< typename StackAllocator >
1751 push_coroutine< Arg & >::push_coroutine( coroutine_fn fn,
1752 attributes const& attrs,
1753 StackAllocator stack_alloc) :
1756 // create a stack-context
1757 stack_context stack_ctx;
1758 // allocate the coroutine-stack
1759 stack_alloc.allocate( stack_ctx, attrs.size);
1760 BOOST_ASSERT( 0 != stack_ctx.sp);
1761 // typedef of internal coroutine-type
1762 typedef detail::push_coroutine_object<
1763 pull_coroutine< Arg & >, Arg &, coroutine_fn, StackAllocator
1765 // reserve space on top of coroutine-stack for internal coroutine-type
1766 std::size_t size = stack_ctx.size - sizeof( object_t);
1767 BOOST_ASSERT( 0 != size);
1768 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1769 BOOST_ASSERT( 0 != sp);
1770 // placement new for internal coroutine
1771 impl_ = new ( sp) object_t(
1772 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1773 BOOST_ASSERT( impl_);
1776 inline push_coroutine< void >::push_coroutine( coroutine_fn fn,
1777 attributes const& attrs) :
1780 // create a stack-context
1781 stack_context stack_ctx;
1782 stack_allocator stack_alloc;
1783 // allocate the coroutine-stack
1784 stack_alloc.allocate( stack_ctx, attrs.size);
1785 BOOST_ASSERT( 0 != stack_ctx.sp);
1786 // typedef of internal coroutine-type
1787 typedef detail::push_coroutine_object<
1788 pull_coroutine< void >, void, coroutine_fn, stack_allocator
1790 // reserve space on top of coroutine-stack for internal coroutine-type
1791 std::size_t size = stack_ctx.size - sizeof( object_t);
1792 BOOST_ASSERT( 0 != size);
1793 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1794 BOOST_ASSERT( 0 != sp);
1795 // placement new for internal coroutine
1796 impl_ = new ( sp) object_t(
1797 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1798 BOOST_ASSERT( impl_);
1801 template< typename StackAllocator >
1802 push_coroutine< void >::push_coroutine( coroutine_fn fn,
1803 attributes const& attrs,
1804 StackAllocator stack_alloc) :
1807 // create a stack-context
1808 stack_context stack_ctx;
1809 // allocate the coroutine-stack
1810 stack_alloc.allocate( stack_ctx, attrs.size);
1811 BOOST_ASSERT( 0 != stack_ctx.sp);
1812 // typedef of internal coroutine-type
1813 typedef detail::push_coroutine_object<
1814 pull_coroutine< void >, void, coroutine_fn, StackAllocator
1816 // reserve space on top of coroutine-stack for internal coroutine-type
1817 std::size_t size = stack_ctx.size - sizeof( object_t);
1818 BOOST_ASSERT( 0 != size);
1819 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1820 BOOST_ASSERT( 0 != sp);
1821 // placement new for internal coroutine
1822 impl_ = new ( sp) object_t(
1823 boost::forward< coroutine_fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1824 BOOST_ASSERT( impl_);
1827 template< typename Arg >
1828 template< typename Fn >
1829 push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
1830 attributes const& attrs) :
1833 // create a stack-context
1834 stack_context stack_ctx;
1835 stack_allocator stack_alloc;
1836 // allocate the coroutine-stack
1837 stack_alloc.allocate( stack_ctx, attrs.size);
1838 BOOST_ASSERT( 0 != stack_ctx.sp);
1839 // typedef of internal coroutine-type
1840 typedef detail::push_coroutine_object<
1841 pull_coroutine< Arg >, Arg, Fn, stack_allocator
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, typename StackAllocator >
1856 push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
1857 attributes const& attrs,
1858 StackAllocator stack_alloc) :
1861 // create a stack-context
1862 stack_context stack_ctx;
1863 // allocate the coroutine-stack
1864 stack_alloc.allocate( stack_ctx, attrs.size);
1865 BOOST_ASSERT( 0 != stack_ctx.sp);
1866 // typedef of internal coroutine-type
1867 typedef detail::push_coroutine_object<
1868 pull_coroutine< Arg >, Arg, Fn, StackAllocator
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 >
1883 push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
1884 attributes const& attrs) :
1887 // create a stack-context
1888 stack_context stack_ctx;
1889 stack_allocator stack_alloc;
1890 // allocate the coroutine-stack
1891 stack_alloc.allocate( stack_ctx, attrs.size);
1892 BOOST_ASSERT( 0 != stack_ctx.sp);
1893 // typedef of internal coroutine-type
1894 typedef detail::push_coroutine_object<
1895 pull_coroutine< Arg & >, Arg &, Fn, stack_allocator
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 Arg >
1909 template< typename Fn, typename StackAllocator >
1910 push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
1911 attributes const& attrs,
1912 StackAllocator stack_alloc) :
1915 // create a stack-context
1916 stack_context stack_ctx;
1917 // allocate the coroutine-stack
1918 stack_alloc.allocate( stack_ctx, attrs.size);
1919 BOOST_ASSERT( 0 != stack_ctx.sp);
1920 // typedef of internal coroutine-type
1921 typedef detail::push_coroutine_object<
1922 pull_coroutine< Arg & >, Arg &, Fn, StackAllocator
1924 // reserve space on top of coroutine-stack for internal coroutine-type
1925 std::size_t size = stack_ctx.size - sizeof( object_t);
1926 BOOST_ASSERT( 0 != size);
1927 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1928 BOOST_ASSERT( 0 != sp);
1929 // placement new for internal coroutine
1930 impl_ = new ( sp) object_t(
1931 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1932 BOOST_ASSERT( impl_);
1935 template< typename Fn >
1936 push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
1937 attributes const& attrs) :
1940 // create a stack-context
1941 stack_context stack_ctx;
1942 stack_allocator stack_alloc;
1943 // allocate the coroutine-stack
1944 stack_alloc.allocate( stack_ctx, attrs.size);
1945 BOOST_ASSERT( 0 != stack_ctx.sp);
1946 // typedef of internal coroutine-type
1947 typedef detail::push_coroutine_object<
1948 pull_coroutine< void >, void, Fn, stack_allocator
1950 // reserve space on top of coroutine-stack for internal coroutine-type
1951 std::size_t size = stack_ctx.size - sizeof( object_t);
1952 BOOST_ASSERT( 0 != size);
1953 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1954 BOOST_ASSERT( 0 != sp);
1955 // placement new for internal coroutine
1956 impl_ = new ( sp) object_t(
1957 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1958 BOOST_ASSERT( impl_);
1961 template< typename Fn, typename StackAllocator >
1962 push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
1963 attributes const& attrs,
1964 StackAllocator stack_alloc) :
1967 // create a stack-context
1968 stack_context stack_ctx;
1969 // allocate the coroutine-stack
1970 stack_alloc.allocate( stack_ctx, attrs.size);
1971 BOOST_ASSERT( 0 != stack_ctx.sp);
1972 // typedef of internal coroutine-type
1973 typedef detail::push_coroutine_object<
1974 pull_coroutine< void >, void, Fn, StackAllocator
1976 // reserve space on top of coroutine-stack for internal coroutine-type
1977 std::size_t size = stack_ctx.size - sizeof( object_t);
1978 BOOST_ASSERT( 0 != size);
1979 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
1980 BOOST_ASSERT( 0 != sp);
1981 // placement new for internal coroutine
1982 impl_ = new ( sp) object_t(
1983 boost::forward< Fn >( fn), attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
1984 BOOST_ASSERT( impl_);
1987 template< typename Arg >
1988 template< typename Fn >
1989 push_coroutine< Arg >::push_coroutine( Fn fn,
1990 attributes const& attrs) :
1993 // create a stack-context
1994 stack_context stack_ctx;
1995 stack_allocator stack_alloc;
1996 // allocate the coroutine-stack
1997 stack_alloc.allocate( stack_ctx, attrs.size);
1998 BOOST_ASSERT( 0 != stack_ctx.sp);
1999 // typedef of internal coroutine-type
2000 typedef detail::push_coroutine_object<
2001 pull_coroutine< Arg >, Arg, Fn, stack_allocator
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, typename StackAllocator >
2016 push_coroutine< Arg >::push_coroutine( Fn fn,
2017 attributes const& attrs,
2018 StackAllocator stack_alloc) :
2021 // create a stack-context
2022 stack_context stack_ctx;
2023 // allocate the coroutine-stack
2024 stack_alloc.allocate( stack_ctx, attrs.size);
2025 BOOST_ASSERT( 0 != stack_ctx.sp);
2026 // typedef of internal coroutine-type
2027 typedef detail::push_coroutine_object<
2028 pull_coroutine< Arg >, Arg, Fn, StackAllocator
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 >
2043 push_coroutine< Arg & >::push_coroutine( Fn fn,
2044 attributes const& attrs) :
2047 // create a stack-context
2048 stack_context stack_ctx;
2049 stack_allocator stack_alloc;
2050 // allocate the coroutine-stack
2051 stack_alloc.allocate( stack_ctx, attrs.size);
2052 BOOST_ASSERT( 0 != stack_ctx.sp);
2053 // typedef of internal coroutine-type
2054 typedef detail::push_coroutine_object<
2055 pull_coroutine< Arg & >, Arg &, Fn, stack_allocator
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 Arg >
2069 template< typename Fn, typename StackAllocator >
2070 push_coroutine< Arg & >::push_coroutine( Fn fn,
2071 attributes const& attrs,
2072 StackAllocator stack_alloc) :
2075 // create a stack-context
2076 stack_context stack_ctx;
2077 // allocate the coroutine-stack
2078 stack_alloc.allocate( stack_ctx, attrs.size);
2079 BOOST_ASSERT( 0 != stack_ctx.sp);
2080 // typedef of internal coroutine-type
2081 typedef detail::push_coroutine_object<
2082 pull_coroutine< Arg & >, Arg &, Fn, StackAllocator
2084 // reserve space on top of coroutine-stack for internal coroutine-type
2085 std::size_t size = stack_ctx.size - sizeof( object_t);
2086 BOOST_ASSERT( 0 != size);
2087 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2088 BOOST_ASSERT( 0 != sp);
2089 // placement new for internal coroutine
2090 impl_ = new ( sp) object_t(
2091 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2092 BOOST_ASSERT( impl_);
2095 template< typename Fn >
2096 push_coroutine< void >::push_coroutine( Fn fn,
2097 attributes const& attrs) :
2100 // create a stack-context
2101 stack_context stack_ctx;
2102 stack_allocator stack_alloc;
2103 // allocate the coroutine-stack
2104 stack_alloc.allocate( stack_ctx, attrs.size);
2105 BOOST_ASSERT( 0 != stack_ctx.sp);
2106 // typedef of internal coroutine-type
2107 typedef detail::push_coroutine_object<
2108 pull_coroutine< void >, void, Fn, stack_allocator
2110 // reserve space on top of coroutine-stack for internal coroutine-type
2111 std::size_t size = stack_ctx.size - sizeof( object_t);
2112 BOOST_ASSERT( 0 != size);
2113 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2114 BOOST_ASSERT( 0 != sp);
2115 // placement new for internal coroutine
2116 impl_ = new ( sp) object_t(
2117 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2118 BOOST_ASSERT( impl_);
2121 template< typename Fn, typename StackAllocator >
2122 push_coroutine< void >::push_coroutine( Fn fn,
2123 attributes const& attrs,
2124 StackAllocator stack_alloc) :
2127 // create a stack-context
2128 stack_context stack_ctx;
2129 // allocate the coroutine-stack
2130 stack_alloc.allocate( stack_ctx, attrs.size);
2131 BOOST_ASSERT( 0 != stack_ctx.sp);
2132 // typedef of internal coroutine-type
2133 typedef detail::push_coroutine_object<
2134 pull_coroutine< void >, void, Fn, StackAllocator
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 >
2149 push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
2150 attributes const& attrs) :
2153 // create a stack-context
2154 stack_context stack_ctx;
2155 stack_allocator stack_alloc;
2156 // allocate the coroutine-stack
2157 stack_alloc.allocate( stack_ctx, attrs.size);
2158 BOOST_ASSERT( 0 != stack_ctx.sp);
2159 // typedef of internal coroutine-type
2160 typedef detail::push_coroutine_object<
2161 pull_coroutine< Arg >, Arg, Fn, stack_allocator
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, typename StackAllocator >
2176 push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn,
2177 attributes const& attrs,
2178 StackAllocator stack_alloc) :
2181 // create a stack-context
2182 stack_context stack_ctx;
2183 // allocate the coroutine-stack
2184 stack_alloc.allocate( stack_ctx, attrs.size);
2185 BOOST_ASSERT( 0 != stack_ctx.sp);
2186 // typedef of internal coroutine-type
2187 typedef detail::push_coroutine_object<
2188 pull_coroutine< Arg >, Arg, Fn, StackAllocator
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 >
2203 push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
2204 attributes const& attrs) :
2207 // create a stack-context
2208 stack_context stack_ctx;
2209 stack_allocator stack_alloc;
2210 // allocate the coroutine-stack
2211 stack_alloc.allocate( stack_ctx, attrs.size);
2212 BOOST_ASSERT( 0 != stack_ctx.sp);
2213 // typedef of internal coroutine-type
2214 typedef detail::push_coroutine_object<
2215 pull_coroutine< Arg & >, Arg &, Fn, stack_allocator
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 Arg >
2229 template< typename Fn, typename StackAllocator >
2230 push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn,
2231 attributes const& attrs,
2232 StackAllocator stack_alloc) :
2235 // create a stack-context
2236 stack_context stack_ctx;
2237 // allocate the coroutine-stack
2238 stack_alloc.allocate( stack_ctx, attrs.size);
2239 BOOST_ASSERT( 0 != stack_ctx.sp);
2240 // typedef of internal coroutine-type
2241 typedef detail::push_coroutine_object<
2242 pull_coroutine< Arg & >, Arg &, Fn, StackAllocator
2244 // reserve space on top of coroutine-stack for internal coroutine-type
2245 std::size_t size = stack_ctx.size - sizeof( object_t);
2246 BOOST_ASSERT( 0 != size);
2247 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2248 BOOST_ASSERT( 0 != sp);
2249 // placement new for internal coroutine
2250 impl_ = new ( sp) object_t(
2251 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2252 BOOST_ASSERT( impl_);
2255 template< typename Fn >
2256 push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
2257 attributes const& attrs) :
2260 // create a stack-context
2261 stack_context stack_ctx;
2262 stack_allocator stack_alloc;
2263 // allocate the coroutine-stack
2264 stack_alloc.allocate( stack_ctx, attrs.size);
2265 BOOST_ASSERT( 0 != stack_ctx.sp);
2266 // typedef of internal coroutine-type
2267 typedef detail::push_coroutine_object<
2268 pull_coroutine< void >, void, Fn, stack_allocator
2270 // reserve space on top of coroutine-stack for internal coroutine-type
2271 std::size_t size = stack_ctx.size - sizeof( object_t);
2272 BOOST_ASSERT( 0 != size);
2273 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2274 BOOST_ASSERT( 0 != sp);
2275 // placement new for internal coroutine
2276 impl_ = new ( sp) object_t(
2277 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2278 BOOST_ASSERT( impl_);
2281 template< typename Fn, typename StackAllocator >
2282 push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn,
2283 attributes const& attrs,
2284 StackAllocator stack_alloc) :
2287 // create a stack-context
2288 stack_context stack_ctx;
2289 // allocate the coroutine-stack
2290 stack_alloc.allocate( stack_ctx, attrs.size);
2291 BOOST_ASSERT( 0 != stack_ctx.sp);
2292 // typedef of internal coroutine-type
2293 typedef detail::push_coroutine_object<
2294 pull_coroutine< void >, void, Fn, StackAllocator
2296 // reserve space on top of coroutine-stack for internal coroutine-type
2297 std::size_t size = stack_ctx.size - sizeof( object_t);
2298 BOOST_ASSERT( 0 != size);
2299 void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
2300 BOOST_ASSERT( 0 != sp);
2301 // placement new for internal coroutine
2302 impl_ = new ( sp) object_t(
2303 fn, attrs, detail::preallocated( sp, size, stack_ctx), stack_alloc);
2304 BOOST_ASSERT( impl_);
2308 template< typename R >
2309 void swap( pull_coroutine< R > & l, pull_coroutine< R > & r) BOOST_NOEXCEPT
2312 template< typename Arg >
2313 void swap( push_coroutine< Arg > & l, push_coroutine< Arg > & r) BOOST_NOEXCEPT
2316 template< typename R >
2317 typename pull_coroutine< R >::iterator
2318 range_begin( pull_coroutine< R > & c)
2319 { return typename pull_coroutine< R >::iterator( & c); }
2321 template< typename R >
2322 typename pull_coroutine< R >::const_iterator
2323 range_begin( pull_coroutine< R > const& c)
2324 { return typename pull_coroutine< R >::const_iterator( & c); }
2326 template< typename R >
2327 typename pull_coroutine< R >::iterator
2328 range_end( pull_coroutine< R > &)
2329 { return typename pull_coroutine< R >::iterator(); }
2331 template< typename R >
2332 typename pull_coroutine< R >::const_iterator
2333 range_end( pull_coroutine< R > const&)
2334 { return typename pull_coroutine< R >::const_iterator(); }
2336 template< typename Arg >
2337 typename push_coroutine< Arg >::iterator
2338 range_begin( push_coroutine< Arg > & c)
2339 { return typename push_coroutine< Arg >::iterator( & c); }
2341 template< typename Arg >
2342 typename push_coroutine< Arg >::iterator
2343 range_end( push_coroutine< Arg > &)
2344 { return typename push_coroutine< Arg >::iterator(); }
2346 template< typename T >
2347 struct asymmetric_coroutine
2349 typedef push_coroutine< T > push_type;
2350 typedef pull_coroutine< T > pull_type;
2354 template< typename T >
2357 typedef push_coroutine< T > push_type;
2358 typedef pull_coroutine< T > pull_type;
2361 template< typename R >
2362 typename pull_coroutine< R >::iterator
2363 begin( pull_coroutine< R > & c)
2364 { return boost::begin( c); }
2366 template< typename R >
2367 typename pull_coroutine< R >::const_iterator
2368 begin( pull_coroutine< R > const& c)
2369 { return boost::begin( c); }
2371 template< typename R >
2372 typename pull_coroutine< R >::iterator
2373 end( pull_coroutine< R > & c)
2374 { return boost::end( c); }
2376 template< typename R >
2377 typename pull_coroutine< R >::const_iterator
2378 end( pull_coroutine< R > const& c)
2379 { return boost::end( c); }
2381 template< typename R >
2382 typename push_coroutine< R >::iterator
2383 begin( push_coroutine< R > & c)
2384 { return boost::begin( c); }
2386 template< typename R >
2387 typename push_coroutine< R >::iterator
2388 end( push_coroutine< R > & c)
2389 { return boost::end( c); }
2393 // forward declaration of Boost.Range traits to break dependency on it
2394 template<typename C, typename Enabler>
2395 struct range_mutable_iterator;
2397 template<typename C, typename Enabler>
2398 struct range_const_iterator;
2400 template< typename Arg >
2401 struct range_mutable_iterator< coroutines::push_coroutine< Arg >, void >
2402 { typedef typename coroutines::push_coroutine< Arg >::iterator type; };
2404 template< typename R >
2405 struct range_mutable_iterator< coroutines::pull_coroutine< R >, void >
2406 { typedef typename coroutines::pull_coroutine< R >::iterator type; };
2410 #ifdef BOOST_HAS_ABI_HEADERS
2411 # include BOOST_ABI_SUFFIX
2414 #endif // BOOST_COROUTINES_ASYMMETRIC_COROUTINE_H