diff --git a/doc/callcc.qbk b/doc/callcc.qbk index 115d496..100b235 100644 --- a/doc/callcc.qbk +++ b/doc/callcc.qbk @@ -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(source) << " "; - source=source(); + std::cout << source.get_data() << " "; + 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(source)`). Note that this example represents a ['generator] +by `source.get_data()`). 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(c2); + int j=c2.get_data(); std::printf("inside c1,j==%d\n",j); - return c2(j+1); + return c2.resume(j+1); }, i); - i=ctx::get_data(c1); + i=c1.get_data(); std::printf("i==%d\n",i); output: @@ -136,9 +136,9 @@ The arguments passed to __cc__, in one continuation, are accessible via `callcc(,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(, i)`, the -variable `i` gets the value of `j+1` assigned (`i=get_data(c1)`). +variable `i` gets the value of `j+1` assigned (`i=c1.get_data()`). 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(c2); + std::tie(i,j)=c2.get_data(); 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(c1); + std::tie(i,j)=c1.get_data(); 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(); 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::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(c); + int data=c.get_data(); std::cout << "f1: entered first time: " << data << std::endl; - c=c(data+1); - data=ctx::get_data(c); + c=c.resume(data+1); + data=c.get_data(); std::cout << "f1: entered second time: " << data << std::endl; - c=c(data+1); - data=ctx::get_data(c); + c=c.resume(data+1); + data=c.get_data(); std::cout << "f1: entered third time: " << data << std::endl; return std::move(c); }; int f2(ctx::continuation && c){ - int data=ctx::transfer_data(c); + int data=c.get_data(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(c); + data=c.get_data(); std::cout << "f1: returned first time: " << data << std::endl; - c=c(data+1); - data=ctx::get_data(c); + c=c.resume(data+1); + data=c.get_data(); 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(source); + char c=source.get_data(); 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 - 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 - continuation operator()(Arg ...arg); + continuation resume(Arg ...arg); template - continuation operator()(exec_ontop_arg_t,Fn && fn,Arg ...arg); + continuation resume_with(Fn && fn,Arg ...arg); + + bool data_available() noexcept; + + template + 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 - continuation operator()(Arg ...arg); + continuation resume(Arg ...arg); template - 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 + get_data(); + +[variablelist +[[Returns:] [Data that have been transferred via `callcc()` or `operator()` are +returned as `std::tuple` 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 - data(continuation & c); - -[variablelist -[[Returns:] [Data that have been trasnferred via `callcc()` or `operator()` are -returned as `std::tuple` or `Arg` if single parameter.]] -] - [heading Call with current contiunation] diff --git a/example/callcc/echosse.cpp b/example/callcc/echosse.cpp index cd2b6ff..6c0a2d6 100644 --- a/example/callcc/echosse.cpp +++ b/example/callcc/echosse.cpp @@ -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); } diff --git a/example/callcc/endless_loop.cpp b/example/callcc/endless_loop.cpp index 28b206a..0a3ce79 100644 --- a/example/callcc/endless_loop.cpp +++ b/example/callcc/endless_loop.cpp @@ -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; } diff --git a/example/callcc/fibonacci.cpp b/example/callcc/fibonacci.cpp index 7a4c064..5caeb88 100644 --- a/example/callcc/fibonacci.cpp +++ b/example/callcc/fibonacci.cpp @@ -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(c) << " "; - c=c(); + std::cout << c.get_data() << " "; + c=c.resume(); } std::cout << std::endl; std::cout << "main: done" << std::endl; diff --git a/example/callcc/jump.cpp b/example/callcc/jump.cpp index 08f3ddf..df82541 100644 --- a/example/callcc/jump.cpp +++ b/example/callcc/jump.cpp @@ -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; diff --git a/example/callcc/jump_mov.cpp b/example/callcc/jump_mov.cpp index 9f9810c..6b8a66d 100644 --- a/example/callcc/jump_mov.cpp +++ b/example/callcc/jump_mov.cpp @@ -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; } diff --git a/example/callcc/jump_ref.cpp b/example/callcc/jump_ref.cpp index 0f51df5..d945620 100644 --- a/example/callcc/jump_ref.cpp +++ b/example/callcc/jump_ref.cpp @@ -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 { diff --git a/example/callcc/jump_void.cpp b/example/callcc/jump_void.cpp index 54d7d6a..064928b 100644 --- a/example/callcc/jump_void.cpp +++ b/example/callcc/jump_void.cpp @@ -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; diff --git a/example/callcc/ontop.cpp b/example/callcc/ontop.cpp index d687c20..0966130 100644 --- a/example/callcc/ontop.cpp +++ b/example/callcc/ontop.cpp @@ -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; }, diff --git a/example/callcc/ontop_void.cpp b/example/callcc/ontop_void.cpp index a16497f..f9d4574 100644 --- a/example/callcc/ontop_void.cpp +++ b/example/callcc/ontop_void.cpp @@ -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; diff --git a/example/callcc/parser.cpp b/example/callcc/parser.cpp index c0277b5..c439f75 100644 --- a/example/callcc/parser.cpp +++ b/example/callcc/parser.cpp @@ -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(source); + while(source.data_available()){ + char c=source.get_data(); printf("Parsed: %c\n",c); - source=source(); + source=source.resume(); } std::cout << "main: done" << std::endl; return EXIT_SUCCESS; diff --git a/example/callcc/throw.cpp b/example/callcc/throw.cpp index c95f9ba..dfbb0b1 100644 --- a/example/callcc/throw.cpp +++ b/example/callcc/throw.cpp @@ -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"); }); diff --git a/example/callcc/types.cpp b/example/callcc/types.cpp index c45cef0..e213267 100644 --- a/example/callcc/types.cpp +++ b/example/callcc/types.cpp @@ -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; } diff --git a/include/boost/context/continuation.hpp b/include/boost/context/continuation.hpp index 23f1daa..cd11391 100644 --- a/include/boost/context/continuation.hpp +++ b/include/boost/context/continuation.hpp @@ -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) diff --git a/performance/callcc/performance.cpp b/performance/callcc/performance.cpp index 2ccdd9a..7fe1e7a 100644 --- a/performance/callcc/performance.cpp +++ b/performance/callcc/performance.cpp @@ -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 diff --git a/test/test_callcc.cpp b/test/test_callcc.cpp index 5be5e1f..4fdedbe 100644 --- a/test/test_callcc.cpp +++ b/test/test_callcc.cpp @@ -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); }