update example section
This commit is contained in:
parent
cf0b1b2844
commit
35e9dcf0d4
@ -23,7 +23,7 @@ project boost/coroutine/example
|
||||
<toolset>gcc,<segmented-stacks>on:<cxxflags>-DBOOST_USE_SEGMENTED_STACKS
|
||||
<toolset>clang,<segmented-stacks>on:<cxxflags>-fsplit-stack
|
||||
<toolset>clang,<segmented-stacks>on:<cxxflags>-DBOOST_USE_SEGMENTED_STACKS
|
||||
<link>static
|
||||
<link>shared
|
||||
<threading>multi
|
||||
;
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/coroutine/all.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
int count = 384;
|
||||
|
||||
@ -41,13 +40,6 @@ void foo( boost::coroutines::asymmetric_coroutine< void >::pull_type & source)
|
||||
source();
|
||||
}
|
||||
|
||||
void thread_fn()
|
||||
{
|
||||
{
|
||||
boost::coroutines::asymmetric_coroutine< void >::push_type sink( foo);
|
||||
sink();
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc, char * argv[])
|
||||
{
|
||||
@ -61,7 +53,8 @@ int main( int argc, char * argv[])
|
||||
std::cout << "application might fail" << std::endl;
|
||||
#endif
|
||||
|
||||
boost::thread( thread_fn).join();
|
||||
boost::coroutines::asymmetric_coroutine< void >::push_type sink( foo);
|
||||
sink();
|
||||
|
||||
std::cout << "Done" << std::endl;
|
||||
|
@ -1,48 +0,0 @@
|
||||
# Boost.Coroutine Library Examples Jamfile
|
||||
|
||||
# Copyright Oliver Kowalke 2009.
|
||||
# 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)
|
||||
|
||||
# For more information, see http://www.boost.org/
|
||||
|
||||
import common ;
|
||||
import feature ;
|
||||
import indirect ;
|
||||
import modules ;
|
||||
import os ;
|
||||
import toolset ;
|
||||
|
||||
project boost/coroutine/example
|
||||
: requirements
|
||||
<library>/boost/context//boost_context
|
||||
<library>/boost/coroutine//boost_coroutine
|
||||
<library>/boost/program_options//boost_program_options
|
||||
<toolset>gcc,<segmented-stacks>on:<cxxflags>-fsplit-stack
|
||||
<toolset>gcc,<segmented-stacks>on:<cxxflags>-DBOOST_USE_SEGMENTED_STACKS
|
||||
<toolset>clang,<segmented-stacks>on:<cxxflags>-fsplit-stack
|
||||
<toolset>clang,<segmented-stacks>on:<cxxflags>-DBOOST_USE_SEGMENTED_STACKS
|
||||
<link>static
|
||||
<threading>multi
|
||||
;
|
||||
|
||||
exe same_fringe
|
||||
: same_fringe.cpp
|
||||
;
|
||||
|
||||
exe fibonacci
|
||||
: fibonacci.cpp
|
||||
;
|
||||
|
||||
exe layout
|
||||
: layout.cpp
|
||||
;
|
||||
|
||||
exe iterator_range
|
||||
: iterator_range.cpp
|
||||
;
|
||||
|
||||
exe await_emu
|
||||
: await_emu.cpp
|
||||
;
|
@ -1,199 +0,0 @@
|
||||
// Copyright Evgeny Panasyuk 2013.
|
||||
// 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)
|
||||
|
||||
// e-mail: E?????[dot]P???????[at]gmail.???
|
||||
|
||||
// Full emulation of await feature from C# language in C++ based on Stackful Coroutines from
|
||||
// Boost.Coroutine library.
|
||||
// This proof-of-concept shows that exact syntax of await feature can be emulated with help of
|
||||
// Stackful Coroutines, demonstrating that it is superior mechanism.
|
||||
// Main aim of this proof-of-concept is to draw attention to Stackful Coroutines.
|
||||
|
||||
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
|
||||
#define BOOST_THREAD_PROVIDES_FUTURE
|
||||
#define BOOST_RESULT_OF_USE_DECLTYPE
|
||||
|
||||
#include <boost/coroutine/asymmetric_coroutine.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/chrono.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
#include <queue>
|
||||
#include <ctime>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
// ___________________________________________________________ //
|
||||
|
||||
template<typename T>
|
||||
class concurrent_queue
|
||||
{
|
||||
queue<T> q;
|
||||
boost::mutex m;
|
||||
boost::condition_variable c;
|
||||
public:
|
||||
template<typename U>
|
||||
void push(U &&u)
|
||||
{
|
||||
boost::lock_guard<boost::mutex> l(m);
|
||||
q.push( boost::forward<U>(u) );
|
||||
c.notify_one();
|
||||
}
|
||||
void pop(T &result)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> u(m);
|
||||
c.wait(u, [&]{return !q.empty();} );
|
||||
result = std::move_if_noexcept(q.front());
|
||||
q.pop();
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::function<void()> Task;
|
||||
concurrent_queue<Task> main_tasks;
|
||||
auto finished = false;
|
||||
|
||||
void reschedule()
|
||||
{
|
||||
this_thread::sleep_for(boost::chrono::milliseconds( rand() % 2000 ));
|
||||
}
|
||||
|
||||
// ___________________________________________________________ //
|
||||
|
||||
typedef coroutines::asymmetric_coroutine<void>::pull_type coro_pull;
|
||||
typedef coroutines::asymmetric_coroutine<void>::push_type coro_push;
|
||||
|
||||
struct CurrentCoro
|
||||
{
|
||||
std::shared_ptr<coro_pull> coro;
|
||||
coro_push *caller;
|
||||
};
|
||||
/*should be thread_local*/ stack<CurrentCoro> coro_stack;
|
||||
|
||||
template<typename F>
|
||||
auto asynchronous(F f) -> future<decltype(f())>
|
||||
{
|
||||
typedef promise<decltype(f())> CoroPromise;
|
||||
|
||||
CoroPromise coro_promise;
|
||||
auto coro_future = coro_promise.get_future();
|
||||
|
||||
// It is possible to avoid shared_ptr and use move-semantic,
|
||||
// but it would require to refuse use of std::function (it requires CopyConstructable),
|
||||
// and would lead to further complication and is unjustified
|
||||
// for purposes of this proof-of-concept
|
||||
CurrentCoro current_coro =
|
||||
{
|
||||
make_shared<coro_pull>(std::bind( [f](CoroPromise &coro_promise, coro_push &caller)
|
||||
{
|
||||
caller();
|
||||
coro_stack.top().caller = &caller;
|
||||
coro_promise.set_value( f() );
|
||||
}, std::move(coro_promise), placeholders::_1 ))
|
||||
};
|
||||
|
||||
coro_stack.push( std::move(current_coro) );
|
||||
(*coro_stack.top().coro)();
|
||||
coro_stack.pop();
|
||||
|
||||
#ifdef _MSC_VER
|
||||
return std::move( coro_future );
|
||||
#else
|
||||
return coro_future;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct Awaiter
|
||||
{
|
||||
template<typename Future>
|
||||
auto operator*(Future &&ft) -> decltype(ft.get())
|
||||
{
|
||||
typedef decltype(ft.get()) Result;
|
||||
typedef typename boost::remove_reference<Future>::type FutureValue;
|
||||
|
||||
auto &¤t_coro = coro_stack.top();
|
||||
auto result = ft.then([current_coro](FutureValue ready) -> Result
|
||||
{
|
||||
main_tasks.push([current_coro]
|
||||
{
|
||||
coro_stack.push(std::move(current_coro));
|
||||
(*coro_stack.top().coro)();
|
||||
coro_stack.pop();
|
||||
});
|
||||
return ready.get();
|
||||
});
|
||||
(*coro_stack.top().caller)();
|
||||
return result.get();
|
||||
}
|
||||
};
|
||||
#define await Awaiter()*
|
||||
|
||||
// ___________________________________________________________ //
|
||||
|
||||
void async_user_handler();
|
||||
|
||||
int main()
|
||||
{
|
||||
srand(time(0));
|
||||
|
||||
// Custom scheduling is not required - can be integrated
|
||||
// to other systems transparently
|
||||
main_tasks.push([]
|
||||
{
|
||||
asynchronous([]
|
||||
{
|
||||
return async_user_handler(),
|
||||
finished = true;
|
||||
});
|
||||
});
|
||||
|
||||
Task task;
|
||||
while(!finished)
|
||||
{
|
||||
main_tasks.pop(task);
|
||||
task();
|
||||
}
|
||||
|
||||
cout << "Done" << std::endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// __________________________________________________________________ //
|
||||
|
||||
int bar(int i)
|
||||
{
|
||||
// await is not limited by "one level" as in C#
|
||||
auto result = await async([i]{ return reschedule(), i*100; });
|
||||
return result + i*10;
|
||||
}
|
||||
|
||||
int foo(int i)
|
||||
{
|
||||
cout << i << ":\tbegin" << endl;
|
||||
cout << await async([i]{ return reschedule(), i*10; }) << ":\tbody" << endl;
|
||||
cout << bar(i) << ":\tend" << endl;
|
||||
return i*1000;
|
||||
}
|
||||
|
||||
void async_user_handler()
|
||||
{
|
||||
vector<future<int>> fs;
|
||||
|
||||
for(auto i=0; i!=5; ++i)
|
||||
fs.push_back( asynchronous([i]{ return foo(i+1); }) );
|
||||
|
||||
BOOST_FOREACH(auto &&f, fs)
|
||||
cout << await f << ":\tafter end" << endl;
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
|
||||
// Copyright Oliver Kowalke 2009.
|
||||
// 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/coroutine/all.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::coroutines::asymmetric_coroutine< int >::pull_type source(
|
||||
[&]( boost::coroutines::asymmetric_coroutine< int >::push_type & sink) {
|
||||
int first = 1, second = 1;
|
||||
sink( first);
|
||||
sink( second);
|
||||
for ( int i = 0; i < 8; ++i)
|
||||
{
|
||||
int third = first + second;
|
||||
first = second;
|
||||
second = third;
|
||||
sink( third);
|
||||
}
|
||||
});
|
||||
|
||||
for ( auto i : source)
|
||||
std::cout << i << " ";
|
||||
|
||||
std::cout << "\nDone" << std::endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
|
||||
// Copyright Oliver Kowalke 2009.
|
||||
// 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/coroutine/all.hpp>
|
||||
|
||||
#include <boost/range/adaptor/filtered.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::coroutines::asymmetric_coroutine<int>::pull_type c(
|
||||
[](boost::coroutines::asymmetric_coroutine<int>::push_type& yield) {
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
yield(i);
|
||||
}
|
||||
});
|
||||
auto crange = boost::make_iterator_range(boost::begin(c), boost::end(c));
|
||||
for (auto n : crange) {
|
||||
std::cout << n << " ";
|
||||
}
|
||||
|
||||
std::cout << "\nDone" << std::endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
|
||||
// Copyright Nat Goodspeed 2013.
|
||||
// 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 <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/coroutine/all.hpp>
|
||||
|
||||
struct FinalEOL{
|
||||
~FinalEOL(){
|
||||
std::cout << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc,char* argv[]){
|
||||
std::vector<std::string> words{
|
||||
"peas", "porridge", "hot", "peas",
|
||||
"porridge", "cold", "peas", "porridge",
|
||||
"in", "the", "pot", "nine",
|
||||
"days", "old" };
|
||||
|
||||
int num=5,width=15;
|
||||
boost::coroutines::asymmetric_coroutine<std::string>::push_type writer(
|
||||
[&](boost::coroutines::asymmetric_coroutine<std::string>::pull_type& in){
|
||||
// finish the last line when we leave by whatever means
|
||||
FinalEOL eol;
|
||||
// pull values from upstream, lay them out 'num' to a line
|
||||
for (;;){
|
||||
for(int i=0;i<num;++i){
|
||||
// when we exhaust the input, stop
|
||||
if(!in) return;
|
||||
std::cout << std::setw(width) << in.get();
|
||||
// now that we've handled this item, advance to next
|
||||
in();
|
||||
}
|
||||
// after 'num' items, line break
|
||||
std::cout << std::endl;
|
||||
}
|
||||
});
|
||||
|
||||
std::copy(std::begin(words),std::end(words),boost::begin(writer));
|
||||
|
||||
std::cout << "\nDone" << std::endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,176 +0,0 @@
|
||||
|
||||
// Copyright Nat Goodspeed 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSEstd::placeholders::_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSEstd::placeholders::_1_0.txt)
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/coroutine/all.hpp>
|
||||
|
||||
struct node
|
||||
{
|
||||
typedef std::shared_ptr< node > ptr_t;
|
||||
|
||||
// Each tree node has an optional left subtree, an optional right subtree
|
||||
// and a value of its own. The value is considered to be between the left
|
||||
// subtree and the right.
|
||||
ptr_t left, right;
|
||||
std::string value;
|
||||
|
||||
// construct leaf
|
||||
node(const std::string& v):
|
||||
left(),right(),value(v)
|
||||
{}
|
||||
// construct nonleaf
|
||||
node(ptr_t l, const std::string& v, ptr_t r):
|
||||
left(l),right(r),value(v)
|
||||
{}
|
||||
|
||||
static ptr_t create(const std::string& v)
|
||||
{
|
||||
return ptr_t(new node(v));
|
||||
}
|
||||
|
||||
static ptr_t create(ptr_t l, const std::string& v, ptr_t r)
|
||||
{
|
||||
return ptr_t(new node(l, v, r));
|
||||
}
|
||||
};
|
||||
|
||||
node::ptr_t create_left_tree_from(const std::string& root)
|
||||
{
|
||||
/* --------
|
||||
root
|
||||
/ \
|
||||
b e
|
||||
/ \
|
||||
a c
|
||||
-------- */
|
||||
|
||||
return node::create(
|
||||
node::create(
|
||||
node::create("a"),
|
||||
"b",
|
||||
node::create("c")),
|
||||
root,
|
||||
node::create("e"));
|
||||
}
|
||||
|
||||
node::ptr_t create_right_tree_from(const std::string& root)
|
||||
{
|
||||
/* --------
|
||||
root
|
||||
/ \
|
||||
a d
|
||||
/ \
|
||||
c e
|
||||
-------- */
|
||||
|
||||
return node::create(
|
||||
node::create("a"),
|
||||
root,
|
||||
node::create(
|
||||
node::create("c"),
|
||||
"d",
|
||||
node::create("e")));
|
||||
}
|
||||
|
||||
// recursively walk the tree, delivering values in order
|
||||
void traverse(node::ptr_t n, boost::coroutines::asymmetric_coroutine<std::string>::push_type& out)
|
||||
{
|
||||
if (n->left)
|
||||
traverse(n->left,out);
|
||||
out(n->value);
|
||||
if (n->right)
|
||||
traverse(n->right,out);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
node::ptr_t left_d(create_left_tree_from("d"));
|
||||
boost::coroutines::asymmetric_coroutine<std::string>::pull_type left_d_reader(
|
||||
[&]( boost::coroutines::asymmetric_coroutine<std::string>::push_type & out) {
|
||||
traverse(left_d,out);
|
||||
});
|
||||
std::cout << "left tree from d:\n";
|
||||
std::copy(boost::begin(left_d_reader),
|
||||
boost::end(left_d_reader),
|
||||
std::ostream_iterator<std::string>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
node::ptr_t right_b(create_right_tree_from("b"));
|
||||
boost::coroutines::asymmetric_coroutine<std::string>::pull_type right_b_reader(
|
||||
[&]( boost::coroutines::asymmetric_coroutine<std::string>::push_type & out) {
|
||||
traverse(right_b,out);
|
||||
});
|
||||
std::cout << "right tree from b:\n";
|
||||
std::copy(boost::begin(right_b_reader),
|
||||
boost::end(right_b_reader),
|
||||
std::ostream_iterator<std::string>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
node::ptr_t right_x(create_right_tree_from("x"));
|
||||
boost::coroutines::asymmetric_coroutine<std::string>::pull_type right_x_reader(
|
||||
[&]( boost::coroutines::asymmetric_coroutine<std::string>::push_type & out) {
|
||||
traverse(right_x,out);
|
||||
});
|
||||
std::cout << "right tree from x:\n";
|
||||
std::copy(boost::begin(right_x_reader),
|
||||
boost::end(right_x_reader),
|
||||
std::ostream_iterator<std::string>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
node::ptr_t left_d(create_left_tree_from("d"));
|
||||
boost::coroutines::asymmetric_coroutine<std::string>::pull_type left_d_reader(
|
||||
[&]( boost::coroutines::asymmetric_coroutine<std::string>::push_type & out) {
|
||||
traverse(left_d,out);
|
||||
});
|
||||
|
||||
node::ptr_t right_b(create_right_tree_from("b"));
|
||||
boost::coroutines::asymmetric_coroutine<std::string>::pull_type right_b_reader(
|
||||
[&]( boost::coroutines::asymmetric_coroutine<std::string>::push_type & out) {
|
||||
traverse(right_b,out);
|
||||
});
|
||||
|
||||
std::cout << "left tree from d == right tree from b? "
|
||||
<< std::boolalpha
|
||||
<< std::equal(boost::begin(left_d_reader),
|
||||
boost::end(left_d_reader),
|
||||
boost::begin(right_b_reader))
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
node::ptr_t left_d(create_left_tree_from("d"));
|
||||
boost::coroutines::asymmetric_coroutine<std::string>::pull_type left_d_reader(
|
||||
[&]( boost::coroutines::asymmetric_coroutine<std::string>::push_type & out) {
|
||||
traverse(left_d,out);
|
||||
});
|
||||
|
||||
node::ptr_t right_x(create_right_tree_from("x"));
|
||||
boost::coroutines::asymmetric_coroutine<std::string>::pull_type right_x_reader(
|
||||
[&]( boost::coroutines::asymmetric_coroutine<std::string>::push_type & out) {
|
||||
traverse(right_x,out);
|
||||
});
|
||||
|
||||
std::cout << "left tree from d == right tree from x? "
|
||||
<< std::boolalpha
|
||||
<< std::equal(boost::begin(left_d_reader),
|
||||
boost::end(left_d_reader),
|
||||
boost::begin(right_x_reader))
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
std::cout << "Done" << std::endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
|
||||
// Copyright Oliver Kowalke 2009.
|
||||
// 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)
|
||||
|
||||
#ifndef TREE_H
|
||||
#define TREE_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4355)
|
||||
#endif
|
||||
|
||||
struct branch;
|
||||
struct leaf;
|
||||
|
||||
struct visitor
|
||||
{
|
||||
virtual ~visitor() {};
|
||||
|
||||
virtual void visit( branch & b) = 0;
|
||||
virtual void visit( leaf & l) = 0;
|
||||
};
|
||||
|
||||
struct node
|
||||
{
|
||||
typedef boost::intrusive_ptr< node > ptr_t;
|
||||
|
||||
std::size_t use_count;
|
||||
|
||||
node() :
|
||||
use_count( 0)
|
||||
{}
|
||||
|
||||
virtual ~node() {}
|
||||
|
||||
virtual void accept( visitor & v) = 0;
|
||||
|
||||
friend inline void intrusive_ptr_add_ref( node * p)
|
||||
{ ++p->use_count; }
|
||||
|
||||
friend inline void intrusive_ptr_release( node * p)
|
||||
{ if ( 0 == --p->use_count) delete p; }
|
||||
};
|
||||
|
||||
struct branch : public node
|
||||
{
|
||||
node::ptr_t left;
|
||||
node::ptr_t right;
|
||||
|
||||
static ptr_t create( node::ptr_t left_, node::ptr_t right_)
|
||||
{ return ptr_t( new branch( left_, right_) ); }
|
||||
|
||||
branch( node::ptr_t left_, node::ptr_t right_) :
|
||||
left( left_), right( right_)
|
||||
{}
|
||||
|
||||
void accept( visitor & v)
|
||||
{ v.visit( * this); }
|
||||
};
|
||||
|
||||
struct leaf : public node
|
||||
{
|
||||
std::string value;
|
||||
|
||||
static ptr_t create( std::string const& value_)
|
||||
{ return ptr_t( new leaf( value_) ); }
|
||||
|
||||
leaf( std::string const& value_) :
|
||||
value( value_)
|
||||
{}
|
||||
|
||||
void accept( visitor & v)
|
||||
{ v.visit( * this); }
|
||||
};
|
||||
|
||||
inline
|
||||
bool operator==( leaf const& l, leaf const& r)
|
||||
{ return l.value == r.value; }
|
||||
|
||||
inline
|
||||
bool operator!=( leaf const& l, leaf const& r)
|
||||
{ return l.value != r.value; }
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // TREE_H
|
@ -1,37 +0,0 @@
|
||||
# Boost.Coroutine Library Examples Jamfile
|
||||
|
||||
# Copyright Oliver Kowalke 2009.
|
||||
# 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)
|
||||
|
||||
# For more information, see http://www.boost.org/
|
||||
|
||||
import common ;
|
||||
import feature ;
|
||||
import indirect ;
|
||||
import modules ;
|
||||
import os ;
|
||||
import toolset ;
|
||||
|
||||
project boost/coroutine/example
|
||||
: requirements
|
||||
<library>/boost/context//boost_context
|
||||
<library>/boost/coroutine//boost_coroutine
|
||||
<library>/boost/program_options//boost_program_options
|
||||
<library>/boost/random//boost_random
|
||||
<toolset>gcc,<segmented-stacks>on:<cxxflags>-fsplit-stack
|
||||
<toolset>gcc,<segmented-stacks>on:<cxxflags>-DBOOST_USE_SEGMENTED_STACKS
|
||||
<toolset>clang,<segmented-stacks>on:<cxxflags>-fsplit-stack
|
||||
<toolset>clang,<segmented-stacks>on:<cxxflags>-DBOOST_USE_SEGMENTED_STACKS
|
||||
<link>static
|
||||
<threading>multi
|
||||
;
|
||||
|
||||
exe simple
|
||||
: simple.cpp
|
||||
;
|
||||
|
||||
exe merge_arrays
|
||||
: merge_arrays.cpp
|
||||
;
|
@ -1,77 +0,0 @@
|
||||
|
||||
// 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/coroutine/all.hpp>
|
||||
|
||||
typedef boost::coroutines::symmetric_coroutine< void > coro_t;
|
||||
|
||||
std::vector< int > merge( std::vector< int > const& a, std::vector< int > const& b)
|
||||
{
|
||||
std::vector< int > c;
|
||||
std::size_t idx_a = 0, idx_b = 0;
|
||||
coro_t::call_type * other_a = 0, * other_b = 0;
|
||||
|
||||
coro_t::call_type coro_a(
|
||||
[&]( coro_t::yield_type & yield) {
|
||||
while ( idx_a < a.size() )
|
||||
{
|
||||
if ( b[idx_b] < a[idx_a])
|
||||
yield( * other_b);
|
||||
c.push_back(a[idx_a++]);
|
||||
}
|
||||
while ( c.size() < a.size() + b.size())
|
||||
c.push_back( b[idx_b]);
|
||||
});
|
||||
|
||||
coro_t::call_type coro_b(
|
||||
[&]( coro_t::yield_type & yield) {
|
||||
while ( idx_b < b.size() )
|
||||
{
|
||||
if ( a[idx_a] < b[idx_b])
|
||||
yield( * other_a);
|
||||
c.push_back(b[idx_b++]);
|
||||
}
|
||||
while ( c.size() < ( a.size() + b.size() ) )
|
||||
c.push_back( a[idx_a]);
|
||||
});
|
||||
|
||||
|
||||
other_a = & coro_a;
|
||||
other_b = & coro_b;
|
||||
|
||||
coro_a();
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void print( std::string const& name, std::vector< int > const& v)
|
||||
{
|
||||
std::cout << name << " : ";
|
||||
for ( auto itm : v)
|
||||
{ std::cout << itm << " "; }
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
int main( int argc, char * argv[])
|
||||
{
|
||||
std::vector< int > a = { 1, 5, 6, 10 };
|
||||
print( "a", a);
|
||||
|
||||
std::vector< int > b = { 2, 4, 7, 8, 9, 13 };
|
||||
print( "b", b);
|
||||
|
||||
std::vector< int > c = merge( a, b);
|
||||
print( "c", c);
|
||||
|
||||
std::cout << "Done" << std::endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
|
||||
// Copyright Oliver Kowalke 2009.
|
||||
// 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/coroutine/all.hpp>
|
||||
|
||||
typedef boost::coroutines::symmetric_coroutine< void > coro_t;
|
||||
|
||||
int main( int argc, char * argv[])
|
||||
{
|
||||
coro_t::call_type * other1 = 0;
|
||||
coro_t::call_type * other2 = 0;
|
||||
|
||||
coro_t::call_type coro1(
|
||||
[&]( coro_t::yield_type & yield) {
|
||||
std::cout << "foo1" << std::endl;
|
||||
yield( * other2);
|
||||
std::cout << "foo2" << std::endl;
|
||||
yield( * other2);
|
||||
std::cout << "foo3" << std::endl;
|
||||
});
|
||||
coro_t::call_type coro2(
|
||||
[&]( coro_t::yield_type & yield) {
|
||||
std::cout << "bar1" << std::endl;
|
||||
yield( * other1);
|
||||
std::cout << "bar2" << std::endl;
|
||||
yield( * other1);
|
||||
std::cout << "bar3" << std::endl;
|
||||
});
|
||||
|
||||
other1 = & coro1;
|
||||
other2 = & coro2;
|
||||
|
||||
coro1();
|
||||
|
||||
std::cout << "Done" << std::endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue
Block a user