mirror of
https://github.com/boostorg/leaf.git
synced 2026-02-22 15:32:24 +00:00
Refactored on_error behavior in the presence of a dynamic allocator
This commit is contained in:
@@ -224,8 +224,6 @@ namespace detail
|
||||
|
||||
namespace detail
|
||||
{
|
||||
class preloaded_base;
|
||||
|
||||
template <class E>
|
||||
struct capturing_slot_node_allocator;
|
||||
|
||||
@@ -238,8 +236,6 @@ namespace detail
|
||||
template <class>
|
||||
friend struct capturing_slot_node_allocator;
|
||||
|
||||
preloaded_base * preloaded_list_;
|
||||
|
||||
class capturing_node:
|
||||
public capture_list::node
|
||||
{
|
||||
@@ -326,7 +322,6 @@ namespace detail
|
||||
|
||||
dynamic_allocator() noexcept:
|
||||
capture_list(nullptr),
|
||||
preloaded_list_(nullptr),
|
||||
last_(&first_)
|
||||
{
|
||||
BOOST_LEAF_ASSERT(first_ == nullptr);
|
||||
@@ -334,34 +329,14 @@ namespace detail
|
||||
|
||||
dynamic_allocator( dynamic_allocator && other ) noexcept:
|
||||
capture_list(std::move(other)),
|
||||
preloaded_list_(nullptr),
|
||||
last_(other.last_ == &other.first_? &first_ : other.last_)
|
||||
{
|
||||
BOOST_LEAF_ASSERT(last_ != nullptr);
|
||||
BOOST_LEAF_ASSERT(*last_ == nullptr);
|
||||
BOOST_LEAF_ASSERT(other.first_ == nullptr);
|
||||
BOOST_LEAF_ASSERT(other.preloaded_list_ == nullptr);
|
||||
other.last_ = &other.first_;
|
||||
}
|
||||
|
||||
preloaded_base * preloaded_list() const noexcept
|
||||
{
|
||||
return preloaded_list_;
|
||||
}
|
||||
|
||||
preloaded_base * link_preloaded_item(preloaded_base * pb) noexcept
|
||||
{
|
||||
BOOST_LEAF_ASSERT(pb != nullptr);
|
||||
preloaded_base * next = preloaded_list_;
|
||||
preloaded_list_ = pb;
|
||||
return next;
|
||||
}
|
||||
|
||||
void unlink_preloaded_item(preloaded_base * next) noexcept
|
||||
{
|
||||
preloaded_list_ = next;
|
||||
}
|
||||
|
||||
template <class E>
|
||||
slot<E> * alloc()
|
||||
{
|
||||
@@ -606,38 +581,6 @@ namespace detail
|
||||
|
||||
namespace detail
|
||||
{
|
||||
#if BOOST_LEAF_CFG_CAPTURE
|
||||
class preloaded_base
|
||||
{
|
||||
protected:
|
||||
|
||||
preloaded_base() noexcept:
|
||||
next_(
|
||||
[]( preloaded_base * this_ ) -> preloaded_base *
|
||||
{
|
||||
if( dynamic_allocator * da = get_dynamic_allocator() )
|
||||
return da->link_preloaded_item(this_);
|
||||
return nullptr;
|
||||
}(this))
|
||||
{
|
||||
}
|
||||
|
||||
~preloaded_base() noexcept
|
||||
{
|
||||
if( dynamic_allocator * da = get_dynamic_allocator() )
|
||||
da->unlink_preloaded_item(next_);
|
||||
else
|
||||
BOOST_LEAF_ASSERT(next_ == nullptr);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
preloaded_base * const next_;
|
||||
|
||||
virtual void reserve( dynamic_allocator & ) const = 0;
|
||||
};
|
||||
#endif // #if BOOST_LEAF_CFG_CAPTURE
|
||||
|
||||
inline int current_id() noexcept
|
||||
{
|
||||
unsigned id = tls::read_current_error_id();
|
||||
@@ -652,13 +595,8 @@ namespace detail
|
||||
return int(id);
|
||||
}
|
||||
|
||||
inline int start_new_error() noexcept(!BOOST_LEAF_CFG_CAPTURE)
|
||||
inline int start_new_error() noexcept
|
||||
{
|
||||
#if BOOST_LEAF_CFG_CAPTURE
|
||||
if( dynamic_allocator * da = get_dynamic_allocator() )
|
||||
for( preloaded_base const * e = da->preloaded_list(); e; e = e->next_ )
|
||||
e->reserve(*da);
|
||||
#endif
|
||||
return new_id();
|
||||
}
|
||||
|
||||
|
||||
@@ -40,19 +40,7 @@ public:
|
||||
# else
|
||||
if( std::uncaught_exception() )
|
||||
# endif
|
||||
# if BOOST_LEAF_CFG_CAPTURE
|
||||
try
|
||||
{
|
||||
return detail::start_new_error();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
BOOST_LEAF_ASSERT(detail::current_id() == err_id_);
|
||||
return detail::new_id();
|
||||
}
|
||||
# else
|
||||
return detail::start_new_error();
|
||||
# endif
|
||||
return detail::new_id();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -260,9 +248,6 @@ namespace detail
|
||||
|
||||
template <class... Item>
|
||||
class preloaded
|
||||
#if BOOST_LEAF_CFG_CAPTURE
|
||||
: preloaded_base
|
||||
#endif
|
||||
{
|
||||
preloaded( preloaded const & ) = delete;
|
||||
preloaded & operator=( preloaded const & ) = delete;
|
||||
@@ -273,13 +258,6 @@ namespace detail
|
||||
bool moved_ = false;
|
||||
#endif
|
||||
|
||||
#if BOOST_LEAF_CFG_CAPTURE
|
||||
void reserve( dynamic_allocator & da ) const override
|
||||
{
|
||||
tuple_for_each_preload<sizeof...(Item),decltype(p_)>::reserve(p_,da);
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
BOOST_LEAF_CONSTEXPR explicit preloaded( Item && ... i ):
|
||||
@@ -302,8 +280,24 @@ namespace detail
|
||||
if( moved_ )
|
||||
return;
|
||||
#endif
|
||||
if( auto id = id_.check_id() )
|
||||
tuple_for_each_preload<sizeof...(Item),decltype(p_)>::trigger(p_,id);
|
||||
if( int const err_id = id_.check_id() )
|
||||
{
|
||||
#if BOOST_LEAF_CFG_CAPTURE
|
||||
if( dynamic_allocator * da = get_dynamic_allocator() )
|
||||
# ifndef BOOST_LEAF_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
# endif
|
||||
tuple_for_each_preload<sizeof...(Item),decltype(p_)>::reserve(p_, *da);
|
||||
# ifndef BOOST_LEAF_NO_EXCEPTIONS
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
tuple_for_each_preload<sizeof...(Item),decltype(p_)>::trigger(p_, err_id);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -153,7 +153,6 @@ if option_enable_unit_tests
|
||||
'on_error_accumulate_nested_new_error_result_test',
|
||||
'on_error_accumulate_nested_success_exception_test',
|
||||
'on_error_accumulate_nested_success_result_test',
|
||||
'on_error_alloc_fail_test',
|
||||
'on_error_defer_basic_test',
|
||||
'on_error_defer_nested_error_exception_test',
|
||||
'on_error_defer_nested_error_result_test',
|
||||
@@ -162,8 +161,6 @@ if option_enable_unit_tests
|
||||
'on_error_defer_nested_success_exception_test',
|
||||
'on_error_defer_nested_success_result_test',
|
||||
'on_error_dynamic_reserve_test1',
|
||||
'on_error_dynamic_reserve_test2',
|
||||
'on_error_dynamic_reserve_test3',
|
||||
'on_error_preload_basic_test',
|
||||
'on_error_preload_exception_test',
|
||||
'on_error_preload_nested_error_exception_test',
|
||||
|
||||
@@ -98,7 +98,6 @@ run on_error_accumulate_nested_new_error_exception_test.cpp ;
|
||||
run on_error_accumulate_nested_new_error_result_test.cpp ;
|
||||
run on_error_accumulate_nested_success_exception_test.cpp ;
|
||||
run on_error_accumulate_nested_success_result_test.cpp ;
|
||||
run on_error_alloc_fail_test.cpp ;
|
||||
run on_error_defer_basic_test.cpp ;
|
||||
run on_error_defer_nested_error_exception_test.cpp ;
|
||||
run on_error_defer_nested_error_result_test.cpp ;
|
||||
@@ -107,8 +106,6 @@ run on_error_defer_nested_new_error_result_test.cpp ;
|
||||
run on_error_defer_nested_success_exception_test.cpp ;
|
||||
run on_error_defer_nested_success_result_test.cpp ;
|
||||
run on_error_dynamic_reserve_test1.cpp ;
|
||||
run on_error_dynamic_reserve_test2.cpp ;
|
||||
run on_error_dynamic_reserve_test3.cpp ;
|
||||
run on_error_preload_basic_test.cpp ;
|
||||
run on_error_preload_exception_test.cpp ;
|
||||
run on_error_preload_nested_error_exception_test.cpp ;
|
||||
|
||||
@@ -1,239 +0,0 @@
|
||||
// Copyright 2018-2025 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/error.hpp>
|
||||
# include <boost/leaf/on_error.hpp>
|
||||
# include <boost/leaf/handle_errors.hpp>
|
||||
# include <boost/leaf/result.hpp>
|
||||
# include <boost/leaf/diagnostics.hpp>
|
||||
# include <boost/leaf/exception.hpp>
|
||||
#endif
|
||||
|
||||
#if !BOOST_LEAF_CFG_CAPTURE || defined(BOOST_LEAF_NO_EXCEPTIONS)
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace leaf = boost::leaf;
|
||||
|
||||
struct alloc_fail_info
|
||||
{
|
||||
int value;
|
||||
};
|
||||
|
||||
namespace boost { namespace leaf { namespace detail {
|
||||
|
||||
template <>
|
||||
struct capturing_slot_node_allocator<alloc_fail_info>
|
||||
{
|
||||
template <class... A>
|
||||
static dynamic_allocator::capturing_slot_node<alloc_fail_info> * new_( A && ... )
|
||||
{
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
static void delete_( dynamic_allocator::capturing_slot_node<alloc_fail_info> * p ) noexcept
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
};
|
||||
|
||||
} } } // namespace boost::leaf::detail
|
||||
|
||||
#include "lightweight_test.hpp"
|
||||
|
||||
template <int N>
|
||||
struct other_info
|
||||
{
|
||||
int value;
|
||||
};
|
||||
|
||||
leaf::result<void> f()
|
||||
{
|
||||
auto load = leaf::on_error( other_info<1>{1}, alloc_fail_info{42}, other_info<2>{2} );
|
||||
return leaf::new_error();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
auto captured = leaf::try_capture_all(
|
||||
[]() -> leaf::result<void>
|
||||
{
|
||||
return f();
|
||||
} );
|
||||
|
||||
int r = leaf::try_handle_all(
|
||||
[&]() -> leaf::result<int>
|
||||
{
|
||||
(void) captured.value();
|
||||
return 0;
|
||||
},
|
||||
[]( std::bad_alloc const &, other_info<1> const & oi1, other_info<2> const * oi2, alloc_fail_info const * afi )
|
||||
{
|
||||
BOOST_TEST_EQ(oi1.value, 1);
|
||||
BOOST_TEST_EQ(oi2, nullptr);
|
||||
BOOST_TEST_EQ(afi, nullptr);
|
||||
return 1;
|
||||
},
|
||||
[]
|
||||
{
|
||||
return 2;
|
||||
} );
|
||||
BOOST_TEST_EQ(r, 1);
|
||||
}
|
||||
|
||||
#if BOOST_LEAF_CFG_DIAGNOSTICS && BOOST_LEAF_CFG_STD_STRING
|
||||
{
|
||||
int r = leaf::try_handle_all(
|
||||
[]() -> leaf::result<int>
|
||||
{
|
||||
BOOST_LEAF_CHECK(f());
|
||||
return 0;
|
||||
},
|
||||
[]( std::bad_alloc const &, leaf::diagnostic_details const & dd )
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << dd;
|
||||
std::string str = s.str();
|
||||
BOOST_TEST(str.find("other_info<1>") != std::string::npos);
|
||||
BOOST_TEST(str.find("other_info<2>") == std::string::npos);
|
||||
BOOST_TEST(str.find("alloc_fail_info") == std::string::npos);
|
||||
return 1;
|
||||
},
|
||||
[]
|
||||
{
|
||||
return 2;
|
||||
} );
|
||||
BOOST_TEST_EQ(r, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
{
|
||||
auto captured = leaf::try_capture_all(
|
||||
[]() -> leaf::result<void>
|
||||
{
|
||||
auto load = leaf::on_error( other_info<1>{1}, alloc_fail_info{42}, other_info<2>{2} );
|
||||
throw std::runtime_error("test");
|
||||
} );
|
||||
|
||||
int r = leaf::try_handle_all(
|
||||
[&]() -> leaf::result<int>
|
||||
{
|
||||
(void) captured.value();
|
||||
return 0;
|
||||
},
|
||||
[]( other_info<1> const & oi1, other_info<2> const * oi2, alloc_fail_info const * afi )
|
||||
{
|
||||
BOOST_TEST_EQ(oi1.value, 1);
|
||||
BOOST_TEST_EQ(oi2, nullptr);
|
||||
BOOST_TEST_EQ(afi, nullptr);
|
||||
return 1;
|
||||
},
|
||||
[]
|
||||
{
|
||||
return 2;
|
||||
} );
|
||||
BOOST_TEST_EQ(r, 1);
|
||||
}
|
||||
|
||||
#if BOOST_LEAF_CFG_DIAGNOSTICS && BOOST_LEAF_CFG_STD_STRING
|
||||
{
|
||||
int r = leaf::try_catch(
|
||||
[]() -> int
|
||||
{
|
||||
auto load = leaf::on_error( other_info<1>{1}, alloc_fail_info{42}, other_info<2>{2} );
|
||||
throw std::runtime_error("test");
|
||||
},
|
||||
[]( leaf::diagnostic_details const & dd )
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << dd;
|
||||
std::string str = s.str();
|
||||
BOOST_TEST(str.find("other_info<1>") != std::string::npos);
|
||||
BOOST_TEST(str.find("other_info<2>") == std::string::npos);
|
||||
BOOST_TEST(str.find("alloc_fail_info") == std::string::npos);
|
||||
return 1;
|
||||
},
|
||||
[]
|
||||
{
|
||||
return 2;
|
||||
} );
|
||||
BOOST_TEST_EQ(r, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
{
|
||||
auto captured = leaf::try_capture_all(
|
||||
[]() -> leaf::result<void>
|
||||
{
|
||||
auto load = leaf::on_error( other_info<1>{1}, alloc_fail_info{42}, other_info<2>{2} );
|
||||
leaf::throw_exception(std::runtime_error("test"));
|
||||
} );
|
||||
|
||||
int r = leaf::try_handle_all(
|
||||
[&]() -> leaf::result<int>
|
||||
{
|
||||
(void) captured.value();
|
||||
return 0;
|
||||
},
|
||||
[]( std::bad_alloc const &, other_info<1> const & oi1, other_info<2> const * oi2, alloc_fail_info const * afi )
|
||||
{
|
||||
BOOST_TEST_EQ(oi1.value, 1);
|
||||
BOOST_TEST_EQ(oi2, nullptr);
|
||||
BOOST_TEST_EQ(afi, nullptr);
|
||||
return 1;
|
||||
},
|
||||
[]
|
||||
{
|
||||
return 2;
|
||||
} );
|
||||
BOOST_TEST_EQ(r, 1);
|
||||
}
|
||||
|
||||
#if BOOST_LEAF_CFG_DIAGNOSTICS && BOOST_LEAF_CFG_STD_STRING
|
||||
{
|
||||
int r = leaf::try_catch(
|
||||
[]() -> int
|
||||
{
|
||||
auto load = leaf::on_error( other_info<1>{1}, alloc_fail_info{42}, other_info<2>{2} );
|
||||
leaf::throw_exception(std::runtime_error("test"));
|
||||
},
|
||||
[]( std::bad_alloc const &, leaf::diagnostic_details const & dd )
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << dd;
|
||||
std::string str = s.str();
|
||||
BOOST_TEST(str.find("other_info<1>") != std::string::npos);
|
||||
BOOST_TEST(str.find("other_info<2>") == std::string::npos);
|
||||
BOOST_TEST(str.find("alloc_fail_info") == std::string::npos);
|
||||
return 1;
|
||||
},
|
||||
[]
|
||||
{
|
||||
return 2;
|
||||
} );
|
||||
BOOST_TEST_EQ(r, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,58 +0,0 @@
|
||||
// Copyright 2018-2025 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/on_error.hpp>
|
||||
# include <boost/leaf/handle_errors.hpp>
|
||||
# include <boost/leaf/result.hpp>
|
||||
# include <boost/leaf/config/tls.hpp>
|
||||
# include <boost/leaf/diagnostics.hpp>
|
||||
#endif
|
||||
|
||||
#include "lightweight_test.hpp"
|
||||
|
||||
namespace leaf = boost::leaf;
|
||||
|
||||
template <int N>
|
||||
struct info
|
||||
{
|
||||
int value;
|
||||
};
|
||||
|
||||
leaf::result<void> f()
|
||||
{
|
||||
BOOST_TEST_EQ(leaf::tls::read_ptr<leaf::detail::slot<info<42>>>(), nullptr);
|
||||
BOOST_TEST_NE(leaf::tls::read_ptr<leaf::detail::slot<info<43>>>(), nullptr);
|
||||
auto load = leaf::on_error( info<42>{42} );
|
||||
BOOST_TEST_EQ(leaf::tls::read_ptr<leaf::detail::slot<info<42>>>(), nullptr);
|
||||
auto e = leaf::new_error(info<43>{});
|
||||
BOOST_TEST(
|
||||
(BOOST_LEAF_CFG_CAPTURE == 0)
|
||||
==
|
||||
(leaf::tls::read_ptr<leaf::detail::slot<info<42>>>() == nullptr));
|
||||
return e;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int r = leaf::try_handle_all(
|
||||
[]() -> leaf::result<int>
|
||||
{
|
||||
BOOST_LEAF_CHECK(f());
|
||||
return 0;
|
||||
},
|
||||
[]( info<43> const & )
|
||||
{
|
||||
return 1;
|
||||
},
|
||||
[]( leaf::diagnostic_details const & )
|
||||
{
|
||||
return 2;
|
||||
} );
|
||||
BOOST_TEST_EQ(r, 1);
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
// Copyright 2018-2025 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)
|
||||
|
||||
#include <boost/leaf/config.hpp>
|
||||
|
||||
#if !BOOST_LEAF_CFG_CAPTURE
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "Unit test not applicable." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#ifdef BOOST_LEAF_TEST_SINGLE_HEADER
|
||||
# include "leaf.hpp"
|
||||
#else
|
||||
# include <boost/leaf/on_error.hpp>
|
||||
# include <boost/leaf/handle_errors.hpp>
|
||||
# include <boost/leaf/result.hpp>
|
||||
# include <boost/leaf/config/tls.hpp>
|
||||
#endif
|
||||
|
||||
#include "lightweight_test.hpp"
|
||||
|
||||
namespace leaf = boost::leaf;
|
||||
|
||||
template <int N>
|
||||
struct info
|
||||
{
|
||||
int value;
|
||||
};
|
||||
|
||||
leaf::result<void> f()
|
||||
{
|
||||
BOOST_TEST_EQ(leaf::tls::read_ptr<leaf::detail::slot<info<42>>>(), nullptr);
|
||||
BOOST_TEST_NE(leaf::tls::read_ptr<leaf::detail::slot<info<43>>>(), nullptr);
|
||||
auto load = leaf::on_error( info<42>{42} );
|
||||
BOOST_TEST_EQ(leaf::tls::read_ptr<leaf::detail::slot<info<42>>>(), nullptr);
|
||||
auto e = leaf::new_error(info<43>{});
|
||||
BOOST_TEST_NE(leaf::tls::read_ptr<leaf::detail::slot<info<42>>>(), nullptr);
|
||||
return e;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int r = leaf::try_handle_all(
|
||||
[]() -> leaf::result<int>
|
||||
{
|
||||
return leaf::try_capture_all(
|
||||
[]() -> leaf::result<int>
|
||||
{
|
||||
BOOST_LEAF_CHECK(f());
|
||||
return 0;
|
||||
} );
|
||||
},
|
||||
[]( info<43> const & )
|
||||
{
|
||||
return 1;
|
||||
},
|
||||
[]
|
||||
{
|
||||
return 2;
|
||||
} );
|
||||
BOOST_TEST_EQ(r, 1);
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -71,21 +71,6 @@ int main()
|
||||
return leaf::new_error();
|
||||
});
|
||||
|
||||
#if BOOST_LEAF_CFG_CAPTURE
|
||||
(void) leaf::try_capture_all(
|
||||
[]() -> leaf::result<void>
|
||||
{
|
||||
leaf::detail::dynamic_allocator * da = leaf::detail::get_dynamic_allocator();
|
||||
BOOST_TEST_NE(da, nullptr);
|
||||
BOOST_TEST_EQ(da->preloaded_list(), nullptr);
|
||||
{
|
||||
auto load = leaf::on_error( info<42>{42} );
|
||||
BOOST_TEST_NE(da->preloaded_list(), nullptr);
|
||||
}
|
||||
BOOST_TEST_EQ(da->preloaded_list(), nullptr);
|
||||
return { };
|
||||
} );
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user