forked from boostorg/container
- Replaced default standard exception classes with Boost.Container own classes, reducing considerably the included files overhead
This commit is contained in:
@ -1341,6 +1341,11 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
[section:release_notes_boost_1_76_00 Boost 1.76 Release]
|
||||
|
||||
* Added [[no-discard]] attribute in all containers to catch bugs related to unused return values.
|
||||
|
||||
* Replaced default standard exception classes with Boost.Container own classes, reducing considerably the included files overhead.
|
||||
Example: in MSVC 19 `boost/container/vector.hpp` preprocessed file size reduces from 1,5MB to 930KB. If you still want to use
|
||||
standard exception classes, you can define `BOOST_CONTAINER_USE_STD_EXCEPTIONS` before using any Boost.Container class.
|
||||
|
||||
* Fixed bugs/issues:
|
||||
* [@https://github.com/boostorg/container/issues/139 GitHub #139: ['"flat_map merge and iterators"]].
|
||||
* [@https://github.com/boostorg/container/issues/141 GitHub #141: ['"small_vector does not propagate no throw properties of move operation of contained type"]].
|
||||
|
@ -151,4 +151,13 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//Configuration options:
|
||||
|
||||
//Define this to use std exception types instead of boost::container's own exception types
|
||||
//#define BOOST_CONTAINER_USE_STD_EXCEPTIONS
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
||||
|
@ -24,9 +24,102 @@
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
#include <exception> //for std exception base
|
||||
|
||||
# if defined(BOOST_CONTAINER_USE_STD_EXCEPTIONS)
|
||||
#include <stdexcept> //for std exception types
|
||||
#include <string> //for implicit std::string conversion
|
||||
#include <new> //for std::bad_alloc
|
||||
|
||||
typedef std::bad_alloc bad_alloc_t;
|
||||
typedef std::out_of_range out_of_range_t;
|
||||
typedef std::out_of_range length_error_t;
|
||||
typedef std::logic_error logic_error_t;
|
||||
typedef std::runtime_error runtime_error_t;
|
||||
|
||||
# else //!BOOST_CONTAINER_USE_STD_EXCEPTIONS
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
|
||||
class exception
|
||||
: public ::std::exception
|
||||
{
|
||||
typedef ::std::exception std_exception_t;
|
||||
|
||||
public:
|
||||
|
||||
//msg must be a static string (guaranteed by callers)
|
||||
explicit exception(const char *msg)
|
||||
: std_exception_t(), m_msg(msg)
|
||||
{}
|
||||
|
||||
virtual const char *what() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return m_msg ? m_msg : "unknown boost::container exception"; }
|
||||
|
||||
private:
|
||||
const char *m_msg;
|
||||
};
|
||||
|
||||
class bad_alloc
|
||||
: public exception
|
||||
{
|
||||
public:
|
||||
bad_alloc()
|
||||
: exception("boost::container::bad_alloc thrown")
|
||||
{}
|
||||
};
|
||||
|
||||
typedef bad_alloc bad_alloc_t;
|
||||
|
||||
class out_of_range
|
||||
: public exception
|
||||
{
|
||||
public:
|
||||
explicit out_of_range(const char *msg)
|
||||
: exception(msg)
|
||||
{}
|
||||
};
|
||||
|
||||
typedef out_of_range out_of_range_t;
|
||||
|
||||
class length_error
|
||||
: public exception
|
||||
{
|
||||
public:
|
||||
explicit length_error(const char *msg)
|
||||
: exception(msg)
|
||||
{}
|
||||
};
|
||||
|
||||
typedef out_of_range length_error_t;
|
||||
|
||||
class logic_error
|
||||
: public exception
|
||||
{
|
||||
public:
|
||||
explicit logic_error(const char *msg)
|
||||
: exception(msg)
|
||||
{}
|
||||
};
|
||||
|
||||
typedef logic_error logic_error_t;
|
||||
|
||||
class runtime_error
|
||||
: public exception
|
||||
{
|
||||
public:
|
||||
explicit runtime_error(const char *msg)
|
||||
: exception(msg)
|
||||
{}
|
||||
};
|
||||
|
||||
typedef runtime_error runtime_error_t;
|
||||
|
||||
} // namespace boost {
|
||||
} // namespace container {
|
||||
|
||||
# endif
|
||||
#else
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstdlib> //for std::abort
|
||||
@ -99,7 +192,11 @@ namespace container {
|
||||
//! </ul>
|
||||
BOOST_NORETURN inline void throw_bad_alloc()
|
||||
{
|
||||
#ifdef BOOST_CONTAINER_USE_STD_EXCEPTIONS
|
||||
throw std::bad_alloc();
|
||||
#else
|
||||
throw bad_alloc();
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Exception callback called by Boost.Container to signal arguments out of range.
|
||||
@ -115,7 +212,11 @@ namespace container {
|
||||
//! </ul>
|
||||
BOOST_NORETURN inline void throw_out_of_range(const char* str)
|
||||
{
|
||||
#ifdef BOOST_CONTAINER_USE_STD_EXCEPTIONS
|
||||
throw std::out_of_range(str);
|
||||
#else
|
||||
throw out_of_range(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Exception callback called by Boost.Container to signal errors resizing.
|
||||
@ -131,7 +232,11 @@ namespace container {
|
||||
//! </ul>
|
||||
BOOST_NORETURN inline void throw_length_error(const char* str)
|
||||
{
|
||||
#ifdef BOOST_CONTAINER_USE_STD_EXCEPTIONS
|
||||
throw std::length_error(str);
|
||||
#else
|
||||
throw length_error(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Exception callback called by Boost.Container to report errors in the internal logical
|
||||
@ -148,7 +253,11 @@ namespace container {
|
||||
//! </ul>
|
||||
BOOST_NORETURN inline void throw_logic_error(const char* str)
|
||||
{
|
||||
#ifdef BOOST_CONTAINER_USE_STD_EXCEPTIONS
|
||||
throw std::logic_error(str);
|
||||
#else
|
||||
throw logic_error(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Exception callback called by Boost.Container to report errors that can only be detected during runtime.
|
||||
@ -164,7 +273,11 @@ namespace container {
|
||||
//! </ul>
|
||||
BOOST_NORETURN inline void throw_runtime_error(const char* str)
|
||||
{
|
||||
#ifdef BOOST_CONTAINER_USE_STD_EXCEPTIONS
|
||||
throw std::runtime_error(str);
|
||||
#else
|
||||
throw runtime_error(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -52,7 +52,12 @@ struct null_memory_resource_imp
|
||||
void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE
|
||||
{
|
||||
(void)bytes; (void)alignment;
|
||||
#if defined(BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS) || defined(BOOST_NO_EXCEPTIONS)
|
||||
throw_bad_alloc();
|
||||
#else
|
||||
throw std::bad_alloc();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <boost/container/detail/min_max.hpp>
|
||||
#include <boost/intrusive/detail/math.hpp>
|
||||
#include <boost/container/throw_exception.hpp>
|
||||
#include <new>
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
@ -135,8 +136,14 @@ void *monotonic_buffer_resource::allocate_from_current(std::size_t aligner, std:
|
||||
|
||||
void* monotonic_buffer_resource::do_allocate(std::size_t bytes, std::size_t alignment)
|
||||
{
|
||||
if(alignment > memory_resource::max_align)
|
||||
if(alignment > memory_resource::max_align){
|
||||
(void)bytes; (void)alignment;
|
||||
#if defined(BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS) || defined(BOOST_NO_EXCEPTIONS)
|
||||
throw_bad_alloc();
|
||||
#else
|
||||
throw std::bad_alloc();
|
||||
#endif
|
||||
}
|
||||
|
||||
//See if there is room in current buffer
|
||||
std::size_t aligner = 0u;
|
||||
|
@ -1844,7 +1844,7 @@ template <class Devector> void test_at()
|
||||
a.at(0) = T(100);
|
||||
BOOST_TEST(a.at(0) == 100);
|
||||
|
||||
BOOST_TEST_THROWS((void)a.at(3), std::out_of_range);
|
||||
BOOST_TEST_THROWS((void)a.at(3), out_of_range_t);
|
||||
}
|
||||
|
||||
{ // const at
|
||||
@ -1853,7 +1853,7 @@ template <class Devector> void test_at()
|
||||
|
||||
BOOST_TEST(a.at(0) == 1);
|
||||
|
||||
BOOST_TEST_THROWS((void)a.at(3), std::out_of_range);
|
||||
BOOST_TEST_THROWS((void)a.at(3), out_of_range_t);
|
||||
}
|
||||
#endif //#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ void test_throw_on_overflow()
|
||||
BOOST_TRY{
|
||||
v.push_back(0);
|
||||
}
|
||||
BOOST_CATCH(std::bad_alloc&)
|
||||
BOOST_CATCH(bad_alloc_t&)
|
||||
{
|
||||
expected_type_thrown = true;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ void test_ctor_ndc()
|
||||
BOOST_TEST_EQ(s.size() , 0u);
|
||||
BOOST_TEST(s.capacity() == N);
|
||||
BOOST_TEST(s.max_size() == N);
|
||||
BOOST_TEST_THROWS( (void)s.at(0u), std::out_of_range );
|
||||
BOOST_TEST_THROWS( (void)s.at(0u), out_of_range_t);
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
@ -36,7 +36,7 @@ void test_ctor_nc(size_t n)
|
||||
BOOST_TEST(s.size() == n);
|
||||
BOOST_TEST(s.capacity() == N);
|
||||
BOOST_TEST(s.max_size() == N);
|
||||
BOOST_TEST_THROWS( (void)s.at(n), std::out_of_range );
|
||||
BOOST_TEST_THROWS( (void)s.at(n), out_of_range_t);
|
||||
if ( 1 < n )
|
||||
{
|
||||
s[0] = 10;
|
||||
@ -55,7 +55,7 @@ void test_ctor_nd(size_t n, T const& v)
|
||||
BOOST_STATIC_ASSERT((static_vector<T, N>::static_capacity) == N);
|
||||
BOOST_TEST(s.size() == n);
|
||||
BOOST_TEST(s.capacity() == N);
|
||||
BOOST_TEST_THROWS( (void)s.at(n), std::out_of_range );
|
||||
BOOST_TEST_THROWS( (void)s.at(n), out_of_range_t);
|
||||
if ( 1 < n )
|
||||
{
|
||||
BOOST_TEST(v == s[0]);
|
||||
@ -80,7 +80,7 @@ void test_support_for_initializer_list()
|
||||
BOOST_TEST(10 == sv[0]);
|
||||
BOOST_TEST(8 == sv[1]);
|
||||
|
||||
BOOST_TEST_THROWS(sv_cap_2({1, 1, 1}), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(sv_cap_2({1, 1, 1}), bad_alloc_t);
|
||||
}
|
||||
|
||||
{
|
||||
@ -89,10 +89,10 @@ void test_support_for_initializer_list()
|
||||
BOOST_TEST(1 == sv[0]);
|
||||
BOOST_TEST(2 == sv[1]);
|
||||
|
||||
BOOST_TEST_THROWS(sv.assign({1, 2, 3}), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(sv.assign({1, 2, 3}), bad_alloc_t);
|
||||
|
||||
static_vector<int, 3> greaterThanSv = {1, 2, 3};
|
||||
BOOST_TEST_THROWS(sv = greaterThanSv, std::bad_alloc);
|
||||
BOOST_TEST_THROWS(sv = greaterThanSv, bad_alloc_t);
|
||||
}
|
||||
|
||||
{
|
||||
@ -101,7 +101,7 @@ void test_support_for_initializer_list()
|
||||
BOOST_TEST(99 == sv[0]);
|
||||
BOOST_TEST(95 == sv[1]);
|
||||
|
||||
BOOST_TEST_THROWS(sv.insert(sv.begin(), {101, 102, 103}), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(sv.insert(sv.begin(), {101, 102, 103}), bad_alloc_t);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -114,7 +114,7 @@ void test_resize_nc(size_t n)
|
||||
s.resize(n);
|
||||
BOOST_TEST(s.size() == n);
|
||||
BOOST_TEST(s.capacity() == N);
|
||||
BOOST_TEST_THROWS( (void)s.at(n), std::out_of_range );
|
||||
BOOST_TEST_THROWS( (void)s.at(n), out_of_range_t);
|
||||
if ( 1 < n )
|
||||
{
|
||||
s[0] = 10;
|
||||
@ -134,7 +134,7 @@ void test_resize_nd(size_t n, T const& v)
|
||||
s.resize(n, v);
|
||||
BOOST_TEST(s.size() == n);
|
||||
BOOST_TEST(s.capacity() == N);
|
||||
BOOST_TEST_THROWS( (void)s.at(n), std::out_of_range );
|
||||
BOOST_TEST_THROWS( (void)s.at(n), out_of_range_t);
|
||||
if ( 1 < n )
|
||||
{
|
||||
BOOST_TEST(v == s[0]);
|
||||
@ -156,14 +156,14 @@ void test_push_back_nd()
|
||||
static_vector<T, N> s;
|
||||
|
||||
BOOST_TEST(s.size() == 0);
|
||||
BOOST_TEST_THROWS( (void)s.at(0), std::out_of_range );
|
||||
BOOST_TEST_THROWS( (void)s.at(0), out_of_range_t);
|
||||
|
||||
for ( size_t i = 0 ; i < N ; ++i )
|
||||
{
|
||||
T t(static_cast<int>(i));
|
||||
s.push_back(t);
|
||||
BOOST_TEST(s.size() == i + 1);
|
||||
BOOST_TEST_THROWS( (void)s.at(i + 1), std::out_of_range );
|
||||
BOOST_TEST_THROWS( (void)s.at(i + 1), out_of_range_t);
|
||||
BOOST_TEST(T((int)i) == s.at(i));
|
||||
BOOST_TEST(T((int)i) == s[i]);
|
||||
BOOST_TEST(T((int)i) == s.back());
|
||||
@ -187,7 +187,7 @@ void test_pop_back_nd()
|
||||
{
|
||||
s.pop_back();
|
||||
BOOST_TEST(s.size() == i - 1);
|
||||
BOOST_TEST_THROWS( (void)s.at(i - 1), std::out_of_range );
|
||||
BOOST_TEST_THROWS( (void)s.at(i - 1), out_of_range_t);
|
||||
BOOST_TEST(T((int)i - 2) == s.at(i - 2));
|
||||
BOOST_TEST(T((int)i - 2) == s[i - 2]);
|
||||
BOOST_TEST(T((int)i - 2) == s.back());
|
||||
@ -418,17 +418,17 @@ void test_capacity_0_nd()
|
||||
static_vector_0_t s;
|
||||
BOOST_TEST(s.size() == 0);
|
||||
BOOST_TEST(s.capacity() == 0);
|
||||
BOOST_TEST_THROWS((void)s.at(0), std::out_of_range);
|
||||
BOOST_TEST_THROWS(s.resize(5u, T(0)), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s.push_back(T(0)), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s.insert(s.end(), T(0)), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s.insert(s.end(), 5u, T(0)), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s.insert(s.end(), v.begin(), v.end()), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s.assign(v.begin(), v.end()), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s.assign(5u, T(0)), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s.assign(5u, T(0)), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(static_vector_0_t s2(v.begin(), v.end()), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(static_vector_0_t s1(5u, T(0)), std::bad_alloc);
|
||||
BOOST_TEST_THROWS((void)s.at(0), out_of_range_t);
|
||||
BOOST_TEST_THROWS(s.resize(5u, T(0)), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(s.push_back(T(0)), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(s.insert(s.end(), T(0)), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(s.insert(s.end(), 5u, T(0)), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(s.insert(s.end(), v.begin(), v.end()), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(s.assign(v.begin(), v.end()), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(s.assign(5u, T(0)), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(s.assign(5u, T(0)), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(static_vector_0_t s2(v.begin(), v.end()), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(static_vector_0_t s1(5u, T(0)), bad_alloc_t);
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
@ -438,15 +438,15 @@ void test_exceptions_nd()
|
||||
typedef static_vector<T, N/2> static_vector_n_half_t;
|
||||
static_vector_n_half_t s(N/2, T(0));
|
||||
|
||||
BOOST_TEST_THROWS(s.resize(N, T(0)), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s.push_back(T(0)), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s.insert(s.end(), T(0)), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s.insert(s.end(), 1, T(0)), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s.insert(s.end(), v.begin(), v.end()), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s.assign(v.begin(), v.end()), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s.assign(N, T(0)), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(static_vector_n_half_t s2(v.begin(), v.end()), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(static_vector_n_half_t s1(N/2+1, T(0)), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s.resize(N, T(0)), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(s.push_back(T(0)), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(s.insert(s.end(), T(0)), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(s.insert(s.end(), 1, T(0)), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(s.insert(s.end(), v.begin(), v.end()), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(s.assign(v.begin(), v.end()), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(s.assign(N, T(0)), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(static_vector_n_half_t s2(v.begin(), v.end()), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(static_vector_n_half_t s1(N/2+1, T(0)), bad_alloc_t);
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
@ -541,12 +541,12 @@ void test_swap_and_move_nd()
|
||||
typedef static_vector<T, N/2> small_vector_t;
|
||||
static_vector<T, N> v(N, T(0));
|
||||
small_vector_t s(N/2, T(1));
|
||||
BOOST_TEST_THROWS(s.swap(v), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s.swap(v), bad_alloc_t);
|
||||
v.resize(N, T(0));
|
||||
BOOST_TEST_THROWS(s = boost::move(v), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s = v, std::bad_alloc);
|
||||
BOOST_TEST_THROWS(s = boost::move(v), bad_alloc_t);
|
||||
BOOST_TEST_THROWS(s = v, bad_alloc_t);
|
||||
v.resize(N, T(0));
|
||||
BOOST_TEST_THROWS(small_vector_t s2(boost::move(v)), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(small_vector_t s2(boost::move(v)), bad_alloc_t);
|
||||
}
|
||||
}
|
||||
|
||||
@ -560,7 +560,7 @@ void test_emplace_0p()
|
||||
for (int i = 0 ; i < int(N) ; ++i )
|
||||
v.emplace_back();
|
||||
BOOST_TEST(v.size() == N);
|
||||
BOOST_TEST_THROWS(v.emplace_back(), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(v.emplace_back(), bad_alloc_t);
|
||||
}
|
||||
}
|
||||
|
||||
@ -574,7 +574,7 @@ void test_emplace_2p()
|
||||
for (int i = 0 ; i < int(N) ; ++i )
|
||||
v.emplace_back(i, 100 + i);
|
||||
BOOST_TEST(v.size() == N);
|
||||
BOOST_TEST_THROWS(v.emplace_back((int)N, 100 + (int)N), std::bad_alloc);
|
||||
BOOST_TEST_THROWS(v.emplace_back((int)N, 100 + (int)N), bad_alloc_t);
|
||||
BOOST_TEST(v.size() == N);
|
||||
for (int i = 0 ; i < int(N) ; ++i )
|
||||
BOOST_TEST(v[i] == T(i, 100 + i));
|
||||
|
Reference in New Issue
Block a user