mirror of
https://github.com/boostorg/leaf.git
synced 2026-01-19 04:22:08 +00:00
tweaks, pretty much complete documentation
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -7,4 +7,5 @@
|
||||
*.opensdf
|
||||
*.db
|
||||
*.opendb
|
||||
bld/*
|
||||
bld/*
|
||||
subprojects/*/
|
||||
|
||||
1146
README.adoc
1146
README.adoc
File diff suppressed because it is too large
Load Diff
133
example/lua_callback_eh.cpp
Normal file
133
example/lua_callback_eh.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
//Copyright (c) 2018 Emil Dotchevski
|
||||
//Copyright (c) 2018 Second Spectrum, Inc.
|
||||
|
||||
//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)
|
||||
|
||||
//This is a simple program that shows how to propagate leaf::error objects out
|
||||
//of a C-callback, and converting them to leaf::result<T> as soon as control
|
||||
//reaches C++.
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
#include <boost/leaf/all.hpp>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace leaf = boost::leaf;
|
||||
|
||||
struct lua_failure: std::exception { };
|
||||
|
||||
struct e_do_work_error { int value; };
|
||||
|
||||
struct e_lua_pcall_error { int value; };
|
||||
struct e_lua_error_message { std::string value; };
|
||||
|
||||
|
||||
//This is a C callback function with a specific signature, made accessible to programs
|
||||
//written in Lua.
|
||||
|
||||
//If it succeeds, it returns an int answer, by pushing it onto the Lua stack. But "sometimes"
|
||||
//it fails, in which case it calls luaL_error. This causes the Lua interpreter to abort and pop
|
||||
//back into the C++ code which called it (see call_lua below).
|
||||
int do_work( lua_State * L ) noexcept
|
||||
{
|
||||
bool success=rand()%2;
|
||||
if( success )
|
||||
{
|
||||
lua_pushnumber(L,42); //Return 42 to the calling Lua program.
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Tell the Lua interpreter to abort the Lua program. Control will reach the
|
||||
//call_lua function which called the Lua interpreter. The e_do_work_error
|
||||
//is communicated, through the Lua interpreter, to that function.
|
||||
leaf::preload( e_do_work_error{-42} );
|
||||
return luaL_error(L,"do_work_error");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<lua_State> init_lua_state() noexcept
|
||||
{
|
||||
//Create a new lua_State, we'll use std::shared_ptr for automatic cleanup.
|
||||
std::shared_ptr<lua_State> L(lua_open(),&lua_close);
|
||||
|
||||
//Register the do_work function (above) as a C callback, under the global
|
||||
//Lua name "do_work". With this, calls from Lua programs to do_work
|
||||
//will land in the do_work C function we've registered.
|
||||
lua_register( &*L, "do_work", &do_work );
|
||||
|
||||
//Pass some Lua code as a C string literal to Lua. This creates a global Lua
|
||||
//function called "call_do_work", which we will later ask Lua to execute.
|
||||
luaL_dostring( &*L, "\
|
||||
\n function call_do_work()\
|
||||
\n return do_work()\
|
||||
\n end" );
|
||||
|
||||
return L;
|
||||
}
|
||||
|
||||
|
||||
//Here we will ask Lua to execute the function call_do_work, which is written
|
||||
//in Lua, and returns the value from do_work, which is written in C++ and
|
||||
//registered with the Lua interpreter as a C callback.
|
||||
|
||||
//If do_work succeeds, we return the resulting int answer. If it fails, we'll
|
||||
//communicate that failure to our caller.
|
||||
int call_lua( lua_State * L )
|
||||
{
|
||||
//Ask the Lua interpreter to call the global Lua function call_do_work.
|
||||
lua_getfield( L, LUA_GLOBALSINDEX, "call_do_work" );
|
||||
if( int err=lua_pcall(L,0,1,0) )
|
||||
{
|
||||
//Something went wrong with the call, so we'll throw lua_failure.
|
||||
//If this is a do_work failure, the e_do_work object preloaded in
|
||||
//do_work will become associated with this exception. If not,
|
||||
//we will still need to communicate that the lua_pcall failed with an
|
||||
//error code and an error message.
|
||||
leaf::preload( e_lua_error_message{lua_tostring(L,1)} );
|
||||
lua_pop(L,1);
|
||||
leaf::throw_exception( lua_failure(), e_lua_pcall_error{err} );
|
||||
}
|
||||
else
|
||||
{
|
||||
//Success! Just return the int answer.
|
||||
int answer=lua_tonumber(L,-1);
|
||||
lua_pop(L,1);
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
|
||||
int main() noexcept
|
||||
{
|
||||
std::shared_ptr<lua_State> L=init_lua_state();
|
||||
leaf::expect<e_do_work_error,e_lua_pcall_error,e_lua_error_message> exp;
|
||||
for( int i=0; i!=10; ++i )
|
||||
try
|
||||
{
|
||||
int r = call_lua(&*L);
|
||||
std::cout << "do_work succeeded, answer=" << r << '\n';
|
||||
}
|
||||
catch( lua_failure const & e )
|
||||
{
|
||||
handle_exception( exp, e,
|
||||
|
||||
//Handle e_do_work failures:
|
||||
leaf::match<e_do_work_error>( [ ]( int v )
|
||||
{
|
||||
std::cout << "Got e_do_work_error, value = " << v << "!\n";
|
||||
} ),
|
||||
|
||||
//Handle all other lua_pcall failures:
|
||||
leaf::match<e_lua_pcall_error,e_lua_error_message>( [ ]( int err, std::string const & msg )
|
||||
{
|
||||
std::cout << "Got e_lua_pcall_error, Lua error code = " << err << ", " << msg << "\n";
|
||||
} )
|
||||
);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
129
example/lua_callback_result.cpp
Normal file
129
example/lua_callback_result.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
//Copyright (c) 2018 Emil Dotchevski
|
||||
//Copyright (c) 2018 Second Spectrum, Inc.
|
||||
|
||||
//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)
|
||||
|
||||
//This is a simple program that shows how to propagate leaf::error objects out
|
||||
//of a C-callback, and converting them to leaf::result<T> as soon as control
|
||||
//reaches C++.
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
#include <boost/leaf/all.hpp>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace leaf = boost::leaf;
|
||||
|
||||
struct e_do_work_error { int value; };
|
||||
|
||||
struct e_lua_pcall_error { int value; };
|
||||
struct e_lua_error_message { std::string value; };
|
||||
|
||||
|
||||
//This is a C callback function with a specific signature, made accessible to programs
|
||||
//written in Lua.
|
||||
|
||||
//If it succeeds, it returns an int answer, by pushing it onto the Lua stack. But "sometimes"
|
||||
//it fails, in which case it calls luaL_error. This causes the Lua interpreter to abort and pop
|
||||
//back into the C++ code which called it (see call_lua below).
|
||||
int do_work( lua_State * L ) noexcept
|
||||
{
|
||||
bool success=rand()%2;
|
||||
if( success )
|
||||
{
|
||||
lua_pushnumber(L,42); //Return 42 to the calling Lua program.
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Tell the Lua interpreter to abort the Lua program. Control will reach the
|
||||
//call_lua function which called the Lua interpreter. The e_do_work_error
|
||||
//is communicated, through the Lua interpreter, to that function.
|
||||
leaf::preload( e_do_work_error{-42} );
|
||||
return luaL_error(L,"do_work_error");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<lua_State> init_lua_state() noexcept
|
||||
{
|
||||
//Create a new lua_State, we'll use std::shared_ptr for automatic cleanup.
|
||||
std::shared_ptr<lua_State> L(lua_open(),&lua_close);
|
||||
|
||||
//Register the do_work function (above) as a C callback, under the global
|
||||
//Lua name "do_work". With this, calls from Lua programs to do_work
|
||||
//will land in the do_work C function we've registered.
|
||||
lua_register( &*L, "do_work", &do_work );
|
||||
|
||||
//Pass some Lua code as a C string literal to Lua. This creates a global Lua
|
||||
//function called "call_do_work", which we will later ask Lua to execute.
|
||||
luaL_dostring( &*L, "\
|
||||
\n function call_do_work()\
|
||||
\n return do_work()\
|
||||
\n end" );
|
||||
|
||||
return L;
|
||||
}
|
||||
|
||||
|
||||
//Here we will ask Lua to execute the function call_do_work, which is written
|
||||
//in Lua, and returns the value from do_work, which is written in C++ and
|
||||
//registered with the Lua interpreter as a C callback.
|
||||
|
||||
//If do_work succeeds, we return the resulting int answer in leaf::result<int>.
|
||||
//If it fails, we'll communicate that failure to our caller.
|
||||
leaf::result<int> call_lua( lua_State * L )
|
||||
{
|
||||
//Ask the Lua interpreter to call the global Lua function call_do_work.
|
||||
lua_getfield( L, LUA_GLOBALSINDEX, "call_do_work" );
|
||||
if( int err=lua_pcall(L,0,1,0) )
|
||||
{
|
||||
//Something went wrong with the call, so we'll return a leaf::error.
|
||||
//If this is a do_work failure, the e_do_work object preloaded in
|
||||
//do_work will become associated with this leaf::error value. If not,
|
||||
//we will still need to communicate that the lua_pcall failed with an
|
||||
//error code and an error message.
|
||||
leaf::preload( e_lua_error_message{lua_tostring(L,1)} );
|
||||
lua_pop(L,1);
|
||||
return leaf::error( e_lua_pcall_error{err} );
|
||||
}
|
||||
else
|
||||
{
|
||||
//Success! Just return the int answer.
|
||||
int answer=lua_tonumber(L,-1);
|
||||
lua_pop(L,1);
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
|
||||
int main() noexcept
|
||||
{
|
||||
std::shared_ptr<lua_State> L=init_lua_state();
|
||||
leaf::expect<e_do_work_error,e_lua_pcall_error,e_lua_error_message> exp;
|
||||
for( int i=0; i!=10; ++i )
|
||||
if( leaf::result<int> r = call_lua(&*L) )
|
||||
std::cout << "do_work succeeded, answer=" << *r << '\n';
|
||||
else
|
||||
{
|
||||
bool matched = handle_error( exp, r,
|
||||
|
||||
//Handle e_do_work failures:
|
||||
leaf::match<e_do_work_error>( [ ]( int v )
|
||||
{
|
||||
std::cout << "Got e_do_work_error, value = " << v << "!\n";
|
||||
} ),
|
||||
|
||||
//Handle all other lua_pcall failures:
|
||||
leaf::match<e_lua_pcall_error,e_lua_error_message>( [ ]( int err, std::string const & msg )
|
||||
{
|
||||
std::cout << "Got e_lua_pcall_error, Lua error code = " << err << ", " << msg << "\n";
|
||||
} )
|
||||
);
|
||||
assert(matched);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -46,7 +46,7 @@ std::shared_ptr<FILE> file_open( char const * file_name )
|
||||
int file_size( FILE & f )
|
||||
{
|
||||
//All exceptions escaping this function will automatically propagate errno.
|
||||
auto propagate = leaf::defer(&leaf::get_errno);
|
||||
auto propagate = leaf::defer([ ] { return e_errno{errno}; } );
|
||||
|
||||
if( fseek(&f,0,SEEK_END) )
|
||||
throw input_file_size_error();
|
||||
|
||||
@@ -45,7 +45,7 @@ leaf::result<std::shared_ptr<FILE>> file_open( char const * file_name )
|
||||
|
||||
leaf::result<int> file_size( FILE & f )
|
||||
{
|
||||
auto propagate = leaf::defer(&leaf::get_errno);
|
||||
auto propagate = leaf::defer([ ] { return e_errno{errno}; } );
|
||||
|
||||
if( fseek(&f,0,SEEK_END) )
|
||||
return leaf::error( e_error_code{input_file_size_error} );
|
||||
|
||||
@@ -57,22 +57,13 @@ boost
|
||||
{
|
||||
int value;
|
||||
friend
|
||||
inline
|
||||
std::ostream &
|
||||
operator<<( std::ostream & os, e_errno const & err )
|
||||
{
|
||||
using namespace std;
|
||||
os << type<e_errno>() << " = " << err.value << ", \"" << std::strerror(err.value) << '"';
|
||||
return os;
|
||||
return os << type<e_errno>() << " = " << err.value << ", \"" << std::strerror(err.value) << '"';
|
||||
}
|
||||
};
|
||||
inline
|
||||
e_errno
|
||||
get_errno() noexcept
|
||||
{
|
||||
using namespace std;
|
||||
return e_errno{errno};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
57
include/boost/leaf/detail/throw_exception.hpp
Normal file
57
include/boost/leaf/detail/throw_exception.hpp
Normal file
@@ -0,0 +1,57 @@
|
||||
//Copyright (c) 2018 Emil Dotchevski
|
||||
//Copyright (c) 2018 Second Spectrum, Inc.
|
||||
|
||||
//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 UUID_75F38740D98D11E881DDB244C82C3C47
|
||||
#define UUID_75F38740D98D11E881DDB244C82C3C47
|
||||
|
||||
#include <boost/leaf/common.hpp>
|
||||
#include <exception>
|
||||
|
||||
#define LEAF_THROW(e) ::boost::leaf::throw_exception(e,LEAF_SOURCE_LOCATION)
|
||||
|
||||
namespace
|
||||
boost
|
||||
{
|
||||
namespace
|
||||
leaf
|
||||
{
|
||||
namespace
|
||||
leaf_detail
|
||||
{
|
||||
inline void enforce_std_exception( std::exception const & ) { }
|
||||
template <class Ex>
|
||||
class
|
||||
exception:
|
||||
public Ex,
|
||||
public error
|
||||
{
|
||||
public:
|
||||
exception( Ex && ex, error && e ) noexcept:
|
||||
Ex(std::move(ex)),
|
||||
error(std::move(e))
|
||||
{
|
||||
enforce_std_exception(*this);
|
||||
}
|
||||
};
|
||||
}
|
||||
template <class... E,class Ex>
|
||||
[[noreturn]]
|
||||
void
|
||||
throw_exception( Ex && ex, E && ... e )
|
||||
{
|
||||
throw leaf_detail::exception<Ex>(std::move(ex),error(std::move(e)...));
|
||||
}
|
||||
template <class... E,class Ex>
|
||||
[[noreturn]]
|
||||
void
|
||||
throw_exception( Ex && ex, error const & err, E && ... e )
|
||||
{
|
||||
throw leaf_detail::exception<Ex>(std::move(ex),err.propagate(std::move(e)...));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -227,7 +227,7 @@ boost
|
||||
}
|
||||
template <class... E>
|
||||
void
|
||||
preload( E && ... e )
|
||||
preload( E && ... e ) noexcept
|
||||
{
|
||||
error::peek_next_error().propagate(std::forward<E>(e)...);
|
||||
}
|
||||
|
||||
@@ -91,23 +91,23 @@ boost
|
||||
////////////////////////////////////////
|
||||
template <int I,class Tuple>
|
||||
struct
|
||||
tuple_propagate
|
||||
tuple_unload
|
||||
{
|
||||
static
|
||||
void
|
||||
propagate( error const & e, Tuple && tup ) noexcept
|
||||
unload( error const & e, Tuple && tup ) noexcept
|
||||
{
|
||||
tuple_propagate<I-1,Tuple>::propagate(e,std::move(tup));
|
||||
tuple_unload<I-1,Tuple>::unload(e,std::move(tup));
|
||||
auto && opt = std::get<I-1>(std::move(tup));
|
||||
if( opt.has_value() )
|
||||
e.propagate(std::move(opt).value());
|
||||
(void) e.propagate(std::move(opt).value());
|
||||
}
|
||||
};
|
||||
template <class Tuple>
|
||||
struct
|
||||
tuple_propagate<0,Tuple>
|
||||
tuple_unload<0,Tuple>
|
||||
{
|
||||
static void propagate( error const &, Tuple && ) noexcept { }
|
||||
static void unload( error const &, Tuple && ) noexcept { }
|
||||
};
|
||||
}
|
||||
////////////////////////////////////////
|
||||
@@ -153,7 +153,7 @@ boost
|
||||
return 0;
|
||||
}
|
||||
virtual void diagnostic_print( std::ostream & ) const = 0;
|
||||
virtual void propagate( error const & ) noexcept = 0;
|
||||
virtual void unload( error const & ) noexcept = 0;
|
||||
};
|
||||
template <class... T>
|
||||
class
|
||||
@@ -180,9 +180,9 @@ boost
|
||||
leaf_detail::tuple_print<sizeof...(T),decltype(s_)>::print(os,s_);
|
||||
}
|
||||
void
|
||||
propagate( error const & e ) noexcept
|
||||
unload( error const & e ) noexcept
|
||||
{
|
||||
leaf_detail::tuple_propagate<sizeof...(T),decltype(s_)>::propagate(e,std::move(s_));
|
||||
leaf_detail::tuple_unload<sizeof...(T),decltype(s_)>::unload(e,std::move(s_));
|
||||
}
|
||||
};
|
||||
void
|
||||
@@ -269,11 +269,11 @@ boost
|
||||
return s_!=0;
|
||||
}
|
||||
error
|
||||
propagate() noexcept
|
||||
unload() noexcept
|
||||
{
|
||||
if( s_ )
|
||||
{
|
||||
s_->propagate(e_);
|
||||
s_->unload(e_);
|
||||
free();
|
||||
}
|
||||
return e_;
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
#define UUID_87F274C4D4BA11E89928D55AC82C3C47
|
||||
|
||||
#include <boost/leaf/expect.hpp>
|
||||
#include <exception>
|
||||
|
||||
#define LEAF_THROW(e) ::boost::leaf::throw_exception(e,LEAF_SOURCE_LOCATION)
|
||||
#include <boost/leaf/detail/throw_exception.hpp>
|
||||
|
||||
namespace
|
||||
boost
|
||||
@@ -18,40 +16,6 @@ boost
|
||||
namespace
|
||||
leaf
|
||||
{
|
||||
namespace
|
||||
leaf_detail
|
||||
{
|
||||
inline void enforce_std_exception( std::exception const & ) { }
|
||||
template <class Ex>
|
||||
class
|
||||
exception:
|
||||
public Ex,
|
||||
public error
|
||||
{
|
||||
public:
|
||||
exception( Ex && ex, error && e ) noexcept:
|
||||
Ex(std::move(ex)),
|
||||
error(std::move(e))
|
||||
{
|
||||
enforce_std_exception(*this);
|
||||
}
|
||||
};
|
||||
}
|
||||
template <class... E,class Ex>
|
||||
[[noreturn]]
|
||||
void
|
||||
throw_exception( Ex && ex, E && ... e )
|
||||
{
|
||||
throw leaf_detail::exception<Ex>(std::move(ex),error(std::move(e)...));
|
||||
}
|
||||
template <class... E,class Ex>
|
||||
[[noreturn]]
|
||||
void
|
||||
throw_exception( Ex && ex, error const & err, E && ... e )
|
||||
{
|
||||
throw leaf_detail::exception<Ex>(std::move(ex),err.propagate(std::move(e)...));
|
||||
}
|
||||
////////////////////////////////////////
|
||||
template <class P,class... E>
|
||||
decltype(P::value) const *
|
||||
peek( expect<E...> const & exp, std::exception const & e ) noexcept
|
||||
|
||||
@@ -44,7 +44,7 @@ boost
|
||||
set_error(error::peek_next_error());
|
||||
has_error_ = true;
|
||||
}
|
||||
propagate();
|
||||
unload();
|
||||
std::rethrow_exception(ex_);
|
||||
}
|
||||
friend
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define UUID_2CD8E6B8CA8D11E8BD3B80D66CE5B91B
|
||||
|
||||
#include <boost/leaf/error_capture.hpp>
|
||||
#include <boost/leaf/detail/throw_exception.hpp>
|
||||
|
||||
#define LEAF_AUTO(v,r) auto _r_##v = r; if( !_r_##v ) return _r_##v.error(); auto & v = *_r_##v
|
||||
#define LEAF_CHECK(r) {auto _r_##v = r; if( !_r_##v ) return _r_##v.error();}
|
||||
@@ -166,41 +167,6 @@ boost
|
||||
move_from(std::move(x));
|
||||
return *this;
|
||||
}
|
||||
void
|
||||
reset( T const & v )
|
||||
{
|
||||
destroy();
|
||||
(void) new(&value_) T(v);
|
||||
which_ = variant::value;
|
||||
}
|
||||
void
|
||||
reset( T && v ) noexcept
|
||||
{
|
||||
destroy();
|
||||
(void) new(&value_) T(std::move(v));
|
||||
which_ = variant::value;
|
||||
}
|
||||
void
|
||||
reset( leaf::error const & e ) noexcept
|
||||
{
|
||||
destroy();
|
||||
(void) new(&err_) leaf::error(e);
|
||||
which_ = variant::err;
|
||||
}
|
||||
void
|
||||
reset( leaf::error_capture const & cap ) noexcept
|
||||
{
|
||||
destroy();
|
||||
(void) new(&cap_) leaf::error_capture(cap);
|
||||
which_ = variant::cap;
|
||||
}
|
||||
void
|
||||
reset( leaf::error_capture && cap ) noexcept
|
||||
{
|
||||
destroy();
|
||||
(void) new(&cap_) leaf::error_capture(std::move(cap));
|
||||
which_ = variant::cap;
|
||||
}
|
||||
explicit
|
||||
operator bool() const noexcept
|
||||
{
|
||||
@@ -212,7 +178,7 @@ boost
|
||||
if( which_==variant::value )
|
||||
return value_;
|
||||
else
|
||||
throw bad_result();
|
||||
LEAF_THROW(bad_result());
|
||||
}
|
||||
T &
|
||||
value()
|
||||
@@ -220,7 +186,7 @@ boost
|
||||
if( which_==variant::value )
|
||||
return value_;
|
||||
else
|
||||
throw bad_result();
|
||||
LEAF_THROW(bad_result());
|
||||
}
|
||||
T const &
|
||||
operator*() const
|
||||
@@ -243,7 +209,9 @@ boost
|
||||
return leaf::error(std::forward<E>(e)...);
|
||||
case variant::
|
||||
cap:
|
||||
reset(cap_.propagate());
|
||||
destroy();
|
||||
(void) new(&err_) leaf::error(cap_.unload());
|
||||
which_ = variant::err;
|
||||
default:
|
||||
assert(which_==variant::err);
|
||||
return err_.propagate(std::forward<E>(e)...);
|
||||
@@ -251,17 +219,13 @@ boost
|
||||
}
|
||||
template <class... E>
|
||||
friend
|
||||
result &&
|
||||
capture( expect<E...> & exp, result && r )
|
||||
result
|
||||
capture( expect<E...> & exp, result const & r )
|
||||
{
|
||||
if( r.which_==variant::err )
|
||||
{
|
||||
auto cap = capture(exp,r.err_);
|
||||
r.err_.~error();
|
||||
(void) new (&r.cap_) error_capture(std::move(cap));
|
||||
r.which_ = variant::cap;
|
||||
}
|
||||
return std::move(r);
|
||||
return capture(exp,r.err_);
|
||||
else
|
||||
return r;
|
||||
}
|
||||
template <class... M,class... E>
|
||||
friend
|
||||
@@ -303,6 +267,11 @@ boost
|
||||
|
||||
typedef result<bool> base;
|
||||
|
||||
result( result<bool> && rb ):
|
||||
base(std::move(rb))
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
~result() noexcept
|
||||
@@ -325,17 +294,12 @@ boost
|
||||
}
|
||||
using base::operator bool;
|
||||
using base::error;
|
||||
using base::reset;
|
||||
void reset( bool const & ) = delete;
|
||||
void reset( bool && ) = delete;
|
||||
template <class... E>
|
||||
friend
|
||||
result &&
|
||||
capture( expect<E...> & exp, result && r )
|
||||
result
|
||||
capture( expect<E...> & exp, result const & r )
|
||||
{
|
||||
result<bool> && rb = std::move(r);
|
||||
(void) capture(exp,std::move(rb));
|
||||
return std::move(r);
|
||||
return capture(exp,static_cast<result<bool> const &>(r));
|
||||
}
|
||||
template <class... M,class... E>
|
||||
friend
|
||||
|
||||
@@ -18,6 +18,8 @@ if not meson.is_subproject()
|
||||
endif
|
||||
endif
|
||||
|
||||
lua=subproject('lua').get_variable('all')
|
||||
|
||||
includes = [ include_directories('include') ]
|
||||
|
||||
leaf = declare_dependency( include_directories: includes )
|
||||
@@ -58,3 +60,6 @@ examples = [
|
||||
foreach e : examples
|
||||
executable(e, 'example/'+e+'.cpp', dependencies: [ leaf ] )
|
||||
endforeach
|
||||
|
||||
executable('lua_callback_result', 'example/lua_callback_result.cpp', dependencies: [ leaf, lua ] )
|
||||
executable('lua_callback_eh', 'example/lua_callback_eh.cpp', dependencies: [ leaf, lua ] )
|
||||
|
||||
10
subprojects/lua.wrap
Normal file
10
subprojects/lua.wrap
Normal file
@@ -0,0 +1,10 @@
|
||||
[wrap-file]
|
||||
directory=lua-5.1.5
|
||||
|
||||
source_url = http://www.lua.org/ftp/lua-5.1.5.tar.gz
|
||||
source_filename = lua-5.1.5.tar.gz
|
||||
source_hash = 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333
|
||||
|
||||
patch_url = https://github.com/zajo/meson_wraps/blob/master/lua/subprojects/lua.tar.gz?raw=true
|
||||
patch_filename = lua.tar.gz
|
||||
patch_hash = 51cd288c6ce32cd338e39cf9a1343dcb2ea9f05293055c96dcce87781d3b0afb
|
||||
Reference in New Issue
Block a user