2
0
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:
Oliver Kowalke
2016-02-08 18:36:58 +01:00
parent 68a57f29b3
commit cf783fd907
11 changed files with 691 additions and 174 deletions

View File

@@ -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
;

View File

@@ -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;

View File

@@ -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
View 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;
}

View File

@@ -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
View 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;
}

View File

@@ -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);
}
};

View File

@@ -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);
}