[SVN r82429]
This commit is contained in:
Ion Gaztañaga
2013-01-10 10:55:50 +00:00
parent 71e9c48f32
commit 99c8d5d9d7
26 changed files with 487 additions and 96 deletions

View File

@@ -189,6 +189,49 @@ Finally, we can just compile, link, and run!
[endsect]
[section:exception_handling Boost.Container and C++ exceptions]
In some environments, such as game development or embedded systems, C++ exceptions are disabled or a customized error handling is needed.
According to document [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html N2271 EASTL -- Electronic Arts Standard Template Library]
exceptions can be disabled for several reasons:
* ["['Exception handling incurs some kind of cost in all compiler implementations, including those that avoid
the cost during normal execution. However, in some cases this cost may arguably offset the cost of the code that it is replacing.]]
* ["['Exception handling is often agreed to be a superior solution for handling a large range of function return values. However,
avoiding the creation of functions that need large ranges of return values is superior to using exception handling to handle such values.]]
* ["['Using exception handling correctly can be difficult in the case of complex software.]]
* ["['The execution of throw and catch can be significantly expensive with some implementations.]]
* ["['Exception handling violates the don't-pay-for-what-you-don't-use design of C++, as it incurs overhead in any non-leaf function that
has destructible stack objects regardless of whether they use exception handling.]]
* ["['The approach that game software usually takes is to avoid the need for exception handling where possible; avoid the possibility
of circumstances that may lead to exceptions. For example, verify up front that there is enough memory for a subsystem to do its job
instead of trying to deal with the problem via exception handling or any other means after it occurs.]]
* ["['However, some game libraries may nevertheless benefit from the use of exception handling. It's best, however,
if such libraries keep the exception handling internal lest they force their usage of exception handling on the rest of the application.]]
In order to support environments without C++ exception support or environments with special error handling needs,
[*Boost.Container] changes error signalling behaviour when `BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS` or `BOOST_NO_EXCEPTIONS`
is defined. The former shall be defined by the user and the latter can be either defined by the user or implicitly defined by [*Boost.Confg]
when the compiler has been invoked with the appropriate flag (like `-fno-exceptions` in GCC).
When dealing with user-defined classes, (e.g. when constructing user-defined classes):
* If `BOOST_NO_EXCEPTIONS` is defined, the library avoids using `try`/`catch`/`throw` statements. The class writer must handle and
propagate error situations internally as no error will be propagated through [*Boost.Container].
* If `BOOST_NO_EXCEPTIONS` is *not* defined, the library propagates exceptions offering the exception guarantees detailed in the documentation.
When the library needs to throw an exception (such as `out_of_range` when an incorrect index is used in `vector::at`)], the library calls
a throw callback declared in `<boost/container/throw_exception.hpp>`:
* If `BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS` is defined, then the programmer must provide its own definition for all
`throw_xxx` functions. Those functions can't return, they must throw an exception or call `std::exit` or `std::abort`.
* Else if `BOOST_NO_EXCEPTIONS` is defined, a `BOOST_ASSERT_MSG` assertion is triggered
(see [@http://www.boost.org/libs/utility/assert.html Boost.Assert] for more information).
If this assertion returns, then `std::abort` is called.
* Else, an appropriate standard library exception is thrown (like `std::out_of_range`).
[endsect]
[section:non_standard_containers Non-standard containers]
[section:stable_vector ['stable_vector]]
@@ -569,6 +612,8 @@ use [*Boost.Container]? There are several reasons for that:
usually implies a no-throw guarantee (if predicate's or allocator's default constructor doesn't throw).
* Small string optimization for [classref boost::container::basic_string basic_string].
* New extensions beyond the standard based on user feedback to improve code performance.
* You need a portable implementation that works when compiling without exceptions support or
you need to customize the error handling when a container needs to signall an exceptional error.
[endsect]
@@ -614,6 +659,12 @@ use [*Boost.Container]? There are several reasons for that:
[section:release_notes Release Notes]
[section:release_notes_boost_1_54_00 Boost 1.54 Release]
* Support for `BOOST_NO_EXCEPTIONS` [@https://svn.boost.org/trac/boost/ticket/7227 #7227].
[endsect]
[section:release_notes_boost_1_53_00 Boost 1.53 Release]
* Fixed bug [@https://svn.boost.org/trac/boost/ticket/7650 #7650].

View File

@@ -46,12 +46,12 @@
#include <boost/container/detail/mpl.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/throw_exception.hpp>
#include <cstddef>
#include <iterator>
#include <boost/assert.hpp>
#include <memory>
#include <algorithm>
#include <stdexcept>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/type_traits/has_trivial_copy.hpp>
@@ -1575,7 +1575,7 @@ class deque : protected deque_base<T, Allocator>
}
void priv_range_check(size_type n) const
{ if (n >= this->size()) BOOST_RETHROW std::out_of_range("deque"); }
{ if (n >= this->size()) throw_out_of_range("deque::at out of range"); }
template <class U>
iterator priv_insert(const_iterator position, BOOST_FWD_REF(U) x)

View File

@@ -27,6 +27,7 @@
#include <boost/container/detail/math_functions.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/pool_common.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/assert.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <cstddef>
@@ -780,7 +781,7 @@ class private_adaptive_node_pool_impl
//In case of error, free memory deallocating all nodes (the new ones allocated
//in this function plus previously stored nodes in chain).
this->deallocate_nodes(chain);
throw std::bad_alloc();
throw_bad_alloc();
}
block_info_t &c_info = *new(mem_address)block_info_t();
mem_address += HdrSize;
@@ -812,7 +813,7 @@ class private_adaptive_node_pool_impl
//In case of error, free memory deallocating all nodes (the new ones allocated
//in this function plus previously stored nodes in chain).
this->deallocate_nodes(chain);
throw std::bad_alloc();
throw_bad_alloc();
}
//First initialize header information on the last subblock
char *hdr_addr = mem_address + m_real_block_alignment*(m_num_subblocks-1);

View File

@@ -18,13 +18,13 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/allocator_traits.hpp> //allocator_traits
#include <boost/container/throw_exception.hpp>
#include <boost/container/detail/multiallocation_chain.hpp> //multiallocation_chain
#include <boost/container/detail/version_type.hpp> //version_type
#include <boost/container/detail/allocation_type.hpp> //allocation_type
#include <boost/container/detail/mpl.hpp> //integral_constant
#include <boost/intrusive/pointer_traits.hpp> //pointer_traits
#include <utility> //pair
#include <stdexcept> //runtime_error
#include <boost/detail/no_exceptions_support.hpp> //BOOST_TRY
namespace boost {
@@ -135,7 +135,7 @@ struct allocator_version_traits<Allocator, 1>
std::pair<pointer, bool> ret(pointer(), false);
if(!(command & allocate_new)){
if(!(command & nothrow_allocation)){
throw std::runtime_error("version 1 allocator without allocate_new flag");
throw_logic_error("version 1 allocator without allocate_new flag");
}
}
else{

View File

@@ -22,13 +22,14 @@
#include <utility>
#include <functional>
#include <memory>
#include <stdexcept>
#include <boost/container/detail/flat_tree.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/move/utility.hpp>
#include <boost/move/detail/move_helpers.hpp>
#include <boost/detail/no_exceptions_support.hpp>
namespace boost {
namespace container {
@@ -478,7 +479,7 @@ class flat_map
{
iterator i = this->find(k);
if(i == this->end()){
throw std::out_of_range("key not found");
throw_out_of_range("flat_map::at key not found");
}
return i->second;
}
@@ -492,7 +493,7 @@ class flat_map
{
const_iterator i = this->find(k);
if(i == this->end()){
throw std::out_of_range("key not found");
throw_out_of_range("flat_map::at key not found");
}
return i->second;
}

View File

@@ -18,6 +18,7 @@
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/move/utility.hpp>
#include <boost/move/iterator.hpp>
#include <boost/move/detail/move_helpers.hpp>
@@ -36,13 +37,11 @@
#include <boost/container/detail/preprocessor.hpp>
#endif
#include <stdexcept>
#include <iterator>
#include <utility>
#include <memory>
#include <functional>
#include <algorithm>
#include <stdexcept>
namespace boost {
namespace container {

View File

@@ -22,7 +22,6 @@
#include <utility>
#include <functional>
#include <memory>
#include <stdexcept>
#include <boost/container/detail/tree.hpp>
#include <boost/container/detail/value_init.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
@@ -30,10 +29,12 @@
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/pair.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/move/utility.hpp>
#include <boost/move/detail/move_helpers.hpp>
#include <boost/static_assert.hpp>
#include <boost/container/detail/value_init.hpp>
#include <boost/detail/no_exceptions_support.hpp>
namespace boost {
namespace container {
@@ -423,7 +424,7 @@ class map
{
iterator i = this->find(k);
if(i == this->end()){
throw std::out_of_range("key not found");
throw_out_of_range("map::at key not found");
}
return i->second;
}
@@ -435,7 +436,7 @@ class map
{
const_iterator i = this->find(k);
if(i == this->end()){
throw std::out_of_range("key not found");
throw_out_of_range("map::at key not found");
}
return i->second;
}

View File

@@ -19,6 +19,7 @@
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/move/utility.hpp>
#include <boost/move/detail/move_helpers.hpp>
#include <boost/intrusive/pointer_traits.hpp>
@@ -37,7 +38,6 @@
#include <boost/container/detail/preprocessor.hpp>
#endif
#include <stdexcept>
#include <iterator>
#include <utility>
#include <memory>

View File

@@ -1,4 +1,4 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
@@ -29,18 +29,21 @@
#include <boost/mpl/bool.hpp>
#include <boost/mpl/not.hpp>
#include <boost/assert.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/container/detail/allocator_version_traits.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/algorithms.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/aligned_storage.hpp>
#include <boost/move/utility.hpp>
#include <boost/move/iterator.hpp>
#include <boost/move/detail/move_helpers.hpp>
#include <algorithm> //max
#include <stdexcept>
#include <memory>
#include <new> //placement new
@@ -1010,8 +1013,9 @@ class stable_vector
void reserve(size_type n)
{
STABLE_VECTOR_CHECK_INVARIANT;
if(n > this->max_size())
throw std::bad_alloc();
if(n > this->max_size()){
throw_length_error("stable_vector::reserve max_size() exceeded");
}
size_type sz = this->size();
size_type old_capacity = this->capacity();
@@ -1143,8 +1147,9 @@ class stable_vector
//! <b>Complexity</b>: Constant.
reference at(size_type n)
{
if(n>=this->size())
throw std::out_of_range("invalid subscript at stable_vector::at");
if(n >= this->size()){
throw_out_of_range("vector::at invalid subscript");
}
return operator[](n);
}
@@ -1158,8 +1163,9 @@ class stable_vector
//! <b>Complexity</b>: Constant.
const_reference at(size_type n)const
{
if(n>=this->size())
throw std::out_of_range("invalid subscript at stable_vector::at");
if(n >= this->size()){
throw_out_of_range("vector::at invalid subscript");
}
return operator[](n);
}

View File

@@ -38,6 +38,7 @@
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/algorithms.hpp>
@@ -54,8 +55,7 @@
#include <functional>
#include <string>
#include <stdexcept>
#include <utility>
#include <utility>
#include <iterator>
#include <memory>
#include <algorithm>
@@ -335,8 +335,9 @@ class basic_string_base
this->priv_storage(new_cap);
}
}
else
throw_length_error();
else{
throw_length_error("basic_string::allocate_initial_block max_size() exceeded");
}
}
void deallocate_block()
@@ -345,13 +346,6 @@ class basic_string_base
size_type max_size() const
{ return allocator_traits_type::max_size(this->alloc()) - 1; }
// Helper functions for exception handling.
void throw_length_error() const
{ throw(std::length_error("basic_string")); }
void throw_out_of_range() const
{ throw(std::out_of_range("basic_string")); }
protected:
size_type priv_capacity() const
{ return this->priv_storage() - 1; }
@@ -663,7 +657,7 @@ class basic_string
{
this->priv_terminate_string();
if (pos > s.size())
this->throw_out_of_range();
throw_out_of_range("basic_string::basic_string out of range position");
else
this->assign
(s.begin() + pos, s.begin() + pos + container_detail::min_value(n, s.size() - pos));
@@ -991,7 +985,7 @@ class basic_string
void reserve(size_type res_arg)
{
if (res_arg > this->max_size()){
this->throw_length_error();
throw_length_error("basic_string::reserve max_size() exceeded");
}
if (this->capacity() < res_arg){
@@ -1083,7 +1077,7 @@ class basic_string
reference at(size_type n)
{
if (n >= this->size())
this->throw_out_of_range();
throw_out_of_range("basic_string::at invalid subscript");
return *(this->priv_addr() + n);
}
@@ -1097,7 +1091,7 @@ class basic_string
//! <b>Complexity</b>: Constant.
const_reference at(size_type n) const {
if (n >= this->size())
this->throw_out_of_range();
throw_out_of_range("basic_string::at invalid subscript");
return *(this->priv_addr() + n);
}
@@ -1142,7 +1136,7 @@ class basic_string
basic_string& append(const basic_string& s, size_type pos, size_type n)
{
if (pos > s.size())
this->throw_out_of_range();
throw_out_of_range("basic_string::append out of range position");
return this->append(s.begin() + pos,
s.begin() + pos + container_detail::min_value(n, s.size() - pos));
}
@@ -1226,7 +1220,7 @@ class basic_string
basic_string& assign(const basic_string& s, size_type pos, size_type n)
{
if (pos > s.size())
this->throw_out_of_range();
throw_out_of_range("basic_string::assign out of range position");
return this->assign(s.begin() + pos,
s.begin() + pos + container_detail::min_value(n, s.size() - pos));
}
@@ -1296,9 +1290,9 @@ class basic_string
{
const size_type sz = this->size();
if (pos > sz)
this->throw_out_of_range();
throw_out_of_range("basic_string::insert out of range position");
if (sz > this->max_size() - s.size())
this->throw_length_error();
throw_length_error("basic_string::insert max_size() exceeded");
this->insert(this->priv_addr() + pos, s.begin(), s.end());
return *this;
}
@@ -1316,10 +1310,10 @@ class basic_string
const size_type sz = this->size();
const size_type str_size = s.size();
if (pos1 > sz || pos2 > str_size)
this->throw_out_of_range();
throw_out_of_range("basic_string::insert out of range position");
size_type len = container_detail::min_value(n, str_size - pos2);
if (sz > this->max_size() - len)
this->throw_length_error();
throw_length_error("basic_string::insert max_size() exceeded");
const CharT *beg_ptr = container_detail::to_raw_pointer(s.begin()) + pos2;
const CharT *end_ptr = beg_ptr + len;
this->insert(this->priv_addr() + pos1, beg_ptr, end_ptr);
@@ -1340,9 +1334,9 @@ class basic_string
basic_string& insert(size_type pos, const CharT* s, size_type n)
{
if (pos > this->size())
this->throw_out_of_range();
throw_out_of_range("basic_string::insert out of range position");
if (this->size() > this->max_size() - n)
this->throw_length_error();
throw_length_error("basic_string::insert max_size() exceeded");
this->insert(this->priv_addr() + pos, s, s + n);
return *this;
}
@@ -1358,10 +1352,10 @@ class basic_string
basic_string& insert(size_type pos, const CharT* s)
{
if (pos > this->size())
this->throw_out_of_range();
throw_out_of_range("basic_string::insert out of range position");
size_type len = Traits::length(s);
if (this->size() > this->max_size() - len)
this->throw_length_error();
throw_length_error("basic_string::insert max_size() exceeded");
this->insert(this->priv_addr() + pos, s, s + len);
return *this;
}
@@ -1375,9 +1369,9 @@ class basic_string
basic_string& insert(size_type pos, size_type n, CharT c)
{
if (pos > this->size())
this->throw_out_of_range();
throw_out_of_range("basic_string::insert out of range position");
if (this->size() > this->max_size() - n)
this->throw_length_error();
throw_length_error("basic_string::insert max_size() exceeded");
this->insert(const_iterator(this->priv_addr() + pos), n, c);
return *this;
}
@@ -1551,7 +1545,7 @@ class basic_string
basic_string& erase(size_type pos = 0, size_type n = npos)
{
if (pos > this->size())
this->throw_out_of_range();
throw_out_of_range("basic_string::erase out of range position");
const pointer addr = this->priv_addr();
erase(addr + pos, addr + pos + container_detail::min_value(n, this->size() - pos));
return *this;
@@ -1633,10 +1627,10 @@ class basic_string
basic_string& replace(size_type pos1, size_type n1, const basic_string& str)
{
if (pos1 > this->size())
this->throw_out_of_range();
throw_out_of_range("basic_string::replace out of range position");
const size_type len = container_detail::min_value(n1, this->size() - pos1);
if (this->size() - len >= this->max_size() - str.size())
this->throw_length_error();
throw_length_error("basic_string::replace max_size() exceeded");
const pointer addr = this->priv_addr();
return this->replace( const_iterator(addr + pos1)
, const_iterator(addr + pos1 + len)
@@ -1656,11 +1650,11 @@ class basic_string
const basic_string& str, size_type pos2, size_type n2)
{
if (pos1 > this->size() || pos2 > str.size())
this->throw_out_of_range();
throw_out_of_range("basic_string::replace out of range position");
const size_type len1 = container_detail::min_value(n1, this->size() - pos1);
const size_type len2 = container_detail::min_value(n2, str.size() - pos2);
if (this->size() - len1 >= this->max_size() - len2)
this->throw_length_error();
throw_length_error("basic_string::replace max_size() exceeded");
const pointer addr = this->priv_addr();
const pointer straddr = str.priv_addr();
return this->replace(addr + pos1, addr + pos1 + len1,
@@ -1684,10 +1678,10 @@ class basic_string
basic_string& replace(size_type pos1, size_type n1, const CharT* s, size_type n2)
{
if (pos1 > this->size())
this->throw_out_of_range();
throw_out_of_range("basic_string::replace out of range position");
const size_type len = container_detail::min_value(n1, this->size() - pos1);
if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
this->throw_length_error();
throw_length_error("basic_string::replace max_size() exceeded");
const pointer addr = this->priv_addr();
return this->replace(addr + pos1, addr + pos1 + len, s, s + n2);
}
@@ -1709,11 +1703,11 @@ class basic_string
basic_string& replace(size_type pos, size_type n1, const CharT* s)
{
if (pos > this->size())
this->throw_out_of_range();
throw_out_of_range("basic_string::replace out of range position");
const size_type len = container_detail::min_value(n1, this->size() - pos);
const size_type n2 = Traits::length(s);
if (n2 > this->max_size() || this->size() - len >= this->max_size() - n2)
this->throw_length_error();
throw_length_error("basic_string::replace max_size() exceeded");
const pointer addr = this->priv_addr();
return this->replace(addr + pos, addr + pos + len,
s, s + Traits::length(s));
@@ -1730,10 +1724,10 @@ class basic_string
basic_string& replace(size_type pos1, size_type n1, size_type n2, CharT c)
{
if (pos1 > this->size())
this->throw_out_of_range();
throw_out_of_range("basic_string::replace out of range position");
const size_type len = container_detail::min_value(n1, this->size() - pos1);
if (n2 > this->max_size() || this->size() - len >= this->max_size() - n2)
this->throw_length_error();
throw_length_error("basic_string::replace max_size() exceeded");
const pointer addr = this->priv_addr();
return this->replace(addr + pos1, addr + pos1 + len, n2, c);
}
@@ -1858,7 +1852,7 @@ class basic_string
size_type copy(CharT* s, size_type n, size_type pos = 0) const
{
if (pos > this->size())
this->throw_out_of_range();
throw_out_of_range("basic_string::copy out of range position");
const size_type len = container_detail::min_value(n, this->size() - pos);
Traits::copy(s, container_detail::to_raw_pointer(this->priv_addr() + pos), len);
return len;
@@ -2230,7 +2224,7 @@ class basic_string
basic_string substr(size_type pos = 0, size_type n = npos) const
{
if (pos > this->size())
this->throw_out_of_range();
throw_out_of_range("basic_string::substr out of range position");
const pointer addr = this->priv_addr();
return basic_string(addr + pos,
addr + pos + container_detail::min_value(n, size() - pos), this->alloc());
@@ -2263,7 +2257,7 @@ class basic_string
int compare(size_type pos1, size_type n1, const basic_string& str) const
{
if (pos1 > this->size())
this->throw_out_of_range();
throw_out_of_range("basic_string::compare out of range position");
const pointer addr = this->priv_addr();
const pointer str_addr = str.priv_addr();
return s_compare(addr + pos1,
@@ -2282,7 +2276,7 @@ class basic_string
int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2) const
{
if (pos1 > this->size() || pos2 > str.size())
this->throw_out_of_range();
throw_out_of_range("basic_string::compare out of range position");
const pointer addr = this->priv_addr();
const pointer str_addr = str.priv_addr();
return s_compare(addr + pos1,
@@ -2309,7 +2303,7 @@ class basic_string
int compare(size_type pos1, size_type n1, const CharT* s, size_type n2) const
{
if (pos1 > this->size())
this->throw_out_of_range();
throw_out_of_range("basic_string::compare out of range position");
const pointer addr = this->priv_addr();
return s_compare( addr + pos1,
addr + pos1 + container_detail::min_value(n1, this->size() - pos1),

View File

@@ -0,0 +1,110 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2012-2013. 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)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_THROW_EXCEPTION_HPP
#define BOOST_CONTAINER_THROW_EXCEPTION_HPP
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#ifndef BOOST_NO_EXCEPTIONS
#include <stdexcept> //for std exception types
#include <new> //for std::bad_alloc
#else
#include <boost/assert.hpp>
#include <cstdlib> //for std::abort
#endif
namespace boost {
namespace container {
#if defined(BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS)
//The user must provide definitions for the following functions
void throw_bad_alloc();
void throw_out_of_range(const char* str);
void throw_length_error(const char* str);
void throw_logic_error(const char* str);
void throw_runtime_error(const char* str);
#elif defined(BOOST_NO_EXCEPTIONS)
inline void throw_bad_alloc()
{
BOOST_ASSERT(!"boost::container bad_alloc thrown");
std::abort();
}
inline void throw_out_of_range(const char* str)
{
BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str);
std::abort();
}
inline void throw_length_error(const char* str)
{
BOOST_ASSERT_MSG(!"boost::container length_error thrown", str);
std::abort();
}
inline void throw_logic_error(const char* str)
{
BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str);
std::abort();
}
inline void throw_runtime_error(const char* str)
{
BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str);
std::abort();
}
#else //defined(BOOST_NO_EXCEPTIONS)
inline void throw_bad_alloc()
{
throw std::bad_alloc();
}
inline void throw_out_of_range(const char* str)
{
throw std::out_of_range(str);
}
inline void throw_length_error(const char* str)
{
throw std::length_error(str);
}
inline void throw_logic_error(const char* str)
{
throw std::logic_error(str);
}
inline void throw_runtime_error(const char* str)
{
throw std::runtime_error(str);
}
#endif
}} //namespace boost { namespace container {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_THROW_EXCEPTION_HPP

View File

@@ -22,7 +22,6 @@
#include <cstddef>
#include <memory>
#include <algorithm>
#include <stdexcept>
#include <iterator>
#include <utility>
#include <boost/detail/no_exceptions_support.hpp>
@@ -41,6 +40,7 @@
#include <boost/container/detail/destroyers.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/allocator_version_traits.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/move/utility.hpp>
#include <boost/move/iterator.hpp>
#include <boost/move/detail/move_helpers.hpp>
@@ -2038,8 +2038,9 @@ class vector : private container_detail::vector_alloc_holder<Allocator>
void priv_check_range(size_type n) const
{
//If n is out of range, throw an out_of_range exception
if (n >= this->size())
throw std::out_of_range("vector::at");
if (n >= this->size()){
throw_out_of_range("vector::at out of range");
}
}
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS

View File

@@ -55,6 +55,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hash_table_test", "hash_tab
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "throw_exception_test", "throw_exception_test.vcproj", "{5A8D91E0-FA57-284F-84FE-D3A6BA792002}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@@ -119,6 +123,10 @@ Global
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.Build.0 = Release|Win32
{5A8D91E0-FA57-284F-84FE-D3A6BA792002}.Debug.ActiveCfg = Debug|Win32
{5A8D91E0-FA57-284F-84FE-D3A6BA792002}.Debug.Build.0 = Debug|Win32
{5A8D91E0-FA57-284F-84FE-D3A6BA792002}.Release.ActiveCfg = Release|Win32
{5A8D91E0-FA57-284F-84FE-D3A6BA792002}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection

View File

@@ -185,6 +185,9 @@
<File
RelativePath="..\..\..\..\boost\container\allocator_traits.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\container_exceptions.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\container_fwd.hpp">
</File>
@@ -221,6 +224,9 @@
<File
RelativePath="..\..\..\..\boost\container\string.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\throw_exception.hpp">
</File>
<File
RelativePath="..\to-do.txt">
</File>
@@ -260,6 +266,9 @@
<File
RelativePath="..\..\..\..\boost\container\detail\function_detector.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\hash_table.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\iterators.hpp">
</File>

View File

@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="throw_exception_test"
ProjectGUID="{5A8D91E0-FA57-284F-84FE-D3A6BA792002}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/throw_exception_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
ExceptionHandling="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/throw_exception_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/throw_exception_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/throw_exception_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/throw_exception_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{A1735C4B-7AC5-3542-C626-3A2AF6C0D762}">
<File
RelativePath="..\..\test\throw_exception_test.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -22,6 +22,7 @@
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
ExceptionHandling="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"

View File

@@ -29,6 +29,7 @@
#include "emplace_test.hpp"
#include "propagate_allocator_test.hpp"
#include "vector_test.hpp"
#include <boost/detail/no_exceptions_support.hpp>
using namespace boost::container;
@@ -143,7 +144,7 @@ bool do_test()
typedef deque<IntType> MyCntDeque;
typedef std::deque<int> MyStdDeque;
const int max = 100;
try{
BOOST_TRY{
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyCntDeque *cntdeque = new MyCntDeque;
@@ -268,10 +269,13 @@ bool do_test()
delete cntdeque;
delete stddeque;
}
catch(std::exception &ex){
BOOST_CATCH(std::exception &ex){
#ifndef BOOST_NO_EXCEPTIONS
std::cout << ex.what() << std::endl;
#endif
return false;
}
BOOST_CATCH_END
std::cout << std::endl << "Test OK!" << std::endl;
return true;

View File

@@ -26,11 +26,11 @@
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/move/utility.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
#include <stdexcept>
#include <cassert>
//!\file

View File

@@ -19,6 +19,7 @@
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/container/detail/allocation_type.hpp>
#include <boost/assert.hpp>
#include <boost/container/detail/utilities.hpp>
@@ -26,7 +27,6 @@
#include <memory>
#include <algorithm>
#include <cstddef>
#include <stdexcept>
#include <cassert>
//!\file
@@ -146,8 +146,8 @@ class expand_bwd_test_allocator
return std::pair<pointer, bool>(mp_buffer, true);
}
else{
assert(0);
throw std::bad_alloc();
throw_bad_alloc();
return std::pair<pointer, bool>(mp_buffer, true);
}
}

View File

@@ -135,7 +135,7 @@ bool test_insert_with_expand_bwd()
for(int iteration = 0; iteration < Iterations; ++iteration)
{
value_type *memory = new value_type[MemorySize];
try {
BOOST_TRY {
std::vector<non_volatile_value_type> initial_data;
initial_data.resize(InitialSize[iteration]);
for(int i = 0; i < InitialSize[iteration]; ++i){
@@ -165,10 +165,11 @@ bool test_insert_with_expand_bwd()
return false;
}
}
catch(...){
BOOST_CATCH(...){
delete [](const_cast<non_volatile_value_type*>(memory));
throw;
BOOST_RETHROW;
}
BOOST_CATCH_END
delete [](const_cast<non_volatile_value_type*>(memory));
}
@@ -193,7 +194,7 @@ bool test_assign_with_expand_bwd()
for(int iteration = 0; iteration <Iterations; ++iteration)
{
value_type *memory = new value_type[MemorySize];
try {
BOOST_TRY {
//Create initial data
std::vector<non_volatile_value_type> initial_data;
initial_data.resize(InitialSize[iteration]);
@@ -227,10 +228,11 @@ bool test_assign_with_expand_bwd()
return false;
}
}
catch(...){
BOOST_CATCH(...){
delete [](const_cast<typename boost::remove_volatile<value_type>::type*>(memory));
throw;
BOOST_RETHROW;
}
BOOST_CATCH_END
delete [](const_cast<typename boost::remove_volatile<value_type>::type*>(memory));
}

View File

@@ -28,7 +28,6 @@
#include <memory>
#include <algorithm>
#include <cstddef>
#include <stdexcept>
//!\file
//!Describes an heap_allocator_v1 that allocates portions of fixed size

View File

@@ -148,7 +148,7 @@ int list_test (bool copied_allocators_equal = true)
const int max = 100;
typedef list_push_data_function<DoublyLinked> push_data_t;
try{
BOOST_TRY{
MyBoostList *boostlist = new MyBoostList;
MyStdList *stdlist = new MyStdList;
@@ -338,9 +338,10 @@ int list_test (bool copied_allocators_equal = true)
delete boostlist;
delete stdlist;
}
catch(...){
throw;
BOOST_CATCH(...){
BOOST_RETHROW;
}
BOOST_CATCH_END
return 0;
}

View File

@@ -44,7 +44,7 @@ int map_test ()
typedef typename MyStdMap::value_type StdPairType;
const int max = 100;
try{
BOOST_TRY{
MyBoostMap *boostmap = new MyBoostMap;
MyStdMap *stdmap = new MyStdMap;
MyBoostMultiMap *boostmultimap = new MyBoostMultiMap;
@@ -467,9 +467,10 @@ int map_test ()
delete boostmultimap;
delete stdmultimap;
}
catch(...){
throw;
BOOST_CATCH(...){
BOOST_RETHROW;
}
BOOST_CATCH_END
return 0;
}
@@ -485,7 +486,7 @@ int map_test_copyable ()
const int max = 100;
try{
BOOST_TRY{
MyBoostMap *boostmap = new MyBoostMap;
MyStdMap *stdmap = new MyStdMap;
MyBoostMultiMap *boostmultimap = new MyBoostMultiMap;
@@ -537,9 +538,10 @@ int map_test_copyable ()
delete stdmultimap;
}
}
catch(...){
throw;
BOOST_CATCH(...){
BOOST_RETHROW;
}
BOOST_CATCH_END
return 0;
}

View File

@@ -443,7 +443,7 @@ int set_test_copyable ()
typedef typename MyBoostSet::value_type IntType;
const int max = 100;
try{
BOOST_TRY{
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyBoostSet *boostset = new MyBoostSet;
@@ -492,9 +492,10 @@ int set_test_copyable ()
delete boostset;
delete boostmultiset;
}
catch(...){
throw;
BOOST_CATCH(...){
BOOST_RETHROW;
}
BOOST_CATCH_END
return 0;
}

View File

@@ -0,0 +1,62 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2012-2013. 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)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#define BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/detail/lightweight_test.hpp>
using namespace boost::container;
static bool bad_alloc_called = false;
static bool out_of_range_called = false;
static bool length_error_called = false;
static bool logic_error_called = false;
static bool runtime_error_called = false;
//User defined throw implementations
namespace boost {
namespace container {
void throw_bad_alloc()
{ bad_alloc_called = true; }
void throw_out_of_range(const char* str)
{ (void)str; out_of_range_called = true; }
void throw_length_error(const char* str)
{ (void)str; length_error_called = true; }
void throw_logic_error(const char* str)
{ (void)str; logic_error_called = true; }
void throw_runtime_error(const char* str)
{ (void)str; runtime_error_called = true; }
}} //boost::container
int main()
{
//Check user-defined throw callbacks are called
throw_bad_alloc();
BOOST_TEST(bad_alloc_called == true);
throw_out_of_range("dummy");
BOOST_TEST(out_of_range_called == true);
throw_length_error("dummy");
BOOST_TEST(length_error_called == true);
throw_logic_error("dummy");
BOOST_TEST(logic_error_called == true);
throw_runtime_error("dummy");
BOOST_TEST(runtime_error_called == true);
return ::boost::report_errors();
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -30,6 +30,7 @@
#include "input_from_forward_iterator.hpp"
#include <boost/move/utility.hpp>
#include <boost/move/iterator.hpp>
#include <boost/detail/no_exceptions_support.hpp>
namespace boost{
namespace container {
@@ -91,7 +92,7 @@ int vector_test()
const int max = 100;
{
try{
BOOST_TRY{
MyBoostVector *boostvector = new MyBoostVector;
MyStdVector *stdvector = new MyStdVector;
boostvector->resize(100);
@@ -292,10 +293,13 @@ int vector_test()
delete stdvector;
delete boostvector;
}
catch(std::exception &ex){
BOOST_CATCH(std::exception &ex){
#ifndef BOOST_NO_EXCEPTIONS
std::cout << ex.what() << std::endl;
#endif
return 1;
}
BOOST_CATCH_END
}
std::cout << std::endl << "Test OK!" << std::endl;
return 0;