mirror of
https://github.com/boostorg/context.git
synced 2026-01-19 04:02:17 +00:00
make execution_context (v2) typesafe
This commit is contained in:
@@ -26,22 +26,30 @@ project boost/context/example/execution_context
|
||||
<threading>multi
|
||||
;
|
||||
|
||||
exe jump
|
||||
: jump.cpp
|
||||
exe jump_void
|
||||
: jump_void.cpp
|
||||
;
|
||||
|
||||
exe parser
|
||||
: parser.cpp
|
||||
exe jump
|
||||
: jump.cpp
|
||||
;
|
||||
|
||||
exe fibonacci
|
||||
: fibonacci.cpp
|
||||
;
|
||||
|
||||
exe parser
|
||||
: parser.cpp
|
||||
;
|
||||
|
||||
exe parameter
|
||||
: parameter.cpp
|
||||
;
|
||||
|
||||
exe ontop_void
|
||||
: ontop_void.cpp
|
||||
;
|
||||
|
||||
exe ontop
|
||||
: ontop.cpp
|
||||
;
|
||||
|
||||
@@ -14,12 +14,12 @@ namespace ctx = boost::context;
|
||||
|
||||
int main() {
|
||||
int n=35;
|
||||
ctx::execution_context source(
|
||||
[n](ctx::execution_context sink,void*)mutable{
|
||||
ctx::execution_context< int > source(
|
||||
[n](ctx::execution_context< int > sink, int) mutable {
|
||||
int a=0;
|
||||
int b=1;
|
||||
while(n-->0){
|
||||
auto result=sink(&a);
|
||||
auto result=sink(a);
|
||||
sink=std::move(std::get<0>(result));
|
||||
auto next=a+b;
|
||||
a=b;
|
||||
@@ -28,9 +28,9 @@ int main() {
|
||||
return sink;
|
||||
});
|
||||
for(int i=0;i<10;++i){
|
||||
auto result=source();
|
||||
auto result=source(i);
|
||||
source=std::move(std::get<0>(result));
|
||||
std::cout<<*(int*)std::get<1>(result)<<" ";
|
||||
std::cout<<std::get<1>(result)<<" ";
|
||||
}
|
||||
std::cout<<std::endl;
|
||||
|
||||
|
||||
@@ -11,27 +11,20 @@
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
ctx::execution_context f1( ctx::execution_context ctxm, void * data) {
|
||||
std::cout << "f1: entered first time" << std::endl;
|
||||
std::tie( ctxm, data) = ctxm();
|
||||
std::cout << "f1: entered second time" << std::endl;
|
||||
ctx::execution_context ctx2 = std::move( * static_cast< ctx::execution_context * >( data) );
|
||||
ctx2( & ctxm);
|
||||
return ctxm;
|
||||
}
|
||||
|
||||
ctx::execution_context f2( ctx::execution_context ctx1, void * data) {
|
||||
std::cout << "f2: entered first time" << std::endl;
|
||||
ctx::execution_context ctxm = std::move( * static_cast< ctx::execution_context * >( data) );
|
||||
ctx::execution_context< int > f1( ctx::execution_context< int > ctxm, int data) {
|
||||
std::cout << "f1: entered first time: " << data << std::endl;
|
||||
std::tie( ctxm, data) = ctxm( data + 2);
|
||||
std::cout << "f1: entered second time: " << data << std::endl;
|
||||
return ctxm;
|
||||
}
|
||||
|
||||
int main() {
|
||||
ctx::execution_context ctx1( f1);
|
||||
void * ignored;
|
||||
std::tie( ctx1, ignored) = ctx1();
|
||||
ctx::execution_context ctx2( f2);
|
||||
std::tie( ctx1, ignored) = ctx1( & ctx2);
|
||||
int data = 1;
|
||||
ctx::execution_context< int > ctx1( f1);
|
||||
std::tie( ctx1, data) = ctx1( data + 2);
|
||||
std::cout << "f1: returned first time: " << data << std::endl;
|
||||
std::tie( ctx1, data) = ctx1( data + 2);
|
||||
std::cout << "f1: returned second time: " << data << std::endl;
|
||||
|
||||
std::cout << "main: done" << std::endl;
|
||||
|
||||
|
||||
31
example/v2/jump_void.cpp
Normal file
31
example/v2/jump_void.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
// Copyright 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/context/all.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
ctx::execution_context< void > f1( ctx::execution_context< void > ctxm) {
|
||||
std::cout << "f1: entered first time" << std::endl;
|
||||
ctxm = ctxm();
|
||||
std::cout << "f1: entered second time" << std::endl;
|
||||
return ctxm;
|
||||
}
|
||||
|
||||
int main() {
|
||||
ctx::execution_context< void > ctx1( f1);
|
||||
ctx1 = ctx1();
|
||||
std::cout << "f1: returned first time" << std::endl;
|
||||
ctx1 = ctx1();
|
||||
std::cout << "f1: returned second time" << std::endl;
|
||||
|
||||
std::cout << "main: done" << std::endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -12,29 +12,29 @@
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
ctx::execution_context f1( ctx::execution_context ctx, void * ignored) {
|
||||
std::cout << "f1: entered first time" << std::endl;
|
||||
std::tie( ctx, ignored) = ctx();
|
||||
std::cout << "f1: entered second time" << std::endl;
|
||||
std::tie( ctx, ignored) = ctx();
|
||||
std::cout << "f1: entered third time" << std::endl;
|
||||
ctx::execution_context< int > f1( ctx::execution_context< int > ctx, int data) {
|
||||
std::cout << "f1: entered first time: " << data << std::endl;
|
||||
std::tie( ctx, data) = ctx( data);
|
||||
std::cout << "f1: entered second time: " << data << std::endl;
|
||||
std::tie( ctx, data) = ctx( data);
|
||||
std::cout << "f1: entered third time: " << data << std::endl;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
std::tuple< ctx::execution_context, void * > f2( ctx::execution_context ctx, void * data) {
|
||||
std::cout << "f2: entered" << std::endl;
|
||||
return std::make_tuple( std::move( ctx), data);
|
||||
ctx::execution_context< int > f2( ctx::execution_context< int > ctx, int data) {
|
||||
std::cout << "f2: entered: " << data << std::endl;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
int main() {
|
||||
void * ignored;
|
||||
ctx::execution_context ctx( f1);
|
||||
std::tie( ctx, ignored) = ctx();
|
||||
std::cout << "f1: returned first time" << std::endl;
|
||||
std::tie( ctx, ignored) = ctx();
|
||||
std::cout << "f1: returned second time" << std::endl;
|
||||
std::tie( ctx, ignored) = ctx( ctx::exec_ontop_arg, f2);
|
||||
std::cout << "f1: returned third time" << std::endl;
|
||||
int data = 3;
|
||||
ctx::execution_context< int > ctx( f1);
|
||||
std::tie( ctx, data) = ctx( data);
|
||||
std::cout << "f1: returned first time: " << data << std::endl;
|
||||
std::tie( ctx, data) = ctx( data);
|
||||
std::cout << "f1: returned second time: " << data << std::endl;
|
||||
std::tie( ctx, data) = ctx( ctx::exec_ontop_arg, f2, data + 2);
|
||||
std::cout << "f1: returned third time: " << data << std::endl;
|
||||
|
||||
std::cout << "main: done" << std::endl;
|
||||
|
||||
|
||||
41
example/v2/ontop_void.cpp
Normal file
41
example/v2/ontop_void.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
|
||||
// Copyright 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 <tuple>
|
||||
|
||||
#include <boost/context/all.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
ctx::execution_context< void > f1( ctx::execution_context< void > ctx) {
|
||||
std::cout << "f1: entered first time" << std::endl;
|
||||
ctx = ctx();
|
||||
std::cout << "f1: entered second time" << std::endl;
|
||||
ctx = ctx();
|
||||
std::cout << "f1: entered third time" << std::endl;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
ctx::execution_context< void > f2( ctx::execution_context< void > ctx) {
|
||||
std::cout << "f2: entered" << std::endl;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
int main() {
|
||||
ctx::execution_context< void > ctx( f1);
|
||||
ctx = ctx();
|
||||
std::cout << "f1: returned first time" << std::endl;
|
||||
ctx = ctx();
|
||||
std::cout << "f1: returned second time" << std::endl;
|
||||
ctx = ctx( ctx::exec_ontop_arg, f2);
|
||||
std::cout << "f1: returned third time" << std::endl;
|
||||
|
||||
std::cout << "main: done" << std::endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -10,28 +10,31 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/context/all.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
typedef boost::variant<int,std::string> variant_t;
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
class X{
|
||||
private:
|
||||
std::exception_ptr excptr_;
|
||||
ctx::execution_context ctx_;
|
||||
ctx::execution_context<variant_t> ctx_;
|
||||
|
||||
public:
|
||||
X():
|
||||
excptr_(),
|
||||
ctx_(
|
||||
[=](ctx::execution_context ctx, void * vp){
|
||||
[=](ctx::execution_context<variant_t> ctx, variant_t data){
|
||||
try {
|
||||
for (;;) {
|
||||
int i = * static_cast< int * >( vp);
|
||||
std::string str = boost::lexical_cast<std::string>(i);
|
||||
auto result = ctx( & str);
|
||||
int i = boost::get<int>(data);
|
||||
data = boost::lexical_cast<std::string>(i);
|
||||
auto result = ctx( data);
|
||||
ctx = std::move( std::get<0>( result) );
|
||||
vp = std::get<1>( result);
|
||||
data = std::get<1>( result);
|
||||
}
|
||||
} catch ( ctx::detail::forced_unwind const&) {
|
||||
throw;
|
||||
@@ -43,13 +46,14 @@ public:
|
||||
{}
|
||||
|
||||
std::string operator()(int i){
|
||||
auto result = ctx_( & i);
|
||||
variant_t data = i;
|
||||
auto result = ctx_( data);
|
||||
ctx_ = std::move( std::get<0>( result) );
|
||||
void * ret = std::get<1>( result);
|
||||
data = std::get<1>( result);
|
||||
if(excptr_){
|
||||
std::rethrow_exception(excptr_);
|
||||
}
|
||||
return * static_cast< std::string * >( ret);
|
||||
return boost::get<std::string>(data);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -96,13 +96,13 @@ int main() {
|
||||
std::exception_ptr except;
|
||||
|
||||
// execute parser in new execution context
|
||||
boost::context::execution_context source(
|
||||
[&is,&done,&except](ctx::execution_context sink,void*){
|
||||
boost::context::execution_context<char> source(
|
||||
[&is,&done,&except](ctx::execution_context<char> sink,char){
|
||||
// create parser with callback function
|
||||
Parser p( is,
|
||||
[&sink](char ch){
|
||||
// resume main execution context
|
||||
auto result = sink(&ch);
|
||||
auto result = sink(ch);
|
||||
sink = std::move(std::get<0>(result));
|
||||
});
|
||||
try {
|
||||
@@ -120,15 +120,15 @@ int main() {
|
||||
|
||||
// user-code pulls parsed data from parser
|
||||
// invert control flow
|
||||
auto result = source();
|
||||
auto result = source('\0');
|
||||
source = std::move(std::get<0>(result));
|
||||
void * vp = std::get<1>(result);
|
||||
char c = std::get<1>(result);
|
||||
if ( except) {
|
||||
std::rethrow_exception(except);
|
||||
}
|
||||
while( ! done) {
|
||||
printf("Parsed: %c\n",* static_cast<char*>(vp));
|
||||
std::tie(source,vp) = source();
|
||||
printf("Parsed: %c\n",c);
|
||||
std::tie(source,c) = source('\0');
|
||||
if (except) {
|
||||
std::rethrow_exception(except);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user