Merge pull request #57 from boostorg/feature/issue56

Issue 56
This commit is contained in:
Emil Dotchevski 2023-08-29 12:18:54 -07:00 committed by GitHub
commit b7ed6273c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 541 additions and 114 deletions

View File

@ -66,6 +66,12 @@ jobs:
os: ubuntu-22.04
install: g++-12-multilib
address-model: 32,64
- toolset: gcc-13
cxxstd: "11,14,17,20,2b"
os: ubuntu-latest
container: ubuntu:23.04
install: g++-13-multilib
address-model: 32,64
- toolset: clang
compiler: clang++-3.9
cxxstd: "11,14"
@ -126,9 +132,26 @@ jobs:
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install: clang-14
- toolset: clang
compiler: clang++-15
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install: clang-15
- toolset: clang
compiler: clang++-16
cxxstd: "11,14,17,20,2b"
os: ubuntu-latest
container: ubuntu:23.04
install: clang-16
- toolset: clang
cxxstd: "11,14,17,2a"
os: macos-11
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-12
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-13
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
@ -144,11 +167,13 @@ jobs:
if: matrix.container
run: |
apt-get update
apt-get -y install sudo python git g++
apt-get -y install sudo python3 git g++
- name: Install packages
if: matrix.install
run: sudo apt-get -y install ${{matrix.install}}
run: |
sudo apt-get update
sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
@ -168,7 +193,7 @@ jobs:
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
python3 tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
@ -180,7 +205,7 @@ jobs:
- name: Generate headers
run: |
cd ../boost-root/libs/leaf
python gen/generate_single_header.py -i include/boost/leaf/detail/all.hpp -p include -o test/leaf.hpp boost/leaf
python3 gen/generate_single_header.py -i include/boost/leaf/detail/all.hpp -p include -o test/leaf.hpp boost/leaf
- name: Run tests
run: |
@ -204,7 +229,6 @@ jobs:
cxxstd: "14,17,latest"
addrmd: 64
os: windows-2022
embedmanifest: embed-manifest-via=linker
- toolset: gcc
cxxstd: "11,14,17,2a"
addrmd: 64
@ -240,7 +264,7 @@ jobs:
- name: Generate headers
run: |
cd ../boost-root/libs/leaf
python gen/generate_single_header.py -i include/boost/leaf/detail/all.hpp -p include -o test/leaf.hpp boost/leaf
python3 gen/generate_single_header.py -i include/boost/leaf/detail/all.hpp -p include -o test/leaf.hpp boost/leaf
- name: Run tests
shell: cmd

2
.gitignore vendored
View File

@ -7,7 +7,7 @@
*.opensdf
*.db
*.opendb
bld/*
_bld/*
doc/html/*
snippets/*
subprojects/*/

2
.vscode/launch.json vendored
View File

@ -8,7 +8,7 @@
"name": "(lldb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/bld/debug/capture_exception_async_test",
"program": "${workspaceFolder}/_bld/debug/capture_exception_async_test",
"args": [ ],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,

25
.vscode/tasks.json vendored
View File

@ -6,13 +6,13 @@
{
"label": "Configure Meson build directories",
"type": "shell",
"command": "cd ${workspaceRoot} && meson -D leaf_boost_examples=true -D leaf_lua_examples=true bld/debug && meson -D leaf_boost_examples=true -D leaf_lua_examples=true -D leaf_hpp=true bld/debug_leaf_hpp && meson -D leaf_boost_examples=true -D leaf_lua_examples=true bld/release --buildtype release && meson -D leaf_boost_examples=true -D leaf_lua_examples=true -D leaf_hpp=true bld/release_leaf_hpp --buildtype release && meson -D leaf_diagnostics=0 -D cpp_eh=none -D b_ndebug=true -D b_lto=true -D leaf_enable_benchmarks=true bld/benchmark --buildtype release",
"command": "cd ${workspaceRoot} && meson -D leaf_boost_examples=true -D leaf_lua_examples=true _bld/debug && meson -D leaf_boost_examples=true -D leaf_lua_examples=true -D leaf_hpp=true _bld/debug_leaf_hpp && meson -D leaf_boost_examples=true -D leaf_lua_examples=true _bld/release --buildtype release && meson -D leaf_boost_examples=true -D leaf_lua_examples=true -D leaf_hpp=true _bld/release_leaf_hpp --buildtype release && meson -D leaf_diagnostics=0 -D cpp_eh=none -D b_ndebug=true -D b_lto=true -D leaf_enable_benchmarks=true _bld/benchmark --buildtype release",
"problemMatcher": []
},
{
"label": "Configure Meson build directories (no Boost)",
"type": "shell",
"command": "cd ${workspaceRoot} && meson -D leaf_lua_examples=true bld/debug && meson -D leaf_lua_examples=true -D leaf_hpp=true bld/debug_leaf_hpp && meson -D leaf_lua_examples=true bld/release --buildtype release && meson -D leaf_lua_examples=true -D leaf_hpp=true bld/release_leaf_hpp --buildtype release",
"command": "cd ${workspaceRoot} && meson -D leaf_lua_examples=true _bld/debug && meson -D leaf_lua_examples=true -D leaf_hpp=true _bld/debug_leaf_hpp && meson -D leaf_lua_examples=true _bld/release --buildtype release && meson -D leaf_lua_examples=true -D leaf_hpp=true _bld/release_leaf_hpp --buildtype release",
"problemMatcher": []
},
{
@ -28,12 +28,12 @@
},
"label": "Build all unit tests and examples (debug)",
"type": "shell",
"command": "cd ${workspaceRoot}/bld/debug && ninja",
"command": "cd ${workspaceRoot}/_bld/debug && ninja",
"problemMatcher": {
"base": "$gcc",
"fileLocation": [
"relative",
"${workspaceRoot}/bld/debug"
"${workspaceRoot}/_bld/debug"
]
}
},
@ -44,12 +44,12 @@
"dependsOn": [
"Generate leaf.hpp"
],
"command": "cd ${workspaceRoot}/bld/debug_leaf_hpp && ninja && meson test && cd ${workspaceRoot}/bld/debug && ninja && meson test",
"command": "cd ${workspaceRoot}/_bld/debug_leaf_hpp && ninja && meson test && cd ${workspaceRoot}/_bld/debug && ninja && meson test",
"problemMatcher": {
"base": "$gcc",
"fileLocation": [
"relative",
"${workspaceRoot}/bld/debug"
"${workspaceRoot}/_bld/debug"
]
}
},
@ -60,12 +60,12 @@
"dependsOn": [
"Generate leaf.hpp"
],
"command": "cd ${workspaceRoot}/bld/release && ninja && meson test && cd ${workspaceRoot}/bld/release_leaf_hpp && ninja && meson test",
"command": "cd ${workspaceRoot}/_bld/release && ninja && meson test && cd ${workspaceRoot}/_bld/release_leaf_hpp && ninja && meson test",
"problemMatcher": {
"base": "$gcc",
"fileLocation": [
"relative",
"${workspaceRoot}/bld/release"
"${workspaceRoot}/_bld/release"
]
}
},
@ -73,9 +73,6 @@
"group": "test",
"label": "Run all unit tests (b2, all configurations)",
"type": "shell",
"dependsOn": [
"Generate leaf.hpp"
],
"command": "../../b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_leaf_hpp,leaf_release_leaf_hpp exception-handling=on,off cxxstd=11,14,1z,17 && ../../b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_leaf_hpp,leaf_release_leaf_hpp,leaf_debug_embedded,leaf_release_embedded exception-handling=off rtti=off cxxstd=11,14,1z,17",
"windows": {
"command": "..\\..\\b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_leaf_hpp,leaf_release_leaf_hpp exception-handling=on,off cxxstd=14,17,latest && ..\\..\\b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_leaf_hpp,leaf_release_leaf_hpp,leaf_debug_embedded,leaf_release_embedded exception-handling=off rtti=off cxxstd=14,17,latest",
@ -84,7 +81,7 @@
"base": "$gcc",
"fileLocation": [
"relative",
"${workspaceRoot}/bld/release"
"${workspaceRoot}/_bld/release"
]
}
},
@ -95,12 +92,12 @@
},
"label": "Test current editor file",
"type": "shell",
"command": "cd ${workspaceRoot}/bld/debug && ninja && { meson test ${fileBasenameNoExtension} || cat ./meson-logs/testlog.txt }",
"command": "cd ${workspaceRoot}/_bld/debug && ninja && { meson test ${fileBasenameNoExtension} || cat ./meson-logs/testlog.txt }",
"problemMatcher": {
"base": "$gcc",
"fileLocation": [
"relative",
"${workspaceRoot}/bld/debug"
"${workspaceRoot}/_bld/debug"
]
}
}

View File

@ -177,7 +177,7 @@ namespace leaf_detail
BOOST_LEAF_ASSERT(err_id != 0);
auto & sl = std::get<I-1>(tup);
if( sl.has_value(err_id) )
load_slot(err_id, std::move(sl).value(err_id));
(void) load_slot<true>(err_id, std::move(sl).value(err_id));
tuple_for_each<I-1,Tuple>::propagate_captured(tup, err_id);
}

View File

@ -107,6 +107,15 @@ namespace leaf_detail
}
}
BOOST_LEAF_CONSTEXPR T & put( int key )
{
BOOST_LEAF_ASSERT(key);
reset();
(void) new(&value_) T;
key_=key;
return value_;
}
BOOST_LEAF_CONSTEXPR T & put( int key, T const & v )
{
BOOST_LEAF_ASSERT(key);

View File

@ -18,7 +18,7 @@
#if BOOST_LEAF_CFG_DIAGNOSTICS
# include <sstream>
# include <string>
# include <set>
# include <vector>
#endif
#if BOOST_LEAF_CFG_STD_SYSTEM_ERROR
@ -141,33 +141,120 @@ namespace leaf_detail
BOOST_LEAF_CONSTEXPR static void print( std::basic_ostream<CharT, Traits> &, e_unexpected_count const &) noexcept { }
};
template <class E>
class BOOST_LEAF_SYMBOL_VISIBLE slot;
class BOOST_LEAF_SYMBOL_VISIBLE e_unexpected_info
{
std::string s_;
std::set<char const *(*)()> already_;
e_unexpected_info( e_unexpected_info const & ) = delete;
e_unexpected_info & operator=( e_unexpected_info const & ) = delete;
struct slot_base
{
public:
slot_base * next_;
virtual void deactivate() noexcept = 0;
virtual void propagate( int err_id ) noexcept = 0;
virtual std::string print( int key_to_print ) const = 0;
virtual ~slot_base() noexcept { };
protected:
BOOST_LEAF_CONSTEXPR slot_base():
next_(nullptr)
{
}
};
template <class E>
class slot_store: public slot_base, public slot<E>
{
slot_store( slot_store const & ) = delete;
slot_store & operator=( slot_store const & ) = delete;
using sl = slot<E>;
void deactivate() noexcept final override
{
sl::deactivate();
}
void propagate( int err_id ) noexcept final override
{
sl::propagate(err_id);
}
std::string print( int key_to_print ) const final override
{
std::stringstream st;
sl::print(st, key_to_print);
return st.str();
}
public:
template <class T>
BOOST_LEAF_CONSTEXPR slot_store( int err_id, T && e )
{
sl::put(err_id, std::forward<T>(e));
}
};
slot_base * first_;
slot_base * * last_;
public:
e_unexpected_info() noexcept
BOOST_LEAF_CONSTEXPR e_unexpected_info() noexcept:
first_(nullptr),
last_(&first_)
{
}
template <class E>
void add(E && e)
BOOST_LEAF_CONSTEXPR e_unexpected_info( e_unexpected_info && other ) noexcept:
first_(other.first_),
last_(other.last_ == &other.first_? &first_ : other.last_)
{
if( !diagnostic<E>::is_invisible && already_.insert(&type<E>).second )
BOOST_LEAF_ASSERT(last_ != nullptr);
BOOST_LEAF_ASSERT(*last_ == nullptr);
other.first_ = nullptr;
other.last_ = nullptr;
}
~e_unexpected_info() noexcept
{
for( slot_base const * p = first_; p; )
{
std::stringstream s;
diagnostic<E>::print(s,e);
(s << '\n').flush();
s_ += s.str();
slot_base const * n = p -> next_;
delete p;
p = n;
}
}
template <class CharT, class Traits>
void print( std::basic_ostream<CharT, Traits> & os ) const
template <class E>
BOOST_LEAF_CONSTEXPR typename std::decay<E>::type & put(int err_id, E && e)
{
os << "Unhandled error objects:\n" << s_;
using T = typename std::decay<E>::type;
BOOST_LEAF_ASSERT(last_ != nullptr);
BOOST_LEAF_ASSERT(*last_ == nullptr);
BOOST_LEAF_ASSERT(tls::read_ptr<slot<T>>() == nullptr);
slot_store<T> * ss = new slot_store<T>(err_id, std::forward<E>(e));
*last_ = ss;
last_ = &ss->next_;
ss->activate();
return ss->value(err_id);
}
void deactivate() noexcept
{
for( slot_base * p=first_; p; p=p->next_ )
p->deactivate();
}
void propagate( int err_id ) noexcept
{
for( slot_base * p=first_; p; p=p->next_ )
p->propagate(err_id);
}
template <class CharT, class Traits>
void print( std::basic_ostream<CharT, Traits> & os, int key_to_print ) const
{
os << "Unhandled error objects:\n";
for( slot_base const * p=first_; p; p=p->next_ )
os << p->print(key_to_print);
}
};
@ -231,18 +318,18 @@ namespace leaf_detail
BOOST_LEAF_ASSERT(x.prev_==nullptr);
}
BOOST_LEAF_CONSTEXPR void activate() noexcept
void activate() noexcept
{
prev_ = tls::read_ptr<slot<E>>();
tls::write_ptr<slot<E>>(this);
}
BOOST_LEAF_CONSTEXPR void deactivate() noexcept
void deactivate() noexcept
{
tls::write_ptr<slot<E>>(prev_);
}
BOOST_LEAF_CONSTEXPR void propagate( int err_id ) noexcept;
void propagate( int err_id ) noexcept(!BOOST_LEAF_CFG_DIAGNOSTICS);
template <class CharT, class Traits>
void print( std::basic_ostream<CharT, Traits> & os, int key_to_print ) const
@ -274,6 +361,22 @@ namespace leaf_detail
#if BOOST_LEAF_CFG_DIAGNOSTICS
template <>
inline void slot<e_unexpected_info>::deactivate() noexcept
{
if( int const err_id = this->key() )
if( e_unexpected_info * info = this->has_value(err_id) )
info->deactivate();
tls::write_ptr<slot<e_unexpected_info>>(prev_);
}
template <>
inline void slot<e_unexpected_info>::propagate( int err_id ) noexcept(!BOOST_LEAF_CFG_DIAGNOSTICS)
{
if( e_unexpected_info * info = this->has_value(err_id) )
info->propagate(err_id);
}
template <class E>
BOOST_LEAF_CONSTEXPR inline void load_unexpected_count( int err_id ) noexcept
{
@ -292,23 +395,42 @@ namespace leaf_detail
if( slot<e_unexpected_info> * sl = tls::read_ptr<slot<e_unexpected_info>>() )
{
if( e_unexpected_info * unx = sl->has_value(err_id) )
unx->add(std::forward<E>(e));
(void) unx->put(err_id, std::forward<E>(e));
else
sl->put(err_id, e_unexpected_info()).add(std::forward<E>(e));
(void) sl->put(err_id).put(err_id, std::forward<E>(e));
}
}
template <class E, class F>
BOOST_LEAF_CONSTEXPR inline void accumulate_unexpected_info( int err_id, F && f ) noexcept
{
if( slot<e_unexpected_info> * sl = tls::read_ptr<slot<e_unexpected_info>>() )
{
if( e_unexpected_info * unx = sl->has_value(err_id) )
(void) std::forward<F>(f)(unx->put(err_id, E{}));
else
(void) std::forward<F>(f)(sl->put(err_id).put(err_id, E{}));
}
}
template <class E>
BOOST_LEAF_CONSTEXPR inline void load_unexpected( int err_id, E && e ) noexcept
BOOST_LEAF_CONSTEXPR inline void load_unexpected( int err_id, E && e )
{
load_unexpected_count<E>(err_id);
load_unexpected_info(err_id, std::forward<E>(e));
}
template <class E, class F>
BOOST_LEAF_CONSTEXPR inline void accumulate_unexpected( int err_id, F && f )
{
load_unexpected_count<E>(err_id);
accumulate_unexpected_info<E>(err_id, std::forward<F>(f));
}
#endif
template <class E>
BOOST_LEAF_CONSTEXPR inline void slot<E>::propagate( int err_id ) noexcept
inline void slot<E>::propagate( int err_id ) noexcept(!BOOST_LEAF_CFG_DIAGNOSTICS)
{
if( this->key()!=err_id && err_id!=0 )
return;
@ -325,15 +447,18 @@ namespace leaf_detail
#endif
}
template <class E>
BOOST_LEAF_CONSTEXPR inline int load_slot( int err_id, E && e ) noexcept
template <bool OverwriteAllowed, class E>
BOOST_LEAF_CONSTEXPR inline int load_slot( int err_id, E && e ) noexcept(!BOOST_LEAF_CFG_DIAGNOSTICS)
{
static_assert(!std::is_pointer<E>::value, "Error objects of pointer types are not allowed");
static_assert(!std::is_same<typename std::decay<E>::type, error_id>::value, "Error objects of type error_id are not allowed");
using T = typename std::decay<E>::type;
BOOST_LEAF_ASSERT((err_id&3)==1);
if( slot<T> * p = tls::read_ptr<slot<T>>() )
(void) p->put(err_id, std::forward<E>(e));
{
if( OverwriteAllowed || !p->has_value(err_id) )
(void) p->put(err_id, std::forward<E>(e));
}
#if BOOST_LEAF_CFG_DIAGNOSTICS
else
{
@ -347,7 +472,7 @@ namespace leaf_detail
}
template <class F>
BOOST_LEAF_CONSTEXPR inline int accumulate_slot( int err_id, F && f ) noexcept
BOOST_LEAF_CONSTEXPR inline int accumulate_slot( int err_id, F && f )
{
static_assert(function_traits<F>::arity==1, "Lambdas passed to accumulate must take a single e-type argument by reference");
using E = typename std::decay<fn_arg_type<F,0>>::type;
@ -360,6 +485,15 @@ namespace leaf_detail
else
(void) std::forward<F>(f)(sl->put(err_id,E()));
}
#if BOOST_LEAF_CFG_DIAGNOSTICS
else
{
int c = int(tls::read_uint<tls_tag_unexpected_enabled_counter>());
BOOST_LEAF_ASSERT(c>=0);
if( c )
accumulate_unexpected<E>(err_id, std::forward<F>(f));
}
#endif
return 0;
}
}
@ -414,7 +548,7 @@ namespace leaf_detail
{
BOOST_LEAF_CONSTEXPR static int load_( int err_id, E && e ) noexcept
{
return load_slot(err_id, std::forward<E>(e));
return load_slot<true>(err_id, std::forward<E>(e));
}
};
@ -423,7 +557,7 @@ namespace leaf_detail
{
BOOST_LEAF_CONSTEXPR static int load_( int err_id, F && f ) noexcept
{
return load_slot(err_id, std::forward<F>(f)());
return load_slot<true>(err_id, std::forward<F>(f)());
}
};
@ -474,7 +608,7 @@ namespace leaf_detail
else
{
err_id = new_id();
(void) load_slot(err_id, ec);
(void) load_slot<true>(err_id, ec);
return (err_id&~3)|1;
}
}

View File

@ -235,11 +235,12 @@ public:
friend std::basic_ostream<CharT, Traits> & operator<<( std::basic_ostream<CharT, Traits> & os, verbose_diagnostic_info const & x )
{
os << "leaf::verbose_diagnostic_info for ";
int const err_id = x.error().value();
x.print(os);
os << ":\n";
x.print_(os, x.tup_, x.error().value());
x.print_(os, x.tup_, err_id);
if( x.e_ui_ )
x.e_ui_->print(os);
x.e_ui_->print(os, err_id);
return os;
}
};

View File

@ -92,34 +92,18 @@ namespace leaf_detail
class preloaded_item
{
using decay_E = typename std::decay<E>::type;
slot<decay_E> * s_;
decay_E e_;
public:
BOOST_LEAF_CONSTEXPR preloaded_item( E && e ):
s_(tls::read_ptr<slot<decay_E>>()),
e_(std::forward<E>(e))
{
}
BOOST_LEAF_CONSTEXPR void trigger( int err_id ) noexcept
{
BOOST_LEAF_ASSERT((err_id&3)==1);
if( s_ )
{
if( !s_->has_value(err_id) )
s_->put(err_id, std::move(e_));
}
#if BOOST_LEAF_CFG_DIAGNOSTICS
else
{
int c = int(tls::read_uint<tls_tag_unexpected_enabled_counter>());
BOOST_LEAF_ASSERT(c>=0);
if( c )
load_unexpected(err_id, std::move(e_));
}
#endif
(void) load_slot<false>(err_id, std::move(e_));
}
};
@ -127,34 +111,18 @@ namespace leaf_detail
class deferred_item
{
using E = decltype(std::declval<F>()());
slot<E> * s_;
F f_;
public:
BOOST_LEAF_CONSTEXPR deferred_item( F && f ) noexcept:
s_(tls::read_ptr<slot<E>>()),
f_(std::forward<F>(f))
{
}
BOOST_LEAF_CONSTEXPR void trigger( int err_id ) noexcept
{
BOOST_LEAF_ASSERT((err_id&3)==1);
if( s_ )
{
if( !s_->has_value(err_id) )
s_->put(err_id, f_());
}
#if BOOST_LEAF_CFG_DIAGNOSTICS
else
{
int c = int(tls::read_uint<tls_tag_unexpected_enabled_counter>());
BOOST_LEAF_ASSERT(c>=0);
if( c )
load_unexpected(err_id, std::forward<E>(f_()));
}
#endif
(void) load_slot<false>(err_id, f_());
}
};
@ -165,27 +133,18 @@ namespace leaf_detail
class accumulating_item<F, A0 &, 1>
{
using E = A0;
slot<E> * s_;
F f_;
public:
BOOST_LEAF_CONSTEXPR accumulating_item( F && f ) noexcept:
s_(tls::read_ptr<slot<E>>()),
f_(std::forward<F>(f))
{
}
BOOST_LEAF_CONSTEXPR void trigger( int err_id ) noexcept
{
BOOST_LEAF_ASSERT((err_id&3)==1);
if( s_ )
{
if( E * e = s_->has_value(err_id) )
(void) f_(*e);
else
(void) f_(s_->put(err_id, E()));
}
accumulate_slot(err_id, std::move(f_));
}
};

View File

@ -134,8 +134,11 @@ if option_enable_unit_tests
'defer_nested_new_error_result_test',
'defer_nested_success_exception_test',
'defer_nested_success_result_test',
'diagnostic_info_test',
'diagnostic_info_test1',
'diagnostic_info_test2',
'diagnostic_info_test3',
'diagnostic_info_test4',
'diagnostic_info_test5',
'e_errno_test',
'e_LastError_test',
'error_code_test',

View File

@ -25,8 +25,8 @@ project
<define>BOOST_LEAF_BOOST_AVAILABLE
<threading>single:<define>BOOST_LEAF_NO_THREADS
<toolset>gcc:<cxxflags>"-Wno-delete-non-virtual-dtor -Wno-parentheses"
<toolset>clang:<cxxflags>"-Wno-dangling-else"
<toolset>darwin:<cxxflags>"-Wno-unused-variable -Wno-delete-non-virtual-dtor -Wno-non-virtual-dtor -Wno-dangling-else"
<toolset>clang:<cxxflags>"-Wno-unused-variable -Wno-delete-non-virtual-dtor -Wno-non-virtual-dtor -Wno-delete-non-abstract-non-virtual-dtor -Wno-dangling-else"
<toolset>darwin:<cxxflags>"-Wno-unused-variable -Wno-delete-non-virtual-dtor -Wno-non-virtual-dtor -Wno-delete-non-abstract-non-virtual-dtor -Wno-dangling-else"
<toolset>msvc:<cxxflags>"-wd 4267 -wd 4996 -wd 4244"
<include>../../..
;
@ -73,8 +73,11 @@ run defer_nested_new_error_exception_test.cpp ;
run defer_nested_new_error_result_test.cpp ;
run defer_nested_success_exception_test.cpp ;
run defer_nested_success_result_test.cpp ;
run diagnostic_info_test.cpp ;
run diagnostic_info_test1.cpp ;
run diagnostic_info_test2.cpp ;
run diagnostic_info_test3.cpp ;
run diagnostic_info_test4.cpp ;
run diagnostic_info_test5.cpp ;
run e_errno_test.cpp ;
run e_LastError_test.cpp ;
run error_code_test.cpp ;

View File

@ -18,7 +18,7 @@ namespace leaf = boost::leaf;
template <int>
struct info
{
int value;
int value = 0;
};
leaf::error_id g()

View File

@ -15,27 +15,35 @@
namespace leaf = boost::leaf;
template <int>
template <int A>
struct info
{
int value;
info():
value(0)
{
}
explicit info(int value):
value(value)
{
}
};
leaf::error_id f0()
{
auto load = leaf::on_error( []( info<0> & ) { } );
return leaf::new_error( info<2>{2} );
return leaf::new_error( info<2>(2) );
}
leaf::error_id f1()
{
auto load = leaf::on_error( info<0>{-1}, info<2>{-1}, []( info<1> & x ) {++x.value;} );
auto load = leaf::on_error( info<0>(-1), info<2>(-1), []( info<1> & x ) {++x.value;} );
return f0();
}
leaf::error_id f2()
{
return f1().load( info<3>{3} );
return f1().load( info<3>(3) );
}
int main()

View File

@ -33,12 +33,20 @@ template <int A>
struct info
{
int value;
info():
value(0)
{
}
explicit info(int value):
value(value)
{
}
};
void f0()
{
auto load = leaf::on_error( info<0>{-1} );
leaf::throw_exception(info<1>{-1});
auto load = leaf::on_error( info<0>(-1) );
leaf::throw_exception(info<1>(-1));
}
void f1()
@ -57,7 +65,7 @@ leaf::error_id f2()
}
catch( leaf::error_id const & err )
{
err.load( info<3>{3} );
err.load( info<3>(3) );
throw;
}
catch(...)

View File

@ -19,12 +19,20 @@ template <int A>
struct info
{
int value;
info():
value(0)
{
}
explicit info(int value):
value(value)
{
}
};
leaf::error_id f0()
{
auto load = leaf::on_error( info<0>{-1} );
return leaf::new_error( info<1>{-1} );
auto load = leaf::on_error( info<0>(-1) );
return leaf::new_error( info<1>(-1) );
}
leaf::error_id f1()
@ -36,7 +44,7 @@ leaf::error_id f1()
leaf::error_id f2()
{
return f1().load( info<3>{3} );
return f1().load( info<3>(3) );
}
int main()

View File

@ -12,8 +12,12 @@
# include <boost/leaf/common.hpp>
#endif
#if BOOST_LEAF_CFG_STD_STRING
# include <sstream>
#endif
#include <iostream>
#include "lightweight_test.hpp"
#include <sstream>
namespace leaf = boost::leaf;

View File

@ -11,8 +11,12 @@
# include <boost/leaf/result.hpp>
#endif
#if BOOST_LEAF_CFG_STD_STRING
# include <sstream>
#endif
#include <iostream>
#include "lightweight_test.hpp"
#include <sstream>
namespace leaf = boost::leaf;

View File

@ -0,0 +1,58 @@
// Copyright 2018-2022 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)
#ifdef BOOST_LEAF_TEST_SINGLE_HEADER
# include "leaf.hpp"
#else
# include <boost/leaf/config.hpp>
# include <boost/leaf/handle_errors.hpp>
# include <boost/leaf/result.hpp>
#endif
#if BOOST_LEAF_CFG_STD_STRING
# include <sstream>
#endif
#include <iostream>
#include "lightweight_test.hpp"
namespace leaf = boost::leaf;
struct info { int value; };
leaf::result<void> f1()
{
return leaf::new_error(info{41});
}
leaf::result<void> f2()
{
auto load = leaf::on_error(info{42});
return f1();
}
int main()
{
leaf::try_handle_all(
[]() -> leaf::result<void>
{
return f2();
},
[]( leaf::verbose_diagnostic_info const & di )
{
#if BOOST_LEAF_CFG_STD_STRING
std::ostringstream st;
st << di;
std::string s = st.str();
#if BOOST_LEAF_CFG_DIAGNOSTICS
BOOST_TEST_NE(s.find("41"), s.npos);
BOOST_TEST_EQ(s.find("42"), s.npos);
#endif
std::cout << s;
#endif
} );
return boost::report_errors();
}

View File

@ -0,0 +1,73 @@
// Copyright 2018-2022 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)
#ifdef BOOST_LEAF_TEST_SINGLE_HEADER
# include "leaf.hpp"
#else
# include <boost/leaf/config.hpp>
# include <boost/leaf/handle_errors.hpp>
# include <boost/leaf/result.hpp>
#endif
#if BOOST_LEAF_CFG_STD_STRING
# include <sstream>
#endif
#include <iostream>
#include <vector>
#include "lightweight_test.hpp"
namespace leaf = boost::leaf;
struct my_error
{
std::vector<int> vec;
void append(int x)
{
vec.push_back(x);
}
friend std::ostream & operator<<( std::ostream & os, my_error const & x )
{
for( auto const & e : x.vec )
os << "appended: " << e << std::endl;
return os;
}
};
leaf::result<void> f1()
{
auto ctx_ = leaf::on_error([](my_error & e) {e.append(42);});
return leaf::new_error("new_error");
}
leaf::result<void> f2()
{
auto ctx_ = leaf::on_error([](my_error & e) {e.append(43);});
return f1();
}
int main()
{
leaf::try_handle_all([]() -> leaf::result<void>
{
return f2();
},
[](leaf::verbose_diagnostic_info const & e)
{
#if BOOST_LEAF_CFG_STD_STRING
std::ostringstream st;
st << e;
std::string s = st.str();
#if BOOST_LEAF_CFG_DIAGNOSTICS
BOOST_TEST_NE(s.find("new_error"), s.npos);
BOOST_TEST_NE(s.find("appended: 42"), s.npos);
BOOST_TEST_NE(s.find("appended: 43"), s.npos);
#endif
std::cout << s;
#endif
} );
return boost::report_errors();
}

View File

@ -0,0 +1,134 @@
// Copyright 2018-2022 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)
#ifdef BOOST_LEAF_TEST_SINGLE_HEADER
# include "leaf.hpp"
#else
# include <boost/leaf/config.hpp>
# include <boost/leaf/handle_errors.hpp>
# include <boost/leaf/result.hpp>
#endif
#if BOOST_LEAF_CFG_STD_STRING
# include <sstream>
#endif
#include <iostream>
#include "lightweight_test.hpp"
namespace leaf = boost::leaf;
namespace
{
int counter = 0;
}
template <int N>
struct info
{
info(info const &) = delete;
info & operator=(info const &) = delete;
int acc = 0;
info()
{
++counter;
}
info( info && x ):
acc(x.acc)
{
++counter;
}
~info()
{
--counter;
}
void accumulate()
{
++acc;
}
friend std::ostream & operator<<( std::ostream & os, info const & x )
{
return os << "info<" << N << ">: acc=" << x.acc;
}
};
leaf::result<void> f1()
{
return leaf::new_error(info<1>(), [](info<4> & x){ x.accumulate(); });
}
leaf::result<void> f2()
{
auto load = leaf::on_error(info<2>{}, [](){ return info<3>(); }, [](info<4> & x){ x.accumulate(); });
return f1();
}
leaf::result<void> f3()
{
return leaf::try_handle_some(
[]() -> leaf::result<void>
{
return f2();
},
[]( leaf::verbose_diagnostic_info const & e )
{
return e.error();
} );
}
int main()
{
BOOST_TEST_EQ(counter, 0);
leaf::try_handle_all(
[]() -> leaf::result<void>
{
return f3();
},
[]( info<1> const &, leaf::verbose_diagnostic_info const & di )
{
#if BOOST_LEAF_CFG_STD_STRING
std::ostringstream st;
st << di;
std::string s = st.str();
# if BOOST_LEAF_CFG_DIAGNOSTICS
auto const n1 = s.find("info<1>: acc=0");
auto const n2 = s.find("info<2>: acc=0");
auto const n3 = s.find("info<3>: acc=0");
auto const n4 = s.find("info<4>: acc=2");
auto const nd = s.find("Unhandled");
BOOST_TEST_NE(n1, s.npos);
BOOST_TEST_NE(n2, s.npos);
BOOST_TEST_NE(n3, s.npos);
BOOST_TEST_NE(n4, s.npos);
BOOST_TEST_NE(nd, s.npos);
BOOST_TEST_LT(n1, nd);
BOOST_TEST_GT(n2, nd);
BOOST_TEST_GT(n3, nd);
BOOST_TEST_GT(n4, nd);
BOOST_TEST_EQ(counter, 4);
# else
BOOST_TEST_EQ(counter, 1);
# endif
std::cout << s;
#endif
},
[]
{
std::abort();
} );
BOOST_TEST_EQ(counter, 0);
leaf::try_handle_all(
[]() -> leaf::result<void>
{
return f2();
},
[]
{
BOOST_TEST_EQ(counter, 0);
} );
return boost::report_errors();
}