diff --git a/example/error_log.cpp b/example/error_log.cpp index ea19e8cb..c5b8e438 100644 --- a/example/error_log.cpp +++ b/example/error_log.cpp @@ -12,6 +12,27 @@ // not captured, only printed. #include + +#ifdef BOOST_LEAF_NO_EXCEPTIONS + +namespace boost +{ + [[noreturn]] void throw_exception( std::exception const & e ) + { + std::terminate(); + } + + struct source_location; + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) + { + throw_exception(e); + } +} + +#endif + +//////////////////////////////////////// + #include #include @@ -125,24 +146,3 @@ int main() } ); return 0; } - -//////////////////////////////////////// - -#ifdef BOOST_LEAF_NO_EXCEPTIONS - -namespace boost -{ - [[noreturn]] void throw_exception( std::exception const & e ) - { - std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); - std::terminate(); - } - - struct source_location; - [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) - { - throw_exception(e); - } -} - -#endif diff --git a/example/error_trace.cpp b/example/error_trace.cpp index c3299b95..4d86423e 100644 --- a/example/error_trace.cpp +++ b/example/error_trace.cpp @@ -13,6 +13,27 @@ // recorded in a std::deque, rather than just printed in-place. #include + +#ifdef BOOST_LEAF_NO_EXCEPTIONS + +namespace boost +{ + [[noreturn]] void throw_exception( std::exception const & e ) + { + std::terminate(); + } + + struct source_location; + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) + { + throw_exception(e); + } +} + +#endif + +//////////////////////////////////////// + #include #include #include @@ -125,24 +146,3 @@ int main() } ); return 0; } - -//////////////////////////////////////// - -#ifdef BOOST_LEAF_NO_EXCEPTIONS - -namespace boost -{ - [[noreturn]] void throw_exception( std::exception const & e ) - { - std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); - std::terminate(); - } - - struct source_location; - [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) - { - throw_exception(e); - } -} - -#endif diff --git a/example/lua_callback_result.cpp b/example/lua_callback_result.cpp index fc7a046f..8a562d98 100644 --- a/example/lua_callback_result.cpp +++ b/example/lua_callback_result.cpp @@ -5,11 +5,32 @@ // This is a simple program that shows how to report error objects out of a // C-callback, converting them to leaf::result as soon as controlreaches C++. +#include + +#ifdef BOOST_LEAF_NO_EXCEPTIONS + +namespace boost +{ + [[noreturn]] void throw_exception( std::exception const & e ) + { + std::terminate(); + } + + struct source_location; + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) + { + throw_exception(e); + } +} + +#endif + +//////////////////////////////////////// + extern "C" { #include "lua.h" #include "lauxlib.h" } -#include #include #include #include @@ -153,22 +174,3 @@ int main() return 0; } - -#ifdef BOOST_LEAF_NO_EXCEPTIONS - -namespace boost -{ - [[noreturn]] void throw_exception( std::exception const & e ) - { - std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); - std::terminate(); - } - - struct source_location; - [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) - { - throw_exception(e); - } -} - -#endif diff --git a/example/print_file/print_file_eh.cpp b/example/print_file/print_file_eh.cpp index 7e1dd79a..adf54f7f 100644 --- a/example/print_file/print_file_eh.cpp +++ b/example/print_file/print_file_eh.cpp @@ -7,7 +7,7 @@ // It reads a text file in a buffer and prints it to std::cout, using LEAF to // handle errors. This version uses exception handling. The version that does -// not use exception handling is in print_file_result.cpp. +// not use exception handling is in print_file_leaf_result.cpp. #include #include diff --git a/example/print_file/print_file_result.cpp b/example/print_file/print_file_leaf_result.cpp similarity index 98% rename from example/print_file/print_file_result.cpp rename to example/print_file/print_file_leaf_result.cpp index 36b67ffd..bb9dd8fb 100644 --- a/example/print_file/print_file_result.cpp +++ b/example/print_file/print_file_leaf_result.cpp @@ -10,6 +10,27 @@ // does use exception handling is in print_file_eh.cpp. #include + +#ifdef BOOST_LEAF_NO_EXCEPTIONS + +namespace boost +{ + [[noreturn]] void throw_exception( std::exception const & e ) + { + std::terminate(); + } + + struct source_location; + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) + { + throw_exception(e); + } +} + +#endif + +//////////////////////////////////////// + #include #include #include @@ -202,24 +223,3 @@ result file_read( FILE & f, void * buf, std::size_t size ) return { }; } - -//////////////////////////////////////// - -#ifdef BOOST_LEAF_NO_EXCEPTIONS - -namespace boost -{ - [[noreturn]] void throw_exception( std::exception const & e ) - { - std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); - std::terminate(); - } - - struct source_location; - [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) - { - throw_exception(e); - } -} - -#endif diff --git a/example/print_file/print_file_outcome_result.cpp b/example/print_file/print_file_outcome_result.cpp index 8a7b32ae..095b53a8 100644 --- a/example/print_file/print_file_outcome_result.cpp +++ b/example/print_file/print_file_outcome_result.cpp @@ -9,8 +9,29 @@ // It reads a text file in a buffer and prints it to std::cout, using LEAF to // handle errors. This version does not use exception handling. -#include #include + +#ifdef BOOST_LEAF_NO_EXCEPTIONS + +namespace boost +{ + [[noreturn]] void throw_exception( std::exception const & e ) + { + std::terminate(); + } + + struct source_location; + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) + { + throw_exception(e); + } +} + +#endif + +//////////////////////////////////////// + +#include #include #include #include @@ -210,24 +231,3 @@ result file_read( FILE & f, void * buf, std::size_t size ) return outcome::success(); } - -//////////////////////////////////////// - -#ifdef BOOST_LEAF_NO_EXCEPTIONS - -namespace boost -{ - [[noreturn]] void throw_exception( std::exception const & e ) - { - std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); - std::terminate(); - } - - struct source_location; - [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) - { - throw_exception(e); - } -} - -#endif diff --git a/example/print_file/print_file_system_result.cpp b/example/print_file/print_file_system_result.cpp new file mode 100644 index 00000000..9325ee03 --- /dev/null +++ b/example/print_file/print_file_system_result.cpp @@ -0,0 +1,233 @@ +// Copyright 2018-2024 Emil Dotchevski and Reverge Studios, 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 the program presented in +// https://boostorg.github.io/leaf/#introduction-result. + +// It reads a text file in a buffer and prints it to std::cout, using LEAF to +// handle errors. This version does not use exception handling. The version that +// does use exception handling is in print_file_eh.cpp. + + +#include + +#ifdef BOOST_LEAF_NO_EXCEPTIONS + +namespace boost +{ + [[noreturn]] void throw_exception( std::exception const & e ) + { + std::terminate(); + } + + struct source_location; + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) + { + throw_exception(e); + } +} + +#endif + +//////////////////////////////////////// + +#include +#include +#include +#include + +namespace leaf = boost::leaf; + + +// First, we need an enum to define our error codes: +enum error_code +{ + bad_command_line = 1, + open_error, + read_error, + size_error, + eof_error, + output_error +}; + + +template +using result = boost::system::result; + +// To enable LEAF to work with boost::system::result, we need to specialize the +// is_result_type template: +namespace boost { namespace leaf { + template struct is_result_type>: std::true_type { }; +} } + + +// We will handle all failures in our main function, but first, here are the +// declarations of the functions it calls, each communicating failures using +// result: + +// Parse the command line, return the file name. +result parse_command_line( int argc, char const * argv[] ); + +// Open a file for reading. +result> file_open( char const * file_name ); + +// Return the size of the file. +result file_size( FILE & f ); + +// Read size bytes from f into buf. +result file_read( FILE & f, void * buf, std::size_t size ); + + +// The main function, which handles all errors. +int main( int argc, char const * argv[] ) +{ + return leaf::try_handle_all( + + [&]() -> result + { + BOOST_LEAF_AUTO(file_name, parse_command_line(argc,argv)); + + auto load = leaf::on_error( leaf::e_file_name{file_name} ); + + BOOST_LEAF_AUTO(f, file_open(file_name)); + + BOOST_LEAF_AUTO(s, file_size(*f)); + + std::string buffer(1 + s, '\0'); + BOOST_LEAF_CHECK(file_read(*f, &buffer[0], buffer.size()-1)); + + std::cout << buffer; + std::cout.flush(); + if( std::cout.fail() ) + return leaf::new_error(output_error, leaf::e_errno{errno}); + + return 0; + }, + + // Each of the lambdas below is an error handler. LEAF will consider + // them, in order, and call the first one that matches the available + // error objects. + + // This handler will be called if the error includes: + // - an object of type error_code equal to open_error, and + // - an object of type leaf::e_errno that has .value equal to ENOENT, + // and + // - an object of type leaf::e_file_name. + []( leaf::match, leaf::match_value, leaf::e_file_name const & fn ) + { + std::cerr << "File not found: " << fn.value << std::endl; + return 1; + }, + + // This handler will be called if the error includes: + // - an object of type error_code equal to open_error, and + // - an object of type leaf::e_errno (regardless of its .value), and + // - an object of type leaf::e_file_name. + []( leaf::match, leaf::e_errno const & errn, leaf::e_file_name const & fn ) + { + std::cerr << "Failed to open " << fn.value << ", errno=" << errn << std::endl; + return 2; + }, + + // This handler will be called if the error includes: + // - an object of type error_code equal to any of size_error, + // read_error, eof_error, and + // - an optional object of type leaf::e_errno (regardless of its + // .value), and + // - an object of type leaf::e_file_name. + []( leaf::match, leaf::e_errno const * errn, leaf::e_file_name const & fn ) + { + std::cerr << "Failed to access " << fn.value; + if( errn ) + std::cerr << ", errno=" << *errn; + std::cerr << std::endl; + return 3; + }, + + // This handler will be called if the error includes: + // - an object of type error_code equal to output_error, and + // - an object of type leaf::e_errno (regardless of its .value), + []( leaf::match, leaf::e_errno const & errn ) + { + std::cerr << "Output error, errno=" << errn << std::endl; + return 4; + }, + + // This handler will be called if we've got a bad_command_line + []( leaf::match ) + { + std::cout << "Bad command line argument" << std::endl; + return 5; + }, + + // This last handler matches any error: it prints diagnostic information + // to help debug logic errors in the program, since it failed to match + // an appropriate error handler to the error condition it encountered. + // In this program this handler will never be called. + []( leaf::error_info const & unmatched ) + { + std::cerr << + "Unknown failure detected" << std::endl << + "Cryptic diagnostic information follows" << std::endl << + unmatched; + return 6; + } ); +} + + +// Implementations of the functions called by main: + + +// Parse the command line, return the file name. +result parse_command_line( int argc, char const * argv[] ) +{ + if( argc == 2 ) + return argv[1]; + else + return leaf::new_error(bad_command_line); +} + + +// Open a file for reading. +result> file_open( char const * file_name ) +{ + if( FILE * f = fopen(file_name, "rb") ) + return std::shared_ptr(f, &fclose); + else + return leaf::new_error(open_error, leaf::e_errno{errno}); +} + + +// Return the size of the file. +result file_size( FILE & f ) +{ + auto load = leaf::on_error([] { return leaf::e_errno{errno}; }); + + if( fseek(&f, 0, SEEK_END) ) + return leaf::new_error(size_error); + + long s = ftell(&f); + if( s == -1L ) + return leaf::new_error(size_error); + + if( fseek(&f,0,SEEK_SET) ) + return leaf::new_error(size_error); + + return std::size_t(s); +} + + +// Read size bytes from f into buf. +result file_read( FILE & f, void * buf, std::size_t size ) +{ + std::size_t n = fread(buf, 1, size, &f); + + if( ferror(&f) ) + return leaf::new_error(read_error, leaf::e_errno{errno}); + + if( n != size ) + return leaf::new_error(eof_error); + + return { }; +} diff --git a/example/print_file/readme.md b/example/print_file/readme.md index 3c5a51cd..76d52688 100644 --- a/example/print_file/readme.md +++ b/example/print_file/readme.md @@ -4,13 +4,16 @@ This directory has three versions of the same simple program, which reads a file, prints it to standard out and handles errors using LEAF, each using a different variation on error handling: -* [print_file_result.cpp](./print_file_result.cpp) reports errors with - `leaf::result`, using an error code `enum` for classification of failures. +* [print_file_leaf_result.cpp](./print_file_leaf_result.cpp) reports errors with + `boost::leaf::result`, using an error code `enum` for classification of failures. -* [print_file_outcome_result.cpp](./print_file_outcome_result.cpp) is the same - as the above, but using `outcome::result`. This demonstrates the ability - to transport arbitrary error objects through APIs that do not use - `leaf::result`. +* [print_file_system_result.cpp](./print_file_system_result.cpp) is the same as + above, but using `boost::system::result` instead of `boost::leaf::result`. + This demonstrates the ability of LEAF to transport arbitrary error objects using an + external result type, rather than `boost::leaf::result`. + +* [print_file_outcome_result.cpp](./print_file_outcome_result.cpp) is the same as + above, but using `boost::outcome::result` instead of `boost::leaf::result`. * [print_file_eh.cpp](./print_file_eh.cpp) throws on error, using an error code `enum` for classification of failures. diff --git a/example/print_half.cpp b/example/print_half.cpp index 1211d277..8e3d0228 100644 --- a/example/print_half.cpp +++ b/example/print_half.cpp @@ -6,6 +6,27 @@ // https://github.com/ned14/outcome/blob/master/doc/src/snippets/using_result.cpp #include + +#ifdef BOOST_LEAF_NO_EXCEPTIONS + +namespace boost +{ + [[noreturn]] void throw_exception( std::exception const & e ) + { + std::terminate(); + } + + struct source_location; + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) + { + throw_exception(e); + } +} + +#endif + +//////////////////////////////////////// + #include #include #include @@ -96,24 +117,3 @@ int main( int argc, char const * argv[] ) return 3; } ); } - -//////////////////////////////////////// - -#ifdef BOOST_LEAF_NO_EXCEPTIONS - -namespace boost -{ - [[noreturn]] void throw_exception( std::exception const & e ) - { - std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); - std::terminate(); - } - - struct source_location; - [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) - { - throw_exception(e); - } -} - -#endif diff --git a/example/try_capture_all_result.cpp b/example/try_capture_all_result.cpp index cabe5897..3165bdea 100644 --- a/example/try_capture_all_result.cpp +++ b/example/try_capture_all_result.cpp @@ -21,6 +21,27 @@ int main() #else #include + +#ifdef BOOST_LEAF_NO_EXCEPTIONS + +namespace boost +{ + [[noreturn]] void throw_exception( std::exception const & e ) + { + std::terminate(); + } + + struct source_location; + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) + { + throw_exception(e); + } +} + +#endif + +//////////////////////////////////////// + #include #include #include @@ -103,25 +124,4 @@ int main() } } -//////////////////////////////////////// - -#ifdef BOOST_LEAF_NO_EXCEPTIONS - -namespace boost -{ - [[noreturn]] void throw_exception( std::exception const & e ) - { - std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); - std::terminate(); - } - - struct source_location; - [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) - { - throw_exception(e); - } -} - -#endif - #endif diff --git a/include/boost/leaf/error.hpp b/include/boost/leaf/error.hpp index 08f0efd1..80401fdc 100644 --- a/include/boost/leaf/error.hpp +++ b/include/boost/leaf/error.hpp @@ -579,30 +579,30 @@ namespace detail namespace detail { - class leaf_category final: public std::error_category + class leaf_error_category final: public std::error_category { bool equivalent( int, std::error_condition const & ) const noexcept final override { return false; } bool equivalent( std::error_code const &, int ) const noexcept final override { return false; } char const * name() const noexcept final override { return "LEAF error"; } std::string message( int ) const final override { return name(); } public: - ~leaf_category() noexcept final override { } + ~leaf_error_category() noexcept final override { } }; template - struct get_error_category + struct get_leaf_error_category { - static leaf_category cat; + static leaf_error_category cat; }; template - leaf_category get_error_category::cat; + leaf_error_category get_leaf_error_category::cat; inline int import_error_code( std::error_code const & ec ) noexcept { if( int err_id = ec.value() ) { - std::error_category const & cat = get_error_category<>::cat; + std::error_category const & cat = get_leaf_error_category<>::cat; if( &ec.category() == &cat ) { BOOST_LEAF_ASSERT((err_id&3) == 1); @@ -622,7 +622,7 @@ namespace detail inline bool is_error_id( std::error_code const & ec ) noexcept { - bool res = (&ec.category() == &detail::get_error_category<>::cat); + bool res = (&ec.category() == &detail::get_leaf_error_category<>::cat); BOOST_LEAF_ASSERT(!res || !ec.value() || ((ec.value()&3) == 1)); return res; } @@ -656,21 +656,23 @@ class BOOST_LEAF_SYMBOL_VISIBLE error_id } #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR - error_id( std::error_code const & ec ) noexcept: - value_(detail::import_error_code(ec)) + template + explicit error_id( T const & ec, typename std::enable_if::value && std::is_constructible::value, int>::type = 0 ) noexcept: + value_(detail::import_error_code(std::error_code(ec))) { BOOST_LEAF_ASSERT(!value_ || ((value_&3) == 1)); } template - error_id( Enum e, typename std::enable_if::value, Enum>::type * = 0 ) noexcept: + error_id( Enum e, typename std::enable_if::value, int>::type = 0 ) noexcept: value_(detail::import_error_code(e)) { } - operator std::error_code() const noexcept + template ::value, int>::type = 0> + operator T() const noexcept { - return std::error_code(value_, detail::get_error_category<>::cat); + return std::error_code(value_, detail::get_leaf_error_category<>::cat); } #endif diff --git a/include/boost/leaf/handle_errors.hpp b/include/boost/leaf/handle_errors.hpp index ade0f135..96d67db4 100644 --- a/include/boost/leaf/handle_errors.hpp +++ b/include/boost/leaf/handle_errors.hpp @@ -530,7 +530,7 @@ try_handle_all( TryBlock && try_block, H && ... h ) noexcept else { detail::unload_result(&r); - error_id id = r.error(); + error_id id(r.error()); ctx.deactivate(); using R = typename std::decay()().value())>::type; return ctx.template handle_error(std::move(id), std::forward(h)...); @@ -550,12 +550,12 @@ try_handle_some( TryBlock && try_block, H && ... h ) noexcept else { detail::unload_result(&r); - error_id id = r.error(); + error_id id(r.error()); ctx.deactivate(); using R = typename std::decay()())>::type; auto rr = ctx.template handle_error(std::move(id), std::forward(h)..., [&r]()->R { return std::move(r); }); if( !rr ) - ctx.unload(rr.error()); + ctx.unload(error_id(rr.error())); return rr; } } @@ -626,7 +626,7 @@ try_handle_all( TryBlock && try_block, H && ... h ) { BOOST_LEAF_ASSERT(ctx.is_active()); detail::unload_result(&r); - error_id id = r.error(); + error_id id(r.error()); ctx.deactivate(); using R = typename std::decay()().value())>::type; return ctx.template handle_error(std::move(id), std::forward(h)...); @@ -646,7 +646,7 @@ try_handle_some( TryBlock && try_block, H && ... h ) else if( ctx.is_active() ) { detail::unload_result(&r); - error_id id = r.error(); + error_id id(r.error()); ctx.deactivate(); using R = typename std::decay()())>::type; auto rr = ctx.template handle_error(std::move(id), std::forward(h)..., @@ -655,12 +655,12 @@ try_handle_some( TryBlock && try_block, H && ... h ) return std::move(r); }); if( !rr ) - ctx.unload(rr.error()); + ctx.unload(error_id(rr.error())); return rr; } else { - ctx.unload(r.error()); + ctx.unload(error_id(r.error())); return r; } } diff --git a/meson.build b/meson.build index f95254f5..6117a291 100644 --- a/meson.build +++ b/meson.build @@ -235,7 +235,7 @@ endif if option_enable_examples print_file_examples = [ - 'print_file_result' + 'print_file_leaf_result' ] if option_exceptions print_file_examples += [ @@ -244,6 +244,7 @@ if option_enable_examples endif if option_boost print_file_examples += [ + 'print_file_system_result', 'print_file_outcome_result' ] endif @@ -258,38 +259,26 @@ endif if option_enable_examples - examples = [ - 'error_log', - 'error_trace', - 'print_half', - 'try_capture_all_result' - ] + executable('error_log', 'example/error_log.cpp', dependencies: [leaf] ) + executable('error_trace', 'example/error_trace.cpp', dependencies: [leaf] ) + executable('print_half', 'example/print_half.cpp', dependencies: [leaf] ) + executable('try_capture_all_result', 'example/try_capture_all_result.cpp', dependencies: [leaf, dep_thread] ) + if option_exceptions - examples += [ - 'exception_to_result', - 'try_capture_all_eh' - ] + executable('exception_to_result', 'example/exception_to_result.cpp', dependencies: [leaf] ) + executable('try_capture_all_eh', 'example/try_capture_all_eh.cpp', dependencies: [leaf, dep_thread] ) if option_lua - examples += [ - 'lua_callback_eh' - ] + executable('lua_callback_eh', 'example/lua_callback_eh.cpp', dependencies: [leaf, dep_lua] ) endif if option_boost - examples += [ - 'asio_beast_leaf_rpc' - ] + executable('asio_beast_leaf_rpc', 'example/asio_beast_leaf_rpc.cpp', dependencies: [leaf, dep_boost], override_options: ['cpp_std=c++17'] ) endif endif + if option_lua - examples += [ - 'lua_callback_result' - ] + executable('lua_callback_result', 'example/lua_callback_result.cpp', dependencies: [leaf, dep_lua] ) endif - foreach e : examples - executable(e, 'example/'+e+'.cpp', dependencies: [leaf, dep_thread, dep_boost, dep_lua] ) - endforeach - endif ################################# diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index e01599cb..39300cac 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -158,5 +158,6 @@ exe error_log : ../example/error_log.cpp : off:no ; exe error_trace : ../example/error_trace.cpp : off:no ; exe exception_to_result : ../example/exception_to_result.cpp : off:no ; exe print_file_eh : ../example/print_file/print_file_eh.cpp : off:no ; -exe print_file_result : ../example/print_file/print_file_result.cpp : off:no ; +exe print_file_leaf_result : ../example/print_file/print_file_leaf_result.cpp : off:no ; +exe print_file_system_result : ../example/print_file/print_file_system_result.cpp : off:no ; exe print_half : ../example/print_half.cpp : off:no ; diff --git a/test/error_code_test.cpp b/test/error_code_test.cpp index cc3ed35c..cf00d580 100644 --- a/test/error_code_test.cpp +++ b/test/error_code_test.cpp @@ -27,6 +27,12 @@ int main() #include "_test_res.hpp" #include "lightweight_test.hpp" +#include "boost/system/result.hpp" +namespace boost { namespace leaf { + template struct is_result_type>: std::true_type { }; + template struct is_result_type>: std::true_type { }; +} } + namespace leaf = boost::leaf; struct e_wrapped_error_code { std::error_code value; }; @@ -213,7 +219,7 @@ void test() int r = leaf::try_handle_all( []() -> R { - return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } )); + return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ); }, []( e_wrapped_error_code const & wec ) { @@ -231,7 +237,7 @@ void test() int r = leaf::try_handle_all( []() -> R { - return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } )); + return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ); }, []( leaf::match_value, errc_a::a0> code ) { @@ -251,7 +257,7 @@ void test() int r = leaf::try_handle_all( []() -> R { - return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } )); + return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ); }, []( leaf::match_value code ) { @@ -271,7 +277,7 @@ void test() int r = leaf::try_handle_all( []() -> R { - return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } )); + return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ); }, []( leaf::match_value, cond_x::x00> cond ) { @@ -292,7 +298,7 @@ void test() int r = leaf::try_handle_all( []() -> R { - return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } )); + return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ); }, []( leaf::match_value cond ) { @@ -503,7 +509,7 @@ void test_void() leaf::try_handle_all( []() -> R { - return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } )); + return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ); }, [&]( e_wrapped_error_code const & wec ) { @@ -522,7 +528,7 @@ void test_void() leaf::try_handle_all( []() -> R { - return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } )); + return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ); }, [&]( leaf::match_value, errc_a::a0> code ) { @@ -543,7 +549,7 @@ void test_void() leaf::try_handle_all( []() -> R { - return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } )); + return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ); }, [&]( leaf::match_value code ) { @@ -564,7 +570,7 @@ void test_void() leaf::try_handle_all( []() -> R { - return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } )); + return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ); }, [&]( leaf::match_value, cond_x::x00> cond ) { @@ -586,7 +592,7 @@ void test_void() leaf::try_handle_all( []() -> R { - return R(leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } )); + return leaf::new_error( e_wrapped_error_code { make_error_code(errc_a::a0) } ); }, [&]( leaf::match_value cond ) { @@ -611,6 +617,8 @@ int main() test>(); test_void>(); test_void>(); + test>(); + test>(); return boost::report_errors(); } diff --git a/test/handle_all_other_result_test.cpp b/test/handle_all_other_result_test.cpp index 164813e7..a5d3a353 100644 --- a/test/handle_all_other_result_test.cpp +++ b/test/handle_all_other_result_test.cpp @@ -44,7 +44,7 @@ ResType g( bool succeed ) if( auto r = f(succeed) ) return r; else - return ResType(leaf::error_id(r.error()).load(info<42>{42})); + return leaf::error_id(r.error()).load(info<42>{42}); } template diff --git a/test/handle_some_other_result_test.cpp b/test/handle_some_other_result_test.cpp index 8b37c127..c955d4e4 100644 --- a/test/handle_some_other_result_test.cpp +++ b/test/handle_some_other_result_test.cpp @@ -45,7 +45,7 @@ ResType g( bool succeed ) if( auto r = f(succeed) ) return r; else - return ResType(leaf::error_id(r.error()).load(info<42>{42})); + return leaf::error_id(r.error()).load(info<42>{42}); } template diff --git a/test/lightweight_test.hpp b/test/lightweight_test.hpp index e4445375..2e060d24 100644 --- a/test/lightweight_test.hpp +++ b/test/lightweight_test.hpp @@ -14,5 +14,11 @@ namespace boost std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); std::terminate(); } + + struct source_location; + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) + { + throw_exception(e); + } } #endif