mirror of
https://github.com/boostorg/leaf.git
synced 2025-05-11 21:24:13 +00:00
commit
b7ed6273c1
36
.github/workflows/ci.yml
vendored
36
.github/workflows/ci.yml
vendored
@ -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
2
.gitignore
vendored
@ -7,7 +7,7 @@
|
||||
*.opensdf
|
||||
*.db
|
||||
*.opendb
|
||||
bld/*
|
||||
_bld/*
|
||||
doc/html/*
|
||||
snippets/*
|
||||
subprojects/*/
|
||||
|
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -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
25
.vscode/tasks.json
vendored
@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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_));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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',
|
||||
|
@ -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 ;
|
||||
|
@ -18,7 +18,7 @@ namespace leaf = boost::leaf;
|
||||
template <int>
|
||||
struct info
|
||||
{
|
||||
int value;
|
||||
int value = 0;
|
||||
};
|
||||
|
||||
leaf::error_id g()
|
||||
|
@ -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()
|
||||
|
@ -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(...)
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
58
test/diagnostic_info_test3.cpp
Normal file
58
test/diagnostic_info_test3.cpp
Normal 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();
|
||||
}
|
73
test/diagnostic_info_test4.cpp
Normal file
73
test/diagnostic_info_test4.cpp
Normal 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();
|
||||
}
|
134
test/diagnostic_info_test5.cpp
Normal file
134
test/diagnostic_info_test5.cpp
Normal 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();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user