2
0
mirror of https://github.com/boostorg/context.git synced 2026-01-19 04:02:17 +00:00

rename of continuation member functions

This commit is contained in:
Oliver Kowalke
2017-03-05 10:22:48 +01:00
parent b4e18ff600
commit 82293a2c03
16 changed files with 217 additions and 221 deletions

View File

@@ -67,7 +67,7 @@ __con__ is only move-constructible and move-assignable.
As a first-class object __con__ can be applied to and returned from a function,
assigned to a variable or stored in a container.
A contiunation is continued by calling `operator()`.
A contiunation is continued by calling `resume()`/`resume_with()`.
[heading Usage]
@@ -78,7 +78,7 @@ A contiunation is continued by calling `operator()`.
int a=0;
int b=1;
for(;;){
sink=sink(a);
sink=sink.resume(a);
auto next=a+b;
a=b;
b=next;
@@ -86,8 +86,8 @@ A contiunation is continued by calling `operator()`.
return std::move(sink);
});
for (int j=0;j<10;++j) {
std::cout << ctx::get_data<int>(source) << " ";
source=source();
std::cout << source.get_data<int>() << " ";
source=source.resume();
}
output:
@@ -104,7 +104,7 @@ after each call.
The lambda that calculates the Fibonacci numbers is executed inside
the continuation represented by `source`. Calculated Fibonacci numbers are
transferred between the two continuations' as argument of __cc__ (and returned
by `ctx::get_data<int>(source)`). Note that this example represents a ['generator]
by `source.get_data<int>()`). Note that this example represents a ['generator]
thus no value is transferred into the lambda via __cc__.
The locale variables `a`, `b` and ` next` remain their values during each
@@ -117,17 +117,17 @@ Calling __cc__ without arguments means, that no data will be transferred, only
the context switch is executed.
The arguments passed to __cc__, in one continuation, are accessible via
`ctx::get_data<>(c)` in the other continuation.
`c.get_data<>()` in the other continuation.
namespace ctx=boost::context;
int i=1;
ctx::continuation c1=callcc([](ctx::continuation && c2){
int j=ctx::get_data<int>(c2);
int j=c2.get_data<int>();
std::printf("inside c1,j==%d\n",j);
return c2(j+1);
return c2.resume(j+1);
},
i);
i=ctx::get_data<int>(c1);
i=c1.get_data<int>();
std::printf("i==%d\n",i);
output:
@@ -136,9 +136,9 @@ The arguments passed to __cc__, in one continuation, are accessible via
`callcc(<lambda>,i)` enters the lambda in continuation represented by `c1` with
argument `i=1`.
The expression c2(j+1)` resumes the continuation `c2` and
The expression `c2.resume(j+1)` resumes the continuation `c2` and
transfers back an integer of `j+1`. On return of `callcc(<lambda>, i)`, the
variable `i` gets the value of `j+1` assigned (`i=get_data<int>(c1)`).
variable `i` gets the value of `j+1` assigned (`i=c1.get_data<int>()`).
More than one argument can be transferred too.
@@ -146,12 +146,12 @@ More than one argument can be transferred too.
int i=2,j=1;
ctx::continuation c1=callcc([](ctx::continuation && c2){
int i, j;
std::tie(i,j)=ctx::get_data<int,int>(c2);
std::tie(i,j)=c2.get_data<int,int>();
std::printf("inside c1,i==%d,j==%d\n",i,j);
return c2(i+j,i-j);
return c2.resume(i+j,i-j);
},
i, j);
std::tie(i,j)=ctx::get_data<int,int>(c1);
std::tie(i,j)=c1.get_data<int,int>();
std::printf("i==%d,j==%d\n",i,j);
output:
@@ -163,25 +163,25 @@ For use-cases, that require to transfer data of different type:
namespace ctx=boost::context;
ctx::continuation f1(ctx::continuation && c) {
int i=3;
c=c(i);
c=c.resume(i);
std::string s{ "abc" };
c=c(s);
c=c.resume(s);
i=7;s="xyz";
c=c(i,s);
c=c();
c=c.resume(i,s);
c=c.resume();
return std::move(c);
}
ctx::continuation c = ctx::callcc( f1);
int i = ctx::get_data< int >( c);
ctx::continuation c=ctx::callcc(f1);
int i=c.get_data<int>();
std::cout << "f1: returned : " << i << std::endl;
c = c();
std::string s = ctx::get_data< std::string >( c);
c=c.resume();
std::string s=c.get_data<std::string>();
std::cout << "f1: returned : " << s << std::endl;
c = c();
std::tie(i,s)=ctx::get_data< int, std::string >( c);
c=c.resume();
std::tie(i,s)=c.get_data< int, std::string >();
std::cout << "f1: returned : " << i << ", " << s << std::endl;
c = c();
c=c.resume();
std::cout << std::boolalpha;
std::cout << "f1: returned data : " << ctx::data_available( c) << std::endl;
@@ -211,31 +211,31 @@ return type or void.
namespace ctx=boost::context;
ctx::continuation f1(ctx::continuation && c) {
int data=ctx::get_data<int>(c);
int data=c.get_data<int>();
std::cout << "f1: entered first time: " << data << std::endl;
c=c(data+1);
data=ctx::get_data<int>(c);
c=c.resume(data+1);
data=c.get_data<int>();
std::cout << "f1: entered second time: " << data << std::endl;
c=c(data+1);
data=ctx::get_data<int>(c);
c=c.resume(data+1);
data=c.get_data<int>();
std::cout << "f1: entered third time: " << data << std::endl;
return std::move(c);
};
int f2(ctx::continuation && c){
int data=ctx::transfer_data<int>(c);
int data=c.get_data<int>(c);
std::cout << "f2: entered: " << data << std::endl;
return data;
};
int data = 0;
ctx::continuation c=ctx::callcc(f1,data+1);
data=ctx::get_data<int>(c);
data=c.get_data<int>();
std::cout << "f1: returned first time: " << data << std::endl;
c=c(data+1);
data=ctx::get_data<int>(c);
c=c.resume(data+1);
data=c.get_data<int>();
std::cout << "f1: returned second time: " << data << std::endl;
c=c(ctx::exec_ontop_arg,f2,-1);
c=c.resume_with(f2,-1);
std::cout << "f1: returned third time" << std::endl;
output:
@@ -247,10 +247,10 @@ return type or void.
f1: entered third time: -1
f1: returned third time
The expression `c(ctx::exec_ontop_arg,f2,-1)` executes
The expression `c.resume_with(f2,-1)` executes
`f2()` on top of contiunation `c`, e.g. an additional stack frame is allocated
on top of the stack (in front of `f1()`). `f2()` returns argument `-1` that will
returned by the second invocation of `c(data+1)` in `f1()`.
returned by the second invocation of `c.resume(data+1)` in `f1()`.
Another option is to execute a function on top of the continuation that throws
an exception.
@@ -268,7 +268,7 @@ an exception.
for (;;) {
try {
std::cout << "entered" << std::endl;
c=c();
c=c.resume();
} catch (my_exception & ex) {
std::cerr << "my_exception: " << ex.what() << std::endl;
return std::move(ex.c);
@@ -276,7 +276,7 @@ an exception.
}
return std::move(c);
});
c = c( ctx::exec_ontop_arg,
c = c.resume_with(
[](ctx::continuation && c){
throw my_exception(std::move(c),"abc");
});
@@ -425,7 +425,7 @@ of the stack.]
Parser p(is,
[&sink](char c){
// resume main continuation
sink=sink(c);
sink=sink.resume(c);
});
// start recursive parsing
p.run();
@@ -433,9 +433,9 @@ of the stack.]
return std::move(sink);
});
while(ctx::data_available(source)){
char c=ctx::get_data<char>(source);
char c=source.get_data<char>();
printf("Parsed: %c\n",c);
source=source();
source=source.resume();
}
output:
@@ -455,9 +455,6 @@ The data (character) is transferred between the two continuations.
#include <boost/context/continuation.hpp>
struct exec_ontop_arg_t {};
const exec_ontop_arg_t exec_ontop_arg{};
class continuation {
public:
continuation() noexcept = default;
@@ -472,10 +469,15 @@ The data (character) is transferred between the two continuations.
continuation & operator=(continuation const& other) noexcept = delete;
template<typename ...Arg>
continuation operator()(Arg ...arg);
continuation resume(Arg ...arg);
template<typename Fn,typename ...Arg>
continuation operator()(exec_ontop_arg_t,Fn && fn,Arg ...arg);
continuation resume_with(Fn && fn,Arg ...arg);
bool data_available() noexcept;
template<typename ...Arg>
<unspecified> get_data();
explicit operator bool() const noexcept;
@@ -540,10 +542,10 @@ e.g. ['continuation::operator bool()] returns `true`.]]
[operator_heading cc..operator_call..operator()]
template<typename ...Arg>
continuation operator()(Arg ...arg);
continuation resume(Arg ...arg);
template<typename Fn,typename ...Arg>
continuation operator()(exec_ontop_arg_t,Fn && fn,Arg ...arg);
continuation resume_with(Fn && fn,Arg ...arg);
[variablelist
[[Effects:] [Captures current continuation and resumes `*this`.
@@ -561,6 +563,26 @@ terminated (return from context-function) via `bool operator()`. If the returned
continuation has terminated no data are transferred.]]
]
[member_heading cc..data_available]
bool data_available() noexcept;
[variablelist
[[Efects:] [Tests if `c` has data.]]
[[Returns:] [`true` if data have been transferred, otherwise `false`.]]
[[Throws:] [Nothing.]]
]
[member_heading cc..get_available]
template<typename ...Arg>
<unspecified> get_data();
[variablelist
[[Returns:] [Data that have been transferred via `callcc()` or `operator()` are
returned as `std::tuple<Arg...>` or `Arg` if single parameter.]]
]
[operator_heading cc..operator_bool..operator bool]
explicit operator bool() const noexcept;
@@ -647,26 +669,6 @@ before `other`, false otherwise.]]
[[Returns:] [`os`]]
]
[hding cc__..Non-member function [`data_available()]]
bool data_available(continuation const& c) noexcept;
[variablelist
[[Efects:] [Tests if `c` has data.]]
[[Returns:] [`true` if data have been transferred, otherwise `false`.]]
[[Throws:] [Nothing.]]
]
[hding cc___..Non-member tempalte function [`data()]]
template<typename ...Arg>
<unspecified> data(continuation & c);
[variablelist
[[Returns:] [Data that have been trasnferred via `callcc()` or `operator()` are
returned as `std::tuple<Arg...>` or `Arg` if single parameter.]]
]
[heading Call with current contiunation]

View File

@@ -26,13 +26,13 @@ void echoSSE( int i) {
}
ctx::continuation echo( ctx::continuation && c) {
int i = ctx::get_data< int >( c);
int i = c.get_data< int >();
for (;;) {
std::cout << i;
echoSSE( i);
std::cout << " ";
c = c();
i = ctx::get_data< int >( c);
c = c.resume();
i = c.get_data< int >();
}
return std::move( c);
}

View File

@@ -14,7 +14,7 @@ namespace ctx = boost::context;
ctx::continuation foo( ctx::continuation && c) {
do {
std::cout << "foo\n";
} while ( c = c() );
} while ( c = c.resume() );
return std::move( c);
}
@@ -22,7 +22,7 @@ int main() {
ctx::continuation c = ctx::callcc( foo);
do {
std::cout << "bar\n";
} while ( c = c() );
} while ( c = c.resume() );
std::cout << "main: done" << std::endl;
return EXIT_SUCCESS;
}

View File

@@ -18,7 +18,7 @@ int main() {
int a=0;
int b=1;
for(;;){
c=c(a);
c=c.resume(a);
auto next=a+b;
a=b;
b=next;
@@ -26,8 +26,8 @@ int main() {
return std::move( c);
});
for ( int j = 0; j < 10; ++j) {
std::cout << ctx::get_data<int>(c) << " ";
c=c();
std::cout << c.get_data<int>() << " ";
c=c.resume();
}
std::cout << std::endl;
std::cout << "main: done" << std::endl;

View File

@@ -12,10 +12,10 @@
namespace ctx = boost::context;
ctx::continuation f1( ctx::continuation && c) {
int data = ctx::get_data< int >(c);
int data = c.get_data< int >();
std::cout << "f1: entered first time: " << data << std::endl;
c = c( data + 2);
data = ctx::get_data< int >( c);
c = c.resume( data + 2);
data = c.get_data< int >();
std::cout << "f1: entered second time: " << data << std::endl;
return std::move( c);
}
@@ -24,11 +24,11 @@ int main() {
ctx::continuation c;
int data = 1;
c = ctx::callcc( f1, data);
data = ctx::get_data< int >( c);
data = c.get_data< int >();
std::cout << "f1: returned first time: " << data << std::endl;
c = c( data + 2);
if ( ctx::data_available( c) ) {
data = ctx::get_data< int >( c);
c = c.resume( data + 2);
if ( c.data_available() ) {
data = c.get_data< int >();
std::cout << "f1: returned second time: " << data << std::endl;
} else {
std::cout << "f1: returned second time: no data" << std::endl;

View File

@@ -47,8 +47,8 @@ public:
};
ctx::continuation f1( ctx::continuation && c) {
moveable data = ctx::get_data< moveable >( c);
c = c( std::move( data) );
moveable data = c.get_data< moveable >();
c = c.resume( std::move( data) );
return std::move( c);
}
@@ -57,7 +57,7 @@ int main() {
moveable data1{ 3 };
c = ctx::callcc( std::allocator_arg, ctx::fixedsize_stack{}, f1, std::move( data1) );
moveable data2;
data2 = ctx::get_data< moveable >( c);
data2 = c.get_data< moveable >();
std::cout << "main: done" << std::endl;
return EXIT_SUCCESS;
}

View File

@@ -12,10 +12,10 @@
namespace ctx = boost::context;
ctx::continuation f1( ctx::continuation && c) {
int & data = ctx::get_data< int & >( c);
int & data = c.get_data< int & >();
std::cout << "f1: entered first time: " << data << std::endl;
data += 2;
c = c( std::ref( data) );
c = c.resume( std::ref( data) );
data += 2;
std::cout << "f1: entered second time: " << data << std::endl;
return std::move( c);
@@ -26,9 +26,9 @@ int main() {
int data_ = 1;
int & data = data_;
c = ctx::callcc( std::allocator_arg, ctx::fixedsize_stack{}, f1, std::ref( data) );
data = ctx::get_data< int & >( c);
data = c.get_data< int & >();
std::cout << "f1: returned first time: " << data << std::endl;
c = c( std::ref( data) );
c = c.resume( std::ref( data) );
if ( c) {
std::cout << "f1: returned second time: " << data << std::endl;
} else {

View File

@@ -11,17 +11,17 @@
namespace ctx = boost::context;
ctx::continuation f1( ctx::continuation && cm) {
ctx::continuation f1( ctx::continuation && c) {
std::cout << "f1: entered first time" << std::endl;
cm = cm();
c = c.resume();
std::cout << "f1: entered second time" << std::endl;
return std::move( cm);
return std::move( c);
}
int main() {
ctx::continuation c = ctx::callcc( f1);
std::cout << "f1: returned first time" << std::endl;
c = c();
c = c.resume();
std::cout << "f1: returned second time" << std::endl;
std::cout << "main: done" << std::endl;

View File

@@ -16,25 +16,25 @@ int main() {
ctx::continuation c;
int data = 0;
c = ctx::callcc( [](ctx::continuation && c) {
int data = ctx::get_data< int >( c);
int data = c.get_data< int >();
std::cout << "f1: entered first time: " << data << std::endl;
c = c( data + 1);
data = ctx::get_data< int >( c);
c = c.resume( data + 1);
data = c.get_data< int >();
std::cout << "f1: entered second time: " << data << std::endl;
c = c( data + 1);
data = ctx::get_data< int >( c);
c = c.resume( data + 1);
data = c.get_data< int >();
std::cout << "f1: entered third time: " << data << std::endl;
return std::move( c);
},
data + 1);
data = ctx::get_data< int >( c);
data = c.get_data< int >();
std::cout << "f1: returned first time: " << data << std::endl;
c = c( data + 1);
data = ctx::get_data< int >( c);
c = c.resume( data + 1);
data = c.get_data< int >();
std::cout << "f1: returned second time: " << data << std::endl;
c = c( ctx::exec_ontop_arg,
c = c.resume_with(
[](ctx::continuation && c){
int data = ctx::get_data< int >( c);
int data = c.get_data< int >();
std::cout << "f2: entered: " << data << std::endl;
return data;
},

View File

@@ -14,9 +14,9 @@ namespace ctx = boost::context;
ctx::continuation f1( ctx::continuation && c) {
std::cout << "f1: entered first time" << std::endl;
c = c();
c = c.resume();
std::cout << "f1: entered second time" << std::endl;
c = c();
c = c.resume();
std::cout << "f1: entered third time" << std::endl;
return std::move( c);
}
@@ -28,9 +28,9 @@ void f2( ctx::continuation && c) {
int main() {
ctx::continuation c = ctx::callcc( f1);
std::cout << "f1: returned first time" << std::endl;
c = c();
c = c.resume();
std::cout << "f1: returned second time" << std::endl;
c = c( ctx::exec_ontop_arg, f2);
c = c.resume_with( f2);
std::cout << "f1: returned third time" << std::endl;
std::cout << "main: done" << std::endl;

View File

@@ -102,17 +102,17 @@ int main() {
Parser p( is,
[&sink](char c){
// resume main execution context
sink=sink(c);
sink=sink.resume(c);
});
// start recursive parsing
p.run();
// resume main execution context
return std::move(sink);
});
while(ctx::data_available(source)){
char c=ctx::get_data<char>(source);
while(source.data_available()){
char c=source.get_data<char>();
printf("Parsed: %c\n",c);
source=source();
source=source.resume();
}
std::cout << "main: done" << std::endl;
return EXIT_SUCCESS;

View File

@@ -27,7 +27,7 @@ int main() {
for (;;) {
try {
std::cout << "entered" << std::endl;
c = c();
c = c.resume();
} catch ( my_exception & ex) {
std::cerr << "my_exception: " << ex.what() << std::endl;
return std::move( ex.c);
@@ -35,7 +35,7 @@ int main() {
}
return std::move( c);
});
c = c( ctx::exec_ontop_arg,
c = c.resume_with(
[](ctx::continuation && c){
throw my_exception(std::move( c), "abc");
});

View File

@@ -14,28 +14,28 @@ namespace ctx = boost::context;
ctx::continuation f1( ctx::continuation && c) {
int i = 3;
c = c( i);
c = c.resume( i);
std::string s{ "abc" };
c = c( s);
c = c.resume( s);
i = 7; s = "xyz";
c = c( i, s);
c = c();
c = c.resume( i, s);
c = c.resume();
return std::move( c);
}
int main() {
ctx::continuation c = ctx::callcc( f1);
int i = ctx::get_data< int >( c);
int i = c.get_data< int >();
std::cout << "f1: returned : " << i << std::endl;
c = c();
std::string s = ctx::get_data< std::string >( c);
c = c.resume();
std::string s = c.get_data< std::string >();
std::cout << "f1: returned : " << s << std::endl;
c = c();
std::tie(i,s)=ctx::get_data< int, std::string >( c);
c = c.resume();
std::tie(i,s)=c.get_data< int, std::string >();
std::cout << "f1: returned : " << i << ", " << s << std::endl;
c = c();
c = c.resume();
std::cout << std::boolalpha;
std::cout << "f1: returned data : " << ctx::data_available( c) << std::endl;
std::cout << "f1: returned data : " << c.data_available() << std::endl;
std::cout << "main: done" << std::endl;
return EXIT_SUCCESS;
}

View File

@@ -298,11 +298,6 @@ private:
friend continuation
callcc( std::allocator_arg_t, preallocated, StackAlloc, Fn &&);
friend bool data_available( continuation const&) noexcept;
template< typename ... Arg >
friend typename detail::result_type< Arg ... >::type get_data( continuation &);
detail::transfer_t t_{ nullptr, nullptr };
continuation( detail::fcontext_t fctx) noexcept :
@@ -343,7 +338,7 @@ public:
continuation & operator=( continuation const& other) noexcept = delete;
template< typename ... Arg >
continuation operator()( Arg ... arg) {
continuation resume( Arg ... arg) {
BOOST_ASSERT( nullptr != t_.fctx);
auto tpl = std::make_tuple( std::forward< Arg >( arg) ... );
return detail::jump_fcontext(
@@ -356,7 +351,7 @@ public:
}
template< typename Fn, typename ... Arg >
continuation operator()( exec_ontop_arg_t, Fn && fn, Arg ... arg) {
continuation resume_with( Fn && fn, Arg ... arg) {
BOOST_ASSERT( nullptr != t_.fctx);
auto tpl = std::make_tuple( std::forward< Fn >( fn), std::forward< Arg >( arg) ... );
return detail::ontop_fcontext(
@@ -369,7 +364,7 @@ public:
context_ontop< continuation, Fn, Arg ... >);
}
continuation operator()() {
continuation resume() {
BOOST_ASSERT( nullptr != t_.fctx);
return detail::jump_fcontext(
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
@@ -381,7 +376,7 @@ public:
}
template< typename Fn >
continuation operator()( exec_ontop_arg_t, Fn && fn) {
continuation resume_with( Fn && fn) {
BOOST_ASSERT( nullptr != t_.fctx);
auto p = std::make_tuple( std::forward< Fn >( fn) );
return detail::ontop_fcontext(
@@ -394,6 +389,16 @@ public:
context_ontop_void< continuation, Fn >);
}
bool data_available() noexcept {
return * this && nullptr != t_.data;
}
template< typename ... Arg >
typename detail::result_type< Arg ... >::type get_data() {
BOOST_ASSERT( nullptr != t_.data);
return detail::result_type< Arg ... >::get( t_);
}
explicit operator bool() const noexcept {
return nullptr != t_.fctx;
}
@@ -441,17 +446,6 @@ public:
}
};
inline
bool data_available( continuation const& c) noexcept {
return c && nullptr != c.t_.data;
}
template< typename ... Arg >
typename detail::result_type< Arg ... >::type get_data( continuation & c) {
BOOST_ASSERT( nullptr != c.t_.data);
return detail::result_type< Arg ... >::get( c.t_);
}
// Arg
template<
typename Fn,
@@ -475,7 +469,7 @@ callcc( std::allocator_arg_t, StackAlloc salloc, Fn && fn, Arg ... arg) {
using Record = detail::record< continuation, StackAlloc, Fn >;
return continuation{
detail::context_create< Record >(
salloc, std::forward< Fn >( fn) ) }(
salloc, std::forward< Fn >( fn) ) }.resume(
std::forward< Arg >( arg) ... );
}
@@ -489,7 +483,7 @@ callcc( std::allocator_arg_t, preallocated palloc, StackAlloc salloc, Fn && fn,
using Record = detail::record< continuation, StackAlloc, Fn >;
return continuation{
detail::context_create< Record >(
palloc, salloc, std::forward< Fn >( fn) ) }(
palloc, salloc, std::forward< Fn >( fn) ) }.resume(
std::forward< Arg >( arg) ... );
}
@@ -511,7 +505,7 @@ callcc( std::allocator_arg_t, StackAlloc salloc, Fn && fn) {
using Record = detail::record< continuation, StackAlloc, Fn >;
return continuation{
detail::context_create< Record >(
salloc, std::forward< Fn >( fn) ) }();
salloc, std::forward< Fn >( fn) ) }.resume();
}
template< typename StackAlloc, typename Fn >
@@ -520,7 +514,7 @@ callcc( std::allocator_arg_t, preallocated palloc, StackAlloc salloc, Fn && fn)
using Record = detail::record< continuation, StackAlloc, Fn >;
return continuation{
detail::context_create< Record >(
palloc, salloc, std::forward< Fn >( fn) ) }();
palloc, salloc, std::forward< Fn >( fn) ) }.resume();
}
#if defined(BOOST_USE_SEGMENTED_STACKS)

View File

@@ -23,7 +23,7 @@ namespace ctx = boost::context;
static ctx::continuation foo( ctx::continuation && c) {
while ( true) {
c = c();
c = c.resume();
}
return std::move( c);
}
@@ -31,11 +31,11 @@ static ctx::continuation foo( ctx::continuation && c) {
duration_type measure_time() {
// cache warum-up
ctx::continuation c = ctx::callcc( foo);
c = c();
c = c.resume();
time_point_type start( clock_type::now() );
for ( std::size_t i = 0; i < jobs; ++i) {
c = c();
c = c.resume();
}
duration_type total = clock_type::now() - start;
total -= overhead_clock(); // overhead of measurement
@@ -50,11 +50,11 @@ cycle_type measure_cycles() {
// cache warum-up
ctx::fixedsize_stack alloc;
ctx::continuation c = ctx::callcc( std::allocator_arg, alloc, foo);
c = c();
c = c.resume();
cycle_type start( cycles() );
for ( std::size_t i = 0; i < jobs; ++i) {
c = c();
c = c.resume();
}
cycle_type total = cycles() - start;
total -= overhead_cycle(); // overhead of measurement

View File

@@ -41,7 +41,7 @@ double value3 = 0.;
struct X {
ctx::continuation foo( ctx::continuation && c) {
value1 = ctx::get_data< int >( c);
value1 = c.get_data< int >();
return std::move( c);
}
};
@@ -121,13 +121,13 @@ void seh( bool & catched) {
#endif
ctx::continuation fn1( ctx::continuation && c) {
value1 = ctx::get_data< int >( c);
value1 = c.get_data< int >();
return std::move( c);
}
ctx::continuation fn2( ctx::continuation && c) {
try {
throw std::runtime_error( ctx::get_data< const char * >( c) );
throw std::runtime_error( c.get_data< const char * >() );
} catch ( std::runtime_error const& e) {
value2 = e.what();
}
@@ -135,7 +135,7 @@ ctx::continuation fn2( ctx::continuation && c) {
}
ctx::continuation fn3( ctx::continuation && c) {
double d = ctx::get_data< double >( c);
double d = c.get_data< double >();
d += 3.45;
value3 = d;
return std::move( c);
@@ -155,9 +155,9 @@ ctx::continuation fn4( ctx::continuation && c) {
ctx::continuation fn6( ctx::continuation && c) {
try {
value1 = 3;
c = c();
c = c.resume();
value1 = 7;
c = c();
c = c.resume();
} catch ( my_exception & e) {
value2 = e.what();
}
@@ -166,71 +166,71 @@ ctx::continuation fn6( ctx::continuation && c) {
ctx::continuation fn7( ctx::continuation && c) {
Y y;
return c();
return c.resume();
}
ctx::continuation fn8( ctx::continuation && c) {
value1 = ctx::get_data< int >( c);
value1 = c.get_data< int >();
return std::move( c);
}
ctx::continuation fn9( ctx::continuation && c) {
value1 = ctx::get_data< int >( c);
c = c( value1);
value1 = ctx::get_data< int >( c);
value1 = c.get_data< int >();
c = c.resume( value1);
value1 = c.get_data< int >();
return std::move( c);
}
ctx::continuation fn10( ctx::continuation && c) {
int & i = ctx::get_data< int & >( c);
return c( std::ref( i) );
int & i = c.get_data< int & >();
return c.resume( std::ref( i) );
}
ctx::continuation fn11( ctx::continuation && c) {
moveable m = ctx::get_data< moveable >( c);
c = c( std::move( m) );
m = ctx::get_data< moveable >( c);
return c( std::move( m) );
moveable m = c.get_data< moveable >();
c = c.resume( std::move( m) );
m = c.get_data< moveable >();
return c.resume( std::move( m) );
}
ctx::continuation fn12( ctx::continuation && c) {
int i; std::string str;
std::tie( i, str) = ctx::get_data< int, std::string >( c);
return c( i, str);
std::tie( i, str) = c.get_data< int, std::string >();
return c.resume( i, str);
}
ctx::continuation fn13( ctx::continuation && c) {
int i; moveable m;
std::tie( i, m) = ctx::get_data< int, moveable >( c);
return c( i, std::move( m) );
std::tie( i, m) = c.get_data< int, moveable >();
return c.resume( i, std::move( m) );
}
ctx::continuation fn14( ctx::continuation && c) {
variant_t data = ctx::get_data< variant_t >( c);
variant_t data = c.get_data< variant_t >();
int i = boost::get< int >( data);
data = boost::lexical_cast< std::string >( i);
return c( data);
return c.resume( data);
}
ctx::continuation fn15( ctx::continuation && c) {
Y * py = ctx::get_data< Y * >( c);
return c( py);
Y * py = c.get_data< Y * >();
return c.resume( py);
}
ctx::continuation fn16( ctx::continuation && c) {
int i = ctx::get_data< int >( c);
int i = c.get_data< int >();
value1 = i;
c = c( i);
value1 = ctx::get_data< int >( c);
c = c.resume( i);
value1 = c.get_data< int >();
return std::move( c);
}
ctx::continuation fn17( ctx::continuation && c) {
int i; int j;
std::tie( i, j) = ctx::get_data< int, int >( c);
std::tie( i, j) = c.get_data< int, int >();
for (;;) {
c = c( i, j);
std::tie( i, j) = ctx::get_data< int, int >( c);
c = c.resume( i, j);
std::tie( i, j) = c.get_data< int, int >();
}
return std::move( c);
}
@@ -248,7 +248,7 @@ void test_move() {
BOOST_CHECK( c1 );
BOOST_CHECK( ! c2 );
BOOST_CHECK_EQUAL( 3, value1);
c1( 0);
c1.resume( 0);
BOOST_CHECK_EQUAL( 0, value1);
BOOST_CHECK( ! c1 );
BOOST_CHECK( ! c2 );
@@ -273,7 +273,7 @@ void test_exception() {
bool catched = false;
std::thread([&catched](){
ctx::continuation c = ctx::callcc([&catched](ctx::continuation && c){
c = c();
c = c.resume();
seh( catched);
return std::move( c);
});
@@ -316,23 +316,23 @@ void test_ontop() {
{
int i = 3, j = 0;
ctx::continuation c = ctx::callcc([](ctx::continuation && c) {
int x = ctx::get_data< int >( c);
int x = c.get_data< int >();
for (;;) {
c = c( x*10);
if ( ctx::data_available( c) ) {
x = ctx::get_data< int >( c);
c = c.resume( x*10);
if ( c.data_available() ) {
x = c.get_data< int >();
}
}
return std::move( c);
}, i);
c = c( ctx::exec_ontop_arg,
c = c.resume_with(
[](ctx::continuation && c){
int x = ctx::get_data< int >( c);
int x = c.get_data< int >();
return x-10;
},
i);
if ( ctx::data_available( c) ) {
j = ctx::get_data< int >( c);
if ( c.data_available() ) {
j = c.get_data< int >();
}
BOOST_CHECK( c );
BOOST_CHECK_EQUAL( j, -70);
@@ -341,14 +341,14 @@ void test_ontop() {
int i = 3, j = 1;
ctx::continuation c;
c = ctx::callcc( fn17, i, j);
c = c( ctx::exec_ontop_arg,
c = c.resume_with(
[](ctx::continuation && c){
int x, y;
std::tie( x, y) = ctx::get_data< int, int >( c);
std::tie( x, y) = c.get_data< int, int >();
return std::make_tuple( x - y, x + y);
},
i, j);
std::tie( i, j) = ctx::get_data< int, int >( c);
std::tie( i, j) = c.get_data< int, int >();
BOOST_CHECK_EQUAL( i, 2);
BOOST_CHECK_EQUAL( j, 4);
}
@@ -359,15 +359,15 @@ void test_ontop() {
BOOST_CHECK( m1.state);
BOOST_CHECK( -1 == m2.value);
BOOST_CHECK( ! m2.state);
c = c( ctx::exec_ontop_arg,
c = c.resume_with(
[](ctx::continuation && c){
moveable m = ctx::get_data< moveable >( c);
moveable m = c.get_data< moveable >();
BOOST_CHECK( m.state);
BOOST_CHECK( 7 == m.value);
return std::move( m);
},
std::move( m1) );
m2 = ctx::get_data< moveable >( c);
m2 = c.get_data< moveable >();
BOOST_CHECK( ! m1.state);
BOOST_CHECK( -1 == m1.value);
BOOST_CHECK( m2.state);
@@ -383,7 +383,7 @@ void test_ontop_exception() {
for (;;) {
value1 = 3;
try {
c = c();
c = c.resume();
} catch ( my_exception & ex) {
value2 = ex.what();
return std::move( ex.c);
@@ -391,10 +391,10 @@ void test_ontop_exception() {
}
return std::move( c);
});
c = c();
c = c.resume();
BOOST_CHECK_EQUAL( 3, value1);
const char * what = "hello world";
c( ctx::exec_ontop_arg,
c.resume_with(
[what](ctx::continuation && c){
throw my_exception( std::move( c), what);
});
@@ -406,11 +406,11 @@ void test_ontop_exception() {
int i = 3, j = 1;
ctx::continuation c = ctx::callcc([]( ctx::continuation && c) {
int x; int y;
std::tie( x, y) = ctx::get_data< int, int >( c);
std::tie( x, y) = c.get_data< int, int >();
for (;;) {
try {
c = c( x+y,x-y);
std::tie( x, y) = ctx::get_data< int, int >( c);
c = c.resume( x+y,x-y);
std::tie( x, y) = c.get_data< int, int >();
} catch ( my_exception & ex) {
value2 = ex.what();
return std::move( ex.c);
@@ -420,13 +420,13 @@ void test_ontop_exception() {
},
i, j);
BOOST_CHECK( c );
std::tie( i, j) = ctx::get_data< int, int >( c);
std::tie( i, j) = c.get_data< int, int >();
BOOST_CHECK_EQUAL( i, 4);
BOOST_CHECK_EQUAL( j, 2);
char const * what = "hello world";
c = c( ctx::exec_ontop_arg,
c = c.resume_with(
[](ctx::continuation && c) {
char const * what = ctx::get_data< char const * >( c);
char const * what = c.get_data< char const * >();
throw my_exception( std::move( c), what);
return what;
},
@@ -460,11 +460,11 @@ void test_termination() {
BOOST_CHECK( ! c );
c = ctx::callcc( fn9, i);
BOOST_CHECK( c );
i = ctx::get_data< int >( c);
i = c.get_data< int >();
BOOST_CHECK_EQUAL( i, value1);
BOOST_CHECK( c );
i = 7;
c = c( i);
c = c.resume( i);
BOOST_CHECK( ! c );
BOOST_CHECK_EQUAL( i, value1);
}
@@ -481,7 +481,7 @@ void test_one_arg() {
int i = 3, j = 0;
ctx::continuation c;
c = ctx::callcc( fn9, i);
j = ctx::get_data< int >( c);
j = c.get_data< int >();
BOOST_CHECK_EQUAL( i, j);
}
{
@@ -489,8 +489,8 @@ void test_one_arg() {
int & i = i_;
BOOST_CHECK_EQUAL( i, i_);
ctx::continuation c = ctx::callcc( fn10, std::ref( i) );
BOOST_CHECK( ctx::data_available( c) );
int & j = ctx::get_data< int & >( c);
BOOST_CHECK( c.data_available() );
int & j = c.get_data< int & >();
BOOST_CHECK_EQUAL( i, i_);
BOOST_CHECK_EQUAL( j, i_);
BOOST_CHECK( & i == & j);
@@ -500,7 +500,7 @@ void test_one_arg() {
Y * py = nullptr;
ctx::continuation c;
c = ctx::callcc( fn15, & y);
py = ctx::get_data< Y * >( c);
py = c.get_data< Y * >();
BOOST_CHECK( py == & y);
}
{
@@ -511,7 +511,7 @@ void test_one_arg() {
BOOST_CHECK( ! m2.state);
ctx::continuation c;
c = ctx::callcc( fn11, std::move( m1) );
m2 = ctx::get_data< moveable >( c);
m2 = c.get_data< moveable >();
BOOST_CHECK( -1 == m1.value);
BOOST_CHECK( ! m1.state);
BOOST_CHECK( 7 == m2.value);
@@ -524,7 +524,7 @@ void test_two_args() {
int i1 = 3, i2 = 0;
std::string str1("abc"), str2;
ctx::continuation c = ctx::callcc( fn12, i1, str1);
std::tie( i2, str2) = ctx::get_data< int, std::string >( c);
std::tie( i2, str2) = c.get_data< int, std::string >();
BOOST_CHECK_EQUAL( i1, i2);
BOOST_CHECK_EQUAL( str1, str2);
}
@@ -537,7 +537,7 @@ void test_two_args() {
BOOST_CHECK( ! m2.state);
ctx::continuation c;
c = ctx::callcc( fn13, i1, std::move( m1) );
std::tie( i2, m2) = ctx::get_data< int, moveable >( c);
std::tie( i2, m2) = c.get_data< int, moveable >();
BOOST_CHECK_EQUAL( i1, i2);
BOOST_CHECK( -1 == m1.value);
BOOST_CHECK( ! m1.state);
@@ -552,7 +552,7 @@ void test_variant() {
variant_t data1 = i, data2;
ctx::continuation c;
c = ctx::callcc( fn14, data1);
data2 = ctx::get_data< variant_t >( c);
data2 = c.get_data< variant_t >();
std::string str = boost::get< std::string >( data2);
BOOST_CHECK_EQUAL( std::string("7"), str);
}