]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/coroutine/test/test_asymmetric_coroutine.cpp
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 #include <boost/coroutine/asymmetric_coroutine.hpp>
18 #include <boost/assert.hpp>
19 #include <boost/bind.hpp>
20 #include <boost/foreach.hpp>
21 #include <boost/move/move.hpp>
22 #include <boost/range.hpp>
23 #include <boost/ref.hpp>
24 #include <boost/test/unit_test.hpp>
25 #include <boost/tuple/tuple.hpp>
26 #include <boost/utility.hpp>
28 namespace coro
= boost::coroutines
;
31 std::string value2
= "";
40 struct X
: private boost::noncopyable
59 void operator()( coro::asymmetric_coroutine
< int >::push_type
&)
66 BOOST_MOVABLE_BUT_NOT_COPYABLE( moveable
)
79 moveable( BOOST_RV_REF( moveable
) other
) :
81 { std::swap( state
, other
.state
); }
83 moveable
& operator=( BOOST_RV_REF( moveable
) other
)
85 if ( this == & other
) return * this;
86 moveable
tmp( boost::move( other
) );
87 std::swap( state
, tmp
.state
);
91 void operator()( coro::asymmetric_coroutine
< int >::push_type
&)
95 struct my_exception
{};
97 void f1( coro::asymmetric_coroutine
< void >::push_type
& c
)
103 void f2( coro::asymmetric_coroutine
< void >::push_type
&)
106 void f3( coro::asymmetric_coroutine
< void >::push_type
& c
)
113 void f4( coro::asymmetric_coroutine
< int >::push_type
& c
)
119 void f5( coro::asymmetric_coroutine
< std::string
>::push_type
& c
)
121 std::string
res("abc");
127 void f6( coro::asymmetric_coroutine
< int >::pull_type
& c
)
128 { value1
= c
.get(); }
130 void f7( coro::asymmetric_coroutine
< std::string
>::pull_type
& c
)
131 { value2
= c
.get(); }
133 void f8( coro::asymmetric_coroutine
< boost::tuple
< double, double > >::pull_type
& c
)
136 boost::tie( x
, y
) = c
.get();
139 boost::tie( x
, y
) = c
.get();
143 void f9( coro::asymmetric_coroutine
< int * >::pull_type
& c
)
144 { value5
= c
.get(); }
146 void f91( coro::asymmetric_coroutine
< int const* >::pull_type
& c
)
147 { value5
= const_cast< int * >( c
.get() ); }
149 void f10( coro::asymmetric_coroutine
< int & >::pull_type
& c
)
151 int const& i
= c
.get();
152 value5
= const_cast< int * >( & i
);
155 void f101( coro::asymmetric_coroutine
< int const& >::pull_type
& c
)
157 int const& i
= c
.get();
158 value5
= const_cast< int * >( & i
);
161 void f11( coro::asymmetric_coroutine
< boost::tuple
< int, int > >::pull_type
& c
)
163 boost::tie( value8
, value9
) = c
.get();
166 void f12( coro::asymmetric_coroutine
< void >::pull_type
& c
)
173 template< typename E
>
174 void f14( coro::asymmetric_coroutine
< void >::pull_type
&, E
const& e
)
177 void f16( coro::asymmetric_coroutine
< int >::push_type
& c
)
186 void f17( coro::asymmetric_coroutine
< int >::pull_type
& c
, std::vector
< int > & vec
)
196 void f19( coro::asymmetric_coroutine
< int* >::push_type
& c
, std::vector
< int * > & vec
)
198 BOOST_FOREACH( int * ptr
, vec
)
202 void f20( coro::asymmetric_coroutine
< int >::push_type
&)
205 void f21( coro::asymmetric_coroutine
< int >::pull_type
& c
)
217 coro::asymmetric_coroutine
< void >::pull_type coro1
;
218 coro::asymmetric_coroutine
< void >::pull_type
coro2( f1
);
219 BOOST_CHECK( ! coro1
);
222 coro1
= boost::move( coro2
);
225 BOOST_CHECK( ! coro2
);
231 BOOST_CHECK( cp
.state
);
232 BOOST_CHECK( ! value3
);
233 coro::asymmetric_coroutine
< int >::pull_type
coro( cp
);
234 BOOST_CHECK( cp
.state
);
235 BOOST_CHECK( value3
);
241 BOOST_CHECK( mv
.state
);
242 BOOST_CHECK( ! value3
);
243 coro::asymmetric_coroutine
< int >::pull_type
coro( boost::move( mv
) );
244 BOOST_CHECK( ! mv
.state
);
245 BOOST_CHECK( value3
);
253 coro::asymmetric_coroutine
< void >::pull_type
coro( f2
);
254 BOOST_CHECK( ! coro
);
255 BOOST_CHECK_EQUAL( ( int)1, value1
);
262 coro::asymmetric_coroutine
< void >::pull_type
coro( f3
);
264 BOOST_CHECK_EQUAL( ( int)1, value1
);
266 BOOST_CHECK( ! coro
);
267 BOOST_CHECK_EQUAL( ( int)2, value1
);
270 void test_result_int()
272 coro::asymmetric_coroutine
< int >::pull_type
coro( f4
);
274 int result
= coro
.get();
276 BOOST_CHECK_EQUAL( 3, result
);
277 result
= coro().get();
279 BOOST_CHECK_EQUAL( 7, result
);
281 BOOST_CHECK( ! coro
);
284 void test_result_string()
286 coro::asymmetric_coroutine
< std::string
>::pull_type
coro( f5
);
288 std::string result
= coro
.get();
290 BOOST_CHECK_EQUAL( std::string("abc"), result
);
291 result
= coro().get();
293 BOOST_CHECK_EQUAL( std::string("xyz"), result
);
295 BOOST_CHECK( ! coro
);
302 coro::asymmetric_coroutine
< int >::push_type
coro( f6
);
305 BOOST_CHECK( ! coro
);
306 BOOST_CHECK_EQUAL( 3, value1
);
309 void test_arg_string()
313 coro::asymmetric_coroutine
< std::string
>::push_type
coro( f7
);
315 coro( std::string("abc") );
316 BOOST_CHECK( ! coro
);
317 BOOST_CHECK_EQUAL( std::string("abc"), value2
);
324 coro::asymmetric_coroutine
< boost::tuple
< double, double > >::push_type
coro( f8
);
326 coro( boost::make_tuple( 7.35, 3.14) );
328 BOOST_CHECK_EQUAL( ( double) 10.49, value4
);
331 coro( boost::make_tuple( 1.15, 3.14) );
332 BOOST_CHECK( ! coro
);
333 BOOST_CHECK_EQUAL( ( double) 4.29, value4
);
341 coro::asymmetric_coroutine
< int * >::push_type
coro( f9
);
344 BOOST_CHECK( ! coro
);
345 BOOST_CHECK_EQUAL( & a
, value5
);
348 void test_const_ptr()
353 coro::asymmetric_coroutine
< int const* >::push_type
coro( f91
);
356 BOOST_CHECK( ! coro
);
357 BOOST_CHECK_EQUAL( & a
, value5
);
365 coro::asymmetric_coroutine
< int & >::push_type
coro( f10
);
368 BOOST_CHECK( ! coro
);
369 BOOST_CHECK_EQUAL( & a
, value5
);
372 void test_const_ref()
377 coro::asymmetric_coroutine
< int const& >::push_type
coro( f101
);
380 BOOST_CHECK( ! coro
);
381 BOOST_CHECK_EQUAL( & a
, value5
);
390 boost::tuple
< int, int > tpl( a
, b
);
391 BOOST_CHECK_EQUAL( a
, tpl
.get
< 0 >() );
392 BOOST_CHECK_EQUAL( b
, tpl
.get
< 1 >() );
393 coro::asymmetric_coroutine
< boost::tuple
< int, int > >::push_type
coro( f11
);
396 BOOST_CHECK( ! coro
);
397 BOOST_CHECK_EQUAL( a
, value8
);
398 BOOST_CHECK_EQUAL( b
, value9
);
405 coro::asymmetric_coroutine
< void >::push_type
coro( f12
);
407 BOOST_CHECK_EQUAL( ( int) 0, value1
);
410 BOOST_CHECK_EQUAL( ( int) 7, value1
);
412 BOOST_CHECK_EQUAL( ( int) 7, value1
);
414 BOOST_CHECK_EQUAL( ( int) 0, value1
);
417 void test_no_unwind()
421 coro::asymmetric_coroutine
< void >::push_type
coro(
424 coro::stack_allocator::traits_type::default_size(),
425 coro::no_stack_unwind
) );
427 BOOST_CHECK_EQUAL( ( int) 0, value1
);
430 BOOST_CHECK_EQUAL( ( int) 7, value1
);
432 BOOST_CHECK_EQUAL( ( int) 7, value1
);
434 BOOST_CHECK_EQUAL( ( int) 7, value1
);
437 void test_exceptions()
440 std::runtime_error
ex("abc");
443 coro::asymmetric_coroutine
< void >::push_type
coro( boost::bind( f14
< std::runtime_error
>, _1
, ex
) );
446 BOOST_CHECK( ! coro
);
449 catch ( std::runtime_error
const&)
451 catch ( std::exception
const&)
455 BOOST_CHECK( thrown
);
458 void test_input_iterator()
461 std::vector
< int > vec
;
462 coro::asymmetric_coroutine
< int >::pull_type
coro( f16
);
463 BOOST_FOREACH( int i
, coro
)
464 { vec
.push_back( i
); }
465 BOOST_CHECK_EQUAL( ( std::size_t)5, vec
.size() );
466 BOOST_CHECK_EQUAL( ( int)1, vec
[0] );
467 BOOST_CHECK_EQUAL( ( int)2, vec
[1] );
468 BOOST_CHECK_EQUAL( ( int)3, vec
[2] );
469 BOOST_CHECK_EQUAL( ( int)4, vec
[3] );
470 BOOST_CHECK_EQUAL( ( int)5, vec
[4] );
473 std::vector
< int > vec
;
474 coro::asymmetric_coroutine
< int >::pull_type
coro( f16
);
475 coro::asymmetric_coroutine
< int >::pull_type::iterator e
= boost::end( coro
);
477 coro::asymmetric_coroutine
< int >::pull_type::iterator i
= boost::begin( coro
);
479 { vec
.push_back( * i
); }
480 BOOST_CHECK_EQUAL( ( std::size_t)5, vec
.size() );
481 BOOST_CHECK_EQUAL( ( int)1, vec
[0] );
482 BOOST_CHECK_EQUAL( ( int)2, vec
[1] );
483 BOOST_CHECK_EQUAL( ( int)3, vec
[2] );
484 BOOST_CHECK_EQUAL( ( int)4, vec
[3] );
485 BOOST_CHECK_EQUAL( ( int)5, vec
[4] );
488 int i1
= 1, i2
= 2, i3
= 3;
489 std::vector
< int* > vec_in
;
490 vec_in
.push_back( & i1
);
491 vec_in
.push_back( & i2
);
492 vec_in
.push_back( & i3
);
493 std::vector
< int* > vec_out
;
494 coro::asymmetric_coroutine
< int* >::pull_type
coro( boost::bind( f19
, _1
, boost::ref( vec_in
) ) );
495 coro::asymmetric_coroutine
< int* >::pull_type::iterator e
= boost::end( coro
);
497 coro::asymmetric_coroutine
< int* >::pull_type::iterator i
= boost::begin( coro
);
501 vec_out
.push_back( p
);
503 BOOST_CHECK_EQUAL( ( std::size_t)3, vec_out
.size() );
504 BOOST_CHECK_EQUAL( & i1
, vec_out
[0] );
505 BOOST_CHECK_EQUAL( & i2
, vec_out
[1] );
506 BOOST_CHECK_EQUAL( & i3
, vec_out
[2] );
510 void test_output_iterator()
513 std::vector
< int > vec
;
514 coro::asymmetric_coroutine
< int >::push_type
coro(
515 boost::bind( f17
, _1
, boost::ref( vec
) ) );
516 coro::asymmetric_coroutine
< int >::push_type::iterator
e( boost::end( coro
) );
517 for ( coro::asymmetric_coroutine
< int >::push_type::iterator
i( boost::begin( coro
) );
522 BOOST_CHECK_EQUAL( ( std::size_t)4, vec
.size() );
523 BOOST_CHECK_EQUAL( ( int)1, vec
[0] );
524 BOOST_CHECK_EQUAL( ( int)2, vec
[1] );
525 BOOST_CHECK_EQUAL( ( int)3, vec
[2] );
526 BOOST_CHECK_EQUAL( ( int)4, vec
[3] );
529 void test_invalid_result()
531 bool catched
= false;
532 coro::asymmetric_coroutine
< int >::pull_type
coro( f20
);
533 BOOST_CHECK( ! coro
);
539 catch ( coro::invalid_result
const&)
543 BOOST_CHECK( catched
);
545 void test_move_coro()
549 coro::asymmetric_coroutine
< int >::push_type
coro1( f21
);
550 coro::asymmetric_coroutine
< int >::push_type coro2
;
552 BOOST_CHECK( ! coro2
);
555 BOOST_CHECK_EQUAL( ( int)1, value1
);
557 coro2
= boost::move( coro1
);
558 BOOST_CHECK( ! coro1
);
562 BOOST_CHECK_EQUAL( ( int)2, value1
);
564 coro1
= boost::move( coro2
);
566 BOOST_CHECK( ! coro2
);
569 BOOST_CHECK_EQUAL( ( int)3, value1
);
571 coro2
= boost::move( coro1
);
572 BOOST_CHECK( ! coro1
);
576 BOOST_CHECK_EQUAL( ( int)4, value1
);
579 void foo( coro::asymmetric_coroutine
< int >::push_type
& yield
)
584 coro::asymmetric_coroutine
< int >::pull_type
make_range()
586 return coro::asymmetric_coroutine
< int >::pull_type( foo
);
589 template< typename Range
>
590 void const_func( Range
const& r
)
597 const_func( make_range() );
600 boost::unit_test::test_suite
* init_unit_test_suite( int, char* [])
602 boost::unit_test::test_suite
* test
=
603 BOOST_TEST_SUITE("Boost.coroutine: asymmetric coroutine test suite");
605 test
->add( BOOST_TEST_CASE( & test_move
) );
606 test
->add( BOOST_TEST_CASE( & test_complete
) );
607 test
->add( BOOST_TEST_CASE( & test_jump
) );
608 test
->add( BOOST_TEST_CASE( & test_result_int
) );
609 test
->add( BOOST_TEST_CASE( & test_result_string
) );
610 test
->add( BOOST_TEST_CASE( & test_arg_int
) );
611 test
->add( BOOST_TEST_CASE( & test_arg_string
) );
612 test
->add( BOOST_TEST_CASE( & test_fp
) );
613 test
->add( BOOST_TEST_CASE( & test_ptr
) );
614 test
->add( BOOST_TEST_CASE( & test_const_ptr
) );
615 test
->add( BOOST_TEST_CASE( & test_invalid_result
) );
616 test
->add( BOOST_TEST_CASE( & test_ref
) );
617 test
->add( BOOST_TEST_CASE( & test_const_ref
) );
618 test
->add( BOOST_TEST_CASE( & test_tuple
) );
619 test
->add( BOOST_TEST_CASE( & test_unwind
) );
620 test
->add( BOOST_TEST_CASE( & test_no_unwind
) );
621 test
->add( BOOST_TEST_CASE( & test_exceptions
) );
622 test
->add( BOOST_TEST_CASE( & test_input_iterator
) );
623 test
->add( BOOST_TEST_CASE( & test_output_iterator
) );
624 test
->add( BOOST_TEST_CASE( & test_range
) );