mirror of
https://github.com/boostorg/context.git
synced 2026-01-19 04:02:17 +00:00
remove template arg from callcc()
This commit is contained in:
@@ -42,6 +42,14 @@ exe jump
|
||||
: jump.cpp
|
||||
;
|
||||
|
||||
exe jump_ref
|
||||
: jump_ref.cpp
|
||||
;
|
||||
|
||||
exe jump_mov
|
||||
: jump_mov.cpp
|
||||
;
|
||||
|
||||
exe fibonacci
|
||||
: fibonacci.cpp
|
||||
;
|
||||
@@ -54,10 +62,10 @@ exe ontop
|
||||
: ontop.cpp
|
||||
;
|
||||
|
||||
exe backtrace
|
||||
: backtrace.cpp
|
||||
;
|
||||
|
||||
exe echosse
|
||||
: echosse.cpp
|
||||
;
|
||||
#exe backtrace
|
||||
# : backtrace.cpp
|
||||
# ;
|
||||
#
|
||||
#exe echosse
|
||||
# : echosse.cpp
|
||||
# ;
|
||||
|
||||
@@ -51,7 +51,7 @@ ctx::continuation f1( ctx::continuation && c) {
|
||||
}
|
||||
|
||||
int main() {
|
||||
ctx::callcc< void >( f1);
|
||||
ctx::callcc( f1);
|
||||
std::cout << "main: done" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -30,16 +30,16 @@ ctx::continuation echo( ctx::continuation && c, int i) {
|
||||
std::cout << i;
|
||||
echoSSE( i);
|
||||
std::cout << " ";
|
||||
c = ctx::callcc< int >( std::move( c), 0);
|
||||
i = ctx::get_data< int >( c);
|
||||
c = ctx::callcc( std::move( c), 0);
|
||||
std::tie( i) = ctx::data< int >( c);
|
||||
}
|
||||
return std::move( c);
|
||||
}
|
||||
|
||||
int main( int argc, char * argv[]) {
|
||||
ctx::continuation c = ctx::callcc< int >( echo, 0);
|
||||
ctx::continuation c = ctx::callcc( echo, 0);
|
||||
for ( int i = 1; i < 10; ++i) {
|
||||
c = ctx::callcc< int >( std::move( c), i);
|
||||
c = ctx::callcc( std::move( c), i);
|
||||
}
|
||||
std::cout << "\nmain: done" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
@@ -15,12 +15,14 @@ namespace ctx = boost::context;
|
||||
int main() {
|
||||
ctx::continuation c;
|
||||
int i=0;
|
||||
c=ctx::callcc< int >(
|
||||
[](ctx::continuation && c, int) mutable {
|
||||
c=ctx::callcc(
|
||||
std::allocator_arg,
|
||||
ctx::fixedsize_stack(),
|
||||
[](ctx::continuation && c, int){
|
||||
int a=0;
|
||||
int b=1;
|
||||
for(;;){
|
||||
c=ctx::callcc< int >(std::move(c),a);
|
||||
c=ctx::callcc(std::move(c),a);
|
||||
auto next=a+b;
|
||||
a=b;
|
||||
b=next;
|
||||
@@ -28,14 +30,11 @@ int main() {
|
||||
return std::move( c);
|
||||
},
|
||||
0);
|
||||
c=ctx::callcc< int >(std::move(c),0); i=ctx::get_data<int>(c); std::cout<<i<<" ";
|
||||
c=ctx::callcc< int >(std::move(c),0); i=ctx::get_data<int>(c); std::cout<<i<<" ";
|
||||
c=ctx::callcc< int >(std::move(c),0); i=ctx::get_data<int>(c); std::cout<<i<<" ";
|
||||
c=ctx::callcc< int >(std::move(c),0); i=ctx::get_data<int>(c); std::cout<<i<<" ";
|
||||
c=ctx::callcc< int >(std::move(c),0); i=ctx::get_data<int>(c); std::cout<<i<<" ";
|
||||
c=ctx::callcc< int >(std::move(c),0); i=ctx::get_data<int>(c); std::cout<<i<<" ";
|
||||
c=ctx::callcc< int >(std::move(c),0); i=ctx::get_data<int>(c); std::cout<<i<<" ";
|
||||
c=ctx::callcc< int >(std::move(c),0); i=ctx::get_data<int>(c); std::cout<<i<<" ";
|
||||
for ( int j = 0; j < 10; ++j) {
|
||||
c=ctx::callcc(std::move(c),0);
|
||||
i=ctx::data<int>(c);
|
||||
std::cout<<i<<" ";
|
||||
}
|
||||
std::cout<<std::endl;
|
||||
std::cout << "main: done" << std::endl;
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ namespace ctx = boost::context;
|
||||
|
||||
ctx::continuation f1( ctx::continuation && c, int data) {
|
||||
std::cout << "f1: entered first time: " << data << std::endl;
|
||||
c = ctx::callcc< int >( std::move( c), data + 2);
|
||||
data = ctx::get_data< int >( c);
|
||||
c = ctx::callcc( std::move( c), data + 2);
|
||||
data = ctx::data< int >( c);
|
||||
std::cout << "f1: entered second time: " << data << std::endl;
|
||||
return std::move( c);
|
||||
}
|
||||
@@ -22,12 +22,12 @@ ctx::continuation f1( ctx::continuation && c, int data) {
|
||||
int main() {
|
||||
ctx::continuation c;
|
||||
int data = 1;
|
||||
c = ctx::callcc< int >( f1, data);
|
||||
data = ctx::get_data< int >( c);
|
||||
c = ctx::callcc( f1, data);
|
||||
data = ctx::data< int >( c);
|
||||
std::cout << "f1: returned first time: " << data << std::endl;
|
||||
c = ctx::callcc< int >( std::move( c), data + 2);
|
||||
c = ctx::callcc( std::move( c), data + 2);
|
||||
if ( ctx::has_data( c) ) {
|
||||
data = ctx::get_data< int >( c);
|
||||
data = ctx::data< int >( c);
|
||||
std::cout << "f1: returned second time: " << data << std::endl;
|
||||
} else {
|
||||
std::cout << "f1: returned second time: no data" << std::endl;
|
||||
|
||||
62
example/callcc/jump_mov.cpp
Normal file
62
example/callcc/jump_mov.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
// Copyright Oliver Kowalke 2016.
|
||||
// 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/continuation.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
class moveable {
|
||||
public:
|
||||
bool state;
|
||||
int value;
|
||||
|
||||
moveable() :
|
||||
state( false),
|
||||
value( -1) {
|
||||
}
|
||||
|
||||
moveable( int v) :
|
||||
state( true),
|
||||
value( v) {
|
||||
}
|
||||
|
||||
moveable( moveable && other) :
|
||||
state( other.state),
|
||||
value( other.value) {
|
||||
other.state = false;
|
||||
other.value = -1;
|
||||
}
|
||||
|
||||
moveable & operator=( moveable && other) {
|
||||
if ( this == & other) return * this;
|
||||
state = other.state;
|
||||
value = other.value;
|
||||
other.state = false;
|
||||
other.value = -1;
|
||||
return * this;
|
||||
}
|
||||
|
||||
moveable( moveable const& other) = delete;
|
||||
moveable & operator=( moveable const& other) = delete;
|
||||
};
|
||||
|
||||
ctx::continuation f1( ctx::continuation && c, moveable && data) {
|
||||
c = ctx::callcc( std::move( c), std::move( data) );
|
||||
return std::move( c);
|
||||
}
|
||||
|
||||
int main() {
|
||||
ctx::continuation c;
|
||||
moveable data1{ 3 };
|
||||
c = ctx::callcc( std::allocator_arg, ctx::fixedsize_stack{}, f1, std::move( data1) );
|
||||
moveable data2;
|
||||
data2 = ctx::data< moveable >( c);
|
||||
std::cout << "main: done" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
38
example/callcc/jump_ref.cpp
Normal file
38
example/callcc/jump_ref.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
// Copyright Oliver Kowalke 2016.
|
||||
// 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/continuation.hpp>
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
ctx::continuation f1( ctx::continuation && c, int & data) {
|
||||
std::cout << "f1: entered first time: " << data << std::endl;
|
||||
data += 2;
|
||||
c = ctx::callcc( std::move( c), std::ref( data) );
|
||||
data += 2;
|
||||
std::cout << "f1: entered second time: " << data << std::endl;
|
||||
return std::move( c);
|
||||
}
|
||||
|
||||
int main() {
|
||||
ctx::continuation c;
|
||||
int data_ = 1;
|
||||
int & data = data_;
|
||||
c = ctx::callcc( std::allocator_arg, ctx::fixedsize_stack{}, f1, std::ref( data) );
|
||||
data = ctx::data< int & >( c);
|
||||
std::cout << "f1: returned first time: " << data << std::endl;
|
||||
c = ctx::callcc( std::move( c), std::ref( data) );
|
||||
if ( c) {
|
||||
std::cout << "f1: returned second time: " << data << std::endl;
|
||||
} else {
|
||||
std::cout << "f1: returned second time: no data" << std::endl;
|
||||
}
|
||||
std::cout << "main: done" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -13,15 +13,15 @@ namespace ctx = boost::context;
|
||||
|
||||
ctx::continuation f1( ctx::continuation && cm) {
|
||||
std::cout << "f1: entered first time" << std::endl;
|
||||
cm = ctx::callcc< void >( std::move( cm) );
|
||||
cm = ctx::callcc( std::move( cm) );
|
||||
std::cout << "f1: entered second time" << std::endl;
|
||||
return std::move( cm);
|
||||
}
|
||||
|
||||
int main() {
|
||||
ctx::continuation c = ctx::callcc< void >( f1);
|
||||
ctx::continuation c = ctx::callcc( f1);
|
||||
std::cout << "f1: returned first time" << std::endl;
|
||||
c = ctx::callcc< void >( std::move( c) );
|
||||
c = ctx::callcc( std::move( c) );
|
||||
std::cout << "f1: returned second time" << std::endl;
|
||||
|
||||
std::cout << "main: done" << std::endl;
|
||||
|
||||
@@ -12,32 +12,31 @@
|
||||
|
||||
namespace ctx = boost::context;
|
||||
|
||||
ctx::continuation f1( ctx::continuation && c, int data) {
|
||||
std::cout << "f1: entered first time: " << data << std::endl;
|
||||
c = ctx::callcc< int >( std::move( c), data + 1);
|
||||
data = ctx::get_data< int >( c);
|
||||
std::cout << "f1: entered second time: " << data << std::endl;
|
||||
c = ctx::callcc< int >( std::move( c), data + 1);
|
||||
data = ctx::get_data< int >( c);
|
||||
std::cout << "f1: entered third time: " << data << std::endl;
|
||||
return std::move( c);
|
||||
}
|
||||
|
||||
int f2( int data) {
|
||||
std::cout << "f2: entered: " << data << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main() {
|
||||
ctx::continuation c;
|
||||
int data = 0;
|
||||
c = ctx::callcc< int >( f1, data + 1);
|
||||
data = ctx::get_data< int >( c);
|
||||
c = ctx::callcc( [](ctx::continuation && c,int data) {
|
||||
std::cout << "f1: entered first time: " << data << std::endl;
|
||||
c = ctx::callcc( std::move( c), data + 1);
|
||||
data = ctx::data< int >( c);
|
||||
std::cout << "f1: entered second time: " << data << std::endl;
|
||||
c = ctx::callcc( std::move( c), data + 1);
|
||||
data = ctx::data< int >( c);
|
||||
std::cout << "f1: entered third time: " << data << std::endl;
|
||||
return std::move( c);
|
||||
},
|
||||
data + 1);
|
||||
data = ctx::data< int >( c);
|
||||
std::cout << "f1: returned first time: " << data << std::endl;
|
||||
c = ctx::callcc< int >( std::move( c), data + 1);
|
||||
data = ctx::get_data< int >( c);
|
||||
c = ctx::callcc( std::move( c), data + 1);
|
||||
data = ctx::data< int >( c);
|
||||
std::cout << "f1: returned second time: " << data << std::endl;
|
||||
c = ctx::callcc< int >( std::move( c), ctx::exec_ontop_arg, f2, data + 1);
|
||||
c = ctx::callcc( std::move( c), ctx::exec_ontop_arg,
|
||||
[](int data){
|
||||
std::cout << "f2: entered: " << data << std::endl;
|
||||
return -1;
|
||||
},
|
||||
data + 1);
|
||||
std::cout << "f1: returned third time" << std::endl;
|
||||
std::cout << "main: done" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
@@ -14,9 +14,9 @@ namespace ctx = boost::context;
|
||||
|
||||
ctx::continuation f1( ctx::continuation && c) {
|
||||
std::cout << "f1: entered first time" << std::endl;
|
||||
c = ctx::callcc< void >( std::move( c) );
|
||||
c = ctx::callcc( std::move( c) );
|
||||
std::cout << "f1: entered second time" << std::endl;
|
||||
c = ctx::callcc< void >( std::move( c) );
|
||||
c = ctx::callcc( std::move( c) );
|
||||
std::cout << "f1: entered third time" << std::endl;
|
||||
return std::move( c);
|
||||
}
|
||||
@@ -26,11 +26,11 @@ void f2() {
|
||||
}
|
||||
|
||||
int main() {
|
||||
ctx::continuation c = ctx::callcc< void >( f1);
|
||||
ctx::continuation c = ctx::callcc( f1);
|
||||
std::cout << "f1: returned first time" << std::endl;
|
||||
c = ctx::callcc< void >( std::move( c) );
|
||||
c = ctx::callcc( std::move( c) );
|
||||
std::cout << "f1: returned second time" << std::endl;
|
||||
c = ctx::callcc< void >( std::move( c), ctx::exec_ontop_arg, f2);
|
||||
c = ctx::callcc( std::move( c), ctx::exec_ontop_arg, f2);
|
||||
std::cout << "f1: returned third time" << std::endl;
|
||||
|
||||
std::cout << "main: done" << std::endl;
|
||||
|
||||
@@ -96,13 +96,13 @@ int main() {
|
||||
boost::context::continuation source;
|
||||
// user-code pulls parsed data from parser
|
||||
// invert control flow
|
||||
source=ctx::callcc<char>(
|
||||
source=ctx::callcc(
|
||||
[&is](ctx::continuation && sink,char){
|
||||
// create parser with callback function
|
||||
Parser p( is,
|
||||
[&sink](char c){
|
||||
// resume main execution context
|
||||
sink=ctx::callcc<char>(std::move(sink),c);
|
||||
sink=ctx::callcc(std::move(sink),c);
|
||||
});
|
||||
// start recursive parsing
|
||||
p.run();
|
||||
@@ -111,9 +111,9 @@ int main() {
|
||||
},
|
||||
'\0');
|
||||
while(ctx::has_data(source)){
|
||||
char c=ctx::get_data<char>(source);
|
||||
char c=ctx::data<char>(source);
|
||||
printf("Parsed: %c\n",c);
|
||||
source=ctx::callcc<char>(std::move(source),'\0');
|
||||
source=ctx::callcc(std::move(source),'\0');
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -21,11 +21,11 @@ struct my_exception : public std::runtime_error {
|
||||
};
|
||||
|
||||
int main() {
|
||||
ctx::continuation c = ctx::callcc< void >([](boost::context::continuation && c) {
|
||||
ctx::continuation c = ctx::callcc([](boost::context::continuation && c) {
|
||||
for (;;) {
|
||||
try {
|
||||
std::cout << "entered" << std::endl;
|
||||
c = ctx::callcc< void >( std::move( c) );
|
||||
c = ctx::callcc( std::move( c) );
|
||||
} catch ( boost::context::ontop_error const& e) {
|
||||
try {
|
||||
std::rethrow_if_nested( e);
|
||||
@@ -37,9 +37,9 @@ int main() {
|
||||
}
|
||||
return std::move( c);
|
||||
});
|
||||
c = ctx::callcc< void >( std::move( c) );
|
||||
c = ctx::callcc< void >( std::move( c) );
|
||||
c = ctx::callcc< void >( std::move( c), ctx::exec_ontop_arg, []() { throw my_exception("abc"); });
|
||||
c = ctx::callcc( std::move( c) );
|
||||
c = ctx::callcc( std::move( c) );
|
||||
c = ctx::callcc( std::move( c), ctx::exec_ontop_arg, []() { throw my_exception("abc"); });
|
||||
|
||||
std::cout << "main: done" << std::endl;
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#if defined(BOOST_NO_CXX17_STD_APPLY)
|
||||
#include <boost/context/detail/apply.hpp>
|
||||
#endif
|
||||
#include <boost/context/detail/decay_copy.hpp>
|
||||
#include <boost/context/detail/disable_overload.hpp>
|
||||
#include <boost/context/detail/exception.hpp>
|
||||
#include <boost/context/detail/exchange.hpp>
|
||||
@@ -293,8 +294,27 @@ fcontext_t context_create( preallocated palloc, StackAlloc salloc, Fn && fn) {
|
||||
return jump_fcontext( fctx, rec).fctx;
|
||||
}
|
||||
|
||||
template< typename ... Ret >
|
||||
struct callcc_helper;
|
||||
template< typename ... Arg >
|
||||
struct result_type {
|
||||
typedef std::tuple< Arg ... > type;
|
||||
|
||||
static
|
||||
type get( void * data) {
|
||||
auto p = static_cast< std::tuple< std::exception_ptr, std::tuple< Arg ... > > * >( data);
|
||||
return std::move( std::get< 1 >( * p) );
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Arg >
|
||||
struct result_type< Arg > {
|
||||
typedef Arg type;
|
||||
|
||||
static
|
||||
type get( void * data) {
|
||||
auto p = static_cast< std::tuple< std::exception_ptr, std::tuple< Arg > > * >( data);
|
||||
return std::forward< Arg >( std::get< 0 >( std::get< 1 >( * p) ) );
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -302,24 +322,52 @@ inline namespace v1 {
|
||||
|
||||
class continuation {
|
||||
private:
|
||||
friend class ontop_error;
|
||||
|
||||
template< typename ... Ret >
|
||||
friend struct detail::callcc_helper;
|
||||
|
||||
template< typename Ctx, typename ArgTuple, typename StackAlloc, typename Fn >
|
||||
friend class detail::record;
|
||||
|
||||
template< typename Ctx, typename StackAlloc, typename Fn >
|
||||
friend class detail::record_void;
|
||||
|
||||
friend class ontop_error;
|
||||
|
||||
template< typename StackAlloc, typename Fn, typename ... Arg >
|
||||
friend continuation
|
||||
callcc( std::allocator_arg_t, StackAlloc, Fn &&, Arg ...);
|
||||
|
||||
template< typename StackAlloc, typename Fn, typename ... Arg >
|
||||
friend continuation
|
||||
callcc( std::allocator_arg_t, preallocated, StackAlloc, Fn &&, Arg ...);
|
||||
|
||||
template< typename ... Arg >
|
||||
friend continuation
|
||||
callcc( continuation &&, Arg ...);
|
||||
|
||||
template< typename Fn, typename ... Arg >
|
||||
friend continuation
|
||||
callcc( continuation &&, exec_ontop_arg_t, Fn &&, Arg ...);
|
||||
|
||||
template< typename StackAlloc, typename Fn >
|
||||
friend continuation
|
||||
callcc( std::allocator_arg_t, StackAlloc, Fn &&);
|
||||
|
||||
template< typename StackAlloc, typename Fn >
|
||||
friend continuation
|
||||
callcc( std::allocator_arg_t, preallocated, StackAlloc, Fn &&);
|
||||
|
||||
friend continuation
|
||||
callcc( continuation &&);
|
||||
|
||||
template< typename Fn >
|
||||
friend continuation
|
||||
callcc( continuation &&, exec_ontop_arg_t, Fn &&);
|
||||
|
||||
friend bool has_data( continuation const&) noexcept;
|
||||
|
||||
template< typename Arg >
|
||||
friend Arg get_data( continuation const&);
|
||||
friend Arg get( continuation const&);
|
||||
|
||||
template< typename ... Arg >
|
||||
friend std::tuple< Arg ... > get_data( continuation const&);
|
||||
friend typename detail::result_type< Arg ... >::type data( continuation const&);
|
||||
|
||||
detail::fcontext_t fctx_{ nullptr };
|
||||
void * data_{ nullptr };
|
||||
@@ -408,6 +456,17 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
inline
|
||||
bool has_data( continuation const& c) noexcept {
|
||||
return c && nullptr != c.data_;
|
||||
}
|
||||
|
||||
template< typename ... Arg >
|
||||
typename detail::result_type< Arg ... >::type data( continuation const& c) {
|
||||
BOOST_ASSERT( nullptr != c.data_);
|
||||
return detail::result_type< Arg ... >::get( c.data_);
|
||||
}
|
||||
|
||||
class ontop_error : public std::exception {
|
||||
private:
|
||||
detail::fcontext_t fctx_;
|
||||
@@ -422,238 +481,164 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
inline
|
||||
bool has_data( continuation const& c) noexcept {
|
||||
return c && nullptr != c.data_;
|
||||
}
|
||||
|
||||
template< typename Arg >
|
||||
Arg get_data( continuation const& c) {
|
||||
BOOST_ASSERT( has_data( c) );
|
||||
using ArgTuple = std::tuple< Arg >;
|
||||
auto p = static_cast< std::tuple< std::exception_ptr, ArgTuple > * >( c.data_);
|
||||
return std::get< 0 >( std::move( std::get< 1 >( * p) ) );
|
||||
}
|
||||
|
||||
template< typename ... Arg >
|
||||
std::tuple< Arg ... > get_data( continuation const& c) {
|
||||
BOOST_ASSERT( nullptr != c.data_);
|
||||
using ArgTuple = std::tuple< Arg ... >;
|
||||
auto p = static_cast< std::tuple< std::exception_ptr, ArgTuple > * >( c.data_);
|
||||
return std::move( std::get< 1 >( * p) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
inline namespace v1 {
|
||||
|
||||
template< typename ... Arg >
|
||||
struct callcc_helper {
|
||||
template< typename StackAlloc, typename Fn >
|
||||
static
|
||||
continuation
|
||||
callcc( std::allocator_arg_t, StackAlloc salloc, Fn && fn, Arg ... arg) {
|
||||
using ArgTuple = std::tuple< Arg ... >;
|
||||
using Record = detail::record< continuation, ArgTuple, StackAlloc, Fn >;
|
||||
return callcc( continuation{
|
||||
context_create< Record >(
|
||||
salloc, std::forward< Fn >( fn) ) },
|
||||
std::forward< Arg >( arg) ... );
|
||||
}
|
||||
|
||||
template< typename StackAlloc, typename Fn >
|
||||
static
|
||||
continuation
|
||||
callcc( std::allocator_arg_t, preallocated palloc, StackAlloc salloc, Fn && fn, Arg ... arg) {
|
||||
using ArgTuple = std::tuple< Arg ... >;
|
||||
using Record = detail::record< continuation, ArgTuple, StackAlloc, Fn >;
|
||||
return callcc( continuation{
|
||||
context_create< Record >(
|
||||
palloc, salloc, std::forward< Fn >( fn) ) },
|
||||
std::forward< Arg >( arg) ... );
|
||||
}
|
||||
|
||||
static
|
||||
continuation
|
||||
callcc( continuation && c, Arg ... arg) {
|
||||
BOOST_ASSERT( nullptr != c.fctx_);
|
||||
using ArgTuple = std::tuple< Arg ... >;
|
||||
ArgTuple tpl{ std::forward< Arg >( arg) ... };
|
||||
auto p = std::make_tuple( std::exception_ptr{}, std::move( tpl) );
|
||||
detail::transfer_t t = detail::jump_fcontext( detail::exchange( c.fctx_, nullptr), & p);
|
||||
if ( nullptr != t.data) {
|
||||
auto p = static_cast< std::tuple< std::exception_ptr, ArgTuple > * >( t.data);
|
||||
std::exception_ptr eptr = std::get< 0 >( * p);
|
||||
if ( eptr) {
|
||||
try {
|
||||
std::rethrow_exception( eptr);
|
||||
} catch (...) {
|
||||
std::throw_with_nested( ontop_error{ t.fctx } );
|
||||
}
|
||||
}
|
||||
}
|
||||
return continuation{ t.fctx, t.data };
|
||||
}
|
||||
|
||||
template< typename Fn >
|
||||
static
|
||||
continuation
|
||||
callcc( continuation && c, exec_ontop_arg_t, Fn && fn, Arg ... arg) {
|
||||
BOOST_ASSERT( nullptr != c.fctx_);
|
||||
using ArgTuple = std::tuple< Arg ... >;
|
||||
ArgTuple tpl{ std::forward< Arg >( arg) ... };
|
||||
auto p = std::make_tuple( fn, std::make_tuple( std::exception_ptr{}, std::move( tpl) ) );
|
||||
detail::transfer_t t = detail::ontop_fcontext(
|
||||
detail::exchange( c.fctx_, nullptr),
|
||||
& p,
|
||||
detail::context_ontop< Fn, Arg ... >);
|
||||
if ( nullptr != t.data) {
|
||||
auto p = static_cast< std::tuple< std::exception_ptr, ArgTuple > * >( t.data);
|
||||
std::exception_ptr eptr = std::get< 0 >( * p);
|
||||
if ( eptr) {
|
||||
try {
|
||||
std::rethrow_exception( eptr);
|
||||
} catch (...) {
|
||||
std::throw_with_nested( ontop_error{ t.fctx } );
|
||||
}
|
||||
}
|
||||
}
|
||||
return continuation{ t.fctx, t.data };
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct callcc_helper< void > {
|
||||
template< typename StackAlloc, typename Fn >
|
||||
static
|
||||
continuation
|
||||
callcc( std::allocator_arg_t, StackAlloc salloc, Fn && fn) {
|
||||
using Record = detail::record_void< continuation, StackAlloc, Fn >;
|
||||
return callcc(
|
||||
continuation{
|
||||
detail::context_create< Record >(
|
||||
salloc, std::forward< Fn >( fn) ) } );
|
||||
}
|
||||
|
||||
template< typename StackAlloc, typename Fn >
|
||||
static
|
||||
continuation
|
||||
callcc( std::allocator_arg_t, preallocated palloc, StackAlloc salloc, Fn && fn) {
|
||||
using Record = detail::record_void< continuation, StackAlloc, Fn >;
|
||||
return callcc(
|
||||
continuation{
|
||||
detail::context_create< Record >(
|
||||
palloc, salloc, std::forward< Fn >( fn) ) } );
|
||||
}
|
||||
|
||||
static
|
||||
continuation
|
||||
callcc( continuation && c) {
|
||||
BOOST_ASSERT( nullptr != c.fctx_);
|
||||
detail::transfer_t t = detail::jump_fcontext( detail::exchange( c.fctx_, nullptr), nullptr);
|
||||
if ( nullptr != t.data) {
|
||||
std::exception_ptr * eptr = static_cast< std::exception_ptr * >( t.data);
|
||||
try {
|
||||
std::rethrow_exception( * eptr);
|
||||
} catch (...) {
|
||||
std::throw_with_nested( ontop_error{ t.fctx } );
|
||||
}
|
||||
}
|
||||
return continuation{ t.fctx };
|
||||
}
|
||||
|
||||
template< typename Fn >
|
||||
static
|
||||
continuation
|
||||
callcc( continuation && c, exec_ontop_arg_t, Fn && fn) {
|
||||
BOOST_ASSERT( nullptr != c.fctx_);
|
||||
auto p = std::make_tuple( fn, std::exception_ptr{} );
|
||||
detail::transfer_t t = detail::ontop_fcontext(
|
||||
detail::exchange( c.fctx_, nullptr),
|
||||
& p,
|
||||
detail::context_ontop_void< Fn >);
|
||||
if ( nullptr != t.data) {
|
||||
std::exception_ptr * eptr = static_cast< std::exception_ptr * >( t.data);
|
||||
try {
|
||||
std::rethrow_exception( * eptr);
|
||||
} catch (...) {
|
||||
std::throw_with_nested( ontop_error{ t.fctx } );
|
||||
}
|
||||
}
|
||||
return continuation{ t.fctx };
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
inline namespace v1 {
|
||||
|
||||
// Arg
|
||||
template<
|
||||
typename ... Ret,
|
||||
typename Fn,
|
||||
typename ... Arg,
|
||||
typename = detail::disable_overload< continuation, Fn >
|
||||
>
|
||||
continuation
|
||||
callcc( Fn && fn, Arg && ... arg) {
|
||||
return detail::callcc_helper< Ret ... >::callcc(
|
||||
callcc( Fn && fn, Arg ... arg) {
|
||||
return callcc(
|
||||
std::allocator_arg, fixedsize_stack(),
|
||||
std::forward< Fn >( fn), std::forward< Arg >( arg) ...);
|
||||
}
|
||||
|
||||
template<
|
||||
typename ... Ret,
|
||||
typename StackAlloc,
|
||||
typename Fn,
|
||||
typename ... Arg
|
||||
>
|
||||
continuation
|
||||
callcc( std::allocator_arg_t, StackAlloc salloc, Fn && fn, Arg && ... arg) {
|
||||
return detail::callcc_helper< Ret ... >::callcc(
|
||||
std::allocator_arg, salloc,
|
||||
std::forward< Fn >( fn), std::forward< Arg >( arg) ...);
|
||||
callcc( std::allocator_arg_t, StackAlloc salloc, Fn && fn, Arg ... arg) {
|
||||
using ArgTuple = std::tuple< Arg ... >;
|
||||
using Record = detail::record< continuation, ArgTuple, StackAlloc, Fn >;
|
||||
return callcc( continuation{
|
||||
detail::context_create< Record >(
|
||||
salloc, std::forward< Fn >( fn) ) },
|
||||
std::forward< Arg >( arg) ... );
|
||||
}
|
||||
|
||||
template<
|
||||
typename ... Ret,
|
||||
typename StackAlloc,
|
||||
typename Fn,
|
||||
typename ... Arg
|
||||
>
|
||||
continuation
|
||||
callcc( std::allocator_arg_t, preallocated palloc, StackAlloc salloc, Fn && fn, Arg && ... arg) {
|
||||
return detail::callcc_helper< Ret ... >::callcc(
|
||||
std::allocator_arg, palloc, salloc,
|
||||
std::forward< Fn >( fn), std::forward< Arg >( arg) ...);
|
||||
callcc( std::allocator_arg_t, preallocated palloc, StackAlloc salloc, Fn && fn, Arg ... arg) {
|
||||
using ArgTuple = std::tuple< Arg ... >;
|
||||
using Record = detail::record< continuation, ArgTuple, StackAlloc, Fn >;
|
||||
return callcc( continuation{
|
||||
detail::context_create< Record >(
|
||||
palloc, salloc, std::forward< Fn >( fn) ) },
|
||||
std::forward< Arg >( arg) ... );
|
||||
}
|
||||
|
||||
template<
|
||||
typename ... Ret,
|
||||
typename ... Arg
|
||||
>
|
||||
template< typename ... Arg >
|
||||
continuation
|
||||
callcc( continuation && c, Arg && ... arg) {
|
||||
return detail::callcc_helper< Ret ... >::callcc(
|
||||
std::move( c), std::forward< Arg >( arg) ... );
|
||||
callcc( continuation && c, Arg ... arg) {
|
||||
BOOST_ASSERT( nullptr != c.fctx_);
|
||||
using ArgTuple = std::tuple< Arg ... >;
|
||||
auto p = std::make_tuple( std::exception_ptr{}, ArgTuple{ std::forward< Arg >( arg) ... } );
|
||||
detail::transfer_t t = detail::jump_fcontext( detail::exchange( c.fctx_, nullptr), & p);
|
||||
if ( nullptr != t.data) {
|
||||
auto p = static_cast< std::tuple< std::exception_ptr, ArgTuple > * >( t.data);
|
||||
std::exception_ptr eptr = std::get< 0 >( * p);
|
||||
if ( eptr) {
|
||||
try {
|
||||
std::rethrow_exception( eptr);
|
||||
} catch (...) {
|
||||
std::throw_with_nested( ontop_error{ t.fctx } );
|
||||
}
|
||||
}
|
||||
}
|
||||
return continuation{ t.fctx, t.data };
|
||||
}
|
||||
|
||||
template< typename Fn, typename ... Arg >
|
||||
continuation
|
||||
callcc( continuation && c, exec_ontop_arg_t, Fn && fn, Arg ... arg) {
|
||||
BOOST_ASSERT( nullptr != c.fctx_);
|
||||
using ArgTuple = std::tuple< Arg ... >;
|
||||
auto p = std::make_tuple( fn, std::make_tuple( std::exception_ptr{}, ArgTuple{ std::forward< Arg >( arg) ... } ) );
|
||||
detail::transfer_t t = detail::ontop_fcontext(
|
||||
detail::exchange( c.fctx_, nullptr),
|
||||
& p,
|
||||
detail::context_ontop< Fn, Arg ... >);
|
||||
if ( nullptr != t.data) {
|
||||
auto p = static_cast< std::tuple< std::exception_ptr, ArgTuple > * >( t.data);
|
||||
std::exception_ptr eptr = std::get< 0 >( * p);
|
||||
if ( eptr) {
|
||||
try {
|
||||
std::rethrow_exception( eptr);
|
||||
} catch (...) {
|
||||
std::throw_with_nested( ontop_error{ t.fctx } );
|
||||
}
|
||||
}
|
||||
}
|
||||
return continuation{ t.fctx, t.data };
|
||||
}
|
||||
|
||||
// void
|
||||
template<
|
||||
typename ... Ret,
|
||||
typename Fn,
|
||||
typename ... Arg
|
||||
typename = detail::disable_overload< continuation, Fn >
|
||||
>
|
||||
continuation
|
||||
callcc( continuation && c, exec_ontop_arg_t, Fn && fn, Arg && ... arg) {
|
||||
return detail::callcc_helper< Ret ... >::callcc(
|
||||
std::move( c),
|
||||
exec_ontop_arg, std::forward< Fn >( fn), std::forward< Arg >( arg) ... );
|
||||
callcc( Fn && fn) {
|
||||
return callcc(
|
||||
std::allocator_arg, fixedsize_stack(),
|
||||
std::forward< Fn >( fn) );
|
||||
}
|
||||
|
||||
template< typename StackAlloc, typename Fn >
|
||||
continuation
|
||||
callcc( std::allocator_arg_t, StackAlloc salloc, Fn && fn) {
|
||||
using Record = detail::record_void< continuation, StackAlloc, Fn >;
|
||||
return callcc(
|
||||
continuation{
|
||||
detail::context_create< Record >(
|
||||
salloc, std::forward< Fn >( fn) ) } );
|
||||
}
|
||||
|
||||
template< typename StackAlloc, typename Fn >
|
||||
continuation
|
||||
callcc( std::allocator_arg_t, preallocated palloc, StackAlloc salloc, Fn && fn) {
|
||||
using Record = detail::record_void< continuation, StackAlloc, Fn >;
|
||||
return callcc(
|
||||
continuation{
|
||||
detail::context_create< Record >(
|
||||
palloc, salloc, std::forward< Fn >( fn) ) } );
|
||||
}
|
||||
|
||||
inline
|
||||
continuation
|
||||
callcc( continuation && c) {
|
||||
BOOST_ASSERT( nullptr != c.fctx_);
|
||||
detail::transfer_t t = detail::jump_fcontext( detail::exchange( c.fctx_, nullptr), nullptr);
|
||||
if ( nullptr != t.data) {
|
||||
std::exception_ptr * eptr = static_cast< std::exception_ptr * >( t.data);
|
||||
try {
|
||||
std::rethrow_exception( * eptr);
|
||||
} catch (...) {
|
||||
std::throw_with_nested( ontop_error{ t.fctx } );
|
||||
}
|
||||
}
|
||||
return continuation{ t.fctx };
|
||||
}
|
||||
|
||||
template< typename Fn >
|
||||
continuation
|
||||
callcc( continuation && c, exec_ontop_arg_t, Fn && fn) {
|
||||
BOOST_ASSERT( nullptr != c.fctx_);
|
||||
auto p = std::make_tuple( fn, std::exception_ptr{} );
|
||||
detail::transfer_t t = detail::ontop_fcontext(
|
||||
detail::exchange( c.fctx_, nullptr),
|
||||
& p,
|
||||
detail::context_ontop_void< Fn >);
|
||||
if ( nullptr != t.data) {
|
||||
std::exception_ptr * eptr = static_cast< std::exception_ptr * >( t.data);
|
||||
try {
|
||||
std::rethrow_exception( * eptr);
|
||||
} catch (...) {
|
||||
std::throw_with_nested( ontop_error{ t.fctx } );
|
||||
}
|
||||
}
|
||||
return continuation{ t.fctx };
|
||||
}
|
||||
|
||||
#if defined(BOOST_USE_SEGMENTED_STACKS)
|
||||
template<
|
||||
typename ... Ret,
|
||||
typename Fn,
|
||||
typename ... Arg
|
||||
>
|
||||
@@ -661,7 +646,6 @@ continuation
|
||||
callcc( std::allocator_arg_t, segmented_stack, Fn &&, Arg ...);
|
||||
|
||||
template<
|
||||
typename ... Ret,
|
||||
typename StackAlloc,
|
||||
typename Fn,
|
||||
typename ... Arg
|
||||
|
||||
36
include/boost/context/detail/decay_copy.hpp
Normal file
36
include/boost/context/detail/decay_copy.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
// 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)
|
||||
|
||||
#ifndef BOOST_CONTEXT_DETAIL_DECAY_COPY_H
|
||||
#define BOOST_CONTEXT_DETAIL_DECAY_COPY_H
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/fiber/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
# include BOOST_ABI_PREFIX
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace context {
|
||||
namespace detail {
|
||||
|
||||
template< typename T >
|
||||
typename std::decay< T >::type
|
||||
decay_copy( T && t) {
|
||||
return std::forward< T >( t);
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
#include BOOST_ABI_SUFFIX
|
||||
#endif
|
||||
|
||||
#endif // BOOST_CONTEXT_DETAIL_DECAY_COPY_H
|
||||
@@ -138,7 +138,7 @@ ctx::continuation fn5( ctx::continuation && c) {
|
||||
}
|
||||
|
||||
ctx::continuation fn4( ctx::continuation && c) {
|
||||
ctx::continuation c1 = ctx::callcc< void >( fn5);
|
||||
ctx::continuation c1 = ctx::callcc( fn5);
|
||||
value3 = 3.14;
|
||||
return std::move( c);
|
||||
}
|
||||
@@ -146,9 +146,9 @@ ctx::continuation fn4( ctx::continuation && c) {
|
||||
ctx::continuation fn6( ctx::continuation && c) {
|
||||
try {
|
||||
value1 = 3;
|
||||
c = ctx::callcc< void >( std::move( c) );
|
||||
c = ctx::callcc( std::move( c) );
|
||||
value1 = 7;
|
||||
c = ctx::callcc< void >( std::move( c) );
|
||||
c = ctx::callcc( std::move( c) );
|
||||
} catch ( my_exception & e) {
|
||||
value2 = e.what();
|
||||
}
|
||||
@@ -157,7 +157,7 @@ ctx::continuation fn6( ctx::continuation && c) {
|
||||
|
||||
ctx::continuation fn7( ctx::continuation && c) {
|
||||
Y y;
|
||||
return ctx::callcc< void >( std::move( c) );
|
||||
return ctx::callcc( std::move( c) );
|
||||
}
|
||||
|
||||
ctx::continuation fn8( ctx::continuation && c, int i) {
|
||||
@@ -167,50 +167,50 @@ ctx::continuation fn8( ctx::continuation && c, int i) {
|
||||
|
||||
ctx::continuation fn9( ctx::continuation && c, int i) {
|
||||
value1 = i;
|
||||
c = ctx::callcc< int >( std::move( c), i);
|
||||
value1 = ctx::get_data< int >( c);
|
||||
c = ctx::callcc( std::move( c), i);
|
||||
value1 = ctx::data< int >( c);
|
||||
return std::move( c);
|
||||
}
|
||||
|
||||
ctx::continuation fn10( ctx::continuation && c, int & i) {
|
||||
return ctx::callcc< int & >( std::move( c), i);
|
||||
return ctx::callcc( std::move( c), std::ref( i) );
|
||||
}
|
||||
|
||||
ctx::continuation fn11( ctx::continuation && c, moveable m) {
|
||||
c = ctx::callcc< moveable >( std::move( c), std::move( m) );
|
||||
m = ctx::get_data< moveable >( c);
|
||||
return ctx::callcc< moveable >( std::move( c), std::move( m) );
|
||||
c = ctx::callcc( std::move( c), std::move( m) );
|
||||
m = ctx::data< moveable >( c);
|
||||
return ctx::callcc( std::move( c), std::move( m) );
|
||||
}
|
||||
|
||||
ctx::continuation fn12( ctx::continuation && c, int i, std::string str) {
|
||||
return ctx::callcc< int, std::string >( std::move( c), i, str);
|
||||
return ctx::callcc( std::move( c), i, str);
|
||||
}
|
||||
|
||||
ctx::continuation fn13( ctx::continuation && c, int i, moveable m) {
|
||||
return ctx::callcc< int, moveable >( std::move( c), i, std::move( m) );
|
||||
return ctx::callcc( std::move( c), i, std::move( m) );
|
||||
}
|
||||
|
||||
ctx::continuation fn14( ctx::continuation && c, variant_t data) {
|
||||
int i = boost::get< int >( data);
|
||||
data = boost::lexical_cast< std::string >( i);
|
||||
return ctx::callcc< variant_t >( std::move( c), data);
|
||||
return ctx::callcc( std::move( c), data);
|
||||
}
|
||||
|
||||
ctx::continuation fn15( ctx::continuation && c, Y * py) {
|
||||
return ctx::callcc< Y * >( std::move( c), py);
|
||||
return ctx::callcc( std::move( c), py);
|
||||
}
|
||||
|
||||
ctx::continuation fn16( ctx::continuation && c, int i) {
|
||||
value1 = i;
|
||||
c = ctx::callcc< int >( std::move( c), i);
|
||||
value1 = ctx::get_data< int >( c);
|
||||
c = ctx::callcc( std::move( c), i);
|
||||
value1 = ctx::data< int >( c);
|
||||
return std::move( c);
|
||||
}
|
||||
|
||||
ctx::continuation fn17( ctx::continuation && c, int i, int j) {
|
||||
for (;;) {
|
||||
c = ctx::callcc< int, int >( std::move( c), i, j);
|
||||
std::tie( i, j) = ctx::get_data< int, int >( c);
|
||||
c = ctx::callcc( std::move( c), i, j);
|
||||
std::tie( i, j) = ctx::data< int, int >( c);
|
||||
}
|
||||
return std::move( c);
|
||||
}
|
||||
@@ -220,15 +220,15 @@ void test_move() {
|
||||
value1 = 0;
|
||||
ctx::continuation c;
|
||||
BOOST_CHECK( ! c );
|
||||
ctx::continuation c1 = ctx::callcc< int >( fn9, 1);
|
||||
ctx::continuation c2 = ctx::callcc< int >( fn9, 3);
|
||||
ctx::continuation c1 = ctx::callcc( fn9, 1);
|
||||
ctx::continuation c2 = ctx::callcc( fn9, 3);
|
||||
BOOST_CHECK( c1 );
|
||||
BOOST_CHECK( c2 );
|
||||
c1 = std::move( c2);
|
||||
BOOST_CHECK( c1 );
|
||||
BOOST_CHECK( ! c2 );
|
||||
BOOST_CHECK_EQUAL( 3, value1);
|
||||
ctx::callcc< int >( std::move( c1), 0);
|
||||
ctx::callcc( std::move( c1), 0);
|
||||
BOOST_CHECK_EQUAL( 0, value1);
|
||||
BOOST_CHECK( ! c1 );
|
||||
BOOST_CHECK( ! c2 );
|
||||
@@ -237,14 +237,14 @@ void test_move() {
|
||||
void test_bind() {
|
||||
value1 = 0;
|
||||
X x;
|
||||
ctx::continuation c = ctx::callcc< int >( std::bind( & X::foo, x, std::placeholders::_1, std::placeholders::_2), 7);
|
||||
ctx::continuation c = ctx::callcc( std::bind( & X::foo, x, std::placeholders::_1, std::placeholders::_2), 7);
|
||||
BOOST_CHECK_EQUAL( 7, value1);
|
||||
}
|
||||
|
||||
void test_exception() {
|
||||
{
|
||||
const char * what = "hello world";
|
||||
ctx::continuation c = ctx::callcc< const char * >( fn2, what);
|
||||
ctx::continuation c = ctx::callcc( fn2, what);
|
||||
BOOST_CHECK_EQUAL( std::string( what), value2);
|
||||
BOOST_CHECK( ! c );
|
||||
}
|
||||
@@ -252,13 +252,13 @@ void test_exception() {
|
||||
{
|
||||
bool catched = false;
|
||||
std::thread([&catched](){
|
||||
ctx::continuation c = ctx::callcc< void >([&catched](ctx::continuation && c){
|
||||
c = ctx::callcc< void >( std::move( c) );
|
||||
ctx::continuation c = ctx::callcc([&catched](ctx::continuation && c){
|
||||
c = ctx::callcc( std::move( c) );
|
||||
seh( catched);
|
||||
return std::move( c);
|
||||
});
|
||||
BOOST_CHECK( c );
|
||||
ctx::callcc< void >( std::move( c) );
|
||||
ctx::callcc( std::move( c) );
|
||||
}).join();
|
||||
BOOST_CHECK( catched);
|
||||
}
|
||||
@@ -267,7 +267,7 @@ void test_exception() {
|
||||
|
||||
void test_fp() {
|
||||
double d = 7.13;
|
||||
ctx::continuation c = ctx::callcc< double >( fn3, d);
|
||||
ctx::continuation c = ctx::callcc( fn3, d);
|
||||
BOOST_CHECK_EQUAL( 10.58, value3);
|
||||
BOOST_CHECK( ! c );
|
||||
}
|
||||
@@ -275,7 +275,7 @@ void test_fp() {
|
||||
void test_stacked() {
|
||||
value1 = 0;
|
||||
value3 = 0.;
|
||||
ctx::continuation c = ctx::callcc< void >( fn4);
|
||||
ctx::continuation c = ctx::callcc( fn4);
|
||||
BOOST_CHECK_EQUAL( 3, value1);
|
||||
BOOST_CHECK_EQUAL( 3.14, value3);
|
||||
BOOST_CHECK( ! c );
|
||||
@@ -287,7 +287,7 @@ void test_prealloc() {
|
||||
ctx::stack_context sctx( alloc.allocate() );
|
||||
void * sp = static_cast< char * >( sctx.sp) - 10;
|
||||
std::size_t size = sctx.size - 10;
|
||||
ctx::continuation c = ctx::callcc< int >( std::allocator_arg, ctx::preallocated( sp, size, sctx), alloc, fn1, 7);
|
||||
ctx::continuation c = ctx::callcc( std::allocator_arg, ctx::preallocated( sp, size, sctx), alloc, fn1, 7);
|
||||
BOOST_CHECK_EQUAL( 7, value1);
|
||||
BOOST_CHECK( ! c );
|
||||
}
|
||||
@@ -295,36 +295,40 @@ void test_prealloc() {
|
||||
void test_ontop() {
|
||||
{
|
||||
int i = 3, j = 0;
|
||||
ctx::continuation c = ctx::callcc< int >([](ctx::continuation && c, int x) {
|
||||
ctx::continuation c = ctx::callcc([](ctx::continuation && c, int x) {
|
||||
for (;;) {
|
||||
c = ctx::callcc< int >( std::move( c), x*10);
|
||||
x = ctx::get_data< int >( c);
|
||||
c = ctx::callcc( std::move( c), x*10);
|
||||
if ( ctx::has_data( c) ) {
|
||||
x = ctx::data< int >( c);
|
||||
}
|
||||
}
|
||||
return std::move( c);
|
||||
}, i);
|
||||
c = ctx::callcc< int >( std::move( c), ctx::exec_ontop_arg, [](int x){ return x-10; }, i);
|
||||
j = ctx::get_data< int >( c);
|
||||
c = ctx::callcc( std::move( c), ctx::exec_ontop_arg, [](int x){ return x-10; }, i);
|
||||
if ( ctx::has_data( c) ) {
|
||||
j = ctx::data< int >( c);
|
||||
}
|
||||
BOOST_CHECK( c );
|
||||
BOOST_CHECK_EQUAL( j, -70);
|
||||
}
|
||||
{
|
||||
int i = 3, j = 1;
|
||||
ctx::continuation c;
|
||||
c = ctx::callcc< int, int >( fn17, i, j);
|
||||
std::tie( i, j) = ctx::get_data< int, int >( c);
|
||||
c = ctx::callcc< int, int >( std::move( c), ctx::exec_ontop_arg, [](int x,int y) { return std::make_tuple( x - y, x + y); }, i, j);
|
||||
std::tie( i, j) = ctx::get_data< int, int >( c);
|
||||
c = ctx::callcc( fn17, i, j);
|
||||
std::tie( i, j) = ctx::data< int, int >( c);
|
||||
c = ctx::callcc( std::move( c), ctx::exec_ontop_arg, [](int x,int y) { return std::make_tuple( x - y, x + y); }, i, j);
|
||||
std::tie( i, j) = ctx::data< int, int >( c);
|
||||
BOOST_CHECK_EQUAL( i, 2);
|
||||
BOOST_CHECK_EQUAL( j, 4);
|
||||
}
|
||||
{
|
||||
moveable m1( 7), m2, dummy;
|
||||
ctx::continuation c = ctx::callcc< moveable >( fn11, std::move( dummy) );
|
||||
ctx::continuation c = ctx::callcc( fn11, std::move( dummy) );
|
||||
BOOST_CHECK( 7 == m1.value);
|
||||
BOOST_CHECK( m1.state);
|
||||
BOOST_CHECK( -1 == m2.value);
|
||||
BOOST_CHECK( ! m2.state);
|
||||
c = ctx::callcc< moveable >( std::move( c),
|
||||
c = ctx::callcc( std::move( c),
|
||||
ctx::exec_ontop_arg,
|
||||
[](moveable m){
|
||||
BOOST_CHECK( m.state);
|
||||
@@ -332,7 +336,7 @@ void test_ontop() {
|
||||
return std::move( m);
|
||||
},
|
||||
std::move( m1) );
|
||||
m2 = ctx::get_data< moveable >( c);
|
||||
m2 = ctx::data< moveable >( c);
|
||||
BOOST_CHECK( ! m1.state);
|
||||
BOOST_CHECK( -1 == m1.value);
|
||||
BOOST_CHECK( m2.state);
|
||||
@@ -344,11 +348,11 @@ void test_ontop_exception() {
|
||||
{
|
||||
value1 = 0;
|
||||
value2 = "";
|
||||
ctx::continuation c = ctx::callcc< void >([](ctx::continuation && c){
|
||||
ctx::continuation c = ctx::callcc([](ctx::continuation && c){
|
||||
for (;;) {
|
||||
value1 = 3;
|
||||
try {
|
||||
c = ctx::callcc< void >( std::move( c) );
|
||||
c = ctx::callcc( std::move( c) );
|
||||
} catch ( ctx::ontop_error const& e) {
|
||||
try {
|
||||
std::rethrow_if_nested( e);
|
||||
@@ -360,10 +364,10 @@ void test_ontop_exception() {
|
||||
}
|
||||
return std::move( c);
|
||||
});
|
||||
c = ctx::callcc< void >( std::move( c) );
|
||||
c = ctx::callcc( std::move( c) );
|
||||
BOOST_CHECK_EQUAL( 3, value1);
|
||||
const char * what = "hello world";
|
||||
ctx::callcc< void >( std::move( c), ctx::exec_ontop_arg, [what](){ throw my_exception( what); });
|
||||
ctx::callcc( std::move( c), ctx::exec_ontop_arg, [what](){ throw my_exception( what); });
|
||||
BOOST_CHECK_EQUAL( 3, value1);
|
||||
BOOST_CHECK_EQUAL( std::string( what), value2);
|
||||
}
|
||||
@@ -371,11 +375,11 @@ void test_ontop_exception() {
|
||||
value2 = "";
|
||||
int i = 3, j = 1;
|
||||
ctx::continuation c;
|
||||
c = ctx::callcc< int, int >([]( ctx::continuation && c, int x, int y) {
|
||||
c = ctx::callcc([]( ctx::continuation && c, int x, int y) {
|
||||
for (;;) {
|
||||
try {
|
||||
c = ctx::callcc< int, int >( std::move( c), x+y,x-y);
|
||||
std::tie( x, y) = ctx::get_data< int, int >( c);
|
||||
c = ctx::callcc( std::move( c), x+y,x-y);
|
||||
std::tie( x, y) = ctx::data< int, int >( c);
|
||||
} catch ( boost::context::ontop_error const& e) {
|
||||
try {
|
||||
std::rethrow_if_nested( e);
|
||||
@@ -389,11 +393,11 @@ void test_ontop_exception() {
|
||||
},
|
||||
i, j);
|
||||
BOOST_CHECK( c );
|
||||
std::tie( i, j) = ctx::get_data< int, int >( c);
|
||||
std::tie( i, j) = ctx::data< int, int >( c);
|
||||
BOOST_CHECK_EQUAL( i, 4);
|
||||
BOOST_CHECK_EQUAL( j, 2);
|
||||
const char * what = "hello world";
|
||||
c = ctx::callcc< int, int >( std::move( c),
|
||||
c = ctx::callcc( std::move( c),
|
||||
ctx::exec_ontop_arg,
|
||||
[what](int x, int y) {
|
||||
throw my_exception(what);
|
||||
@@ -410,14 +414,14 @@ void test_ontop_exception() {
|
||||
void test_termination() {
|
||||
{
|
||||
value1 = 0;
|
||||
ctx::continuation c = ctx::callcc< void >( fn7);
|
||||
ctx::continuation c = ctx::callcc( fn7);
|
||||
BOOST_CHECK_EQUAL( 3, value1);
|
||||
}
|
||||
BOOST_CHECK_EQUAL( 7, value1);
|
||||
{
|
||||
value1 = 0;
|
||||
BOOST_CHECK_EQUAL( 0, value1);
|
||||
ctx::continuation c = ctx::callcc< void >( fn5);
|
||||
ctx::continuation c = ctx::callcc( fn5);
|
||||
BOOST_CHECK_EQUAL( 3, value1);
|
||||
BOOST_CHECK( ! c );
|
||||
}
|
||||
@@ -427,13 +431,13 @@ void test_termination() {
|
||||
int i = 3;
|
||||
ctx::continuation c;
|
||||
BOOST_CHECK( ! c );
|
||||
c = ctx::callcc< int >( fn9, i);
|
||||
c = ctx::callcc( fn9, i);
|
||||
BOOST_CHECK( c );
|
||||
i = ctx::get_data< int >( c);
|
||||
i = ctx::data< int >( c);
|
||||
BOOST_CHECK_EQUAL( i, value1);
|
||||
BOOST_CHECK( c );
|
||||
i = 7;
|
||||
c = ctx::callcc< int >( std::move( c), i);
|
||||
c = ctx::callcc( std::move( c), i);
|
||||
BOOST_CHECK( ! c );
|
||||
BOOST_CHECK_EQUAL( i, value1);
|
||||
}
|
||||
@@ -444,14 +448,14 @@ void test_one_arg() {
|
||||
int dummy = 0;
|
||||
value1 = 0;
|
||||
ctx::continuation c;
|
||||
c = ctx::callcc< int >( fn8, 7);
|
||||
c = ctx::callcc( fn8, 7);
|
||||
BOOST_CHECK_EQUAL( 7, value1);
|
||||
}
|
||||
{
|
||||
int i = 3, j = 0;
|
||||
ctx::continuation c;
|
||||
c = ctx::callcc< int >( fn9, i);
|
||||
j = ctx::get_data< int >( c);
|
||||
c = ctx::callcc( fn9, i);
|
||||
j = ctx::data< int >( c);
|
||||
BOOST_CHECK_EQUAL( i, j);
|
||||
}
|
||||
{
|
||||
@@ -460,9 +464,11 @@ void test_one_arg() {
|
||||
int & j = j_;
|
||||
BOOST_CHECK_EQUAL( i, i_);
|
||||
BOOST_CHECK_EQUAL( j, j_);
|
||||
BOOST_CHECK( & i != & j);
|
||||
ctx::continuation c;
|
||||
c = ctx::callcc< int & >( fn10, i);
|
||||
j = ctx::get_data< int & >( c);
|
||||
c = ctx::callcc( fn10, std::ref( i) );
|
||||
BOOST_CHECK( ctx::has_data( c) );
|
||||
j = ctx::data< int & >( c);
|
||||
BOOST_CHECK_EQUAL( i, i_);
|
||||
BOOST_CHECK_EQUAL( j, i_);
|
||||
}
|
||||
@@ -470,8 +476,8 @@ void test_one_arg() {
|
||||
Y y;
|
||||
Y * py = nullptr;
|
||||
ctx::continuation c;
|
||||
c = ctx::callcc< Y * >( fn15, & y);
|
||||
py = ctx::get_data< Y * >( c);
|
||||
c = ctx::callcc( fn15, & y);
|
||||
py = ctx::data< Y * >( c);
|
||||
BOOST_CHECK( py == & y);
|
||||
}
|
||||
{
|
||||
@@ -481,8 +487,8 @@ void test_one_arg() {
|
||||
BOOST_CHECK( -1 == m2.value);
|
||||
BOOST_CHECK( ! m2.state);
|
||||
ctx::continuation c;
|
||||
c = ctx::callcc< moveable >( fn11, std::move( m1) );
|
||||
m2 = ctx::get_data< moveable >( c);
|
||||
c = ctx::callcc( fn11, std::move( m1) );
|
||||
m2 = ctx::data< moveable >( c);
|
||||
BOOST_CHECK( -1 == m1.value);
|
||||
BOOST_CHECK( ! m1.state);
|
||||
BOOST_CHECK( 7 == m2.value);
|
||||
@@ -494,9 +500,8 @@ void test_two_args() {
|
||||
{
|
||||
int i1 = 3, i2 = 0;
|
||||
std::string str1("abc"), str2;
|
||||
ctx::continuation c;
|
||||
c = ctx::callcc< int, std::string >( fn12, i1, str1);
|
||||
std::tie( i2, str2) = ctx::get_data< int, std::string >( c);
|
||||
ctx::continuation c = ctx::callcc( fn12, i1, str1);
|
||||
std::tie( i2, str2) = ctx::data< int, std::string >( c);
|
||||
BOOST_CHECK_EQUAL( i1, i2);
|
||||
BOOST_CHECK_EQUAL( str1, str2);
|
||||
}
|
||||
@@ -508,8 +513,8 @@ void test_two_args() {
|
||||
BOOST_CHECK( -1 == m2.value);
|
||||
BOOST_CHECK( ! m2.state);
|
||||
ctx::continuation c;
|
||||
c = ctx::callcc< int, moveable >( fn13, i1, std::move( m1) );
|
||||
std::tie( i2, m2) = ctx::get_data< int, moveable >( c);
|
||||
c = ctx::callcc( fn13, i1, std::move( m1) );
|
||||
std::tie( i2, m2) = ctx::data< int, moveable >( c);
|
||||
BOOST_CHECK_EQUAL( i1, i2);
|
||||
BOOST_CHECK( -1 == m1.value);
|
||||
BOOST_CHECK( ! m1.state);
|
||||
@@ -523,8 +528,8 @@ void test_variant() {
|
||||
int i = 7;
|
||||
variant_t data1 = i, data2;
|
||||
ctx::continuation c;
|
||||
c = ctx::callcc< variant_t >( fn14, data1);
|
||||
data2 = ctx::get_data< variant_t >( c);
|
||||
c = ctx::callcc( fn14, data1);
|
||||
data2 = ctx::data< variant_t >( c);
|
||||
std::string str = boost::get< std::string >( data2);
|
||||
BOOST_CHECK_EQUAL( std::string("7"), str);
|
||||
}
|
||||
@@ -532,7 +537,7 @@ void test_variant() {
|
||||
|
||||
#ifdef BOOST_WINDOWS
|
||||
void test_bug12215() {
|
||||
ctx::continuation c = ctx::callcc< void >(
|
||||
ctx::continuation c = ctx::callcc(
|
||||
[](ctx::continuation && c) {
|
||||
char buffer[MAX_PATH];
|
||||
GetModuleFileName( nullptr, buffer, MAX_PATH);
|
||||
|
||||
Reference in New Issue
Block a user