From 67e3c8ef6a152085d305a6bd4cc76cd581d9cc2a Mon Sep 17 00:00:00 2001 From: Oliver Kowalke Date: Mon, 3 Feb 2014 19:21:48 +0100 Subject: [PATCH] add examples for symmetric coroutines --- example/cpp03/symmetric/Jamfile.v2 | 9 ++ example/cpp03/symmetric/dice_game.cpp | 69 +++++++++++++++ example/cpp03/symmetric/merge_arrays.cpp | 104 +++++++++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 example/cpp03/symmetric/dice_game.cpp create mode 100644 example/cpp03/symmetric/merge_arrays.cpp diff --git a/example/cpp03/symmetric/Jamfile.v2 b/example/cpp03/symmetric/Jamfile.v2 index 0cf0951..2ea1fd7 100644 --- a/example/cpp03/symmetric/Jamfile.v2 +++ b/example/cpp03/symmetric/Jamfile.v2 @@ -18,6 +18,7 @@ project boost/coroutine/example : requirements ../../../build//boost_coroutine /boost/program_options//boost_program_options + /boost/random//boost_random /boost/thread//boost_thread gcc-4.7,on:-fsplit-stack gcc-4.7,on:-DBOOST_USE_SEGMENTED_STACKS @@ -32,3 +33,11 @@ project boost/coroutine/example exe simple : simple.cpp ; + +exe dice_game + : dice_game.cpp + ; + +exe merge_arrays + : merge_arrays.cpp + ; diff --git a/example/cpp03/symmetric/dice_game.cpp b/example/cpp03/symmetric/dice_game.cpp new file mode 100644 index 0000000..56da967 --- /dev/null +++ b/example/cpp03/symmetric/dice_game.cpp @@ -0,0 +1,69 @@ + +// Copyright Keld Helsgaun 2000, Oliver Kowalke 2014. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include + +#include +#include +#include +#include +#include + +typedef boost::coroutines::symmetric_coroutine< void > coro_t; + +class player +{ +private: + int die() + { + boost::random::uniform_int_distribution<> dist( 1, 6); + return dist( gen); + } + + void run_( coro_t::self_type & self) + { + int sum = 0; + while ( ( sum += die() ) < 100) + self( nxt->coro); + std::cout << "player " << id << " winns" << std::endl; + } + + player( player const&); + player & operator=( player const&); + +public: + int id; + player * nxt; + coro_t coro; + boost::random::random_device gen; + + player( int id_) : + id( id_), nxt( 0), + coro( boost::bind( & player::run_, this, _1) ), + gen() + {} + + void run() + { coro(); } +}; + +int main( int argc, char * argv[]) +{ + player * first = new player( 1); + player * p = first; + for ( int i = 2; i <= 4; ++i) + { + p->nxt = new player( i); + p = p->nxt; + } + p->nxt = first; + first->run(); + + std::cout << "Done" << std::endl; + + return EXIT_SUCCESS; +} diff --git a/example/cpp03/symmetric/merge_arrays.cpp b/example/cpp03/symmetric/merge_arrays.cpp new file mode 100644 index 0000000..095fc87 --- /dev/null +++ b/example/cpp03/symmetric/merge_arrays.cpp @@ -0,0 +1,104 @@ + +// Copyright Keld Helsgaun 2000, Oliver Kowalke 2014. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include + +#include +#include +#include + +typedef boost::coroutines::symmetric_coroutine< void > coro_t; + +class merger +{ +private: + std::size_t max_; + std::vector< int > & to_; + + void run_( coro_t::self_type & self) + { + while ( idx < from.size() ) + { + if ( other->from[other->idx] < from[idx]) + self( other->coro); + to_.push_back(from[idx++]); + } + while ( to_.size() < max_) + to_.push_back( other->from[other->idx]); + } + + merger( merger const&); + merger & operator=( merger const&); + +public: + std::vector< int > const& from; + std::size_t idx; + merger * other; + coro_t coro; + + merger( std::vector< int > const& from_, std::vector< int > & to, std::size_t max) : + max_( max), + to_( to), + from( from_), + idx( 0), + other( 0), + coro( boost::bind( & merger::run_, this, _1) ) + {} + + void run() + { coro(); } +}; + +std::vector< int > merge( std::vector< int > const& a, std::vector< int > const& b) +{ + std::vector< int > c; + merger ma( a, c, a.size() + b. size() ); + merger mb( b, c, a.size() + b. size() ); + + ma.other = & mb; + mb.other = & ma; + + ma.run(); + + return c; +} + +void print( std::string const& name, std::vector< int > const& v) +{ + std::cout << name << " : "; + BOOST_FOREACH( int itm, v) + { std::cout << itm << " "; } + std::cout << "\n"; +} + +int main( int argc, char * argv[]) +{ + std::vector< int > a; + a.push_back( 1); + a.push_back( 5); + a.push_back( 6); + a.push_back( 10); + print( "a", a); + + std::vector< int > b; + b.push_back( 2); + b.push_back( 4); + b.push_back( 7); + b.push_back( 8); + b.push_back( 9); + b.push_back( 13); + print( "b", b); + + std::vector< int > c = merge( a, b); + print( "c", c); + + std::cout << "Done" << std::endl; + + return EXIT_SUCCESS; +}