Container, Interprocess, Intrusive, Move merge for 1.54

[SVN r84341]
This commit is contained in:
Ion Gaztañaga
2013-05-18 10:40:55 +00:00
parent 14f376128a
commit 53bd56aca1
20 changed files with 3137 additions and 800 deletions

View File

@@ -32,7 +32,10 @@
#include <limits> //numeric_limits<>::max()
#include <new> //placement new
#include <memory> //std::allocator
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/container/detail/preprocessor.hpp>
#endif
///@cond
@@ -211,7 +214,7 @@ struct allocator_traits
//!
//! <b>Throws</b>: Nothing
static void deallocate(Alloc &a, pointer p, size_type n)
{ return a.deallocate(p, n); }
{ a.deallocate(p, n); }
//! <b>Effects</b>: calls `a.allocate(n, p)` if that call is well-formed;
//! otherwise, invokes `a.allocate(n)`
@@ -250,7 +253,19 @@ struct allocator_traits
//! <b>Returns</b>: `a.select_on_container_copy_construction()` if that expression is well-formed;
//! otherwise, a.
static Alloc select_on_container_copy_construction(const Alloc &a)
static
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
typename container_detail::if_c
< boost::container::container_detail::
has_member_function_callable_with_select_on_container_copy_construction
<const Alloc>::value
, Alloc
, const Alloc &
>::type
#else
Alloc
#endif
select_on_container_copy_construction(const Alloc &a)
{
const bool value = boost::container::container_detail::
has_member_function_callable_with_select_on_container_copy_construction
@@ -295,7 +310,7 @@ struct allocator_traits
static Alloc priv_select_on_container_copy_construction(boost::true_type, const Alloc &a)
{ return a.select_on_container_copy_construction(); }
static Alloc priv_select_on_container_copy_construction(boost::false_type, const Alloc &a)
static const Alloc &priv_select_on_container_copy_construction(boost::false_type, const Alloc &a)
{ return a; }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)

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>
@@ -830,11 +830,11 @@ class deque : protected deque_base<T, Allocator>
if (len > size()) {
FwdIt mid = first;
std::advance(mid, this->size());
boost::copy_or_move(first, mid, begin());
boost::container::copy(first, mid, begin());
this->insert(this->cend(), mid, last);
}
else{
this->erase(boost::copy_or_move(first, last, this->begin()), cend());
this->erase(boost::container::copy(first, last, this->begin()), cend());
}
}
#endif
@@ -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)
@@ -1721,11 +1721,11 @@ class deque : protected deque_base<T, Allocator>
this->members_.m_finish = new_finish;
}
else{
pos = this->members_.m_finish - elemsafter;
pos = old_finish - elemsafter;
if (elemsafter >= n) {
iterator finish_n = this->members_.m_finish - difference_type(n);
iterator finish_n = old_finish - difference_type(n);
::boost::container::uninitialized_move_alloc
(this->alloc(), finish_n, this->members_.m_finish, this->members_.m_finish);
(this->alloc(), finish_n, old_finish, old_finish);
this->members_.m_finish = new_finish;
boost::move_backward(pos, finish_n, old_finish);
interf.copy_n_and_update(pos, n);
@@ -1733,25 +1733,17 @@ class deque : protected deque_base<T, Allocator>
else {
const size_type raw_gap = n - elemsafter;
::boost::container::uninitialized_move_alloc
(this->alloc(), pos, old_finish, this->members_.m_finish + raw_gap);
(this->alloc(), pos, old_finish, old_finish + raw_gap);
BOOST_TRY{
interf.copy_n_and_update(pos, elemsafter);
interf.uninitialized_copy_n_and_update(old_finish, raw_gap);
}
BOOST_CATCH(...){
this->priv_destroy_range(this->members_.m_finish, this->members_.m_finish + (old_finish - pos));
this->priv_destroy_range(old_finish, old_finish + elemsafter);
BOOST_RETHROW
}
BOOST_CATCH_END
this->members_.m_finish = new_finish;
interf.copy_n_and_update(pos, elemsafter);
/*
interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
this->members_.m_finish += n-elemsafter;
::boost::container::uninitialized_move_alloc
(this->alloc(), pos, old_finish, this->members_.m_finish);
this->members_.m_finish = new_finish;
interf.copy_remaining_to(pos);
*/
}
}
}
@@ -1840,12 +1832,10 @@ class deque : protected deque_base<T, Allocator>
++cur_node) {
FwdIt mid = first;
std::advance(mid, this->s_buffer_size());
::boost::container::uninitialized_copy_or_move_alloc
(this->alloc(), first, mid, *cur_node);
::boost::container::uninitialized_copy_alloc(this->alloc(), first, mid, *cur_node);
first = mid;
}
::boost::container::uninitialized_copy_or_move_alloc
(this->alloc(), first, last, this->members_.m_finish.m_first);
::boost::container::uninitialized_copy_alloc(this->alloc(), first, last, this->members_.m_finish.m_first);
}
BOOST_CATCH(...){
this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node));

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

@@ -27,6 +27,32 @@
namespace boost { namespace container { namespace container_detail {
template<class A, class FwdIt, class Iterator>
struct move_insert_range_proxy
{
typedef typename allocator_traits<A>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type;
move_insert_range_proxy(A& a, FwdIt first)
: a_(a), first_(first)
{}
void uninitialized_copy_n_and_update(Iterator p, size_type n)
{
this->first_ = ::boost::container::uninitialized_move_alloc_n_source
(this->a_, this->first_, n, p);
}
void copy_n_and_update(Iterator p, size_type n)
{
this->first_ = ::boost::container::move_n_source(this->first_, n, p);
}
A &a_;
FwdIt first_;
};
template<class A, class FwdIt, class Iterator>
struct insert_range_proxy
{
@@ -37,15 +63,14 @@ struct insert_range_proxy
: a_(a), first_(first)
{}
void uninitialized_copy_n_and_update(Iterator pos, size_type n)
void uninitialized_copy_n_and_update(Iterator p, size_type n)
{
this->first_ = ::boost::container::uninitialized_copy_or_move_alloc_n_source
(this->a_, this->first_, n, pos);
this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(this->a_, this->first_, n, p);
}
void copy_n_and_update(Iterator pos, size_type n)
void copy_n_and_update(Iterator p, size_type n)
{
this->first_ = ::boost::container::copy_or_move_n_source(this->first_, n, pos);
this->first_ = ::boost::container::copy_n_source(this->first_, n, p);
}
A &a_;
@@ -63,10 +88,10 @@ struct insert_n_copies_proxy
: a_(a), v_(v)
{}
void uninitialized_copy_n_and_update(Iterator p, size_type n)
{ std::uninitialized_fill_n(p, n, v_); }
void uninitialized_copy_n_and_update(Iterator p, size_type n) const
{ boost::container::uninitialized_fill_alloc_n(this->a_, v_, n, p); }
void copy_n_and_update(Iterator p, size_type n)
void copy_n_and_update(Iterator p, size_type n) const
{ std::fill_n(p, n, v_); }
A &a_;
@@ -85,25 +110,10 @@ struct insert_default_constructed_n_proxy
: a_(a)
{}
void uninitialized_copy_n_and_update(Iterator p, size_type n)
{
Iterator orig_p = p;
size_type n_left = n;
BOOST_TRY{
for(; n_left--; ++p){
alloc_traits::construct(this->a_, container_detail::to_raw_pointer(&*p));
}
}
BOOST_CATCH(...){
for(; orig_p != p; ++orig_p){
alloc_traits::destroy(this->a_, container_detail::to_raw_pointer(&*orig_p++));
}
BOOST_RETHROW
}
BOOST_CATCH_END
}
void uninitialized_copy_n_and_update(Iterator p, size_type n) const
{ boost::container::uninitialized_default_alloc_n(this->a_, n, p); }
void copy_n_and_update(Iterator, size_type)
void copy_n_and_update(Iterator, size_type) const
{
BOOST_ASSERT(false);
}
@@ -123,7 +133,7 @@ struct insert_copy_proxy
: a_(a), v_(v)
{}
void uninitialized_copy_n_and_update(Iterator p, size_type n)
void uninitialized_copy_n_and_update(Iterator p, size_type n) const
{
BOOST_ASSERT(n == 1); (void)n;
alloc_traits::construct( this->a_
@@ -132,7 +142,7 @@ struct insert_copy_proxy
);
}
void copy_n_and_update(Iterator p, size_type n)
void copy_n_and_update(Iterator p, size_type n) const
{
BOOST_ASSERT(n == 1); (void)n;
*p =v_;
@@ -154,7 +164,7 @@ struct insert_move_proxy
: a_(a), v_(v)
{}
void uninitialized_copy_n_and_update(Iterator p, size_type n)
void uninitialized_copy_n_and_update(Iterator p, size_type n) const
{
BOOST_ASSERT(n == 1); (void)n;
alloc_traits::construct( this->a_
@@ -163,7 +173,7 @@ struct insert_move_proxy
);
}
void copy_n_and_update(Iterator p, size_type n)
void copy_n_and_update(Iterator p, size_type n) const
{
BOOST_ASSERT(n == 1); (void)n;
*p = ::boost::move(v_);

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

@@ -33,6 +33,9 @@
#include <boost/container/detail/value_init.hpp>
#include <boost/container/detail/destroyers.hpp>
#include <boost/container/allocator_traits.hpp>
#ifdef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
#include <boost/intrusive/pointer_traits.hpp>
#endif
#include <boost/aligned_storage.hpp>
namespace boost {
@@ -73,10 +76,19 @@ class flat_tree_value_compare
template<class Pointer>
struct get_flat_tree_iterators
{
#ifdef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
typedef Pointer iterator;
typedef typename boost::intrusive::
pointer_traits<Pointer>::element_type iterator_element_type;
typedef typename boost::intrusive::
pointer_traits<Pointer>:: template
rebind_pointer<const iterator_element_type>::type const_iterator;
#else //BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
typedef typename container_detail::
vector_iterator<Pointer> iterator;
typedef typename container_detail::
vector_const_iterator<Pointer> const_iterator;
#endif //BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
};
@@ -145,7 +157,7 @@ class flat_tree
void swap(Data &d)
{
value_compare& mycomp = *this, & othercomp = d;
container_detail::do_swap(mycomp, othercomp);
boost::container::swap_dispatch(mycomp, othercomp);
this->m_vect.swap(d.m_vect);
}
@@ -785,7 +797,7 @@ class flat_tree
const value_compare &value_comp = this->m_data;
commit_data.position = this->priv_lower_bound(b, e, KeyOfValue()(val));
return std::pair<iterator,bool>
( *reinterpret_cast<iterator*>(&commit_data.position)
( iterator(vector_iterator_get_ptr(commit_data.position))
, commit_data.position == e || value_comp(val, *commit_data.position));
}
@@ -813,10 +825,10 @@ class flat_tree
if(pos != this->cbegin() && !value_comp(val, pos[-1])){
if(value_comp(pos[-1], val)){
commit_data.position = pos;
return std::pair<iterator,bool>(*reinterpret_cast<iterator*>(&pos), true);
return std::pair<iterator,bool>(iterator(vector_iterator_get_ptr(pos)), true);
}
else{
return std::pair<iterator,bool>(*reinterpret_cast<iterator*>(&pos), false);
return std::pair<iterator,bool>(iterator(vector_iterator_get_ptr(pos)), false);
}
}
return this->priv_insert_unique_prepare(this->cbegin(), pos, val, commit_data);

View File

@@ -114,7 +114,7 @@ class constant_iterator
const T& operator*() const
{ return dereference(); }
const T& operator[] (Difference n) const
const T& operator[] (Difference ) const
{ return dereference(); }
const T* operator->() const
@@ -335,7 +335,7 @@ class repeat_iterator
T& operator*() const
{ return dereference(); }
T& operator[] (Difference n) const
T& operator[] (Difference ) const
{ return dereference(); }
T *operator->() const

View File

@@ -51,6 +51,12 @@
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS+1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
#include BOOST_PP_ITERATE()
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME swap
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
#include BOOST_PP_ITERATE()
namespace boost {
namespace container {
namespace container_detail {

View File

@@ -208,8 +208,6 @@ class private_node_pool_impl
BOOST_ASSERT(m_allocated==0);
size_type blocksize = get_rounded_size
(m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value);
typename blockslist_t::iterator
it(m_blocklist.begin()), itend(m_blocklist.end()), aux;
//We iterate though the NodeBlock list to free the memory
while(!m_blocklist.empty()){

File diff suppressed because it is too large Load Diff

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

@@ -584,6 +584,7 @@ class scoped_allocator_adaptor_base
typedef OuterAlloc outer_allocator_type;
typedef scoped_allocator_adaptor<InnerAllocs...> inner_allocator_type;
typedef allocator_traits<inner_allocator_type> inner_traits_type;
typedef boost::integral_constant<
bool,
outer_traits_type::propagate_on_container_copy_assignment::value ||
@@ -723,6 +724,7 @@ class scoped_allocator_adaptor_base<OuterAlloc, true
( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \
, BOOST_CONTAINER_PP_IDENTITY, nat) \
> inner_allocator_type; \
typedef allocator_traits<inner_allocator_type> inner_traits_type; \
typedef boost::integral_constant< \
bool, \
outer_traits_type::propagate_on_container_copy_assignment::value || \
@@ -860,6 +862,7 @@ class scoped_allocator_adaptor_base
typedef OuterAlloc outer_allocator_type;
typedef allocator_traits<OuterAlloc> outer_traits_type;
typedef scoped_allocator_adaptor<OuterAlloc> inner_allocator_type;
typedef allocator_traits<inner_allocator_type> inner_traits_type;
typedef typename outer_traits_type::
propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
typedef typename outer_traits_type::
@@ -1029,6 +1032,7 @@ class scoped_allocator_adaptor
//! Type: `scoped_allocator_adaptor<OuterAlloc>` if `sizeof...(InnerAllocs)` is zero; otherwise,
//! `scoped_allocator_adaptor<InnerAllocs...>`.
typedef typename base_type::inner_allocator_type inner_allocator_type;
typedef allocator_traits<inner_allocator_type> inner_traits_type;
typedef typename outer_traits_type::value_type value_type;
typedef typename outer_traits_type::size_type size_type;
typedef typename outer_traits_type::difference_type difference_type;
@@ -1220,7 +1224,7 @@ class scoped_allocator_adaptor
return scoped_allocator_adaptor
(internal_type_t()
,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
,outer_traits_type::select_on_container_copy_construction(this->inner_allocator())
,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
);
}
/// @cond

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>
@@ -169,7 +169,7 @@ class slist_iterator
{ return this->m_it->m_data; }
pointer operator->() const
{ return ::boost::intrusive::pointer_traits<pointer>::to_pointer(this->m_it->m_data); }
{ return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->m_it->m_data); }
//Increment / Decrement
slist_iterator& operator++()

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
@@ -330,7 +333,8 @@ struct index_traits
static void readjust_end_node(index_type &index, node_base_type &end_node)
{
if(!index.empty()){
node_base_ptr &end_node_idx_ref = *(--index_traits::get_fix_up_end(index));
index_iterator end_node_it(index_traits::get_fix_up_end(index));
node_base_ptr &end_node_idx_ref = *(--end_node_it);
end_node_idx_ref = node_base_ptr_traits::pointer_to(end_node);
end_node.up = node_base_ptr_ptr_traits::pointer_to(end_node_idx_ref);
}
@@ -942,7 +946,7 @@ class stable_vector
size_type size() const BOOST_CONTAINER_NOEXCEPT
{
const size_type index_size = this->index.size();
return index_size ? (index_size - ExtraPointers) : 0;
return (index_size - ExtraPointers) & (std::size_t(0u) -std::size_t(index_size != 0));
}
//! <b>Effects</b>: Returns the largest possible size of the stable_vector.
@@ -998,7 +1002,9 @@ class stable_vector
const size_type node_extra_capacity = this->internal_data.pool_size;
const size_type extra_capacity = (bucket_extra_capacity < node_extra_capacity)
? bucket_extra_capacity : node_extra_capacity;
return (index_size ? (index_size - ExtraPointers + extra_capacity) : index_size);
const size_type index_offset =
(ExtraPointers + extra_capacity) & (size_type(0u) - size_type(index_size != 0));
return index_size - index_offset;
}
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
@@ -1010,8 +1016,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();
@@ -1098,7 +1105,7 @@ class stable_vector
//!
//! <b>Complexity</b>: Constant.
reference back() BOOST_CONTAINER_NOEXCEPT
{ return static_cast<node_reference>(*this->index[this->size() - ExtraPointers]).value; }
{ return static_cast<node_reference>(*this->index[this->size()-1u]).value; }
//! <b>Requires</b>: !empty()
//!
@@ -1109,7 +1116,7 @@ class stable_vector
//!
//! <b>Complexity</b>: Constant.
const_reference back() const BOOST_CONTAINER_NOEXCEPT
{ return static_cast<const_node_reference>(*this->index[this->size() - ExtraPointers]).value; }
{ return static_cast<const_node_reference>(*this->index[this->size()-1u]).value; }
//! <b>Requires</b>: size() > n.
//!
@@ -1120,7 +1127,10 @@ class stable_vector
//!
//! <b>Complexity</b>: Constant.
reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT
{ return static_cast<node_reference>(*this->index[n]).value; }
{
BOOST_ASSERT(n < this->size());
return static_cast<node_reference>(*this->index[n]).value;
}
//! <b>Requires</b>: size() > n.
//!
@@ -1131,7 +1141,10 @@ class stable_vector
//!
//! <b>Complexity</b>: Constant.
const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
{ return static_cast<const_node_reference>(*this->index[n]).value; }
{
BOOST_ASSERT(n < this->size());
return static_cast<const_node_reference>(*this->index[n]).value;
}
//! <b>Requires</b>: size() > n.
//!
@@ -1143,8 +1156,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 +1172,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);
}
@@ -1705,7 +1720,7 @@ class stable_vector
void priv_swap_members(stable_vector &x)
{
container_detail::do_swap(this->internal_data.pool_size, x.internal_data.pool_size);
boost::container::swap_dispatch(this->internal_data.pool_size, x.internal_data.pool_size);
index_traits_type::readjust_end_node(this->index, this->internal_data.end_node);
index_traits_type::readjust_end_node(x.index, x.internal_data.end_node);
}

File diff suppressed because it is too large Load Diff

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; }
@@ -432,7 +426,7 @@ class basic_string_base
{
if(this->is_short()){
if(other.is_short()){
container_detail::do_swap(this->members_.m_repr, other.members_.m_repr);
std::swap(this->members_.m_repr, other.members_.m_repr);
}
else{
short_t short_backup(this->members_.m_repr.short_repr());
@@ -453,7 +447,7 @@ class basic_string_base
this->members_.m_repr.short_repr() = short_backup;
}
else{
container_detail::do_swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
boost::container::swap_dispatch(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
}
}
}
@@ -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

File diff suppressed because it is too large Load Diff