add examples for symmetric coroutines

This commit is contained in:
Oliver Kowalke
2014-02-03 19:21:48 +01:00
parent 341503066c
commit 67e3c8ef6a
3 changed files with 182 additions and 0 deletions

View File

@@ -18,6 +18,7 @@ project boost/coroutine/example
: requirements
<library>../../../build//boost_coroutine
<library>/boost/program_options//boost_program_options
<library>/boost/random//boost_random
<library>/boost/thread//boost_thread
<toolset>gcc-4.7,<segmented-stacks>on:<cxxflags>-fsplit-stack
<toolset>gcc-4.7,<segmented-stacks>on:<cxxflags>-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
;

View File

@@ -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 <cstdlib>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/coroutine/all.hpp>
#include <boost/move/move.hpp>
#include <boost/random/random_device.hpp>
#include <boost/random/uniform_int_distribution.hpp>
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;
}

View File

@@ -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 <cstdlib>
#include <cstddef>
#include <iostream>
#include <vector>
#include <boost/bind.hpp>
#include <boost/coroutine/all.hpp>
#include <boost/foreach.hpp>
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;
}