|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r81663 - in branches/release: boost/container boost/container/detail libs/container libs/container/doc libs/container/example libs/container/proj libs/container/proj/vc7ide libs/container/test
From: igaztanaga_at_[hidden]
Date: 2012-12-01 18:01:52
Author: igaztanaga
Date: 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
New Revision: 81663
URL: http://svn.boost.org/trac/boost/changeset/81663
Log:
Merged container from trunk
Added:
branches/release/boost/container/detail/allocator_version_traits.hpp
- copied unchanged from r81662, /trunk/boost/container/detail/allocator_version_traits.hpp
Properties modified:
branches/release/boost/container/ (props changed)
branches/release/libs/container/ (props changed)
Text files modified:
branches/release/boost/container/allocator_traits.hpp | 22
branches/release/boost/container/deque.hpp | 261 +++++++-------
branches/release/boost/container/detail/adaptive_node_pool_impl.hpp | 714 ++++++++++++++++++++++++++-------------
branches/release/boost/container/detail/advanced_insert_int.hpp | 491 +++++++++++----------------
branches/release/boost/container/detail/destroyers.hpp | 11
branches/release/boost/container/detail/flat_tree.hpp | 72 ++--
branches/release/boost/container/detail/iterators.hpp | 2
branches/release/boost/container/detail/multiallocation_chain.hpp | 132 +++---
branches/release/boost/container/detail/node_alloc_holder.hpp | 101 +++--
branches/release/boost/container/detail/node_pool_impl.hpp | 32
branches/release/boost/container/detail/pair.hpp | 4
branches/release/boost/container/detail/pool_common.hpp | 2
branches/release/boost/container/detail/preprocessor.hpp | 42 +-
branches/release/boost/container/detail/tree.hpp | 19
branches/release/boost/container/detail/type_traits.hpp | 4
branches/release/boost/container/detail/utilities.hpp | 369 +++++++++++++++++++-
branches/release/boost/container/detail/workaround.hpp | 12
branches/release/boost/container/flat_map.hpp | 108 +++---
branches/release/boost/container/flat_set.hpp | 106 ++--
branches/release/boost/container/list.hpp | 177 ++++-----
branches/release/boost/container/map.hpp | 108 +++---
branches/release/boost/container/scoped_allocator.hpp | 104 +++--
branches/release/boost/container/scoped_allocator_fwd.hpp | 6
branches/release/boost/container/set.hpp | 22
branches/release/boost/container/slist.hpp | 172 ++++-----
branches/release/boost/container/stable_vector.hpp | 253 +++++--------
branches/release/boost/container/string.hpp | 403 ++++++++++-----------
branches/release/boost/container/vector.hpp | 425 +++++++++++-----------
branches/release/libs/container/doc/container.qbk | 10
branches/release/libs/container/example/doc_move_containers.cpp | 2
branches/release/libs/container/proj/to-do.txt | 99 -----
branches/release/libs/container/proj/vc7ide/container.vcproj | 3
branches/release/libs/container/test/allocator_traits_test.cpp | 2
branches/release/libs/container/test/deque_test.cpp | 12
branches/release/libs/container/test/dummy_test_allocator.hpp | 12
branches/release/libs/container/test/emplace_test.hpp | 247 +++++++++----
branches/release/libs/container/test/expand_bwd_test_allocator.hpp | 7
branches/release/libs/container/test/flat_tree_test.cpp | 74 ++++
branches/release/libs/container/test/list_test.hpp | 3
branches/release/libs/container/test/map_test.hpp | 25
branches/release/libs/container/test/movable_int.hpp | 3
branches/release/libs/container/test/scoped_allocator_adaptor_test.cpp | 2
branches/release/libs/container/test/scoped_allocator_usage_test.cpp | 2
branches/release/libs/container/test/set_test.hpp | 82 ++--
branches/release/libs/container/test/string_test.cpp | 3
branches/release/libs/container/test/vector_test.cpp | 9
branches/release/libs/container/test/vector_test.hpp | 4
47 files changed, 2634 insertions(+), 2141 deletions(-)
Modified: branches/release/boost/container/allocator_traits.hpp
==============================================================================
--- branches/release/boost/container/allocator_traits.hpp (original)
+++ branches/release/boost/container/allocator_traits.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -28,7 +28,7 @@
#include <boost/container/detail/memory_util.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/container/detail/mpl.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include <limits> //numeric_limits<>::max()
#include <new> //placement new
#include <memory> //std::allocator
@@ -165,22 +165,22 @@
propagate_on_container_swap, boost::false_type)
propagate_on_container_swap;
- #if !defined(BOOST_NO_TEMPLATE_ALIASES)
+ #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
//C++11
template <typename T> using rebind_alloc = typename boost::intrusive::detail::type_rebinder<Alloc, T>::type;
template <typename T> using rebind_traits = allocator_traits< rebind_alloc<T> >;
- #else // #if !defined(BOOST_NO_TEMPLATE_ALIASES)
+ #else // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
//Some workaround for C++03 or C++11 compilers with no template aliases
template <typename T>
struct rebind_alloc : boost::intrusive::detail::type_rebinder<Alloc,T>::type
{
typedef typename boost::intrusive::detail::type_rebinder<Alloc,T>::type Base;
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename... Args>
rebind_alloc(BOOST_FWD_REF(Args)... args)
: Base(boost::forward<Args>(args)...)
{}
- #else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
rebind_alloc(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
@@ -189,14 +189,14 @@
//
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
- #endif // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
};
template <typename T>
struct rebind_traits
: allocator_traits<typename boost::intrusive::detail::type_rebinder<Alloc, T>::type>
{};
- #endif // #if !defined(BOOST_NO_TEMPLATE_ALIASES)
+ #endif // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class T>
struct portable_rebind_alloc
{ typedef typename boost::intrusive::detail::type_rebinder<Alloc, T>::type type; };
@@ -259,7 +259,7 @@
return allocator_traits::priv_select_on_container_copy_construction(flag, a);
}
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: calls `a.construct(p, std::forward<Args>(args)...)` if that call is well-formed;
//! otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)`
template <class T, class ...Args>
@@ -298,7 +298,7 @@
static Alloc priv_select_on_container_copy_construction(boost::false_type, const Alloc &a)
{ return a; }
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T, class ...Args>
static void priv_construct(boost::false_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)
{
@@ -322,7 +322,7 @@
template<class T, class ...Args>
static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p, BOOST_FWD_REF(Args) ...args)
{ ::new((void*)p) T(::boost::forward<Args>(args)...); }
- #else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
public:
#define BOOST_PP_LOCAL_MACRO(n) \
template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
@@ -371,7 +371,7 @@
//
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
- #endif // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
///@endcond
Modified: branches/release/boost/container/deque.hpp
==============================================================================
--- branches/release/boost/container/deque.hpp (original)
+++ branches/release/boost/container/deque.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -58,9 +58,11 @@
#include <boost/type_traits/has_trivial_assign.hpp>
#include <boost/type_traits/has_nothrow_copy.hpp>
#include <boost/type_traits/has_nothrow_assign.hpp>
-#include <boost/move/move.hpp>
-#include <boost/move/move_helpers.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/detail/move_helpers.hpp>
#include <boost/container/detail/advanced_insert_int.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
namespace boost {
namespace container {
@@ -79,8 +81,7 @@
typedef T value_type;
typedef Allocator allocator_type;
static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
- static const bool trivial_dctr_after_move = false;
- //::boost::has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
+ static const bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move<value_type>::value;
static const bool trivial_copy = has_trivial_copy<value_type>::value;
static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
static const bool trivial_assign = has_trivial_assign<value_type>::value;
@@ -304,7 +305,7 @@
{
this->m_node = new_node;
this->m_first = *new_node;
- this->m_last = this->m_first + difference_type(this->s_buffer_size());
+ this->m_last = this->m_first + this->s_buffer_size();
}
friend const_iterator operator+(difference_type n, const const_iterator& x)
@@ -565,9 +566,6 @@
typedef typename Base::ptr_alloc_ptr index_pointer;
static size_type s_buffer_size()
{ return Base::s_buffer_size(); }
- typedef container_detail::advanced_insert_aux_int<iterator> advanced_insert_aux_int_t;
- typedef repeat_iterator<T, difference_type> r_iterator;
- typedef boost::move_iterator<r_iterator> move_it;
typedef allocator_traits<Allocator> allocator_traits_type;
/// @endcond
@@ -590,10 +588,10 @@
//! <b>Effects</b>: Constructs a deque taking the allocator as parameter.
//!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
- explicit deque(const allocator_type& a)
+ explicit deque(const allocator_type& a) BOOST_CONTAINER_NOEXCEPT
: Base(a)
{}
@@ -607,8 +605,8 @@
explicit deque(size_type n)
: Base(n, allocator_type())
{
- container_detail::default_construct_aux_proxy<Allocator, iterator> proxy(this->alloc(), n);
- proxy.uninitialized_copy_remaining_to(this->begin());
+ container_detail::insert_default_constructed_n_proxy<Allocator, iterator> proxy(this->alloc());
+ proxy.uninitialized_copy_n_and_update(this->begin(), n);
//deque_base will deallocate in case of exception...
}
@@ -717,7 +715,7 @@
//! <b>Complexity</b>: Linear to the number of elements.
~deque() BOOST_CONTAINER_NOEXCEPT
{
- priv_destroy_range(this->members_.m_start, this->members_.m_finish);
+ this->priv_destroy_range(this->members_.m_start, this->members_.m_finish);
}
//! <b>Effects</b>: Makes *this contain the same elements as x.
@@ -1020,7 +1018,7 @@
this->priv_erase_last_n(len - new_size);
else{
const size_type n = new_size - this->size();
- container_detail::default_construct_aux_proxy<Allocator, iterator> proxy(this->alloc(), n);
+ container_detail::insert_default_constructed_n_proxy<Allocator, iterator> proxy(this->alloc());
priv_insert_back_aux_impl(n, proxy);
}
}
@@ -1176,9 +1174,8 @@
this->priv_push_front_simple_commit();
}
else{
- typedef container_detail::advanced_insert_aux_non_movable_emplace<Allocator, iterator, Args...> type;
- type &&proxy = type(this->alloc(), boost::forward<Args>(args)...);
- this->priv_insert_front_aux_impl(1, proxy);
+ typedef container_detail::insert_non_movable_emplace_proxy<Allocator, iterator, Args...> type;
+ this->priv_insert_front_aux_impl(1, type(this->alloc(), boost::forward<Args>(args)...));
}
}
@@ -1199,9 +1196,8 @@
this->priv_push_back_simple_commit();
}
else{
- typedef container_detail::advanced_insert_aux_non_movable_emplace<Allocator, iterator, Args...> type;
- type &&proxy = type(this->alloc(), boost::forward<Args>(args)...);
- this->priv_insert_back_aux_impl(1, proxy);
+ typedef container_detail::insert_non_movable_emplace_proxy<Allocator, iterator, Args...> type;
+ this->priv_insert_back_aux_impl(1, type(this->alloc(), boost::forward<Args>(args)...));
}
}
@@ -1226,9 +1222,8 @@
return (this->end()-1);
}
else{
- typedef container_detail::advanced_insert_aux_emplace<Allocator, iterator, Args...> type;
- type &&proxy = type(this->alloc(), boost::forward<Args>(args)...);
- return this->priv_insert_aux_impl(p, 1, proxy);
+ typedef container_detail::insert_emplace_proxy<Allocator, iterator, Args...> type;
+ return this->priv_insert_aux_impl(p, 1, type(this->alloc(), boost::forward<Args>(args)...));
}
}
@@ -1247,9 +1242,8 @@
priv_push_front_simple_commit(); \
} \
else{ \
- container_detail::BOOST_PP_CAT(BOOST_PP_CAT \
- (advanced_insert_aux_non_movable_emplace, n), arg) \
- <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
+ container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
+ <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
priv_insert_front_aux_impl(1, proxy); \
} \
@@ -1266,9 +1260,8 @@
priv_push_back_simple_commit(); \
} \
else{ \
- container_detail::BOOST_PP_CAT(BOOST_PP_CAT( \
- advanced_insert_aux_non_movable_emplace, n), arg) \
- <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
+ container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
+ <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
priv_insert_back_aux_impl(1, proxy); \
} \
@@ -1287,8 +1280,8 @@
return (this->end()-1); \
} \
else{ \
- container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
- <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
+ container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
+ <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
return this->priv_insert_aux_impl(p, 1, proxy); \
} \
@@ -1424,7 +1417,7 @@
#endif
)
{
- container_detail::advanced_insert_aux_proxy<Allocator, FwdIt, iterator> proxy(this->alloc(), first, last);
+ container_detail::insert_range_proxy<Allocator, FwdIt, iterator> proxy(this->alloc(), first);
return priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy);
}
#endif
@@ -1477,8 +1470,8 @@
{
const_iterator next = pos;
++next;
- difference_type index = pos - this->members_.m_start;
- if (size_type(index) < (this->size() >> 1)) {
+ size_type index = pos - this->members_.m_start;
+ if (index < (this->size()/2)) {
boost::move_backward(begin(), iterator(pos), iterator(next));
pop_front();
}
@@ -1504,9 +1497,9 @@
return this->members_.m_finish;
}
else {
- difference_type n = last - first;
- difference_type elems_before = first - this->members_.m_start;
- if (elems_before < static_cast<difference_type>(this->size() - n) - elems_before) {
+ const size_type n = static_cast<size_type>(last - first);
+ const size_type elems_before = static_cast<size_type>(first - this->members_.m_start);
+ if (elems_before < (this->size() - n) - elems_before) {
boost::move_backward(begin(), iterator(first), iterator(last));
iterator new_start = this->members_.m_start + n;
if(!Base::traits_t::trivial_dctr_after_move)
@@ -1584,81 +1577,49 @@
void priv_range_check(size_type n) const
{ if (n >= this->size()) BOOST_RETHROW std::out_of_range("deque"); }
- iterator priv_insert(const_iterator position, const value_type &x)
+ template <class U>
+ iterator priv_insert(const_iterator position, BOOST_FWD_REF(U) x)
{
if (position == cbegin()){
- this->push_front(x);
+ this->push_front(::boost::forward<U>(x));
return begin();
}
else if (position == cend()){
- this->push_back(x);
- return (end()-1);
- }
- else {
- return this->insert(position, size_type(1), x);
- }
- }
-
- iterator priv_insert(const_iterator position, BOOST_RV_REF(value_type) mx)
- {
- if (position == cbegin()) {
- this->push_front(boost::move(mx));
- return begin();
- }
- else if (position == cend()) {
- this->push_back(boost::move(mx));
- return(end()-1);
+ this->push_back(::boost::forward<U>(x));
+ return --end();
}
else {
- return this->insert(position, move_it(r_iterator(mx, 1)), move_it(r_iterator()));
- }
- }
-
- void priv_push_front(const value_type &t)
- {
- if(this->priv_push_front_simple_available()){
- allocator_traits_type::construct
- ( this->alloc(), this->priv_push_front_simple_pos(), t);
- this->priv_push_front_simple_commit();
- }
- else{
- this->insert(cbegin(), size_type(1), t);
+ return priv_insert_aux_impl
+ (position, (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
}
}
- void priv_push_front(BOOST_RV_REF(value_type) t)
+ template <class U>
+ void priv_push_front(BOOST_FWD_REF(U) x)
{
if(this->priv_push_front_simple_available()){
allocator_traits_type::construct
- ( this->alloc(), this->priv_push_front_simple_pos(), boost::move(t));
+ ( this->alloc(), this->priv_push_front_simple_pos(), ::boost::forward<U>(x));
this->priv_push_front_simple_commit();
}
else{
- this->insert(cbegin(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
+ priv_insert_aux_impl
+ (this->cbegin(), (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
}
}
- void priv_push_back(const value_type &t)
+ template <class U>
+ void priv_push_back(BOOST_FWD_REF(U) x)
{
if(this->priv_push_back_simple_available()){
allocator_traits_type::construct
- ( this->alloc(), this->priv_push_back_simple_pos(), t);
+ ( this->alloc(), this->priv_push_back_simple_pos(), ::boost::forward<U>(x));
this->priv_push_back_simple_commit();
}
else{
- this->insert(cend(), size_type(1), t);
- }
- }
-
- void priv_push_back(BOOST_RV_REF(T) t)
- {
- if(this->priv_push_back_simple_available()){
- allocator_traits_type::construct
- ( this->alloc(), this->priv_push_back_simple_pos(), boost::move(t));
- this->priv_push_back_simple_commit();
- }
- else{
- this->insert(cend(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
+ priv_insert_aux_impl
+ (this->cend(), (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
+ container_detail::insert_copy_proxy<Allocator, iterator> proxy(this->alloc(), x);
}
}
@@ -1710,7 +1671,8 @@
}
}
- iterator priv_insert_aux_impl(const_iterator p, size_type n, advanced_insert_aux_int_t &interf)
+ template<class InsertProxy>
+ iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy interf)
{
iterator pos(p);
const size_type pos_n = p - this->cbegin();
@@ -1719,58 +1681,85 @@
pos = this->begin();
}
- const difference_type elemsbefore = pos - this->members_.m_start;
- size_type length = this->size();
- if (elemsbefore < static_cast<difference_type>(length / 2)) {
- iterator new_start = this->priv_reserve_elements_at_front(n);
- iterator old_start = this->members_.m_start;
- pos = this->members_.m_start + elemsbefore;
- if (elemsbefore >= difference_type(n)) {
- iterator start_n = this->members_.m_start + difference_type(n);
- ::boost::container::uninitialized_move_alloc
- (this->alloc(), this->members_.m_start, start_n, new_start);
+ const size_type elemsbefore = static_cast<size_type>(pos - this->members_.m_start);
+ const size_type length = this->size();
+ if (elemsbefore < length / 2) {
+ const iterator new_start = this->priv_reserve_elements_at_front(n);
+ const iterator old_start = this->members_.m_start;
+ if(!elemsbefore){
+ interf.uninitialized_copy_n_and_update(new_start, n);
this->members_.m_start = new_start;
- boost::move(start_n, pos, old_start);
- interf.copy_remaining_to(pos - difference_type(n));
}
- else {
- difference_type mid_count = (difference_type(n) - elemsbefore);
- iterator mid_start = old_start - mid_count;
- interf.uninitialized_copy_some_and_update(mid_start, mid_count, true);
- this->members_.m_start = mid_start;
- ::boost::container::uninitialized_move_alloc
- (this->alloc(), old_start, pos, new_start);
- this->members_.m_start = new_start;
- interf.copy_remaining_to(old_start);
+ else{
+ pos = this->members_.m_start + elemsbefore;
+ if (elemsbefore >= n) {
+ const iterator start_n = this->members_.m_start + n;
+ ::boost::container::uninitialized_move_alloc
+ (this->alloc(), this->members_.m_start, start_n, new_start);
+ this->members_.m_start = new_start;
+ boost::move(start_n, pos, old_start);
+ interf.copy_n_and_update(pos - n, n);
+ }
+ else {
+ const size_type mid_count = n - elemsbefore;
+ const iterator mid_start = old_start - mid_count;
+ interf.uninitialized_copy_n_and_update(mid_start, mid_count);
+ this->members_.m_start = mid_start;
+ ::boost::container::uninitialized_move_alloc
+ (this->alloc(), old_start, pos, new_start);
+ this->members_.m_start = new_start;
+ interf.copy_n_and_update(old_start, elemsbefore);
+ }
}
}
else {
- iterator new_finish = this->priv_reserve_elements_at_back(n);
- iterator old_finish = this->members_.m_finish;
- const difference_type elemsafter =
- difference_type(length) - elemsbefore;
- pos = this->members_.m_finish - elemsafter;
- if (elemsafter >= difference_type(n)) {
- iterator finish_n = this->members_.m_finish - difference_type(n);
- ::boost::container::uninitialized_move_alloc
- (this->alloc(), finish_n, this->members_.m_finish, this->members_.m_finish);
+ const iterator new_finish = this->priv_reserve_elements_at_back(n);
+ const iterator old_finish = this->members_.m_finish;
+ const size_type elemsafter = length - elemsbefore;
+ if(!elemsafter){
+ interf.uninitialized_copy_n_and_update(old_finish, n);
this->members_.m_finish = new_finish;
- boost::move_backward(pos, finish_n, old_finish);
- interf.copy_remaining_to(pos);
}
- else {
- 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);
+ else{
+ pos = this->members_.m_finish - elemsafter;
+ if (elemsafter >= n) {
+ iterator finish_n = this->members_.m_finish - difference_type(n);
+ ::boost::container::uninitialized_move_alloc
+ (this->alloc(), finish_n, this->members_.m_finish, this->members_.m_finish);
+ this->members_.m_finish = new_finish;
+ boost::move_backward(pos, finish_n, old_finish);
+ interf.copy_n_and_update(pos, n);
+ }
+ else {
+ const size_type raw_gap = n - elemsafter;
+ ::boost::container::uninitialized_move_alloc
+ (this->alloc(), pos, old_finish, this->members_.m_finish + raw_gap);
+ BOOST_TRY{
+ 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));
+ 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);
+ */
+ }
}
}
return this->begin() + pos_n;
}
- iterator priv_insert_back_aux_impl(size_type n, advanced_insert_aux_int_t &interf)
+ template <class InsertProxy>
+ iterator priv_insert_back_aux_impl(size_type n, InsertProxy interf)
{
if(!this->members_.m_map){
this->priv_initialize_map(0);
@@ -1778,19 +1767,20 @@
iterator new_finish = this->priv_reserve_elements_at_back(n);
iterator old_finish = this->members_.m_finish;
- interf.uninitialized_copy_some_and_update(old_finish, n, true);
+ interf.uninitialized_copy_n_and_update(old_finish, n);
this->members_.m_finish = new_finish;
return iterator(this->members_.m_finish - n);
}
- iterator priv_insert_front_aux_impl(size_type n, advanced_insert_aux_int_t &interf)
+ template <class InsertProxy>
+ iterator priv_insert_front_aux_impl(size_type n, InsertProxy interf)
{
if(!this->members_.m_map){
this->priv_initialize_map(0);
}
iterator new_start = this->priv_reserve_elements_at_front(n);
- interf.uninitialized_copy_some_and_update(new_start, difference_type(n), true);
+ interf.uninitialized_copy_n_and_update(new_start, n);
this->members_.m_start = new_start;
return new_start;
}
@@ -2015,15 +2005,14 @@
/// @cond
namespace boost {
-/*
+
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::deque<T, Allocator> >
-{
- enum { value = has_trivial_destructor<Allocator>::value };
-};
-*/
+ : public ::boost::has_trivial_destructor_after_move<Allocator>
+{};
+
}
/// @endcond
Modified: branches/release/boost/container/detail/adaptive_node_pool_impl.hpp
==============================================================================
--- branches/release/boost/container/detail/adaptive_node_pool_impl.hpp (original)
+++ branches/release/boost/container/detail/adaptive_node_pool_impl.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -21,16 +21,28 @@
#include <boost/container/detail/utilities.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/list.hpp>
#include <boost/intrusive/slist.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/math_functions.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/pool_common.hpp>
#include <boost/assert.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
#include <cstddef>
namespace boost {
namespace container {
+
+namespace adaptive_pool_flag {
+
+static const unsigned int none = 0u;
+static const unsigned int align_only = 1u << 0u;
+static const unsigned int size_ordered = 1u << 1u;
+static const unsigned int address_ordered = 1u << 2u;
+
+} //namespace adaptive_pool_flag{
+
namespace container_detail {
template<class size_type>
@@ -42,42 +54,160 @@
size_type hdr_offset;
};
+template<class SizeType, unsigned int Flags>
+struct less_func;
+
+template<class SizeType>
+struct less_func<SizeType, adaptive_pool_flag::none>
+{
+ static bool less(SizeType, SizeType, const void *, const void *)
+ { return true; }
+};
+
+template<class SizeType>
+struct less_func<SizeType, adaptive_pool_flag::size_ordered>
+{
+ static bool less(SizeType ls, SizeType rs, const void *, const void *)
+ { return ls < rs; }
+};
+
+template<class SizeType>
+struct less_func<SizeType, adaptive_pool_flag::address_ordered>
+{
+ static bool less(SizeType, SizeType, const void *la, const void *ra)
+ { return &la < &ra; }
+};
+
+template<class SizeType>
+struct less_func<SizeType, adaptive_pool_flag::size_ordered | adaptive_pool_flag::address_ordered>
+{
+ static bool less(SizeType ls, SizeType rs, const void *la, const void *ra)
+ { return (ls < rs) || ((ls == rs) && (la < ra)); }
+};
+
+template<class VoidPointer, class SizeType, bool ordered>
+struct block_container_traits
+{
+ typedef typename bi::make_set_base_hook
+ < bi::void_pointer<VoidPointer>
+ , bi::optimize_size<true>
+ , bi::link_mode<bi::normal_link> >::type hook_t;
+
+ template<class T>
+ struct container
+ {
+ typedef typename bi::make_multiset
+ <T, bi::base_hook<hook_t>, bi::size_type<SizeType> >::type type;
+ };
+
+ template<class Container>
+ static void reinsert_was_used(Container &container, typename Container::reference v, bool)
+ {
+ typedef typename Container::const_iterator const_block_iterator;
+ const const_block_iterator this_block
+ (Container::s_iterator_to(const_cast<typename Container::const_reference>(v)));
+ const_block_iterator next_block(this_block);
+ if(++next_block != container.cend()){
+ if(this_block->free_nodes.size() > next_block->free_nodes.size()){
+ container.erase(this_block);
+ container.insert(v);
+ }
+ }
+ }
+
+ template<class Container>
+ static void insert_was_empty(Container &container, typename Container::value_type &v, bool)
+ {
+ container.insert(v);
+ }
+
+ template<class Container>
+ static void erase_first(Container &container)
+ {
+ container.erase(container.cbegin());
+ }
+
+ template<class Container>
+ static void erase_last(Container &container)
+ {
+ container.erase(--container.cend());
+ }
+};
+
template<class VoidPointer, class SizeType>
+struct block_container_traits<VoidPointer, SizeType, false>
+{
+ typedef typename bi::make_list_base_hook
+ < bi::void_pointer<VoidPointer>
+ , bi::link_mode<bi::normal_link> >::type hook_t;
+
+ template<class T>
+ struct container
+ {
+ typedef typename bi::make_list
+ <T, bi::base_hook<hook_t>, bi::size_type<SizeType>, bi::constant_time_size<false> >::type type;
+ };
+
+ template<class Container>
+ static void reinsert_was_used(Container &container, typename Container::value_type &v, bool is_full)
+ {
+ if(is_full){
+ container.erase(Container::s_iterator_to(v));
+ container.push_back(v);
+ }
+ }
+
+ template<class Container>
+ static void insert_was_empty(Container &container, typename Container::value_type &v, bool is_full)
+ {
+ if(is_full){
+ container.push_back(v);
+ }
+ else{
+ container.push_front(v);
+ }
+ }
+
+ template<class Container>
+ static void erase_first(Container &container)
+ {
+ container.pop_front();
+ }
+
+ template<class Container>
+ static void erase_last(Container &container)
+ {
+ container.pop_back();
+ }
+};
+
+template<class MultiallocationChain, class VoidPointer, class SizeType, unsigned int Flags>
struct adaptive_pool_types
{
typedef VoidPointer void_pointer;
- typedef typename bi::make_set_base_hook
- < bi::void_pointer<void_pointer>
- , bi::optimize_size<true>
- , bi::constant_time_size<false>
- , bi::link_mode<bi::normal_link> >::type multiset_hook_t;
-
+ static const bool ordered = (Flags & (adaptive_pool_flag::size_ordered | adaptive_pool_flag::address_ordered)) != 0;
+ typedef block_container_traits<VoidPointer, SizeType, ordered> block_container_traits_t;
+ typedef typename block_container_traits_t::hook_t hook_t;
typedef hdr_offset_holder_t<SizeType> hdr_offset_holder;
+ static const unsigned int order_flags = Flags & (adaptive_pool_flag::size_ordered | adaptive_pool_flag::address_ordered);
+ typedef MultiallocationChain free_nodes_t;
struct block_info_t
- :
- public hdr_offset_holder,
- public multiset_hook_t
+ : public hdr_offset_holder,
+ public hook_t
{
- typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
//An intrusive list of free node from this block
free_nodes_t free_nodes;
friend bool operator <(const block_info_t &l, const block_info_t &r)
{
-// { return l.free_nodes.size() < r.free_nodes.size(); }
- //Let's order blocks first by free nodes and then by address
- //so that highest address fully free blocks are deallocated.
- //This improves returning memory to the OS (trimming).
- const bool is_less = l.free_nodes.size() < r.free_nodes.size();
- const bool is_equal = l.free_nodes.size() == r.free_nodes.size();
- return is_less || (is_equal && (&l < &r));
+ return less_func<SizeType, order_flags>::
+ less(l.free_nodes.size(), r.free_nodes.size(), &l , &r);
}
friend bool operator ==(const block_info_t &l, const block_info_t &r)
{ return &l == &r; }
};
- typedef typename bi::make_multiset
- <block_info_t, bi::base_hook<multiset_hook_t> >::type block_multiset_t;
+ typedef typename block_container_traits_t:: template container<block_info_t>::type block_container_t;
};
template<class size_type>
@@ -113,9 +243,9 @@
, size_type &num_subblocks, size_type &real_num_node, size_type overhead_percent
, size_type hdr_size, size_type hdr_offset_size, size_type payload_per_allocation)
{
+ const size_type hdr_subblock_elements = (alignment - hdr_size - payload_per_allocation)/real_node_size;
size_type elements_per_subblock = (alignment - hdr_offset_size)/real_node_size;
size_type possible_num_subblock = (elements_per_block - 1)/elements_per_subblock + 1;
- size_type hdr_subblock_elements = (alignment - hdr_size - payload_per_allocation)/real_node_size;
while(((possible_num_subblock-1)*elements_per_subblock + hdr_subblock_elements) < elements_per_block){
++possible_num_subblock;
}
@@ -135,7 +265,7 @@
real_num_node = (possible_num_subblock-1)*elements_per_subblock + hdr_subblock_elements;
}
-template<class SegmentManagerBase, bool AlignOnly = false>
+template<class SegmentManagerBase, unsigned int Flags>
class private_adaptive_node_pool_impl
{
//Non-copyable
@@ -147,27 +277,42 @@
typedef typename SegmentManagerBase::void_pointer void_pointer;
static const typename SegmentManagerBase::
size_type PayloadPerAllocation = SegmentManagerBase::PayloadPerAllocation;
+ //Flags
+ //align_only
+ static const bool AlignOnly = (Flags & adaptive_pool_flag::align_only) != 0;
typedef bool_<AlignOnly> IsAlignOnly;
typedef true_ AlignOnlyTrue;
typedef false_ AlignOnlyFalse;
+ //size_ordered
+ static const bool SizeOrdered = (Flags & adaptive_pool_flag::size_ordered) != 0;
+ typedef bool_<SizeOrdered> IsSizeOrdered;
+ typedef true_ SizeOrderedTrue;
+ typedef false_ SizeOrderedFalse;
+ //address_ordered
+ static const bool AddressOrdered = (Flags & adaptive_pool_flag::address_ordered) != 0;
+ typedef bool_<AddressOrdered> IsAddressOrdered;
+ typedef true_ AddressOrderedTrue;
+ typedef false_ AddressOrderedFalse;
public:
- typedef typename node_slist<void_pointer>::node_t node_t;
- typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
- typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
- typedef typename SegmentManagerBase::size_type size_type;
+ typedef typename SegmentManagerBase::multiallocation_chain multiallocation_chain;
+ typedef typename SegmentManagerBase::size_type size_type;
private:
- typedef typename adaptive_pool_types<void_pointer, size_type>::block_info_t block_info_t;
- typedef typename adaptive_pool_types<void_pointer, size_type>::block_multiset_t block_multiset_t;
- typedef typename block_multiset_t::iterator block_iterator;
- typedef typename adaptive_pool_types<void_pointer, size_type>::hdr_offset_holder hdr_offset_holder;
+ typedef adaptive_pool_types
+ <multiallocation_chain, void_pointer, size_type, Flags> adaptive_pool_types_t;
+ typedef typename adaptive_pool_types_t::free_nodes_t free_nodes_t;
+ typedef typename adaptive_pool_types_t::block_info_t block_info_t;
+ typedef typename adaptive_pool_types_t::block_container_t block_container_t;
+ typedef typename adaptive_pool_types_t::block_container_traits_t block_container_traits_t;
+ typedef typename block_container_t::iterator block_iterator;
+ typedef typename block_container_t::const_iterator const_block_iterator;
+ typedef typename adaptive_pool_types_t::hdr_offset_holder hdr_offset_holder;
- static const size_type MaxAlign = alignment_of<node_t>::value;
+ static const size_type MaxAlign = alignment_of<void_pointer>::value;
static const size_type HdrSize = ((sizeof(block_info_t)-1)/MaxAlign+1)*MaxAlign;
static const size_type HdrOffsetSize = ((sizeof(hdr_offset_holder)-1)/MaxAlign+1)*MaxAlign;
-
public:
//!Segment manager typedef
typedef SegmentManagerBase segment_manager_base_type;
@@ -181,7 +326,7 @@
, unsigned char overhead_percent
)
: m_max_free_blocks(max_free_blocks)
- , m_real_node_size(lcm(node_size, size_type(alignment_of<node_t>::value)))
+ , m_real_node_size(lcm(node_size, size_type(alignment_of<void_pointer>::value)))
//Round the size to a power of two value.
//This is the total memory size (including payload) that we want to
//allocate from the general-purpose allocator
@@ -195,7 +340,7 @@
, m_real_num_node(AlignOnly ? (m_real_block_alignment - PayloadPerAllocation - HdrSize)/m_real_node_size : 0)
//General purpose allocator
, mp_segment_mngr_base(segment_mngr_base)
- , m_block_multiset()
+ , m_block_container()
, m_totally_free_blocks(0)
{
if(!AlignOnly){
@@ -214,7 +359,7 @@
//!Destructor. Deallocates all allocated blocks. Never throws
~private_adaptive_node_pool_impl()
- { priv_clear(); }
+ { this->priv_clear(); }
size_type get_real_num_node() const
{ return m_real_num_node; }
@@ -226,84 +371,157 @@
//!Allocates array of count elements. Can throw
void *allocate_node()
{
- priv_invariants();
+ this->priv_invariants();
//If there are no free nodes we allocate a new block
- if (m_block_multiset.empty()){
- priv_alloc_block(1);
+ if(!m_block_container.empty()){
+ //We take the first free node the multiset can't be empty
+ free_nodes_t &free_nodes = m_block_container.begin()->free_nodes;
+ BOOST_ASSERT(!free_nodes.empty());
+ const size_type free_nodes_count = free_nodes.size();
+ void *first_node = container_detail::to_raw_pointer(free_nodes.pop_front());
+ if(free_nodes.empty()){
+ block_container_traits_t::erase_first(m_block_container);
+ }
+ m_totally_free_blocks -= static_cast<size_type>(free_nodes_count == m_real_num_node);
+ this->priv_invariants();
+ return first_node;
+ }
+ else{
+ multiallocation_chain chain;
+ this->priv_append_from_new_blocks(1, chain, IsAlignOnly());
+ return container_detail::to_raw_pointer(chain.pop_front());
}
- //We take the first free node the multiset can't be empty
- return priv_take_first_node();
}
//!Deallocates an array pointed by ptr. Never throws
void deallocate_node(void *pElem)
{
- multiallocation_chain chain;
- chain.push_front(void_pointer(pElem));
- this->priv_reinsert_nodes_in_block(chain, 1);
- //Update free block count<
- if(m_totally_free_blocks > m_max_free_blocks){
- this->priv_deallocate_free_blocks(m_max_free_blocks);
- }
- priv_invariants();
+ this->priv_invariants();
+ block_info_t &block_info = *this->priv_block_from_node(pElem);
+ BOOST_ASSERT(block_info.free_nodes.size() < m_real_num_node);
+
+ //We put the node at the beginning of the free node list
+ block_info.free_nodes.push_back(void_pointer(pElem));
+
+ //The loop reinserts all blocks except the last one
+ this->priv_reinsert_block(block_info, block_info.free_nodes.size() == 1);
+ this->priv_deallocate_free_blocks(m_max_free_blocks);
+ this->priv_invariants();
}
//!Allocates n nodes.
//!Can throw
- multiallocation_chain allocate_nodes(const size_type n)
+ void allocate_nodes(const size_type n, multiallocation_chain &chain)
{
- multiallocation_chain chain;
size_type i = 0;
- try{
- priv_invariants();
+ BOOST_TRY{
+ this->priv_invariants();
while(i != n){
//If there are no free nodes we allocate all needed blocks
- if (m_block_multiset.empty()){
- priv_alloc_block(((n - i) - 1)/m_real_num_node + 1);
+ if (m_block_container.empty()){
+ this->priv_append_from_new_blocks(n - i, chain, IsAlignOnly());
+ BOOST_ASSERT(m_block_container.empty() || (++m_block_container.cbegin() == m_block_container.cend()));
+ BOOST_ASSERT(chain.size() == n);
+ break;
}
- free_nodes_t &free_nodes = m_block_multiset.begin()->free_nodes;
+ free_nodes_t &free_nodes = m_block_container.begin()->free_nodes;
const size_type free_nodes_count_before = free_nodes.size();
- if(free_nodes_count_before == m_real_num_node){
- --m_totally_free_blocks;
- }
- const size_type num_elems = ((n-i) < free_nodes_count_before) ? (n-i) : free_nodes_count_before;
- for(size_type j = 0; j != num_elems; ++j){
- void *new_node = &free_nodes.front();
- free_nodes.pop_front();
- chain.push_back(new_node);
+ m_totally_free_blocks -= static_cast<size_type>(free_nodes_count_before == m_real_num_node);
+ const size_type num_left = n-i;
+ const size_type num_elems = (num_left < free_nodes_count_before) ? num_left : free_nodes_count_before;
+ typedef typename free_nodes_t::iterator free_nodes_iterator;
+
+ if(num_left < free_nodes_count_before){
+ const free_nodes_iterator it_bbeg(free_nodes.before_begin());
+ free_nodes_iterator it_bend(it_bbeg);
+ for(size_type j = 0; j != num_elems; ++j){
+ ++it_bend;
+ }
+ free_nodes_iterator it_end = it_bend; ++it_end;
+ free_nodes_iterator it_beg = it_bbeg; ++it_beg;
+ free_nodes.erase_after(it_bbeg, it_end, num_elems);
+ chain.incorporate_after(chain.last(), &*it_beg, &*it_bend, num_elems);
+ //chain.splice_after(chain.last(), free_nodes, it_bbeg, it_bend, num_elems);
+ BOOST_ASSERT(!free_nodes.empty());
}
-
- if(free_nodes.empty()){
- m_block_multiset.erase(m_block_multiset.begin());
+ else{
+ const free_nodes_iterator it_beg(free_nodes.begin()), it_bend(free_nodes.last());
+ free_nodes.clear();
+ chain.incorporate_after(chain.last(), &*it_beg, &*it_bend, num_elems);
+ block_container_traits_t::erase_first(m_block_container);
}
i += num_elems;
}
}
- catch(...){
- this->deallocate_nodes(boost::move(chain));
- throw;
+ BOOST_CATCH(...){
+ this->deallocate_nodes(chain);
+ BOOST_RETHROW
}
- priv_invariants();
- return boost::move(chain);
+ BOOST_CATCH_END
+ this->priv_invariants();
}
//!Deallocates a linked list of nodes. Never throws
- void deallocate_nodes(multiallocation_chain nodes)
+ void deallocate_nodes(multiallocation_chain &nodes)
{
- this->priv_reinsert_nodes_in_block(nodes, nodes.size());
- if(m_totally_free_blocks > m_max_free_blocks){
+ this->priv_invariants();
+ //To take advantage of node locality, wait until two
+ //nodes belong to different blocks. Only then reinsert
+ //the block of the first node in the block tree.
+ //Cache of the previous block
+ block_info_t *prev_block_info = 0;
+
+ //If block was empty before this call, it's not already
+ //inserted in the block tree.
+ bool prev_block_was_empty = false;
+ typedef typename free_nodes_t::iterator free_nodes_iterator;
+ {
+ const free_nodes_iterator itbb(nodes.before_begin()), ite(nodes.end());
+ free_nodes_iterator itf(nodes.begin()), itbf(itbb);
+ size_type splice_node_count = size_type(-1);
+ while(itf != ite){
+ void *pElem = container_detail::to_raw_pointer(&*itf);
+ block_info_t &block_info = *this->priv_block_from_node(pElem);
+ BOOST_ASSERT(block_info.free_nodes.size() < m_real_num_node);
+ ++splice_node_count;
+
+ //If block change is detected calculate the cached block position in the tree
+ if(&block_info != prev_block_info){
+ if(prev_block_info){ //Make sure we skip the initial "dummy" cache
+ free_nodes_iterator it(itbb); ++it;
+ nodes.erase_after(itbb, itf, splice_node_count);
+ prev_block_info->free_nodes.incorporate_after(prev_block_info->free_nodes.last(), &*it, &*itbf, splice_node_count);
+ this->priv_reinsert_block(*prev_block_info, prev_block_was_empty);
+ splice_node_count = 0;
+ }
+ //Update cache with new data
+ prev_block_was_empty = block_info.free_nodes.empty();
+ prev_block_info = &block_info;
+ }
+ itbf = itf;
+ ++itf;
+ }
+ }
+ if(prev_block_info){
+ //The loop reinserts all blocks except the last one
+ const free_nodes_iterator itfirst(nodes.begin()), itlast(nodes.last());
+ const size_type splice_node_count = nodes.size();
+ nodes.clear();
+ prev_block_info->free_nodes.incorporate_after(prev_block_info->free_nodes.last(), &*itfirst, &*itlast, splice_node_count);
+ this->priv_reinsert_block(*prev_block_info, prev_block_was_empty);
+ this->priv_invariants();
this->priv_deallocate_free_blocks(m_max_free_blocks);
}
}
void deallocate_free_blocks()
- { this->priv_deallocate_free_blocks(0); }
+ { this->priv_deallocate_free_blocks(0); }
size_type num_free_nodes()
{
- typedef typename block_multiset_t::const_iterator citerator;
+ typedef typename block_container_t::const_iterator citerator;
size_type count = 0;
- citerator it (m_block_multiset.begin()), itend(m_block_multiset.end());
+ citerator it (m_block_container.begin()), itend(m_block_container.end());
for(; it != itend; ++it){
count += it->free_nodes.size();
}
@@ -318,7 +536,7 @@
BOOST_ASSERT(m_real_num_node == other.m_real_num_node);
std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
std::swap(m_totally_free_blocks, other.m_totally_free_blocks);
- m_block_multiset.swap(other.m_block_multiset);
+ m_block_container.swap(other.m_block_container);
}
//Deprecated, use deallocate_free_blocks
@@ -326,83 +544,54 @@
{ this->priv_deallocate_free_blocks(0); }
private:
+
void priv_deallocate_free_blocks(size_type max_free_blocks)
+ { //Trampoline function to ease inlining
+ if(m_totally_free_blocks > max_free_blocks){
+ this->priv_deallocate_free_blocks_impl(max_free_blocks);
+ }
+ }
+
+ void priv_deallocate_free_blocks_impl(size_type max_free_blocks)
{
- priv_invariants();
+ this->priv_invariants();
//Now check if we've reached the free nodes limit
//and check if we have free blocks. If so, deallocate as much
//as we can to stay below the limit
- for( block_iterator itend = m_block_multiset.end()
- ; m_totally_free_blocks > max_free_blocks
- ; --m_totally_free_blocks
- ){
- BOOST_ASSERT(!m_block_multiset.empty());
- block_iterator it = itend;
+ multiallocation_chain chain;
+ {
+ const const_block_iterator itend = m_block_container.cend();
+ const_block_iterator it = itend;
--it;
- BOOST_ASSERT(it->free_nodes.size() == m_real_num_node);
- m_block_multiset.erase_and_dispose(it, block_destroyer(this));
- }
- }
-
- void priv_reinsert_nodes_in_block(multiallocation_chain &chain, size_type n)
- {
- block_iterator block_it(m_block_multiset.end());
- while(n--){
- void *pElem = container_detail::to_raw_pointer(chain.pop_front());
- priv_invariants();
- block_info_t *block_info = this->priv_block_from_node(pElem);
- BOOST_ASSERT(block_info->free_nodes.size() < m_real_num_node);
- //We put the node at the beginning of the free node list
- node_t * to_deallocate = static_cast<node_t*>(pElem);
- block_info->free_nodes.push_front(*to_deallocate);
-
- block_iterator this_block(block_multiset_t::s_iterator_to(*block_info));
- block_iterator next_block(this_block);
- ++next_block;
+ size_type totally_free_blocks = m_totally_free_blocks;
- //Cache the free nodes from the block
- size_type this_block_free_nodes = this_block->free_nodes.size();
-
- if(this_block_free_nodes == 1){
- m_block_multiset.insert(m_block_multiset.begin(), *block_info);
+ for( ; totally_free_blocks > max_free_blocks; --totally_free_blocks){
+ BOOST_ASSERT(it->free_nodes.size() == m_real_num_node);
+ void *addr = priv_first_subblock_from_block(const_cast<block_info_t*>(&*it));
+ --it;
+ block_container_traits_t::erase_last(m_block_container);
+ chain.push_front(void_pointer(addr));
}
- else{
- block_iterator next_block(this_block);
- ++next_block;
- if(next_block != block_it){
- size_type next_free_nodes = next_block->free_nodes.size();
- if(this_block_free_nodes > next_free_nodes){
- //Now move the block to the new position
- m_block_multiset.erase(this_block);
- m_block_multiset.insert(*block_info);
- }
- }
- }
- //Update free block count
- if(this_block_free_nodes == m_real_num_node){
- ++m_totally_free_blocks;
- }
- priv_invariants();
+ BOOST_ASSERT((m_totally_free_blocks - max_free_blocks) == chain.size());
+ m_totally_free_blocks = max_free_blocks;
}
+ this->mp_segment_mngr_base->deallocate_many(chain);
}
- node_t *priv_take_first_node()
+ void priv_reinsert_block(block_info_t &prev_block_info, const bool prev_block_was_empty)
{
- BOOST_ASSERT(m_block_multiset.begin() != m_block_multiset.end());
- //We take the first free node the multiset can't be empty
- free_nodes_t &free_nodes = m_block_multiset.begin()->free_nodes;
- node_t *first_node = &free_nodes.front();
- const size_type free_nodes_count = free_nodes.size();
- BOOST_ASSERT(0 != free_nodes_count);
- free_nodes.pop_front();
- if(free_nodes_count == 1){
- m_block_multiset.erase(m_block_multiset.begin());
+ //Cache the free nodes from the block
+ const size_type this_block_free_nodes = prev_block_info.free_nodes.size();
+ const bool is_full = this_block_free_nodes == m_real_num_node;
+
+ //Update free block count
+ m_totally_free_blocks += static_cast<size_type>(is_full);
+ if(prev_block_was_empty){
+ block_container_traits_t::insert_was_empty(m_block_container, prev_block_info, is_full);
}
- else if(free_nodes_count == m_real_num_node){
- --m_totally_free_blocks;
+ else{
+ block_container_traits_t::reinsert_was_used(m_block_container, prev_block_info, is_full);
}
- priv_invariants();
- return first_node;
}
class block_destroyer;
@@ -411,33 +600,31 @@
class block_destroyer
{
public:
- block_destroyer(const this_type *impl)
- : mp_impl(impl)
+ block_destroyer(const this_type *impl, multiallocation_chain &chain)
+ : mp_impl(impl), m_chain(chain)
{}
- void operator()(typename block_multiset_t::pointer to_deallocate)
+ void operator()(typename block_container_t::pointer to_deallocate)
{ return this->do_destroy(to_deallocate, IsAlignOnly()); }
private:
- void do_destroy(typename block_multiset_t::pointer to_deallocate, AlignOnlyTrue)
+ void do_destroy(typename block_container_t::pointer to_deallocate, AlignOnlyTrue)
{
- size_type free_nodes = to_deallocate->free_nodes.size();
- (void)free_nodes;
- BOOST_ASSERT(free_nodes == mp_impl->m_real_num_node);
- mp_impl->mp_segment_mngr_base->deallocate(to_deallocate);
+ BOOST_ASSERT(to_deallocate->free_nodes.size() == mp_impl->m_real_num_node);
+ m_chain.push_back(to_deallocate);
}
- void do_destroy(typename block_multiset_t::pointer to_deallocate, AlignOnlyFalse)
+ void do_destroy(typename block_container_t::pointer to_deallocate, AlignOnlyFalse)
{
- size_type free_nodes = to_deallocate->free_nodes.size();
- (void)free_nodes;
- BOOST_ASSERT(free_nodes == mp_impl->m_real_num_node);
+ BOOST_ASSERT(to_deallocate->free_nodes.size() == mp_impl->m_real_num_node);
BOOST_ASSERT(0 == to_deallocate->hdr_offset);
- hdr_offset_holder *hdr_off_holder = mp_impl->priv_first_subblock_from_block(container_detail::to_raw_pointer(to_deallocate));
- mp_impl->mp_segment_mngr_base->deallocate(hdr_off_holder);
+ hdr_offset_holder *hdr_off_holder =
+ mp_impl->priv_first_subblock_from_block(container_detail::to_raw_pointer(to_deallocate));
+ m_chain.push_back(hdr_off_holder);
}
const this_type *mp_impl;
+ multiallocation_chain &m_chain;
};
//This macro will activate invariant checking. Slow, but helpful for debugging the code.
@@ -446,44 +633,45 @@
#ifdef BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
#undef BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
{
- //We iterate through the block tree to free the memory
- block_iterator it(m_block_multiset.begin()),
- itend(m_block_multiset.end()), to_deallocate;
- if(it != itend){
- for(++it; it != itend; ++it){
- block_iterator prev(it);
- --prev;
- size_type sp = prev->free_nodes.size(),
- si = it->free_nodes.size();
- BOOST_ASSERT(sp <= si);
- (void)sp; (void)si;
- }
- }
- //Check that the total free nodes are correct
- it = m_block_multiset.begin();
- itend = m_block_multiset.end();
- size_type total_free_nodes = 0;
- for(; it != itend; ++it){
- total_free_nodes += it->free_nodes.size();
- }
- BOOST_ASSERT(total_free_nodes >= m_totally_free_blocks*m_real_num_node);
+ const const_block_iterator itend(m_block_container.end());
- //Check that the total totally free blocks are correct
- it = m_block_multiset.begin();
- itend = m_block_multiset.end();
- total_free = 0;
- for(; it != itend; ++it){
- total_free += it->free_nodes.size() == m_real_num_node;
+ { //We iterate through the block tree to free the memory
+ const_block_iterator it(m_block_container.begin());
+
+ if(it != itend){
+ for(++it; it != itend; ++it){
+ const_block_iterator prev(it);
+ --prev;
+ BOOST_ASSERT(*prev < *it);
+ (void)prev; (void)it;
+ }
+ }
+ }
+ { //Check that the total free nodes are correct
+ const_block_iterator it(m_block_container.cbegin());
+ size_type total_free_nodes = 0;
+ for(; it != itend; ++it){
+ total_free_nodes += it->free_nodes.size();
+ }
+ BOOST_ASSERT(total_free_nodes >= m_totally_free_blocks*m_real_num_node);
+ }
+ { //Check that the total totally free blocks are correct
+ BOOST_ASSERT(m_block_container.size() >= m_totally_free_blocks);
+ const_block_iterator it = m_block_container.cend();
+ size_type total_free_blocks = m_totally_free_blocks;
+ while(total_free_blocks--){
+ BOOST_ASSERT((--it)->free_nodes.size() == m_real_num_node);
+ }
}
- BOOST_ASSERT(total_free >= m_totally_free_blocks);
if(!AlignOnly){
//Check that header offsets are correct
- it = m_block_multiset.begin();
+ const_block_iterator it = m_block_container.begin();
for(; it != itend; ++it){
- hdr_offset_holder *hdr_off_holder = priv_first_subblock_from_block(&*it);
+ hdr_offset_holder *hdr_off_holder = this->priv_first_subblock_from_block(const_cast<block_info_t *>(&*it));
for(size_type i = 0, max = m_num_subblocks; i < max; ++i){
- BOOST_ASSERT(hdr_off_holder->hdr_offset == size_type(reinterpret_cast<char*>(&*it)- reinterpret_cast<char*>(hdr_off_holder)));
+ const size_type offset = reinterpret_cast<char*>(const_cast<block_info_t *>(&*it)) - reinterpret_cast<char*>(hdr_off_holder);
+ BOOST_ASSERT(hdr_off_holder->hdr_offset == offset);
BOOST_ASSERT(0 == ((size_type)hdr_off_holder & (m_real_block_alignment - 1)));
BOOST_ASSERT(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
hdr_off_holder = reinterpret_cast<hdr_offset_holder *>(reinterpret_cast<char*>(hdr_off_holder) + m_real_block_alignment);
@@ -499,19 +687,21 @@
void priv_clear()
{
#ifndef NDEBUG
- block_iterator it = m_block_multiset.begin();
- block_iterator itend = m_block_multiset.end();
- size_type num_free_nodes = 0;
+ block_iterator it = m_block_container.begin();
+ block_iterator itend = m_block_container.end();
+ size_type n_free_nodes = 0;
for(; it != itend; ++it){
//Check for memory leak
BOOST_ASSERT(it->free_nodes.size() == m_real_num_node);
- ++num_free_nodes;
+ ++n_free_nodes;
}
- BOOST_ASSERT(num_free_nodes == m_totally_free_blocks);
+ BOOST_ASSERT(n_free_nodes == m_totally_free_blocks);
#endif
//Check for memory leaks
- priv_invariants();
- m_block_multiset.clear_and_dispose(block_destroyer(this));
+ this->priv_invariants();
+ multiallocation_chain chain;
+ m_block_container.clear_and_dispose(block_destroyer(this, chain));
+ this->mp_segment_mngr_base->deallocate_many(chain);
m_totally_free_blocks = 0;
}
@@ -533,93 +723,129 @@
}
block_info_t *priv_block_from_node(void *node) const
- { return priv_block_from_node(node, IsAlignOnly()); }
+ { return this->priv_block_from_node(node, IsAlignOnly()); }
hdr_offset_holder *priv_first_subblock_from_block(block_info_t *block) const
+ { return this->priv_first_subblock_from_block(block, IsAlignOnly()); }
+
+ hdr_offset_holder *priv_first_subblock_from_block(block_info_t *block, AlignOnlyFalse) const
{
- hdr_offset_holder *hdr_off_holder = reinterpret_cast<hdr_offset_holder*>
+ hdr_offset_holder *const hdr_off_holder = reinterpret_cast<hdr_offset_holder*>
(reinterpret_cast<char*>(block) - (m_num_subblocks-1)*m_real_block_alignment);
BOOST_ASSERT(hdr_off_holder->hdr_offset == size_type(reinterpret_cast<char*>(block) - reinterpret_cast<char*>(hdr_off_holder)));
- BOOST_ASSERT(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
+ BOOST_ASSERT(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
BOOST_ASSERT(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
return hdr_off_holder;
}
+ hdr_offset_holder *priv_first_subblock_from_block(block_info_t *block, AlignOnlyTrue) const
+ {
+ return reinterpret_cast<hdr_offset_holder*>(block);
+ }
+
+ void priv_dispatch_block_chain_or_free
+ ( multiallocation_chain &chain, block_info_t &c_info, size_type num_node
+ , char *mem_address, size_type total_elements, bool insert_block_if_free)
+ {
+ BOOST_ASSERT(chain.size() <= total_elements);
+ //First add all possible nodes to the chain
+ const size_type left = total_elements - chain.size();
+ const size_type max_chain = (num_node < left) ? num_node : left;
+ mem_address = static_cast<char *>(container_detail::to_raw_pointer
+ (chain.incorporate_after(chain.last(), void_pointer(mem_address), m_real_node_size, max_chain)));
+ //Now store remaining nodes in the free list
+ if(const size_type max_free = num_node - max_chain){
+ free_nodes_t & free_nodes = c_info.free_nodes;
+ free_nodes.incorporate_after(free_nodes.last(), void_pointer(mem_address), m_real_node_size, max_free);
+ if(insert_block_if_free){
+ m_block_container.push_front(c_info);
+ }
+ }
+ }
+
//!Allocates a several blocks of nodes. Can throw
- void priv_alloc_block(size_type n, AlignOnlyTrue)
+ void priv_append_from_new_blocks(size_type min_elements, multiallocation_chain &chain, AlignOnlyTrue)
{
- size_type real_block_size = m_real_block_alignment - PayloadPerAllocation;
+ BOOST_ASSERT(m_block_container.empty());
+ BOOST_ASSERT(min_elements > 0);
+ const size_type n = (min_elements - 1)/m_real_num_node + 1;
+ const size_type real_block_size = m_real_block_alignment - PayloadPerAllocation;
+ const size_type total_elements = chain.size() + min_elements;
for(size_type i = 0; i != n; ++i){
//We allocate a new NodeBlock and put it the last
//element of the tree
char *mem_address = static_cast<char*>
(mp_segment_mngr_base->allocate_aligned(real_block_size, m_real_block_alignment));
- if(!mem_address) throw std::bad_alloc();
- ++m_totally_free_blocks;
- block_info_t *c_info = new(mem_address)block_info_t();
- m_block_multiset.insert(m_block_multiset.end(), *c_info);
-
+ if(!mem_address){
+ //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();
+ }
+ block_info_t &c_info = *new(mem_address)block_info_t();
mem_address += HdrSize;
- //We initialize all Nodes in Node Block to insert
- //them in the free Node list
- typename free_nodes_t::iterator prev_insert_pos = c_info->free_nodes.before_begin();
- for(size_type i = 0; i < m_real_num_node; ++i){
- prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *(node_t*)mem_address);
- mem_address += m_real_node_size;
+ if(i != (n-1)){
+ chain.incorporate_after(chain.last(), void_pointer(mem_address), m_real_node_size, m_real_num_node);
+ }
+ else{
+ this->priv_dispatch_block_chain_or_free(chain, c_info, m_real_num_node, mem_address, total_elements, true);
}
}
}
- void priv_alloc_block(size_type n, AlignOnlyFalse)
+ void priv_append_from_new_blocks(size_type min_elements, multiallocation_chain &chain, AlignOnlyFalse)
{
- size_type real_block_size = m_real_block_alignment*m_num_subblocks - PayloadPerAllocation;
- size_type elements_per_subblock = (m_real_block_alignment - HdrOffsetSize)/m_real_node_size;
- size_type hdr_subblock_elements = (m_real_block_alignment - HdrSize - PayloadPerAllocation)/m_real_node_size;
+ BOOST_ASSERT(m_block_container.empty());
+ BOOST_ASSERT(min_elements > 0);
+ const size_type n = (min_elements - 1)/m_real_num_node + 1;
+ const size_type real_block_size = m_real_block_alignment*m_num_subblocks - PayloadPerAllocation;
+ const size_type elements_per_subblock = (m_real_block_alignment - HdrOffsetSize)/m_real_node_size;
+ const size_type hdr_subblock_elements = (m_real_block_alignment - HdrSize - PayloadPerAllocation)/m_real_node_size;
+ const size_type total_elements = chain.size() + min_elements;
for(size_type i = 0; i != n; ++i){
//We allocate a new NodeBlock and put it the last
//element of the tree
char *mem_address = static_cast<char*>
(mp_segment_mngr_base->allocate_aligned(real_block_size, m_real_block_alignment));
- if(!mem_address) throw std::bad_alloc();
- ++m_totally_free_blocks;
-
+ if(!mem_address){
+ //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();
+ }
//First initialize header information on the last subblock
char *hdr_addr = mem_address + m_real_block_alignment*(m_num_subblocks-1);
- block_info_t *c_info = new(hdr_addr)block_info_t();
+ block_info_t &c_info = *new(hdr_addr)block_info_t();
//Some structural checks
- BOOST_ASSERT(static_cast<void*>(&static_cast<hdr_offset_holder*>(c_info)->hdr_offset) ==
- static_cast<void*>(c_info));
- typename free_nodes_t::iterator prev_insert_pos = c_info->free_nodes.before_begin();
- for( size_type subblock = 0, maxsubblock = m_num_subblocks - 1
- ; subblock < maxsubblock
- ; ++subblock, mem_address += m_real_block_alignment){
- //Initialize header offset mark
- new(mem_address) hdr_offset_holder(size_type(hdr_addr - mem_address));
- char *pNode = mem_address + HdrOffsetSize;
- for(size_type i = 0; i < elements_per_subblock; ++i){
- prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *new (pNode) node_t);
- pNode += m_real_node_size;
+ BOOST_ASSERT(static_cast<void*>(&static_cast<hdr_offset_holder&>(c_info).hdr_offset) ==
+ static_cast<void*>(&c_info)); (void)c_info;
+ if(i != (n-1)){
+ for( size_type subblock = 0, maxsubblock = m_num_subblocks - 1
+ ; subblock < maxsubblock
+ ; ++subblock, mem_address += m_real_block_alignment){
+ //Initialize header offset mark
+ new(mem_address) hdr_offset_holder(size_type(hdr_addr - mem_address));
+ chain.incorporate_after
+ (chain.last(), void_pointer(mem_address + HdrOffsetSize), m_real_node_size, elements_per_subblock);
}
+ chain.incorporate_after(chain.last(), void_pointer(hdr_addr + HdrSize), m_real_node_size, hdr_subblock_elements);
}
- {
- char *pNode = hdr_addr + HdrSize;
- //We initialize all Nodes in Node Block to insert
- //them in the free Node list
- for(size_type i = 0; i < hdr_subblock_elements; ++i){
- prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *new (pNode) node_t);
- pNode += m_real_node_size;
+ else{
+ for( size_type subblock = 0, maxsubblock = m_num_subblocks - 1
+ ; subblock < maxsubblock
+ ; ++subblock, mem_address += m_real_block_alignment){
+ //Initialize header offset mark
+ new(mem_address) hdr_offset_holder(size_type(hdr_addr - mem_address));
+ this->priv_dispatch_block_chain_or_free
+ (chain, c_info, elements_per_subblock, mem_address + HdrOffsetSize, total_elements, false);
}
+ this->priv_dispatch_block_chain_or_free
+ (chain, c_info, hdr_subblock_elements, hdr_addr + HdrSize, total_elements, true);
}
- //Insert the block after the free node list is full
- m_block_multiset.insert(m_block_multiset.end(), *c_info);
}
}
- //!Allocates a block of nodes. Can throw std::bad_alloc
- void priv_alloc_block(size_type n)
- { return priv_alloc_block(n, IsAlignOnly()); }
-
private:
typedef typename boost::intrusive::pointer_traits
<void_pointer>::template rebind_pointer<segment_manager_base_type>::type segment_mngr_base_ptr_t;
@@ -633,9 +859,9 @@
//This is the real number of nodes per block
//const
size_type m_real_num_node;
- segment_mngr_base_ptr_t mp_segment_mngr_base; //Segment manager
- block_multiset_t m_block_multiset; //Intrusive block list
- size_type m_totally_free_blocks; //Free blocks
+ segment_mngr_base_ptr_t mp_segment_mngr_base; //Segment manager
+ block_container_t m_block_container; //Intrusive block list
+ size_type m_totally_free_blocks; //Free blocks
};
} //namespace container_detail {
Modified: branches/release/boost/container/detail/advanced_insert_int.hpp
==============================================================================
--- branches/release/boost/container/detail/advanced_insert_int.hpp (original)
+++ branches/release/boost/container/detail/advanced_insert_int.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -20,160 +20,177 @@
#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/destroyers.hpp>
#include <boost/aligned_storage.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include <iterator> //std::iterator_traits
#include <boost/assert.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
namespace boost { namespace container { namespace container_detail {
-//This class will be interface for operations dependent on FwdIt types used advanced_insert_aux_impl
-template<class Iterator>
-struct advanced_insert_aux_int
+template<class A, class FwdIt, class Iterator>
+struct insert_range_proxy
{
- typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
- virtual void copy_remaining_to(Iterator p) = 0;
- virtual void uninitialized_copy_remaining_to(Iterator p) = 0;
- virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
- virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
- virtual ~advanced_insert_aux_int() {}
+ typedef typename allocator_traits<A>::size_type size_type;
+ typedef typename allocator_traits<A>::value_type value_type;
+
+ insert_range_proxy(A& a, FwdIt first)
+ : a_(a), first_(first)
+ {}
+
+ void uninitialized_copy_n_and_update(Iterator pos, size_type n)
+ {
+ this->first_ = ::boost::container::uninitialized_copy_or_move_alloc_n_source
+ (this->a_, this->first_, n, pos);
+ }
+
+ void copy_n_and_update(Iterator pos, size_type n)
+ {
+ this->first_ = ::boost::container::copy_or_move_n_source(this->first_, n, pos);
+ }
+
+ A &a_;
+ FwdIt first_;
};
-//This class template will adapt each FwIt types to advanced_insert_aux_int
-template<class A, class FwdIt, class Iterator>
-struct advanced_insert_aux_proxy
- : public advanced_insert_aux_int<Iterator>
+
+template<class A, class Iterator>
+struct insert_n_copies_proxy
{
typedef typename allocator_traits<A>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type;
- typedef typename advanced_insert_aux_int<Iterator>::difference_type difference_type;
- advanced_insert_aux_proxy(A& a, FwdIt first, FwdIt last)
- : a_(a), first_(first), last_(last)
+ insert_n_copies_proxy(A& a, const value_type &v)
+ : a_(a), v_(v)
{}
- virtual ~advanced_insert_aux_proxy()
- {}
+ void uninitialized_copy_n_and_update(Iterator p, size_type n)
+ { std::uninitialized_fill_n(p, n, v_); }
- virtual void copy_remaining_to(Iterator p)
- { ::boost::copy_or_move(this->first_, this->last_, p); }
+ void copy_n_and_update(Iterator p, size_type n)
+ { std::fill_n(p, n, v_); }
- virtual void uninitialized_copy_remaining_to(Iterator p)
- { ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, this->last_, p); }
+ A &a_;
+ const value_type &v_;
+};
- virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
+template<class A, class Iterator>
+struct insert_default_constructed_n_proxy
+{
+ typedef ::boost::container::allocator_traits<A> alloc_traits;
+ typedef typename allocator_traits<A>::size_type size_type;
+ typedef typename allocator_traits<A>::value_type value_type;
+
+
+ explicit insert_default_constructed_n_proxy(A &a)
+ : a_(a)
+ {}
+
+ void uninitialized_copy_n_and_update(Iterator p, size_type n)
{
- FwdIt mid = this->first_;
- std::advance(mid, division_count);
- if(first_n){
- ::boost::container::uninitialized_copy_or_move_alloc(this->a_, this->first_, mid, pos);
- this->first_ = mid;
+ 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));
+ }
}
- else{
- ::boost::container::uninitialized_copy_or_move_alloc(this->a_, mid, this->last_, pos);
- this->last_ = mid;
+ 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
}
- virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
+ void copy_n_and_update(Iterator, size_type)
{
- FwdIt mid = this->first_;
- std::advance(mid, division_count);
- if(first_n){
- ::boost::copy_or_move(this->first_, mid, pos);
- this->first_ = mid;
- }
- else{
- ::boost::copy_or_move(mid, this->last_, pos);
- this->last_ = mid;
- }
+ BOOST_ASSERT(false);
}
+
+ private:
A &a_;
- FwdIt first_, last_;
};
-//This class template will adapt default construction insertions to advanced_insert_aux_int
template<class A, class Iterator>
-struct default_construct_aux_proxy
- : public advanced_insert_aux_int<Iterator>
+struct insert_copy_proxy
{
- typedef ::boost::container::allocator_traits<A> alloc_traits;
- typedef typename allocator_traits<A>::size_type size_type;
- typedef typename allocator_traits<A>::value_type value_type;
- typedef typename advanced_insert_aux_int<Iterator>::difference_type difference_type;
-
- default_construct_aux_proxy(A &a, size_type count)
- : a_(a), count_(count)
- {}
+ typedef boost::container::allocator_traits<A> alloc_traits;
+ typedef typename alloc_traits::size_type size_type;
+ typedef typename alloc_traits::value_type value_type;
- virtual ~default_construct_aux_proxy()
+ insert_copy_proxy(A& a, const value_type &v)
+ : a_(a), v_(v)
{}
- virtual void copy_remaining_to(Iterator)
- { //This should never be called with any count
- BOOST_ASSERT(this->count_ == 0);
+ void uninitialized_copy_n_and_update(Iterator p, size_type n)
+ {
+ BOOST_ASSERT(n == 1); (void)n;
+ alloc_traits::construct( this->a_
+ , container_detail::to_raw_pointer(&*p)
+ , v_
+ );
}
- virtual void uninitialized_copy_remaining_to(Iterator p)
- { this->priv_uninitialized_copy(p, this->count_); }
-
- virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
+ void copy_n_and_update(Iterator p, size_type n)
{
- size_type new_count;
- if(first_n){
- new_count = division_count;
- }
- else{
- BOOST_ASSERT(difference_type(this->count_)>= division_count);
- new_count = this->count_ - division_count;
- }
- this->priv_uninitialized_copy(pos, new_count);
+ BOOST_ASSERT(n == 1); (void)n;
+ *p =v_;
}
- virtual void copy_some_and_update(Iterator , difference_type division_count, bool first_n)
+ A &a_;
+ const value_type &v_;
+};
+
+
+template<class A, class Iterator>
+struct insert_move_proxy
+{
+ typedef boost::container::allocator_traits<A> alloc_traits;
+ typedef typename alloc_traits::size_type size_type;
+ typedef typename alloc_traits::value_type value_type;
+
+ insert_move_proxy(A& a, value_type &v)
+ : a_(a), v_(v)
+ {}
+
+ void uninitialized_copy_n_and_update(Iterator p, size_type n)
{
- BOOST_ASSERT(this->count_ == 0);
- size_type new_count;
- if(first_n){
- new_count = division_count;
- }
- else{
- BOOST_ASSERT(difference_type(this->count_)>= division_count);
- new_count = this->count_ - division_count;
- }
- //This function should never called with a count different to zero
- BOOST_ASSERT(new_count == 0);
- (void)new_count;
+ BOOST_ASSERT(n == 1); (void)n;
+ alloc_traits::construct( this->a_
+ , container_detail::to_raw_pointer(&*p)
+ , ::boost::move(v_)
+ );
}
- private:
- void priv_uninitialized_copy(Iterator p, const size_type n)
+ void copy_n_and_update(Iterator p, size_type n)
{
- BOOST_ASSERT(n <= this->count_);
- Iterator orig_p = p;
- size_type i = 0;
- try{
- for(; i < n; ++i, ++p){
- alloc_traits::construct(this->a_, container_detail::to_raw_pointer(&*p));
- }
- }
- catch(...){
- while(i--){
- alloc_traits::destroy(this->a_, container_detail::to_raw_pointer(&*orig_p++));
- }
- throw;
- }
- this->count_ -= n;
+ BOOST_ASSERT(n == 1); (void)n;
+ *p = ::boost::move(v_);
}
+
A &a_;
- size_type count_;
+ value_type &v_;
};
+template<class It, class A>
+insert_move_proxy<A, It> get_insert_value_proxy(A& a, BOOST_RV_REF(typename std::iterator_traits<It>::value_type) v)
+{
+ return insert_move_proxy<A, It>(a, v);
+}
+
+template<class It, class A>
+insert_copy_proxy<A, It> get_insert_value_proxy(A& a, const typename std::iterator_traits<It>::value_type &v)
+{
+ return insert_copy_proxy<A, It>(a, v);
+}
+
}}} //namespace boost { namespace container { namespace container_detail {
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/variadic_templates_tools.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include <typeinfo>
//#include <iostream> //For debugging purposes
@@ -181,138 +198,74 @@
namespace container {
namespace container_detail {
-
-//This class template will adapt emplace construction insertions of movable types
-//to advanced_insert_aux_int
template<class A, class Iterator, class ...Args>
-struct advanced_insert_aux_non_movable_emplace
- : public advanced_insert_aux_int<Iterator>
+struct insert_non_movable_emplace_proxy
{
- typedef boost::container::allocator_traits<A> alloc_traits;
- typedef typename allocator_traits<A>::size_type size_type;
- typedef typename allocator_traits<A>::value_type value_type;
- typedef typename advanced_insert_aux_int<Iterator>::difference_type difference_type;
- typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
+ typedef boost::container::allocator_traits<A> alloc_traits;
+ typedef typename alloc_traits::size_type size_type;
+ typedef typename alloc_traits::value_type value_type;
- explicit advanced_insert_aux_non_movable_emplace(A &a, Args&&... args)
- : a_(a)
- , args_(args...)
- , used_(false)
- {}
+ typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
- ~advanced_insert_aux_non_movable_emplace()
+ explicit insert_non_movable_emplace_proxy(A &a, Args&&... args)
+ : a_(a), args_(args...)
{}
- virtual void copy_remaining_to(Iterator)
- //This code can't be called since value_type is not movable or copyable
- { BOOST_ASSERT(false); }
-
- virtual void uninitialized_copy_remaining_to(Iterator p)
- { this->priv_uninitialized_copy_remaining_to(index_tuple_t(), p); }
-
- virtual void uninitialized_copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
- { this->priv_uninitialized_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
-
- virtual void copy_some_and_update(Iterator, difference_type, bool )
- //This code can't be called since value_type is not movable or copyable
- { BOOST_ASSERT(false); }
+ void uninitialized_copy_n_and_update(Iterator p, size_type n)
+ { this->priv_uninitialized_copy_some_and_update(index_tuple_t(), p, n); }
private:
template<int ...IdxPack>
- void priv_uninitialized_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, difference_type division_count, bool first_n)
- {
- BOOST_ASSERT(division_count <=1);
- if((first_n && division_count == 1) || (!first_n && division_count == 0)){
- if(!this->used_){
- alloc_traits::construct( this->a_
- , container_detail::to_raw_pointer(&*p)
- , ::boost::forward<Args>(get<IdxPack>(this->args_))...
- );
- this->used_ = true;
- }
- }
- }
-
- template<int ...IdxPack>
- void priv_uninitialized_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p)
+ void priv_uninitialized_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, size_type n)
{
- if(!this->used_){
- alloc_traits::construct( this->a_
- , container_detail::to_raw_pointer(&*p)
- , ::boost::forward<Args>(get<IdxPack>(this->args_))...
- );
- this->used_ = true;
- }
+ BOOST_ASSERT(n == 1); (void)n;
+ alloc_traits::construct( this->a_
+ , container_detail::to_raw_pointer(&*p)
+ , ::boost::forward<Args>(get<IdxPack>(this->args_))...
+ );
}
protected:
A &a_;
tuple<Args&...> args_;
- bool used_;
};
-//This class template will adapt emplace construction insertions of movable types
-//to advanced_insert_aux_int
template<class A, class Iterator, class ...Args>
-struct advanced_insert_aux_emplace
- : public advanced_insert_aux_non_movable_emplace<A, Iterator, Args...>
+struct insert_emplace_proxy
+ : public insert_non_movable_emplace_proxy<A, Iterator, Args...>
{
- typedef advanced_insert_aux_non_movable_emplace<A, Iterator, Args...> base_t;
- typedef boost::container::allocator_traits<A> alloc_traits;
- typedef typename base_t::value_type value_type;
- typedef typename base_t::difference_type difference_type;
- typedef typename base_t::index_tuple_t index_tuple_t;
+ typedef insert_non_movable_emplace_proxy<A, Iterator, Args...> base_t;
+ typedef boost::container::allocator_traits<A> alloc_traits;
+ typedef typename base_t::value_type value_type;
+ typedef typename base_t::size_type size_type;
+ typedef typename base_t::index_tuple_t index_tuple_t;
- explicit advanced_insert_aux_emplace(A &a, Args&&... args)
+ explicit insert_emplace_proxy(A &a, Args&&... args)
: base_t(a, ::boost::forward<Args>(args)...)
{}
- ~advanced_insert_aux_emplace()
- {}
-
- //Override only needed functions
- virtual void copy_remaining_to(Iterator p)
- { this->priv_copy_remaining_to(index_tuple_t(), p); }
-
- virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
- { this->priv_copy_some_and_update(index_tuple_t(), p, division_count, first_n); }
+ void copy_n_and_update(Iterator p, size_type n)
+ { this->priv_copy_some_and_update(index_tuple_t(), p, n); }
private:
+
template<int ...IdxPack>
- void priv_copy_remaining_to(const index_tuple<IdxPack...>&, Iterator p)
+ void priv_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, size_type n)
{
- if(!this->used_){
- aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
- value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
- alloc_traits::construct(this->a_, vp,
- ::boost::forward<Args>(get<IdxPack>(this->args_))...);
- scoped_destructor<A> d(this->a_, vp);
+ BOOST_ASSERT(n ==1); (void)n;
+ aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
+ value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
+ alloc_traits::construct(this->a_, vp,
+ ::boost::forward<Args>(get<IdxPack>(this->args_))...);
+ BOOST_TRY{
*p = ::boost::move(*vp);
- d.release();
- this->used_ = true;
}
- }
-
- template<int ...IdxPack>
- void priv_copy_some_and_update(const index_tuple<IdxPack...>&, Iterator p, difference_type division_count, bool first_n)
- {
- BOOST_ASSERT(division_count <=1);
- if((first_n && division_count == 1) || (!first_n && division_count == 0)){
- if(!this->used_){
- aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
- value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
- alloc_traits::construct(this->a_, vp,
- ::boost::forward<Args>(get<IdxPack>(this->args_))...);
- try {
- *p = ::boost::move(*vp);
- } catch (...) {
- alloc_traits::destroy(this->a_, vp);
- throw;
- }
- alloc_traits::destroy(this->a_, vp);
- this->used_ = true;
- }
+ BOOST_CATCH(...){
+ alloc_traits::destroy(this->a_, vp);
+ BOOST_RETHROW
}
+ BOOST_CATCH_END
+ alloc_traits::destroy(this->a_, vp);
}
};
@@ -327,115 +280,73 @@
namespace container {
namespace container_detail {
-#define BOOST_PP_LOCAL_MACRO(n) \
-template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
-struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_non_movable_emplace, n), arg) \
- : public advanced_insert_aux_int<Iterator> \
+#define BOOST_PP_LOCAL_MACRO(N) \
+template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, class P) > \
+struct BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
{ \
typedef boost::container::allocator_traits<A> alloc_traits; \
- typedef typename allocator_traits<A>::size_type size_type; \
- typedef typename allocator_traits<A>::value_type value_type; \
- typedef typename advanced_insert_aux_int<Iterator>::difference_type \
- difference_type; \
+ typedef typename alloc_traits::size_type size_type; \
+ typedef typename alloc_traits::value_type value_type; \
\
- BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_non_movable_emplace, n), arg) \
- ( A &a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
+ BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
+ ( A &a BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
: a_(a) \
- , used_(false) \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_INIT, _) \
- {} \
- \
- virtual void copy_remaining_to(Iterator) \
- { BOOST_ASSERT(false); } \
+ BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_PARAM_INIT, _) \
+ {} \
\
- virtual void uninitialized_copy_remaining_to(Iterator p) \
+ void uninitialized_copy_n_and_update(Iterator p, size_type n) \
{ \
- if(!this->used_){ \
- alloc_traits::construct \
- ( this->a_ \
- , container_detail::to_raw_pointer(&*p) \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
- ); \
- this->used_ = true; \
- } \
+ BOOST_ASSERT(n == 1); (void)n; \
+ alloc_traits::construct \
+ ( this->a_ \
+ , container_detail::to_raw_pointer(&*p) \
+ BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
+ ); \
} \
\
- virtual void uninitialized_copy_some_and_update \
- (Iterator p, difference_type division_count, bool first_n) \
- { \
- BOOST_ASSERT(division_count <=1); \
- if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
- if(!this->used_){ \
- alloc_traits::construct \
- ( this->a_ \
- , container_detail::to_raw_pointer(&*p) \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
- ); \
- this->used_ = true; \
- } \
- } \
- } \
- \
- virtual void copy_some_and_update(Iterator, difference_type, bool) \
+ void copy_n_and_update(Iterator, size_type) \
{ BOOST_ASSERT(false); } \
\
+ protected: \
A &a_; \
- bool used_; \
- BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
+ BOOST_PP_REPEAT(N, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
}; \
\
-template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
-struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
- : BOOST_PP_CAT(BOOST_PP_CAT( \
- advanced_insert_aux_non_movable_emplace, n), arg) \
- < A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P) > \
+template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, class P) > \
+struct BOOST_PP_CAT(insert_emplace_proxy_arg, N) \
+ : BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
+ < A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > \
{ \
- typedef BOOST_PP_CAT(BOOST_PP_CAT( \
- advanced_insert_aux_non_movable_emplace, n), arg) \
- <A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P) > base_t; \
+ typedef BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
+ <A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > base_t; \
typedef typename base_t::value_type value_type; \
- typedef typename base_t::difference_type difference_type; \
+ typedef typename base_t::size_type size_type; \
typedef boost::container::allocator_traits<A> alloc_traits; \
\
- BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
- ( A &a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
- : base_t(a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ) \
- {} \
+ BOOST_PP_CAT(insert_emplace_proxy_arg, N) \
+ ( A &a BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
+ : base_t(a BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ) \
+ {} \
\
- virtual void copy_remaining_to(Iterator p) \
+ void copy_n_and_update(Iterator p, size_type n) \
{ \
- if(!this->used_){ \
- aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
- value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
- alloc_traits::construct(this->a_, vp \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
- scoped_destructor<A> d(this->a_, vp); \
+ BOOST_ASSERT(n == 1); (void)n; \
+ aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
+ value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
+ alloc_traits::construct(this->a_, vp \
+ BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
+ BOOST_TRY{ \
*p = ::boost::move(*vp); \
- d.release(); \
- this->used_ = true; \
} \
- } \
- \
- virtual void copy_some_and_update \
- (Iterator p, difference_type division_count, bool first_n) \
- { \
- BOOST_ASSERT(division_count <=1); \
- if((first_n && division_count == 1) || (!first_n && division_count == 0)){ \
- if(!this->used_){ \
- aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
- value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
- alloc_traits::construct(this->a_, vp \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
- scoped_destructor<A> d(this->a_, vp); \
- *p = ::boost::move(*vp); \
- d.release(); \
- this->used_ = true; \
- } \
+ BOOST_CATCH(...){ \
+ alloc_traits::destroy(this->a_, vp); \
+ BOOST_RETHROW \
} \
+ BOOST_CATCH_END \
+ alloc_traits::destroy(this->a_, vp); \
} \
}; \
//!
-
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
Modified: branches/release/boost/container/detail/destroyers.hpp
==============================================================================
--- branches/release/boost/container/detail/destroyers.hpp (original)
+++ branches/release/boost/container/detail/destroyers.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -188,13 +188,17 @@
void increment_size_backwards(size_type inc)
{ m_n += inc; m_p -= inc; }
+
+ void shrink_forward(size_type inc)
+ { m_n -= inc; m_p += inc; }
~scoped_destructor_n()
{
if(!m_p) return;
value_type *raw_ptr = container_detail::to_raw_pointer(m_p);
- for(size_type i = 0; i < m_n; ++i, ++raw_ptr)
+ while(m_n--){
AllocTraits::destroy(m_a, raw_ptr);
+ }
}
private:
@@ -323,7 +327,7 @@
void operator()(const typename A::pointer &p)
{
allocator_traits<A>::destroy(a_, container_detail::to_raw_pointer(p));
- c_.push_front(p);
+ c_.push_back(p);
}
};
@@ -348,8 +352,7 @@
~allocator_multialloc_chain_node_deallocator()
{
- if(!c_.empty())
- a_.deallocate_individual(boost::move(c_));
+ a_.deallocate_individual(c_);
}
};
Modified: branches/release/boost/container/detail/flat_tree.hpp
==============================================================================
--- branches/release/boost/container/detail/flat_tree.hpp (original)
+++ branches/release/boost/container/detail/flat_tree.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -25,7 +25,7 @@
#include <utility>
#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/pair.hpp>
@@ -48,7 +48,7 @@
typedef Value first_argument_type;
typedef Value second_argument_type;
typedef bool return_type;
- public:
+ public:
flat_tree_value_compare()
: Compare()
{}
@@ -65,7 +65,7 @@
const Compare &get_comp() const
{ return *this; }
-
+
Compare &get_comp()
{ return *this; }
};
@@ -238,7 +238,7 @@
flat_tree& operator=(BOOST_RV_REF(flat_tree) mx)
{ m_data = boost::move(mx.m_data); return *this; }
- public:
+ public:
// accessors:
Compare key_comp() const
{ return this->m_data.get_comp(); }
@@ -441,17 +441,17 @@
//Prereserve all memory so that iterators are not invalidated
this->reserve(this->size()+len);
- const const_iterator beg(this->cbegin());
- const_iterator pos(beg);
+ const const_iterator b(this->cbegin());
+ const_iterator pos(b);
//Loop in burst sizes
while(len){
const size_type burst = len < BurstSize ? len : BurstSize;
- const const_iterator cend_(this->cend());
+ const const_iterator ce(this->cend());
len -= burst;
for(size_type i = 0; i != burst; ++i){
//Get the insertion position for each key
- pos = const_cast<const flat_tree&>(*this).priv_upper_bound(pos, cend_, KeyOfValue()(*first));
- positions[i] = static_cast<size_type>(pos - beg);
+ pos = const_cast<const flat_tree&>(*this).priv_upper_bound(pos, ce, KeyOfValue()(*first));
+ positions[i] = static_cast<size_type>(pos - b);
++first;
}
//Insert all in a single step in the precalculated positions
@@ -489,22 +489,22 @@
//Prereserve all memory so that iterators are not invalidated
this->reserve(this->size()+len);
- const const_iterator beg(this->cbegin());
- const_iterator pos(beg);
+ const const_iterator b(this->cbegin());
+ const_iterator pos(b);
const value_compare &value_comp = this->m_data;
skips[0u] = 0u;
//Loop in burst sizes
while(len){
const size_type burst = len < BurstSize ? len : BurstSize;
size_type unique_burst = 0u;
- const const_iterator cend_(this->cend());
+ const const_iterator ce(this->cend());
while(unique_burst < burst && len > 0){
//Get the insertion position for each key
const value_type & val = *first++;
--len;
- pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, cend_, KeyOfValue()(val));
+ pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, ce, KeyOfValue()(val));
//Check if already present
- if(pos != cend_ && !value_comp(val, *pos)){
+ if(pos != ce && !value_comp(val, *pos)){
if(unique_burst > 0){
++skips[unique_burst-1];
}
@@ -512,7 +512,7 @@
}
//If not present, calculate position
- positions[unique_burst] = static_cast<size_type>(pos - beg);
+ positions[unique_burst] = static_cast<size_type>(pos - b);
skips[unique_burst++] = 0u;
}
if(unique_burst){
@@ -692,22 +692,22 @@
// set operations:
iterator find(const key_type& k)
{
- const Compare &key_comp_ = this->m_data.get_comp();
+ const Compare &key_cmp = this->m_data.get_comp();
iterator i = this->lower_bound(k);
- if (i != this->end() && key_comp_(k, KeyOfValue()(*i))){
- i = this->end();
+ if (i != this->end() && key_cmp(k, KeyOfValue()(*i))){
+ i = this->end();
}
return i;
}
const_iterator find(const key_type& k) const
{
- const Compare &key_comp_ = this->m_data.get_comp();
+ const Compare &key_cmp = this->m_data.get_comp();
const_iterator i = this->lower_bound(k);
- if (i != this->end() && key_comp_(k, KeyOfValue()(*i))){
- i = this->end();
+ if (i != this->end() && key_cmp(k, KeyOfValue()(*i))){
+ i = this->end();
}
return i;
}
@@ -737,11 +737,11 @@
std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
{ return this->priv_equal_range(this->begin(), this->end(), k); }
- size_type capacity() const
+ size_type capacity() const
{ return this->m_data.m_vect.capacity(); }
- void reserve(size_type count_)
- { this->m_data.m_vect.reserve(count_); }
+ void reserve(size_type cnt)
+ { this->m_data.m_vect.reserve(cnt); }
private:
struct insert_commit_data
@@ -780,13 +780,13 @@
}
std::pair<iterator,bool> priv_insert_unique_prepare
- (const_iterator beg, const_iterator end_, const value_type& val, insert_commit_data &commit_data)
+ (const_iterator b, const_iterator e, const value_type& val, insert_commit_data &commit_data)
{
const value_compare &value_comp = this->m_data;
- commit_data.position = this->priv_lower_bound(beg, end_, KeyOfValue()(val));
+ commit_data.position = this->priv_lower_bound(b, e, KeyOfValue()(val));
return std::pair<iterator,bool>
( *reinterpret_cast<iterator*>(&commit_data.position)
- , commit_data.position == end_ || value_comp(val, *commit_data.position));
+ , commit_data.position == e || value_comp(val, *commit_data.position));
}
std::pair<iterator,bool> priv_insert_unique_prepare
@@ -854,7 +854,7 @@
RanIt priv_lower_bound(RanIt first, RanIt last,
const key_type & key) const
{
- const Compare &key_comp_ = this->m_data.get_comp();
+ const Compare &key_cmp = this->m_data.get_comp();
KeyOfValue key_extract;
difference_type len = last - first, half;
RanIt middle;
@@ -864,7 +864,7 @@
middle = first;
middle += half;
- if (key_comp_(key_extract(*middle), key)) {
+ if (key_cmp(key_extract(*middle), key)) {
++middle;
first = middle;
len = len - half - 1;
@@ -879,7 +879,7 @@
RanIt priv_upper_bound(RanIt first, RanIt last,
const key_type & key) const
{
- const Compare &key_comp_ = this->m_data.get_comp();
+ const Compare &key_cmp = this->m_data.get_comp();
KeyOfValue key_extract;
difference_type len = last - first, half;
RanIt middle;
@@ -889,12 +889,12 @@
middle = first;
middle += half;
- if (key_comp_(key, key_extract(*middle))) {
+ if (key_cmp(key, key_extract(*middle))) {
len = half;
}
else{
first = ++middle;
- len = len - half - 1;
+ len = len - half - 1;
}
}
return first;
@@ -904,7 +904,7 @@
std::pair<RanIt, RanIt>
priv_equal_range(RanIt first, RanIt last, const key_type& key) const
{
- const Compare &key_comp_ = this->m_data.get_comp();
+ const Compare &key_cmp = this->m_data.get_comp();
KeyOfValue key_extract;
difference_type len = last - first, half;
RanIt middle, left, right;
@@ -914,12 +914,12 @@
middle = first;
middle += half;
- if (key_comp_(key_extract(*middle), key)){
+ if (key_cmp(key_extract(*middle), key)){
first = middle;
++first;
len = len - half - 1;
}
- else if (key_comp_(key, key_extract(*middle))){
+ else if (key_cmp(key, key_extract(*middle))){
len = half;
}
else {
@@ -1033,7 +1033,7 @@
class C, class A>
struct has_trivial_destructor_after_move<boost::container::container_detail::flat_tree<K, V, KOV, C, A> >
{
- static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
};
*/
} //namespace boost {
Modified: branches/release/boost/container/detail/iterators.hpp
==============================================================================
--- branches/release/boost/container/detail/iterators.hpp (original)
+++ branches/release/boost/container/detail/iterators.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -20,7 +20,7 @@
#include "config_begin.hpp"
#include <boost/container/detail/workaround.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/type_traits.hpp>
Modified: branches/release/boost/container/detail/multiallocation_chain.hpp
==============================================================================
--- branches/release/boost/container/detail/multiallocation_chain.hpp (original)
+++ branches/release/boost/container/detail/multiallocation_chain.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -19,7 +19,7 @@
#include <boost/intrusive/slist.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/type_traits/make_unsigned.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
namespace boost {
namespace container {
@@ -50,41 +50,38 @@
typedef typename boost::intrusive::
pointer_traits<node_ptr> node_ptr_traits;
- static node & build_node(const VoidPointer &p)
- {
- return *::new (static_cast<node*>(static_cast<void*>(container_detail::to_raw_pointer(p)))) node;
- }
+ static node & to_node(const VoidPointer &p)
+ { return *static_cast<node*>(static_cast<void*>(container_detail::to_raw_pointer(p))); }
- static VoidPointer destroy_node(node &n)
- {
- VoidPointer retptr = node_ptr_traits::pointer_to(n);
- n.~node();
- return retptr;
- }
+ static VoidPointer from_node(node &n)
+ { return node_ptr_traits::pointer_to(n); }
- static node_ptr to_node_ptr(VoidPointer p)
+ static node_ptr to_node_ptr(const VoidPointer &p)
{ return node_ptr_traits::static_cast_from(p); }
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain)
public:
- typedef VoidPointer void_pointer;
- typedef typename slist_impl_t::iterator iterator;
- typedef typename slist_impl_t::size_type size_type;
+ typedef VoidPointer void_pointer;
+ typedef typename slist_impl_t::iterator iterator;
+ typedef typename slist_impl_t::size_type size_type;
basic_multiallocation_chain()
: slist_impl_()
{}
+ basic_multiallocation_chain(const void_pointer &b, const void_pointer &before_e, size_type n)
+ : slist_impl_(to_node_ptr(b), to_node_ptr(before_e), n)
+ {}
+
basic_multiallocation_chain(BOOST_RV_REF(basic_multiallocation_chain) other)
- : slist_impl_()
- { slist_impl_.swap(other.slist_impl_); }
+ : slist_impl_(::boost::move(other.slist_impl_))
+ {}
basic_multiallocation_chain& operator=(BOOST_RV_REF(basic_multiallocation_chain) other)
{
- basic_multiallocation_chain tmp(boost::move(other));
- this->swap(tmp);
+ slist_impl_ = ::boost::move(other.slist_impl_);
return *this;
}
@@ -110,43 +107,54 @@
{ slist_impl_.clear(); }
iterator insert_after(iterator it, void_pointer m)
- { return slist_impl_.insert_after(it, build_node(m)); }
+ { return slist_impl_.insert_after(it, to_node(m)); }
- void push_front(void_pointer m)
- { return slist_impl_.push_front(build_node(m)); }
+ void push_front(const void_pointer &m)
+ { return slist_impl_.push_front(to_node(m)); }
- void push_back(void_pointer m)
- { return slist_impl_.push_back(build_node(m)); }
+ void push_back(const void_pointer &m)
+ { return slist_impl_.push_back(to_node(m)); }
void_pointer pop_front()
{
node & n = slist_impl_.front();
- void_pointer ret = destroy_node(n);
+ void_pointer ret = from_node(n);
slist_impl_.pop_front();
return ret;
}
- void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin_, iterator before_end)
- { slist_impl_.splice_after(after_this, x.slist_impl_, before_begin_, before_end); }
-
- void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin_, iterator before_end, size_type n)
- { slist_impl_.splice_after(after_this, x.slist_impl_, before_begin_, before_end, n); }
+ void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n)
+ { slist_impl_.splice_after(after_this, x.slist_impl_, before_b, before_e, n); }
void splice_after(iterator after_this, basic_multiallocation_chain &x)
{ slist_impl_.splice_after(after_this, x.slist_impl_); }
- void incorporate_after(iterator after_this, void_pointer begin_ , iterator before_end)
+ void erase_after(iterator before_b, iterator e, size_type n)
+ { slist_impl_.erase_after(before_b, e, n); }
+
+ void_pointer incorporate_after(iterator after_this, const void_pointer &b, size_type unit_bytes, size_type num_units)
{
- slist_impl_.incorporate_after(after_this, to_node_ptr(begin_), to_node_ptr(before_end));
+ typedef typename boost::intrusive::pointer_traits<char_ptr> char_pointer_traits;
+ char_ptr elem = char_pointer_traits::static_cast_from(b);
+ if(num_units){
+ char_ptr prev_elem = elem;
+ elem += unit_bytes;
+ for(size_type i = 0; i != num_units-1; ++i, elem += unit_bytes){
+ ::new (container_detail::to_raw_pointer(prev_elem)) void_pointer(elem);
+ prev_elem = elem;
+ }
+ slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(prev_elem), num_units);
+ }
+ return elem;
}
- void incorporate_after(iterator after_this, void_pointer begin_, void_pointer before_end, size_type n)
- { slist_impl_.incorporate_after(after_this, to_node_ptr(begin_), to_node_ptr(before_end), n); }
+ void incorporate_after(iterator after_this, void_pointer b, void_pointer before_e, size_type n)
+ { slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(before_e), n); }
void swap(basic_multiallocation_chain &x)
{ slist_impl_.swap(x.slist_impl_); }
- static iterator iterator_to(void_pointer p)
+ static iterator iterator_to(const void_pointer &p)
{ return slist_impl_t::s_iterator_to(to_node(p)); }
std::pair<void_pointer, void_pointer> extract_data()
@@ -170,11 +178,13 @@
template<class MultiallocationChain, class T>
class transform_multiallocation_chain
+ : public MultiallocationChain
{
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(transform_multiallocation_chain)
+ //transform_multiallocation_chain(const transform_multiallocation_chain &);
+ //transform_multiallocation_chain & operator=(const transform_multiallocation_chain &);
- MultiallocationChain holder_;
typedef typename MultiallocationChain::void_pointer void_pointer;
typedef typename boost::intrusive::pointer_traits
<void_pointer> void_pointer_traits;
@@ -193,39 +203,41 @@
typedef typename MultiallocationChain::size_type size_type;
transform_multiallocation_chain()
- : holder_()
+ : MultiallocationChain()
{}
transform_multiallocation_chain(BOOST_RV_REF(transform_multiallocation_chain) other)
- : holder_()
- { this->swap(other); }
+ : MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other)))
+ {}
transform_multiallocation_chain(BOOST_RV_REF(MultiallocationChain) other)
- : holder_(boost::move(other))
+ : MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other)))
{}
transform_multiallocation_chain& operator=(BOOST_RV_REF(transform_multiallocation_chain) other)
{
- transform_multiallocation_chain tmp(boost::move(other));
- this->swap(tmp);
- return *this;
+ return static_cast<MultiallocationChain&>
+ (this->MultiallocationChain::operator=(::boost::move(static_cast<MultiallocationChain&>(other))));
}
-
- void push_front(pointer mem)
+/*
+ void push_front(const pointer &mem)
{ holder_.push_front(mem); }
+ void push_back(const pointer &mem)
+ { return holder_.push_back(mem); }
+
void swap(transform_multiallocation_chain &other_chain)
{ holder_.swap(other_chain.holder_); }
- void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_begin_, iterator before_end, size_type n)
- { holder_.splice_after(after_this.base(), x.holder_, before_begin_.base(), before_end.base(), n); }
-
- void incorporate_after(iterator after_this, pointer begin_, pointer before_end, size_type n)
- { holder_.incorporate_after(after_this.base(), begin_, before_end, n); }
+ void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n)
+ { holder_.splice_after(after_this.base(), x.holder_, before_b.base(), before_e.base(), n); }
+ void incorporate_after(iterator after_this, pointer b, pointer before_e, size_type n)
+ { holder_.incorporate_after(after_this.base(), b, before_e, n); }
+*/
pointer pop_front()
- { return cast(holder_.pop_front()); }
-
+ { return cast(this->MultiallocationChain::pop_front()); }
+/*
bool empty() const
{ return holder_.empty(); }
@@ -246,23 +258,21 @@
void clear()
{ holder_.clear(); }
-
+*/
iterator insert_after(iterator it, pointer m)
- { return iterator(holder_.insert_after(it.base(), m)); }
+ { return iterator(this->MultiallocationChain::insert_after(it.base(), m)); }
- static iterator iterator_to(pointer p)
+ static iterator iterator_to(const pointer &p)
{ return iterator(MultiallocationChain::iterator_to(p)); }
std::pair<pointer, pointer> extract_data()
{
- std::pair<void_pointer, void_pointer> data(holder_.extract_data());
+ std::pair<void_pointer, void_pointer> data(this->MultiallocationChain::extract_data());
return std::pair<pointer, pointer>(cast(data.first), cast(data.second));
}
-
- MultiallocationChain extract_multiallocation_chain()
- {
- return MultiallocationChain(boost::move(holder_));
- }
+/*
+ MultiallocationChain &extract_multiallocation_chain()
+ { return holder_; }*/
};
}}}
Modified: branches/release/boost/container/detail/node_alloc_holder.hpp
==============================================================================
--- branches/release/boost/container/detail/node_alloc_holder.hpp (original)
+++ branches/release/boost/container/detail/node_alloc_holder.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -21,7 +21,7 @@
#include <utility>
#include <functional>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/container/detail/version_type.hpp>
@@ -30,6 +30,8 @@
#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/destroyers.hpp>
+#include <boost/container/detail/allocator_version_traits.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp>
@@ -89,6 +91,7 @@
typedef typename ICont::const_iterator icont_citerator;
typedef allocator_destroyer<NodeAlloc> Destroyer;
typedef allocator_traits<NodeAlloc> NodeAllocTraits;
+ typedef allocator_version_traits<NodeAlloc> AllocVersionTraits;
private:
BOOST_COPYABLE_AND_MOVABLE(node_alloc_holder)
@@ -151,22 +154,10 @@
{ return allocator_traits_type::max_size(this->node_alloc()); }
NodePtr allocate_one()
- { return this->allocate_one(alloc_version()); }
-
- NodePtr allocate_one(allocator_v1)
- { return this->node_alloc().allocate(1); }
-
- NodePtr allocate_one(allocator_v2)
- { return this->node_alloc().allocate_one(); }
+ { return AllocVersionTraits::allocate_one(this->node_alloc()); }
void deallocate_one(const NodePtr &p)
- { return this->deallocate_one(p, alloc_version()); }
-
- void deallocate_one(const NodePtr &p, allocator_v1)
- { this->node_alloc().deallocate(p, 1); }
-
- void deallocate_one(const NodePtr &p, allocator_v2)
- { this->node_alloc().deallocate_one(p); }
+ { AllocVersionTraits::deallocate_one(this->node_alloc(), p); }
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
@@ -235,40 +226,51 @@
}
template<class FwdIterator, class Inserter>
- FwdIterator allocate_many_and_construct
+ void allocate_many_and_construct
(FwdIterator beg, difference_type n, Inserter inserter)
{
- if(n){
- typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
+ /*
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ ::boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), it);
+ node_deallocator.release();
+ //This does not throw
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
+ return (p);
+ */
+ typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
- //Try to allocate memory in a single block
- multiallocation_chain mem(this->node_alloc().allocate_individual(n));
- int constructed = 0;
- Node *p = 0;
- BOOST_TRY{
- for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
- p = container_detail::to_raw_pointer(mem.pop_front());
- //This can throw
- constructed = 0;
- boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), beg);
- ++constructed;
- //This does not throw
- typedef typename Node::hook_type hook_type;
- ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
- //This can throw in some containers (predicate might throw)
- inserter(*p);
- }
+ //Try to allocate memory in a single block
+ typedef typename multiallocation_chain::iterator multialloc_iterator;
+ multiallocation_chain mem;
+ this->node_alloc().allocate_individual(n, mem);
+ multialloc_iterator itbeg(mem.begin()), itlast(mem.last());
+ mem.clear();
+ Node *p = 0;
+ NodeAlloc &nalloc = this->node_alloc();
+ BOOST_TRY{
+ while(n--){
+ p = container_detail::to_raw_pointer(&*itbeg);
+ ++itbeg;
+ //This can throw
+ Deallocator node_deallocator(p, nalloc);
+ boost::container::construct_in_place(nalloc, container_detail::addressof(p->m_data), beg);
+ ++beg;
+ node_deallocator.release();
+ //This does not throw
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(p)) hook_type;
+ //This can throw in some containers (predicate might throw)
+ inserter(*p);
}
- BOOST_CATCH(...){
- if(constructed){
- allocator_traits<NodeAlloc>::destroy(this->node_alloc(), container_detail::to_raw_pointer(p));
- }
- this->node_alloc().deallocate_individual(boost::move(mem));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
}
- return beg;
+ BOOST_CATCH(...){
+ mem.incorporate_after(mem.last(), &*itbeg, &*itlast, n);
+ this->node_alloc().deallocate_individual(mem);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
}
void clear(allocator_v1)
@@ -281,7 +283,7 @@
this->icont().clear_and_dispose(builder);
//BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled<typename NodeAlloc::multiallocation_chain>::value == true));
if(!chain.empty())
- this->node_alloc().deallocate_individual(boost::move(chain));
+ this->node_alloc().deallocate_individual(chain);
}
icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v1)
@@ -289,8 +291,13 @@
icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v2)
{
- allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
- return this->icont().erase_and_dispose(first, last, chain_holder.get_chain_builder());
+ typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
+ NodeAlloc & nalloc = this->node_alloc();
+ multiallocation_chain chain;
+ allocator_destroyer_and_chain_builder<NodeAlloc> chain_builder(nalloc, chain);
+ icont_iterator ret_it = this->icont().erase_and_dispose(first, last, chain_builder);
+ nalloc.deallocate_individual(chain);
+ return ret_it;
}
template<class Key, class Comparator>
Modified: branches/release/boost/container/detail/node_pool_impl.hpp
==============================================================================
--- branches/release/boost/container/detail/node_pool_impl.hpp (original)
+++ branches/release/boost/container/detail/node_pool_impl.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -26,10 +26,12 @@
#include <boost/container/detail/math_functions.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/pool_common.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
#include <boost/assert.hpp>
#include <cstddef>
#include <functional> //std::unary_function
+
namespace boost {
namespace container {
namespace container_detail {
@@ -85,19 +87,19 @@
{ return container_detail::to_raw_pointer(mp_segment_mngr_base); }
void *allocate_node()
- { return priv_alloc_node(); }
+ { return this->priv_alloc_node(); }
//!Deallocates an array pointed by ptr. Never throws
void deallocate_node(void *ptr)
- { priv_dealloc_node(ptr); }
+ { this->priv_dealloc_node(ptr); }
//!Allocates a singly linked list of n nodes ending in null pointer.
- multiallocation_chain allocate_nodes(const size_type n)
+ void allocate_nodes(const size_type n, multiallocation_chain &chain)
{
//Preallocate all needed blocks to fulfill the request
size_type cur_nodes = m_freelist.size();
if(cur_nodes < n){
- priv_alloc_block(((n - cur_nodes) - 1)/m_nodes_per_block + 1);
+ this->priv_alloc_block(((n - cur_nodes) - 1)/m_nodes_per_block + 1);
}
//We just iterate the needed nodes to get the last we'll erase
@@ -118,20 +120,18 @@
//Now take the last erased node and just splice it in the end
//of the intrusive list that will be traversed by the multialloc iterator.
- multiallocation_chain chain;
chain.incorporate_after(chain.before_begin(), &*first_node, &*last_node, n);
m_allocated += n;
- return boost::move(chain);
}
- void deallocate_nodes(multiallocation_chain chain)
+ void deallocate_nodes(multiallocation_chain &chain)
{
typedef typename multiallocation_chain::iterator iterator;
iterator it(chain.begin()), itend(chain.end());
while(it != itend){
void *pElem = &*it;
++it;
- priv_dealloc_node(pElem);
+ this->priv_dealloc_node(pElem);
}
}
@@ -275,7 +275,7 @@
{
//If there are no free nodes we allocate a new block
if (m_freelist.empty())
- priv_alloc_block();
+ this->priv_alloc_block(1);
//We take the first free node
node_t *n = (node_t*)&m_freelist.front();
m_freelist.pop_front();
@@ -295,14 +295,13 @@
}
//!Allocates several blocks of nodes. Can throw
- void priv_alloc_block(size_type num_blocks = 1)
+ void priv_alloc_block(size_type num_blocks)
{
- if(!num_blocks)
- return;
+ BOOST_ASSERT(num_blocks > 0);
size_type blocksize =
get_rounded_size(m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value);
- try{
+ BOOST_TRY{
for(size_type i = 0; i != num_blocks; ++i){
//We allocate a new NodeBlock and put it as first
//element in the free Node list
@@ -313,15 +312,16 @@
//We initialize all Nodes in Node Block to insert
//them in the free Node list
- for(size_type i = 0; i < m_nodes_per_block; ++i, pNode += m_real_node_size){
+ for(size_type j = 0; j < m_nodes_per_block; ++j, pNode += m_real_node_size){
m_freelist.push_front(*new (pNode) node_t);
}
}
}
- catch(...){
+ BOOST_CATCH(...){
//to-do: if possible, an efficient way to deallocate allocated blocks
- throw;
+ BOOST_RETHROW
}
+ BOOST_CATCH_END
}
//!Deprecated, use deallocate_free_blocks
Modified: branches/release/boost/container/detail/pair.hpp
==============================================================================
--- branches/release/boost/container/detail/pair.hpp (original)
+++ branches/release/boost/container/detail/pair.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -27,7 +27,7 @@
#include <utility> //std::pair
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include <boost/type_traits/is_class.hpp>
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
@@ -336,7 +336,7 @@
: public ::boost::true_type
{};
-#ifdef BOOST_NO_RVALUE_REFERENCES
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
template<class T1, class T2>
struct has_move_emulation_enabled< ::boost::container::container_detail::pair<T1, T2> >
Modified: branches/release/boost/container/detail/pool_common.hpp
==============================================================================
--- branches/release/boost/container/detail/pool_common.hpp (original)
+++ branches/release/boost/container/detail/pool_common.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -34,7 +34,7 @@
typedef slist_hook_t node_t;
typedef typename bi::make_slist
- <node_t, bi::linear<true>, bi::base_hook<slist_hook_t> >::type node_slist_t;
+ <node_t, bi::linear<true>, bi::cache_last<true>, bi::base_hook<slist_hook_t> >::type node_slist_t;
};
template<class T>
Modified: branches/release/boost/container/detail/preprocessor.hpp
==============================================================================
--- branches/release/boost/container/detail/preprocessor.hpp (original)
+++ branches/release/boost/container/detail/preprocessor.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -17,6 +17,7 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
+#include <boost/move/utility.hpp>
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
//#error "This file is not needed when perfect forwarding is available"
@@ -38,6 +39,7 @@
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/move/utility.hpp>
#define BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS 10
@@ -47,7 +49,7 @@
//This cast is ugly but it is necessary until "perfect forwarding"
//is achieved in C++0x. Meanwhile, if we want to be able to
//bind rvalues with non-const references, we have to be ugly
-#ifndef BOOST_NO_RVALUE_REFERENCES
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_PARAM_LIST(z, n, data) \
BOOST_PP_CAT(P, n) && BOOST_PP_CAT(p, n) \
//!
@@ -55,13 +57,13 @@
#define BOOST_CONTAINER_PP_PARAM_LIST(z, n, data) \
const BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n) \
//!
-#endif //#ifndef BOOST_NO_RVALUE_REFERENCES
+#endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q(z, n, Data) \
const BOOST_PP_CAT(Q, n) & BOOST_PP_CAT(q, n) \
//!
-#ifndef BOOST_NO_RVALUE_REFERENCES
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_PARAM(U, u) \
U && u \
//!
@@ -69,22 +71,22 @@
#define BOOST_CONTAINER_PP_PARAM(U, u) \
const U & u \
//!
-#endif //#ifndef BOOST_NO_RVALUE_REFERENCES
+#endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
-#ifndef BOOST_NO_RVALUE_REFERENCES
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
//!
-#else //BOOST_NO_RVALUE_REFERENCES
+#else //BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
//!
-#endif //#ifndef BOOST_NO_RVALUE_REFERENCES
+#endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
-#ifndef BOOST_NO_RVALUE_REFERENCES
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
@@ -97,7 +99,7 @@
template<class T>
struct ref_holder<T &>
{
- ref_holder(T &t)
+ explicit ref_holder(T &t)
: t_(t)
{}
T &t_;
@@ -107,7 +109,7 @@
template<class T>
struct ref_holder<const T>
{
- ref_holder(const T &t)
+ explicit ref_holder(const T &t)
: t_(t)
{}
const T &t_;
@@ -117,7 +119,7 @@
template<class T>
struct ref_holder<const T &&>
{
- ref_holder(const T &t)
+ explicit ref_holder(const T &t)
: t_(t)
{}
const T &t_;
@@ -127,7 +129,7 @@
template<class T>
struct ref_holder
{
- ref_holder(T &&t)
+ explicit ref_holder(T &&t)
: t_(t)
{}
T &t_;
@@ -137,10 +139,10 @@
template<class T>
struct ref_holder<T &&>
{
- ref_holder(T &&t)
- : t(t)
+ explicit ref_holder(T &&t)
+ : t_(t)
{}
- T &t;
+ T &t_;
T && get() { return ::boost::move(t_); }
};
@@ -160,25 +162,25 @@
#endif //defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
-#else //BOOST_NO_RVALUE_REFERENCES
+#else //BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data) \
BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
//!
-#endif //#ifndef BOOST_NO_RVALUE_REFERENCES
+#endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
-#if !defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) BOOST_PP_CAT(this->m_p, n).get() \
//!
-#else //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+#else //!defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) \
::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(this->m_p, n) ) \
//!
-#endif //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+#endif //!defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
#define BOOST_CONTAINER_PP_PARAM_INC(z, n, data) \
BOOST_PP_CAT(++this->m_p, n) \
Modified: branches/release/boost/container/detail/tree.hpp
==============================================================================
--- branches/release/boost/container/detail/tree.hpp (original)
+++ branches/release/boost/container/detail/tree.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -15,7 +15,7 @@
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/detail/no_exceptions_support.hpp>
@@ -28,6 +28,7 @@
#include <boost/container/detail/pair.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/allocator_traits.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp>
#endif
@@ -247,19 +248,20 @@
{
if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
//First recycle a node (this can't throw)
- try{
+ BOOST_TRY{
//This can throw
p->do_assign(other.m_data);
return p;
}
- catch(...){
+ BOOST_CATCH(...){
//If there is an exception destroy the whole source
m_holder.destroy_node(p);
while((p = m_icont.unlink_leftmost_without_rebalance())){
m_holder.destroy_node(p);
}
- throw;
+ BOOST_RETHROW
}
+ BOOST_CATCH_END
}
else{
return m_holder.create_node(other.m_data);
@@ -284,19 +286,20 @@
{
if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
//First recycle a node (this can't throw)
- try{
+ BOOST_TRY{
//This can throw
p->do_move_assign(const_cast<Node &>(other).m_data);
return p;
}
- catch(...){
+ BOOST_CATCH(...){
//If there is an exception destroy the whole source
m_holder.destroy_node(p);
while((p = m_icont.unlink_leftmost_without_rebalance())){
m_holder.destroy_node(p);
}
- throw;
+ BOOST_RETHROW
}
+ BOOST_CATCH_END
}
else{
return m_holder.create_node(other.m_data);
@@ -1121,7 +1124,7 @@
struct has_trivial_destructor_after_move
<boost::container::container_detail::rbtree<K, V, KOV, C, A> >
{
- static const bool value = has_trivial_destructor<A>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
};
*/
} //namespace boost {
Modified: branches/release/boost/container/detail/type_traits.hpp
==============================================================================
--- branches/release/boost/container/detail/type_traits.hpp (original)
+++ branches/release/boost/container/detail/type_traits.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -21,7 +21,7 @@
#include "config_begin.hpp"
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
namespace boost {
namespace container {
@@ -90,7 +90,7 @@
typedef T type;
};
-#ifndef BOOST_NO_RVALUE_REFERENCES
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template<class T>
struct remove_reference<T&&>
Modified: branches/release/boost/container/detail/utilities.hpp
==============================================================================
--- branches/release/boost/container/detail/utilities.hpp (original)
+++ branches/release/boost/container/detail/utilities.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -18,11 +18,14 @@
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_member_pointer.hpp>
#include <boost/type_traits/is_class.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/iterator.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/allocator_traits.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
#include <algorithm>
+#include <iterator>
namespace boost {
namespace container {
@@ -123,16 +126,6 @@
enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo };
};
-template<class T>
-struct move_const_ref_type
- : if_c
-// < ::boost::is_fundamental<T>::value || ::boost::is_pointer<T>::value || ::boost::is_member_pointer<T>::value || ::boost::is_enum<T>::value
- < !::boost::is_class<T>::value
- ,const T &
- ,BOOST_CATCH_CONST_RLVALUE(T)
- >
-{};
-
} //namespace container_detail {
//////////////////////////////////////////////////////////////////////////////
@@ -154,15 +147,97 @@
typename F> // F models ForwardIterator
F uninitialized_move_alloc(A &a, I f, I l, F r)
{
- while (f != l) {
- allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), boost::move(*f));
- ++f; ++r;
+ F back = r;
+ BOOST_TRY{
+ while (f != l) {
+ allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), boost::move(*f));
+ ++f; ++r;
+ }
+ }
+ BOOST_CATCH(...){
+ for (; back != r; ++back){
+ allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
+ }
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ return r;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// uninitialized_move_alloc_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//! \code
+//! for (; n--; ++result, ++first)
+//! allocator_traits::construct(a, &*result, boost::move(*first));
+//! \endcode
+//!
+//! <b>Returns</b>: result
+template
+ <typename A,
+ typename I, // I models InputIterator
+ typename F> // F models ForwardIterator
+F uninitialized_move_alloc_n(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
+{
+ F back = r;
+ BOOST_TRY{
+ while (n--) {
+ allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), boost::move(*f));
+ ++f; ++r;
+ }
+ }
+ BOOST_CATCH(...){
+ for (; back != r; ++back){
+ allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
+ }
+ BOOST_RETHROW;
}
+ BOOST_CATCH_END
return r;
}
//////////////////////////////////////////////////////////////////////////////
//
+// uninitialized_move_alloc_n_source
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//! \code
+//! for (; n--; ++result, ++first)
+//! allocator_traits::construct(a, &*result, boost::move(*first));
+//! \endcode
+//!
+//! <b>Returns</b>: first (after incremented)
+template
+ <typename A,
+ typename I, // I models InputIterator
+ typename F> // F models ForwardIterator
+I uninitialized_move_alloc_n_source(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
+{
+ F back = r;
+ BOOST_TRY{
+ while (n--) {
+ allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), boost::move(*f));
+ ++f; ++r;
+ }
+ }
+ BOOST_CATCH(...){
+ for (; back != r; ++back){
+ allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
+ }
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ return f;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
// uninitialized_copy_alloc
//
//////////////////////////////////////////////////////////////////////////////
@@ -180,15 +255,97 @@
typename F> // F models ForwardIterator
F uninitialized_copy_alloc(A &a, I f, I l, F r)
{
- while (f != l) {
- allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), *f);
- ++f; ++r;
+ F back = r;
+ BOOST_TRY{
+ while (f != l) {
+ allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), *f);
+ ++f; ++r;
+ }
+ }
+ BOOST_CATCH(...){
+ for (; back != r; ++back){
+ allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
+ }
+ BOOST_RETHROW;
}
+ BOOST_CATCH_END
return r;
}
//////////////////////////////////////////////////////////////////////////////
//
+// uninitialized_copy_alloc_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//! \code
+//! for (; n--; ++result, ++first)
+//! allocator_traits::construct(a, &*result, *first);
+//! \endcode
+//!
+//! <b>Returns</b>: result
+template
+ <typename A,
+ typename I, // I models InputIterator
+ typename F> // F models ForwardIterator
+F uninitialized_copy_alloc_n(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
+{
+ F back = r;
+ BOOST_TRY{
+ while (n--) {
+ allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), *f);
+ ++f; ++r;
+ }
+ }
+ BOOST_CATCH(...){
+ for (; back != r; ++back){
+ allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
+ }
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ return r;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// uninitialized_copy_alloc_n_source
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//! \code
+//! for (; n--; ++result, ++first)
+//! allocator_traits::construct(a, &*result, *first);
+//! \endcode
+//!
+//! <b>Returns</b>: first (after incremented)
+template
+ <typename A,
+ typename I, // I models InputIterator
+ typename F> // F models ForwardIterator
+I uninitialized_copy_alloc_n_source(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
+{
+ F back = r;
+ BOOST_TRY{
+ while (n--) {
+ allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), *f);
+ ++f; ++r;
+ }
+ }
+ BOOST_CATCH(...){
+ for (; back != r; ++back){
+ allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
+ }
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
+ return f;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
// uninitialized_copy_alloc
//
//////////////////////////////////////////////////////////////////////////////
@@ -206,10 +363,20 @@
typename T>
void uninitialized_fill_alloc(A &a, F f, F l, const T &t)
{
- while (f != l) {
- allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*f), t);
- ++f;
+ F back = f;
+ BOOST_TRY{
+ while (f != l) {
+ allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*f), t);
+ ++f;
+ }
+ }
+ BOOST_CATCH(...){
+ for (; back != l; ++back){
+ allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
+ }
+ BOOST_RETHROW;
}
+ BOOST_CATCH_END
}
//////////////////////////////////////////////////////////////////////////////
@@ -242,6 +409,168 @@
return ::boost::container::uninitialized_copy_alloc(a, f, l, r);
}
+//////////////////////////////////////////////////////////////////////////////
+//
+// uninitialized_copy_or_move_alloc_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename A
+,typename I // I models InputIterator
+,typename F> // F models ForwardIterator
+F uninitialized_copy_or_move_alloc_n
+ (A &a, I f, typename std::iterator_traits<I>::difference_type n, F r
+ ,typename boost::container::container_detail::enable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ return ::boost::container::uninitialized_move_alloc_n(a, f, n, r);
+}
+
+template
+<typename A
+,typename I // I models InputIterator
+,typename F> // F models ForwardIterator
+F uninitialized_copy_or_move_alloc_n
+ (A &a, I f, typename std::iterator_traits<I>::difference_type n, F r
+ ,typename boost::container::container_detail::disable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ return ::boost::container::uninitialized_copy_alloc_n(a, f, n, r);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// uninitialized_copy_or_move_alloc_n_source
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename A
+,typename I // I models InputIterator
+,typename F> // F models ForwardIterator
+I uninitialized_copy_or_move_alloc_n_source
+ (A &a, I f, typename std::iterator_traits<I>::difference_type n, F r
+ ,typename boost::container::container_detail::enable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ return ::boost::container::uninitialized_move_alloc_n_source(a, f, n, r);
+}
+
+template
+<typename A
+,typename I // I models InputIterator
+,typename F> // F models ForwardIterator
+I uninitialized_copy_or_move_alloc_n_source
+ (A &a, I f, typename std::iterator_traits<I>::difference_type n, F r
+ ,typename boost::container::container_detail::disable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ return ::boost::container::uninitialized_copy_alloc_n_source(a, f, n, r);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// copy_or_move
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+inline F copy_or_move(I f, I l, F r
+ ,typename boost::container::container_detail::enable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ while (f != l) {
+ *r = ::boost::move(*f);
+ ++f; ++r;
+ }
+ return r;
+}
+
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+inline F copy_or_move(I f, I l, F r
+ ,typename boost::container::container_detail::disable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ while (f != l) {
+ *r = *f;
+ ++f; ++r;
+ }
+ return r;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// copy_or_move_n
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+inline F copy_or_move_n(I f, typename std::iterator_traits<I>::difference_type n, F r
+ ,typename boost::container::container_detail::enable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ while (n--) {
+ *r = ::boost::move(*f);
+ ++f; ++r;
+ }
+ return r;
+}
+
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+inline F copy_or_move_n(I f, typename std::iterator_traits<I>::difference_type n, F r
+ ,typename boost::container::container_detail::disable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ while (n--) {
+ *r = *f;
+ ++f; ++r;
+ }
+ return r;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// copy_or_move_n_source
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+inline I copy_or_move_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r
+ ,typename boost::container::container_detail::enable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ while (n--) {
+ *r = ::boost::move(*f);
+ ++f; ++r;
+ }
+ return f;
+}
+
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+inline I copy_or_move_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r
+ ,typename boost::container::container_detail::disable_if
+ < boost::move_detail::is_move_iterator<I> >::type* = 0)
+{
+ while (n--) {
+ *r = *f;
+ ++f; ++r;
+ }
+ return f;
+}
} //namespace container {
} //namespace boost {
Modified: branches/release/boost/container/detail/workaround.hpp
==============================================================================
--- branches/release/boost/container/detail/workaround.hpp (original)
+++ branches/release/boost/container/detail/workaround.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -13,20 +13,24 @@
#include <boost/container/detail/config_begin.hpp>
-#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)\
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)\
&& !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL)
#define BOOST_CONTAINER_PERFECT_FORWARDING
#endif
-#if defined(BOOST_NO_NOEXCEPT)
- #define BOOST_CONTAINER_NOEXCEPT
+#if defined(BOOST_NO_CXX11_NOEXCEPT)
+ #if defined(BOOST_MSVC)
+ #define BOOST_CONTAINER_NOEXCEPT throw()
+ #else
+ #define BOOST_CONTAINER_NOEXCEPT
+ #endif
#define BOOST_CONTAINER_NOEXCEPT_IF(x)
#else
#define BOOST_CONTAINER_NOEXCEPT noexcept
#define BOOST_CONTAINER_NOEXCEPT_IF(x) noexcept(x)
#endif
-#if !defined(BOOST_NO_VARIADIC_TEMPLATES) && defined(__GXX_EXPERIMENTAL_CXX0X__)\
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(__GXX_EXPERIMENTAL_CXX0X__)\
&& (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40700)
#define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST
#endif
Modified: branches/release/boost/container/flat_map.hpp
==============================================================================
--- branches/release/boost/container/flat_map.hpp (original)
+++ branches/release/boost/container/flat_map.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -27,8 +27,8 @@
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/allocator_traits.hpp>
-#include <boost/move/move.hpp>
-#include <boost/move/move_helpers.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/detail/move_helpers.hpp>
namespace boost {
namespace container {
@@ -251,7 +251,7 @@
//! was passed to the object's constructor.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -261,7 +261,7 @@
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator()
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -271,7 +271,7 @@
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
//////////////////////////////////////////////
@@ -285,7 +285,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<iterator>(m_flat_tree.begin()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -293,7 +293,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<const_iterator>(m_flat_tree.begin()); }
//! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -301,7 +301,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<iterator>(m_flat_tree.end()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -309,7 +309,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<const_iterator>(m_flat_tree.end()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -318,7 +318,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -327,7 +327,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -336,7 +336,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<reverse_iterator>(m_flat_tree.rend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -345,7 +345,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -353,7 +353,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<const_iterator>(m_flat_tree.cbegin()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -361,7 +361,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<const_iterator>(m_flat_tree.cend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -370,7 +370,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -379,7 +379,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
+ const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
//////////////////////////////////////////////
@@ -393,7 +393,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.empty(); }
//! <b>Effects</b>: Returns the number of the elements contained in the container.
@@ -401,7 +401,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.size(); }
//! <b>Effects</b>: Returns the largest possible size of the container.
@@ -409,7 +409,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.max_size(); }
//! <b>Effects</b>: Number of elements for which memory has been allocated.
@@ -418,7 +418,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type capacity() const
+ size_type capacity() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.capacity(); }
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
@@ -428,10 +428,10 @@
//!
//! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
//!
- //! <b>Note</b>: If capacity() is less than "count", iterators and references to
+ //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
//! to values might be invalidated.
- void reserve(size_type count_)
- { m_flat_tree.reserve(count_); }
+ void reserve(size_type cnt)
+ { m_flat_tree.reserve(cnt); }
//! <b>Effects</b>: Tries to deallocate the excess of memory created
// with previous allocations. The size of the vector is unchanged
@@ -740,7 +740,7 @@
//! <b>Postcondition</b>: size() == 0.
//!
//! <b>Complexity</b>: linear in size().
- void clear()
+ void clear() BOOST_CONTAINER_NOEXCEPT
{ m_flat_tree.clear(); }
//////////////////////////////////////////////
@@ -900,15 +900,15 @@
/// @cond
} //namespace container {
-/*
+
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class K, class T, class C, class Allocator>
struct has_trivial_destructor_after_move<boost::container::flat_map<K, T, C, Allocator> >
{
- static const bool value = has_trivial_destructor<Allocator>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
};
-*/
+
namespace container {
// Forward declaration of operators < and ==, needed for friend declaration.
@@ -1099,7 +1099,7 @@
//! was passed to the object's constructor.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -1109,7 +1109,7 @@
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator()
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -1119,7 +1119,7 @@
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
//////////////////////////////////////////////
@@ -1133,7 +1133,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<iterator>(m_flat_tree.begin()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -1141,7 +1141,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<const_iterator>(m_flat_tree.begin()); }
//! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -1149,7 +1149,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<iterator>(m_flat_tree.end()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -1157,7 +1157,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<const_iterator>(m_flat_tree.end()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -1166,7 +1166,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -1175,7 +1175,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -1184,7 +1184,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<reverse_iterator>(m_flat_tree.rend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -1193,7 +1193,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -1201,7 +1201,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<const_iterator>(m_flat_tree.cbegin()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -1209,7 +1209,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<const_iterator>(m_flat_tree.cend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -1218,7 +1218,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -1227,7 +1227,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
+ const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
//////////////////////////////////////////////
@@ -1241,7 +1241,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.empty(); }
//! <b>Effects</b>: Returns the number of the elements contained in the container.
@@ -1249,7 +1249,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.size(); }
//! <b>Effects</b>: Returns the largest possible size of the container.
@@ -1257,7 +1257,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.max_size(); }
//! <b>Effects</b>: Number of elements for which memory has been allocated.
@@ -1266,7 +1266,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type capacity() const
+ size_type capacity() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.capacity(); }
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
@@ -1276,10 +1276,10 @@
//!
//! <b>Throws</b>: If memory allocation allocation throws or T's copy constructor throws.
//!
- //! <b>Note</b>: If capacity() is less than "count", iterators and references to
+ //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
//! to values might be invalidated.
- void reserve(size_type count_)
- { m_flat_tree.reserve(count_); }
+ void reserve(size_type cnt)
+ { m_flat_tree.reserve(cnt); }
//! <b>Effects</b>: Tries to deallocate the excess of memory created
// with previous allocations. The size of the vector is unchanged
@@ -1516,7 +1516,7 @@
//! <b>Postcondition</b>: size() == 0.
//!
//! <b>Complexity</b>: linear in size().
- void clear()
+ void clear() BOOST_CONTAINER_NOEXCEPT
{ m_flat_tree.clear(); }
//////////////////////////////////////////////
@@ -1655,15 +1655,15 @@
/// @cond
namespace boost {
-/*
+
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class K, class T, class C, class Allocator>
struct has_trivial_destructor_after_move< boost::container::flat_multimap<K, T, C, Allocator> >
{
- static const bool value = has_trivial_destructor<Allocator>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
};
-*/
+
} //namespace boost {
/// @endcond
Modified: branches/release/boost/container/flat_set.hpp
==============================================================================
--- branches/release/boost/container/flat_set.hpp (original)
+++ branches/release/boost/container/flat_set.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -25,8 +25,8 @@
#include <boost/container/detail/flat_tree.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/allocator_traits.hpp>
-#include <boost/move/move.hpp>
-#include <boost/move/move_helpers.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/detail/move_helpers.hpp>
namespace boost {
namespace container {
@@ -197,7 +197,7 @@
//! was passed to the object's constructor.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.get_allocator(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -207,7 +207,7 @@
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator()
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.get_stored_allocator(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -217,7 +217,7 @@
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.get_stored_allocator(); }
//////////////////////////////////////////////
@@ -231,7 +231,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.begin(); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -239,7 +239,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.begin(); }
//! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -247,7 +247,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.end(); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -255,7 +255,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.end(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -264,7 +264,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.rbegin(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -273,7 +273,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.rbegin(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -282,7 +282,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.rend(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -291,7 +291,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.rend(); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -299,7 +299,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.cbegin(); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -307,7 +307,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.cend(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -316,7 +316,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.crbegin(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -325,7 +325,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
+ const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.crend(); }
@@ -340,7 +340,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.empty(); }
//! <b>Effects</b>: Returns the number of the elements contained in the container.
@@ -348,7 +348,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.size(); }
//! <b>Effects</b>: Returns the largest possible size of the container.
@@ -356,7 +356,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.max_size(); }
//! <b>Effects</b>: Number of elements for which memory has been allocated.
@@ -365,7 +365,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type capacity() const
+ size_type capacity() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.capacity(); }
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
@@ -375,10 +375,10 @@
//!
//! <b>Throws</b>: If memory allocation allocation throws or Key's copy constructor throws.
//!
- //! <b>Note</b>: If capacity() is less than "count", iterators and references to
+ //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
//! to values might be invalidated.
- void reserve(size_type count_)
- { m_flat_tree.reserve(count_); }
+ void reserve(size_type cnt)
+ { m_flat_tree.reserve(cnt); }
//! <b>Effects</b>: Tries to deallocate the excess of memory created
// with previous allocations. The size of the vector is unchanged
@@ -582,7 +582,7 @@
//! <b>Postcondition</b>: size() == 0.
//!
//! <b>Complexity</b>: linear in size().
- void clear()
+ void clear() BOOST_CONTAINER_NOEXCEPT
{ m_flat_tree.clear(); }
//////////////////////////////////////////////
@@ -726,15 +726,15 @@
/// @cond
} //namespace container {
-/*
+
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class Key, class C, class Allocator>
struct has_trivial_destructor_after_move<boost::container::flat_set<Key, C, Allocator> >
{
- static const bool value = has_trivial_destructor<Allocator>::value &&has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<Allocator>::value &&has_trivial_destructor_after_move<C>::value;
};
-*/
+
namespace container {
// Forward declaration of operators < and ==, needed for friend declaration.
@@ -884,7 +884,7 @@
//! was passed to the object's constructor.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.get_allocator(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -894,7 +894,7 @@
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator()
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.get_stored_allocator(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -904,7 +904,7 @@
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.get_stored_allocator(); }
//! <b>Effects</b>: Returns an iterator to the first element contained in the container.
@@ -912,7 +912,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.begin(); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -928,7 +928,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.cbegin(); }
//! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -936,7 +936,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.end(); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -944,7 +944,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.end(); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -952,7 +952,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.cend(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -961,7 +961,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.rbegin(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -970,7 +970,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.rbegin(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -979,7 +979,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.crbegin(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -988,7 +988,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.rend(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -997,7 +997,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.rend(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -1006,7 +1006,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
+ const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.crend(); }
//////////////////////////////////////////////
@@ -1020,7 +1020,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.empty(); }
//! <b>Effects</b>: Returns the number of the elements contained in the container.
@@ -1028,7 +1028,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.size(); }
//! <b>Effects</b>: Returns the largest possible size of the container.
@@ -1036,7 +1036,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.max_size(); }
//! <b>Effects</b>: Number of elements for which memory has been allocated.
@@ -1045,7 +1045,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type capacity() const
+ size_type capacity() const BOOST_CONTAINER_NOEXCEPT
{ return m_flat_tree.capacity(); }
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
@@ -1055,10 +1055,10 @@
//!
//! <b>Throws</b>: If memory allocation allocation throws or Key's copy constructor throws.
//!
- //! <b>Note</b>: If capacity() is less than "count", iterators and references to
+ //! <b>Note</b>: If capacity() is less than "cnt", iterators and references to
//! to values might be invalidated.
- void reserve(size_type count_)
- { m_flat_tree.reserve(count_); }
+ void reserve(size_type cnt)
+ { m_flat_tree.reserve(cnt); }
//! <b>Effects</b>: Tries to deallocate the excess of memory created
// with previous allocations. The size of the vector is unchanged
@@ -1244,7 +1244,7 @@
//! <b>Postcondition</b>: size() == 0.
//!
//! <b>Complexity</b>: linear in size().
- void clear()
+ void clear() BOOST_CONTAINER_NOEXCEPT
{ m_flat_tree.clear(); }
//////////////////////////////////////////////
@@ -1388,15 +1388,15 @@
/// @cond
} //namespace container {
-/*
+
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class Key, class C, class Allocator>
struct has_trivial_destructor_after_move<boost::container::flat_multiset<Key, C, Allocator> >
{
- static const bool value = has_trivial_destructor<Allocator>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
};
-*/
+
namespace container {
/// @endcond
Modified: branches/release/boost/container/list.hpp
==============================================================================
--- branches/release/boost/container/list.hpp (original)
+++ branches/release/boost/container/list.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -18,8 +18,9 @@
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/version_type.hpp>
-#include <boost/move/move.hpp>
-#include <boost/move/move_helpers.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/detail/move_helpers.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/algorithms.hpp>
@@ -140,9 +141,6 @@
friend bool operator!= (const list_const_iterator& l, const list_const_iterator& r)
{ return l.m_it != r.m_it; }
- IIterator &get()
- { return this->m_it; }
-
const IIterator &get() const
{ return this->m_it; }
};
@@ -187,9 +185,6 @@
list_iterator operator--(int)
{ IIterator tmp = this->m_it; --*this; return list_iterator(tmp); }
- IIterator &get()
- { return this->m_it; }
-
const IIterator &get() const
{ return this->m_it; }
};
@@ -303,10 +298,10 @@
//! <b>Effects</b>: Constructs a list taking the allocator as parameter.
//!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
- explicit list(const allocator_type &a)
+ explicit list(const allocator_type &a) BOOST_CONTAINER_NOEXCEPT
: AllocHolder(a)
{}
@@ -398,7 +393,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements.
- ~list()
+ ~list() BOOST_CONTAINER_NOEXCEPT
{} //AllocHolder clears the list
//! <b>Effects</b>: Makes *this contain the same elements as x.
@@ -498,7 +493,7 @@
//! <b>Throws</b>: If allocator's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return allocator_type(this->node_alloc()); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -508,7 +503,7 @@
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator()
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
{ return this->node_alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -518,7 +513,7 @@
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return this->node_alloc(); }
//////////////////////////////////////////////
@@ -532,7 +527,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
{ return iterator(this->icont().begin()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
@@ -540,7 +535,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
{ return this->cbegin(); }
//! <b>Effects</b>: Returns an iterator to the end of the list.
@@ -548,7 +543,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
{ return iterator(this->icont().end()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
@@ -556,7 +551,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
{ return this->cend(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -565,7 +560,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
{ return reverse_iterator(end()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -574,7 +569,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
{ return this->crbegin(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -583,7 +578,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
{ return reverse_iterator(begin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -592,7 +587,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
{ return this->crend(); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
@@ -600,7 +595,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
{ return const_iterator(this->non_const_icont().begin()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
@@ -608,7 +603,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
{ return const_iterator(this->non_const_icont().end()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -617,7 +612,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
{ return const_reverse_iterator(this->cend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -626,7 +621,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
+ const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
{ return const_reverse_iterator(this->cbegin()); }
//////////////////////////////////////////////
@@ -640,7 +635,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
{ return !this->size(); }
//! <b>Effects</b>: Returns the number of the elements contained in the list.
@@ -648,7 +643,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
{ return this->icont().size(); }
//! <b>Effects</b>: Returns the largest possible size of the list.
@@ -656,7 +651,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
{ return AllocHolder::max_size(); }
//! <b>Effects</b>: Inserts or erases elements at the end such that
@@ -700,7 +695,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference front()
+ reference front() BOOST_CONTAINER_NOEXCEPT
{ return *this->begin(); }
//! <b>Requires</b>: !empty()
@@ -711,7 +706,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference front() const
+ const_reference front() const BOOST_CONTAINER_NOEXCEPT
{ return *this->begin(); }
//! <b>Requires</b>: !empty()
@@ -722,7 +717,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference back()
+ reference back() BOOST_CONTAINER_NOEXCEPT
{ return *(--this->end()); }
//! <b>Requires</b>: !empty()
@@ -733,7 +728,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference back() const
+ const_reference back() const BOOST_CONTAINER_NOEXCEPT
{ return *(--this->end()); }
//////////////////////////////////////////////
@@ -939,8 +934,10 @@
{
//Optimized allocation and construction
insertion_functor func(this->icont(), p.get());
+ iterator before_p(p.get());
+ --before_p;
this->allocate_many_and_construct(first, std::distance(first, last), func);
- return iterator(func.inserted_first());
+ return ++before_p;
}
#endif
@@ -949,7 +946,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Amortized constant time.
- void pop_front()
+ void pop_front() BOOST_CONTAINER_NOEXCEPT
{ this->erase(this->cbegin()); }
//! <b>Effects</b>: Removes the last element from the list.
@@ -957,7 +954,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Amortized constant time.
- void pop_back()
+ void pop_back() BOOST_CONTAINER_NOEXCEPT
{ const_iterator tmp = this->cend(); this->erase(--tmp); }
//! <b>Requires</b>: p must be a valid iterator of *this.
@@ -967,7 +964,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Amortized constant time.
- iterator erase(const_iterator p)
+ iterator erase(const_iterator p) BOOST_CONTAINER_NOEXCEPT
{ return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc()))); }
//! <b>Requires</b>: first and last must be valid iterator to elements in *this.
@@ -977,7 +974,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the distance between first and last.
- iterator erase(const_iterator first, const_iterator last)
+ iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
{ return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
//! <b>Effects</b>: Swaps the contents of *this and x.
@@ -993,7 +990,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements in the list.
- void clear()
+ void clear() BOOST_CONTAINER_NOEXCEPT
{ AllocHolder::clear(alloc_version()); }
//////////////////////////////////////////////
@@ -1003,13 +1000,12 @@
//////////////////////////////////////////////
//! <b>Requires</b>: p must point to an element contained
- //! by the list. x != *this
+ //! by the list. x != *this. this' allocator and x's allocator shall compare equal
//!
//! <b>Effects</b>: Transfers all the elements of list x to this list, before the
//! the element pointed by p. No destructors or copy constructors are called.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
//!
@@ -1017,19 +1013,18 @@
//! this list. Iterators of this list and all the references are not invalidated.
void splice(const_iterator p, list& x) BOOST_CONTAINER_NOEXCEPT
{
- BOOST_ASSERT(*this != x);
+ BOOST_ASSERT(this != &x);
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont());
}
//! <b>Requires</b>: p must point to an element contained
- //! by the list. x != *this
+ //! by the list. x != *this. this' allocator and x's allocator shall compare equal
//!
//! <b>Effects</b>: Transfers all the elements of list x to this list, before the
//! the element pointed by p. No destructors or copy constructors are called.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
//!
@@ -1040,13 +1035,13 @@
//! <b>Requires</b>: p must point to an element contained
//! by this list. i must point to an element contained in list x.
+ //! this' allocator and x's allocator shall compare equal
//!
//! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
//! before the the element pointed by p. No destructors or copy constructors are called.
//! If p == i or p == ++i, this function is a null operation.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
//!
@@ -1054,20 +1049,20 @@
//! list. Iterators of this list and all the references are not invalidated.
void splice(const_iterator p, list &x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
{
- BOOST_ASSERT(*this != x);
+ //BOOST_ASSERT(this != &x);
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont(), i.get());
}
//! <b>Requires</b>: p must point to an element contained
//! by this list. i must point to an element contained in list x.
+ //! this' allocator and x's allocator shall compare equal.
//!
//! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
//! before the the element pointed by p. No destructors or copy constructors are called.
//! If p == i or p == ++i, this function is a null operation.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
//!
@@ -1078,12 +1073,12 @@
//! <b>Requires</b>: p must point to an element contained
//! by this list. first and last must point to elements contained in list x.
+ //! this' allocator and x's allocator shall compare equal
//!
//! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
//! before the the element pointed by p. No destructors or copy constructors are called.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Linear to the number of elements transferred.
//!
@@ -1091,19 +1086,18 @@
//! list. Iterators of this list and all the references are not invalidated.
void splice(const_iterator p, list &x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
{
- BOOST_ASSERT(*this != x);
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont(), first.get(), last.get());
}
//! <b>Requires</b>: p must point to an element contained
//! by this list. first and last must point to elements contained in list x.
+ //! this' allocator and x's allocator shall compare equal.
//!
//! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
//! before the the element pointed by p. No destructors or copy constructors are called.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Linear to the number of elements transferred.
//!
@@ -1114,13 +1108,12 @@
//! <b>Requires</b>: p must point to an element contained
//! by this list. first and last must point to elements contained in list x.
- //! n == std::distance(first, last)
+ //! n == std::distance(first, last). this' allocator and x's allocator shall compare equal
//!
//! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
//! before the the element pointed by p. No destructors or copy constructors are called.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
//!
@@ -1130,20 +1123,18 @@
//! <b>Note</b>: Non-standard extension
void splice(const_iterator p, list &x, const_iterator first, const_iterator last, size_type n) BOOST_CONTAINER_NOEXCEPT
{
- BOOST_ASSERT(*this != x);
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
}
//! <b>Requires</b>: p must point to an element contained
//! by this list. first and last must point to elements contained in list x.
- //! n == std::distance(first, last)
+ //! n == std::distance(first, last). this' allocator and x's allocator shall compare equal
//!
//! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
//! before the the element pointed by p. No destructors or copy constructors are called.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
//!
@@ -1156,7 +1147,7 @@
//! <b>Effects</b>: Removes all the elements that compare equal to value.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
//!
//! <b>Complexity</b>: Linear time. It performs exactly size() comparisons for equality.
//!
@@ -1184,9 +1175,9 @@
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
//! elements that are equal from the list.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
//!
- //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
+ //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
//!
//! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
@@ -1198,7 +1189,7 @@
//!
//! <b>Throws</b>: If pred throws.
//!
- //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
+ //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
//!
//! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
@@ -1216,7 +1207,7 @@
//! that is, if an element from *this is equivalent to one from x, then the element
//! from *this will precede the one from x.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
//!
//! <b>Complexity</b>: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons.
@@ -1230,7 +1221,7 @@
//! that is, if an element from *this is equivalent to one from x, then the element
//! from *this will precede the one from x.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
//!
//! <b>Complexity</b>: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons.
@@ -1245,22 +1236,18 @@
//! in order into *this. The merge is stable; that is, if an element from *this is
//! equivalent to one from x, then the element from *this will precede the one from x.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comp throws.
//!
//! <b>Complexity</b>: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons.
//!
//! <b>Note</b>: Iterators and references to *this are not invalidated.
template <class StrictWeakOrdering>
- void merge(list &x, StrictWeakOrdering comp)
+ void merge(list &x, const StrictWeakOrdering &comp)
{
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().merge(x.icont(),
- ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
- }
- else{
- throw std::runtime_error("list::merge called with unequal allocators");
- }
+ BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+ this->icont().merge(x.icont(),
+ ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
}
//! <b>Requires</b>: p must be a comparison function that induces a strict weak
@@ -1271,7 +1258,7 @@
//! in order into *this. The merge is stable; that is, if an element from *this is
//! equivalent to one from x, then the element from *this will precede the one from x.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comp throws.
//!
//! <b>Complexity</b>: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons.
@@ -1284,7 +1271,7 @@
//! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
//! The sort is stable, that is, the relative order of equivalent elements is preserved.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
//!
//! <b>Notes</b>: Iterators and references are not invalidated.
//!
@@ -1296,7 +1283,7 @@
//! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
//! The sort is stable, that is, the relative order of equivalent elements is preserved.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comp throws.
//!
//! <b>Notes</b>: Iterators and references are not invalidated.
//!
@@ -1318,7 +1305,7 @@
//! <b>Complexity</b>: This function is linear time.
//!
//! <b>Note</b>: Iterators and references are not invalidated
- void reverse()
+ void reverse() BOOST_CONTAINER_NOEXCEPT
{ this->icont().reverse(); }
/// @cond
@@ -1382,31 +1369,18 @@
class insertion_functor
{
Icont &icont_;
- typedef typename Icont::iterator iiterator;
typedef typename Icont::const_iterator iconst_iterator;
-
const iconst_iterator pos_;
- iiterator ret_;
- bool first_;
public:
insertion_functor(Icont &icont, typename Icont::const_iterator pos)
- : icont_(icont), pos_(pos), ret_(pos.unconst()), first_(true)
+ : icont_(icont), pos_(pos)
{}
void operator()(Node &n)
{
- if(first_){
- ret_ = this->icont_.insert(pos_, n);
- first_ = false;
- }
- else{
- this->icont_.insert(pos_, n);
- }
+ this->icont_.insert(pos_, n);
}
-
- iiterator inserted_first() const
- { return ret_; }
};
//Functors for member algorithm defaults
@@ -1483,15 +1457,14 @@
/// @cond
} //namespace container {
-/*
+
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::list<T, Allocator> >
-{
- static const bool value = has_trivial_destructor<Allocator>::value;
-};
-*/
+ : public ::boost::has_trivial_destructor_after_move<Allocator>
+{};
+
namespace container {
/// @endcond
Modified: branches/release/boost/container/map.hpp
==============================================================================
--- branches/release/boost/container/map.hpp (original)
+++ branches/release/boost/container/map.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -30,8 +30,8 @@
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/pair.hpp>
#include <boost/container/detail/type_traits.hpp>
-#include <boost/move/move.hpp>
-#include <boost/move/move_helpers.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>
@@ -229,7 +229,7 @@
//! was passed to the object's constructor.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.get_allocator(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -239,7 +239,7 @@
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator()
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
{ return m_tree.get_stored_allocator(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -249,7 +249,7 @@
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.get_stored_allocator(); }
//////////////////////////////////////////////
@@ -263,7 +263,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
{ return m_tree.begin(); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -271,7 +271,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
{ return this->cbegin(); }
//! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -279,7 +279,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
{ return m_tree.end(); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -287,7 +287,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
{ return this->cend(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -296,7 +296,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
{ return m_tree.rbegin(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -305,7 +305,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
{ return this->crbegin(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -314,7 +314,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
{ return m_tree.rend(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -323,7 +323,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
{ return this->crend(); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -331,7 +331,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.begin(); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -339,7 +339,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.end(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -348,7 +348,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.rbegin(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -357,7 +357,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
+ const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.rend(); }
//////////////////////////////////////////////
@@ -371,7 +371,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.empty(); }
//! <b>Effects</b>: Returns the number of the elements contained in the container.
@@ -379,7 +379,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.size(); }
//! <b>Effects</b>: Returns the largest possible size of the container.
@@ -387,7 +387,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.max_size(); }
//////////////////////////////////////////////
@@ -621,7 +621,7 @@
//! returns end().
//!
//! <b>Complexity</b>: Amortized constant time
- iterator erase(const_iterator position)
+ iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT
{ return m_tree.erase(position); }
//! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
@@ -629,7 +629,7 @@
//! <b>Returns</b>: Returns the number of erased elements.
//!
//! <b>Complexity</b>: log(size()) + count(k)
- size_type erase(const key_type& x)
+ size_type erase(const key_type& x) BOOST_CONTAINER_NOEXCEPT
{ return m_tree.erase(x); }
//! <b>Effects</b>: Erases all the elements in the range [first, last).
@@ -637,7 +637,7 @@
//! <b>Returns</b>: Returns last.
//!
//! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
- iterator erase(const_iterator first, const_iterator last)
+ iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
{ return m_tree.erase(first, last); }
//! <b>Effects</b>: Swaps the contents of *this and x.
@@ -653,7 +653,7 @@
//! <b>Postcondition</b>: size() == 0.
//!
//! <b>Complexity</b>: linear in size().
- void clear()
+ void clear() BOOST_CONTAINER_NOEXCEPT
{ m_tree.clear(); }
//////////////////////////////////////////////
@@ -827,15 +827,15 @@
const multimap<Key,T,Compare,Allocator>& y);
} //namespace container {
-/*
+
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class K, class T, class C, class Allocator>
struct has_trivial_destructor_after_move<boost::container::map<K, T, C, Allocator> >
{
- static const bool value = has_trivial_destructor<Allocator>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
};
-*/
+
namespace container {
/// @endcond
@@ -951,9 +951,9 @@
//!
//! <b>Complexity</b>: Linear in N.
template <class InputIterator>
- multimap(ordered_range_t ordered_range_, InputIterator first, InputIterator last, const Compare& comp = Compare(),
+ multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(),
const allocator_type& a = allocator_type())
- : m_tree(ordered_range_, first, last, comp, a)
+ : m_tree(ordered_range, first, last, comp, a)
{}
//! <b>Effects</b>: Copy constructs a multimap.
@@ -1016,7 +1016,7 @@
//! was passed to the object's constructor.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.get_allocator(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -1026,7 +1026,7 @@
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator()
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
{ return m_tree.get_stored_allocator(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -1036,7 +1036,7 @@
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.get_stored_allocator(); }
//////////////////////////////////////////////
@@ -1050,7 +1050,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
{ return m_tree.begin(); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -1058,7 +1058,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
{ return this->cbegin(); }
//! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -1066,7 +1066,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
{ return m_tree.end(); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -1074,7 +1074,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
{ return this->cend(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -1083,7 +1083,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
{ return m_tree.rbegin(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -1092,7 +1092,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
{ return this->crbegin(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -1101,7 +1101,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
{ return m_tree.rend(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -1110,7 +1110,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
{ return this->crend(); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -1118,7 +1118,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.begin(); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -1126,7 +1126,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.end(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -1135,7 +1135,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.rbegin(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -1144,7 +1144,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
+ const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.rend(); }
//////////////////////////////////////////////
@@ -1158,7 +1158,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.empty(); }
//! <b>Effects</b>: Returns the number of the elements contained in the container.
@@ -1166,7 +1166,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.size(); }
//! <b>Effects</b>: Returns the largest possible size of the container.
@@ -1174,7 +1174,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
{ return m_tree.max_size(); }
//////////////////////////////////////////////
@@ -1317,7 +1317,7 @@
//! returns end().
//!
//! <b>Complexity</b>: Amortized constant time
- iterator erase(const_iterator position)
+ iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT
{ return m_tree.erase(position); }
//! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
@@ -1325,7 +1325,7 @@
//! <b>Returns</b>: Returns the number of erased elements.
//!
//! <b>Complexity</b>: log(size()) + count(k)
- size_type erase(const key_type& x)
+ size_type erase(const key_type& x) BOOST_CONTAINER_NOEXCEPT
{ return m_tree.erase(x); }
//! <b>Effects</b>: Erases all the elements in the range [first, last).
@@ -1333,7 +1333,7 @@
//! <b>Returns</b>: Returns last.
//!
//! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
- iterator erase(const_iterator first, const_iterator last)
+ iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
{ return m_tree.erase(first, last); }
//! <b>Effects</b>: Swaps the contents of *this and x.
@@ -1349,7 +1349,7 @@
//! <b>Postcondition</b>: size() == 0.
//!
//! <b>Complexity</b>: linear in size().
- void clear()
+ void clear() BOOST_CONTAINER_NOEXCEPT
{ m_tree.clear(); }
//////////////////////////////////////////////
@@ -1486,15 +1486,15 @@
/// @cond
} //namespace container {
-/*
+
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class K, class T, class C, class Allocator>
struct has_trivial_destructor_after_move<boost::container::multimap<K, T, C, Allocator> >
{
- static const bool value = has_trivial_destructor<Allocator>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
};
-*/
+
namespace container {
/// @endcond
Modified: branches/release/boost/container/scoped_allocator.hpp
==============================================================================
--- branches/release/boost/container/scoped_allocator.hpp (original)
+++ branches/release/boost/container/scoped_allocator.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -30,8 +30,8 @@
#include <boost/container/detail/utilities.hpp>
#include <utility>
#include <boost/container/detail/pair.hpp>
-#include <boost/move/move.hpp>
-
+#include <boost/move/utility.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
namespace boost { namespace container {
@@ -259,7 +259,7 @@
//! Thanks Mathias!
//With variadic templates, we need a single class to implement the trait
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T, class ...Args>
struct is_constructible_impl
@@ -290,7 +290,7 @@
: is_constructible<T, allocator_arg_t, InnerAlloc, Args...>
{};
- #else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
//Without variadic templates, we need to use de preprocessor to generate
//some specializations.
@@ -382,14 +382,14 @@
>
{};*/
- #endif // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#else // #if !defined(BOOST_NO_SFINAE_EXPR)
//Without advanced SFINAE expressions, we can't use is_constructible
//so backup to constructible_with_allocator_xxx
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template < class T, class InnerAlloc, class ...Args>
struct is_constructible_with_allocator_prefix
@@ -401,7 +401,7 @@
: constructible_with_allocator_suffix<T>
{};*/
- #else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template < class T
, class InnerAlloc
@@ -423,11 +423,11 @@
: constructible_with_allocator_suffix<T>
{};*/
- #endif // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#endif // #if !defined(BOOST_NO_SFINAE_EXPR)
-#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template < typename OutermostAlloc
, typename InnerAlloc
@@ -489,7 +489,7 @@
(outermost_alloc, p, ::boost::forward<Args>(args)...);
}
-#else //#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+#else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define BOOST_PP_LOCAL_MACRO(n) \
template < typename OutermostAlloc \
@@ -564,9 +564,9 @@
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
-#endif //#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+#endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename OuterAlloc, class ...InnerAllocs>
class scoped_allocator_adaptor_base
@@ -679,7 +679,7 @@
inner_allocator_type m_inner;
};
-#else //#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+#else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
//Let's add a dummy first template parameter to allow creating
//specializations up to maximum InnerAlloc count
@@ -829,13 +829,13 @@
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
-#endif //#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+#endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
//Specialization for adaptor without any InnerAlloc
template <typename OuterAlloc>
class scoped_allocator_adaptor_base
< OuterAlloc
- #if defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
, true
BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, nat)
#endif
@@ -850,7 +850,7 @@
{
typedef scoped_allocator_adaptor_base
<typename allocator_traits<OuterAlloc>::template portable_rebind_alloc<U>::type
- #if defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
, true
BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, container_detail::nat)
#endif
@@ -887,7 +887,7 @@
scoped_allocator_adaptor_base
(const scoped_allocator_adaptor_base<
OuterA2
- #if defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
, true
BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, container_detail::nat)
#endif
@@ -899,7 +899,7 @@
scoped_allocator_adaptor_base
(BOOST_RV_REF_BEG scoped_allocator_adaptor_base<
OuterA2
- #if defined(BOOST_NO_VARIADIC_TEMPLATES)
+ #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
, true
BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, container_detail::nat)
#endif
@@ -946,7 +946,7 @@
///@endcond
//Scoped allocator
-#if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
@@ -992,7 +992,7 @@
#endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
-#else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template <typename OuterAlloc
BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, class Q)
@@ -1001,7 +1001,7 @@
#endif
: public container_detail::scoped_allocator_adaptor_base
<OuterAlloc
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, InnerAllocs...
#else
, true BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
@@ -1014,7 +1014,7 @@
/// @cond
typedef container_detail::scoped_allocator_adaptor_base
<OuterAlloc
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, InnerAllocs...
#else
, true BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
@@ -1058,7 +1058,7 @@
{
typedef scoped_allocator_adaptor
< typename outer_traits_type::template portable_rebind_alloc<U>::type
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, InnerAllocs...
#else
BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
@@ -1086,7 +1086,7 @@
: base_type(::boost::move(other.base()))
{}
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
//!
@@ -1097,7 +1097,7 @@
scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs & ...innerAllocs)
: base_type(::boost::forward<OuterA2>(outerAlloc), innerAllocs...)
{}
- #else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#define BOOST_PP_LOCAL_MACRO(n) \
template <class OuterA2> \
@@ -1111,14 +1111,14 @@
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
- #endif // #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Requires</b>: OuterAlloc shall be constructible from OuterA2.
//!
//! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator from other.
template <class OuterA2>
scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, InnerAllocs...
#else
BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
@@ -1133,7 +1133,7 @@
//! rvalue from other.
template <class OuterA2>
scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor<OuterA2
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, InnerAllocs...
#else
BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
@@ -1229,7 +1229,7 @@
const base_type &base() const { return *this; }
/// @endcond
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>:
//! 1) If `uses_allocator<T, inner_allocator_type>::value` is false calls
@@ -1274,7 +1274,7 @@
, p, ::boost::forward<Args>(args)...);
}
- #else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//Disable this overload if the first argument is pair as some compilers have
//overload selection problems when the first parameter is a pair.
@@ -1295,7 +1295,7 @@
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
- #endif // #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template <class T1, class T2>
void construct(std::pair<T1,T2>* p)
@@ -1338,52 +1338,56 @@
void construct_pair(Pair* p)
{
this->construct(container_detail::addressof(p->first));
- try {
+ BOOST_TRY{
this->construct(container_detail::addressof(p->second));
}
- catch (...) {
+ BOOST_CATCH(...){
this->destroy(container_detail::addressof(p->first));
- throw;
+ BOOST_RETHROW
}
+ BOOST_CATCH_END
}
template <class Pair, class U, class V>
void construct_pair(Pair* p, BOOST_FWD_REF(U) x, BOOST_FWD_REF(V) y)
{
this->construct(container_detail::addressof(p->first), ::boost::forward<U>(x));
- try {
+ BOOST_TRY{
this->construct(container_detail::addressof(p->second), ::boost::forward<V>(y));
}
- catch (...) {
+ BOOST_CATCH(...){
this->destroy(container_detail::addressof(p->first));
- throw;
+ BOOST_RETHROW
}
+ BOOST_CATCH_END
}
template <class Pair, class Pair2>
void construct_pair(Pair* p, const Pair2& pr)
{
this->construct(container_detail::addressof(p->first), pr.first);
- try {
+ BOOST_TRY{
this->construct(container_detail::addressof(p->second), pr.second);
}
- catch (...) {
+ BOOST_CATCH(...){
this->destroy(container_detail::addressof(p->first));
- throw;
+ BOOST_RETHROW
}
+ BOOST_CATCH_END
}
template <class Pair, class Pair2>
void construct_pair(Pair* p, BOOST_RV_REF(Pair2) pr)
{
this->construct(container_detail::addressof(p->first), ::boost::move(pr.first));
- try {
+ BOOST_TRY{
this->construct(container_detail::addressof(p->second), ::boost::move(pr.second));
}
- catch (...) {
+ BOOST_CATCH(...){
this->destroy(container_detail::addressof(p->first));
- throw;
+ BOOST_RETHROW
}
+ BOOST_CATCH_END
}
//template <class T1, class T2, class... Args1, class... Args2>
@@ -1399,7 +1403,7 @@
};
template <typename OuterA1, typename OuterA2
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename... InnerAllocs
#else
BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, class Q)
@@ -1407,21 +1411,21 @@
>
inline bool operator==(
const scoped_allocator_adaptor<OuterA1
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
,InnerAllocs...
#else
BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
#endif
>& a,
const scoped_allocator_adaptor<OuterA2
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
,InnerAllocs...
#else
BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
#endif
>& b)
{
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
const bool has_zero_inner = sizeof...(InnerAllocs) == 0u;
#else
const bool has_zero_inner =
@@ -1434,7 +1438,7 @@
}
template <typename OuterA1, typename OuterA2
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename... InnerAllocs
#else
BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, class Q)
@@ -1442,14 +1446,14 @@
>
inline bool operator!=(
const scoped_allocator_adaptor<OuterA1
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
,InnerAllocs...
#else
BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
#endif
>& a,
const scoped_allocator_adaptor<OuterA2
- #if !defined(BOOST_NO_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
,InnerAllocs...
#else
BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
Modified: branches/release/boost/container/scoped_allocator_fwd.hpp
==============================================================================
--- branches/release/boost/container/scoped_allocator_fwd.hpp (original)
+++ branches/release/boost/container/scoped_allocator_fwd.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -18,7 +18,7 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
-#if defined(BOOST_NO_VARIADIC_TEMPLATES)
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/container/detail/preprocessor.hpp>
#include <boost/container/detail/type_traits.hpp>
#endif
@@ -27,7 +27,7 @@
///@cond
-#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
@@ -45,7 +45,7 @@
#endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
-#else // #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename OuterAlloc
BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS
Modified: branches/release/boost/container/set.hpp
==============================================================================
--- branches/release/boost/container/set.hpp (original)
+++ branches/release/boost/container/set.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -23,11 +23,11 @@
#include <functional>
#include <memory>
-#include <boost/move/move.hpp>
-#include <boost/move/move_helpers.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/detail/move_helpers.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/tree.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp>
#endif
@@ -646,15 +646,15 @@
/// @cond
} //namespace container {
-/*
+
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class Key, class C, class Allocator>
struct has_trivial_destructor_after_move<boost::container::set<Key, C, Allocator> >
{
- static const bool value = has_trivial_destructor<Allocator>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
};
-*/
+
namespace container {
// Forward declaration of operators < and ==, needed for friend declaration.
@@ -757,10 +757,10 @@
//!
//! <b>Complexity</b>: Linear in N.
template <class InputIterator>
- multiset( ordered_range_t ordered_range_, InputIterator first, InputIterator last
+ multiset( ordered_range_t, InputIterator first, InputIterator last
, const Compare& comp = Compare()
, const allocator_type& a = allocator_type())
- : m_tree(ordered_range_, first, last, comp, a)
+ : m_tree(ordered_range, first, last, comp, a)
{}
//! <b>Effects</b>: Copy constructs a multiset.
@@ -1259,15 +1259,15 @@
/// @cond
} //namespace container {
-/*
+
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class Key, class C, class Allocator>
struct has_trivial_destructor_after_move<boost::container::multiset<Key, C, Allocator> >
{
- static const bool value = has_trivial_destructor<Allocator>::value && has_trivial_destructor<C>::value;
+ static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
};
-*/
+
namespace container {
/// @endcond
Modified: branches/release/boost/container/slist.hpp
==============================================================================
--- branches/release/boost/container/slist.hpp (original)
+++ branches/release/boost/container/slist.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -19,8 +19,8 @@
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
-#include <boost/move/move.hpp>
-#include <boost/move/move_helpers.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/detail/move_helpers.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/mpl.hpp>
@@ -140,9 +140,6 @@
friend bool operator!= (const slist_const_iterator& l, const slist_const_iterator& r)
{ return l.m_it != r.m_it; }
- IIterator &get()
- { return this->m_it; }
-
const IIterator &get() const
{ return this->m_it; }
};
@@ -181,9 +178,6 @@
slist_iterator operator++(int)
{ IIterator tmp = this->m_it; ++*this; return slist_iterator(tmp); }
- IIterator &get()
- { return this->m_it; }
-
const IIterator &get() const
{ return this->m_it; }
};
@@ -319,10 +313,10 @@
//! <b>Effects</b>: Constructs a list taking the allocator as parameter.
//!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
- explicit slist(const allocator_type& a)
+ explicit slist(const allocator_type& a) BOOST_CONTAINER_NOEXCEPT
: AllocHolder(a)
{}
@@ -407,7 +401,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements.
- ~slist()
+ ~slist() BOOST_CONTAINER_NOEXCEPT
{} //AllocHolder clears the slist
//! <b>Effects</b>: Makes *this contain the same elements as x.
@@ -511,7 +505,7 @@
//! <b>Throws</b>: If allocator's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return allocator_type(this->node_alloc()); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -521,7 +515,7 @@
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator()
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
{ return this->node_alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -531,7 +525,7 @@
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return this->node_alloc(); }
//////////////////////////////////////////////
@@ -547,7 +541,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator before_begin()
+ iterator before_begin() BOOST_CONTAINER_NOEXCEPT
{ return iterator(end()); }
//! <b>Effects</b>: Returns a non-dereferenceable const_iterator
@@ -557,7 +551,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator before_begin() const
+ const_iterator before_begin() const BOOST_CONTAINER_NOEXCEPT
{ return this->cbefore_begin(); }
//! <b>Effects</b>: Returns an iterator to the first element contained in the list.
@@ -565,7 +559,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
{ return iterator(this->icont().begin()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
@@ -573,7 +567,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
{ return this->cbegin(); }
//! <b>Effects</b>: Returns an iterator to the end of the list.
@@ -581,7 +575,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
{ return iterator(this->icont().end()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
@@ -589,7 +583,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
{ return this->cend(); }
//! <b>Effects</b>: Returns a non-dereferenceable const_iterator
@@ -599,7 +593,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbefore_begin() const
+ const_iterator cbefore_begin() const BOOST_CONTAINER_NOEXCEPT
{ return const_iterator(end()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
@@ -607,7 +601,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
{ return const_iterator(this->non_const_icont().begin()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
@@ -615,7 +609,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
{ return const_iterator(this->non_const_icont().end()); }
//! <b>Returns</b>: The iterator to the element before i in the sequence.
@@ -627,7 +621,7 @@
//! <b>Complexity</b>: Linear to the number of elements before i.
//!
//! <b>Note</b>: Non-standard extension.
- iterator previous(iterator p)
+ iterator previous(iterator p) BOOST_CONTAINER_NOEXCEPT
{ return iterator(this->icont().previous(p.get())); }
//! <b>Returns</b>: The const_iterator to the element before i in the sequence.
@@ -986,9 +980,9 @@
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of
//! this list. Iterators of this list and all the references are not invalidated.
- void splice_after(const_iterator prev_pos, slist& x)
+ void splice_after(const_iterator prev_pos, slist& x) BOOST_CONTAINER_NOEXCEPT
{
- BOOST_ASSERT(*this != x);
+ BOOST_ASSERT(this != &x);
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice_after(prev_pos.get(), x.icont());
}
@@ -1006,65 +1000,63 @@
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of
//! this list. Iterators of this list and all the references are not invalidated.
- void splice_after(const_iterator prev_pos, BOOST_RV_REF(slist) x)
+ void splice_after(const_iterator prev_pos, BOOST_RV_REF(slist) x) BOOST_CONTAINER_NOEXCEPT
{ this->splice_after(prev_pos, static_cast<slist&>(x)); }
//! <b>Requires</b>: prev_pos must be a valid iterator of this.
//! i must point to an element contained in list x.
+ //! this' allocator and x's allocator shall compare equal.
//!
//! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
//! after the element pointed by prev_pos.
//! If prev_pos == prev or prev_pos == ++prev, this function is a null operation.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice_after(const_iterator prev_pos, slist& x, const_iterator prev)
+ void splice_after(const_iterator prev_pos, slist& x, const_iterator prev) BOOST_CONTAINER_NOEXCEPT
{
- BOOST_ASSERT(*this != x);
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice_after(prev_pos.get(), x.icont(), prev.get());
}
//! <b>Requires</b>: prev_pos must be a valid iterator of this.
//! i must point to an element contained in list x.
+ //! this' allocator and x's allocator shall compare equal.
//!
//! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
//! after the element pointed by prev_pos.
//! If prev_pos == prev or prev_pos == ++prev, this function is a null operation.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice_after(const_iterator prev_pos, BOOST_RV_REF(slist) x, const_iterator prev)
+ void splice_after(const_iterator prev_pos, BOOST_RV_REF(slist) x, const_iterator prev) BOOST_CONTAINER_NOEXCEPT
{ this->splice_after(prev_pos, static_cast<slist&>(x), prev); }
//! <b>Requires</b>: prev_pos must be a valid iterator of this.
//! before_first and before_last must be valid iterators of x.
//! prev_pos must not be contained in [before_first, before_last) range.
+ //! this' allocator and x's allocator shall compare equal.
//!
//! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
//! from list x to this list, after the element pointed by prev_pos.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Linear to the number of transferred elements.
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void splice_after(const_iterator prev_pos, slist& x,
- const_iterator before_first, const_iterator before_last)
+ const_iterator before_first, const_iterator before_last) BOOST_CONTAINER_NOEXCEPT
{
- BOOST_ASSERT(*this != x);
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice_after
(prev_pos.get(), x.icont(), before_first.get(), before_last.get());
@@ -1073,31 +1065,31 @@
//! <b>Requires</b>: prev_pos must be a valid iterator of this.
//! before_first and before_last must be valid iterators of x.
//! prev_pos must not be contained in [before_first, before_last) range.
+ //! this' allocator and x's allocator shall compare equal.
//!
//! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
//! from list x to this list, after the element pointed by prev_pos.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Linear to the number of transferred elements.
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void splice_after(const_iterator prev_pos, BOOST_RV_REF(slist) x,
- const_iterator before_first, const_iterator before_last)
+ const_iterator before_first, const_iterator before_last) BOOST_CONTAINER_NOEXCEPT
{ this->splice_after(prev_pos, static_cast<slist&>(x), before_first, before_last); }
//! <b>Requires</b>: prev_pos must be a valid iterator of this.
//! before_first and before_last must be valid iterators of x.
//! prev_pos must not be contained in [before_first, before_last) range.
- //! n == std::distance(before_first, before_last)
+ //! n == std::distance(before_first, before_last).
+ //! this' allocator and x's allocator shall compare equal.
//!
//! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
//! from list x to this list, after the element pointed by prev_pos.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
//!
@@ -1105,9 +1097,8 @@
//! list. Iterators of this list and all the references are not invalidated.
void splice_after(const_iterator prev_pos, slist& x,
const_iterator before_first, const_iterator before_last,
- size_type n)
+ size_type n) BOOST_CONTAINER_NOEXCEPT
{
- BOOST_ASSERT(*this != x);
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice_after
(prev_pos.get(), x.icont(), before_first.get(), before_last.get(), n);
@@ -1116,13 +1107,13 @@
//! <b>Requires</b>: prev_pos must be a valid iterator of this.
//! before_first and before_last must be valid iterators of x.
//! prev_pos must not be contained in [before_first, before_last) range.
- //! n == std::distance(before_first, before_last)
+ //! n == std::distance(before_first, before_last).
+ //! this' allocator and x's allocator shall compare equal.
//!
//! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
//! from list x to this list, after the element pointed by prev_pos.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
//!
@@ -1130,7 +1121,7 @@
//! list. Iterators of this list and all the references are not invalidated.
void splice_after(const_iterator prev_pos, BOOST_RV_REF(slist) x,
const_iterator before_first, const_iterator before_last,
- size_type n)
+ size_type n) BOOST_CONTAINER_NOEXCEPT
{ this->splice_after(prev_pos, static_cast<slist&>(x), before_first, before_last, n); }
//! <b>Effects</b>: Removes all the elements that compare equal to value.
@@ -1163,9 +1154,9 @@
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
//! elements that are equal from the list.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
//!
- //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
+ //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
//!
//! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
@@ -1177,7 +1168,7 @@
//!
//! <b>Throws</b>: If pred throws.
//!
- //! <b>Complexity</b>: Linear time (size()-1 comparisons equality comparisons).
+ //! <b>Complexity</b>: Linear time (size()-1 comparisons calls to pred()).
//!
//! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
@@ -1195,7 +1186,7 @@
//! that is, if an element from *this is equivalent to one from x, then the element
//! from *this will precede the one from x.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
//!
//! <b>Complexity</b>: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons.
@@ -1209,7 +1200,7 @@
//! that is, if an element from *this is equivalent to one from x, then the element
//! from *this will precede the one from x.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
//!
//! <b>Complexity</b>: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons.
@@ -1224,7 +1215,7 @@
//! in order into *this. The merge is stable; that is, if an element from *this is
//! equivalent to one from x, then the element from *this will precede the one from x.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comp throws.
//!
//! <b>Complexity</b>: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons.
@@ -1233,13 +1224,9 @@
template <class StrictWeakOrdering>
void merge(slist& x, StrictWeakOrdering comp)
{
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().merge(x.icont(),
- ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
- }
- else{
- throw std::runtime_error("list::merge called with unequal allocators");
- }
+ BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+ this->icont().merge(x.icont(),
+ ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
}
//! <b>Requires</b>: p must be a comparison function that induces a strict weak
@@ -1250,7 +1237,7 @@
//! in order into *this. The merge is stable; that is, if an element from *this is
//! equivalent to one from x, then the element from *this will precede the one from x.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comp throws.
//!
//! <b>Complexity</b>: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons.
@@ -1263,7 +1250,7 @@
//! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
//! The sort is stable, that is, the relative order of equivalent elements is preserved.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comparison throws.
//!
//! <b>Notes</b>: Iterators and references are not invalidated.
//!
@@ -1275,7 +1262,7 @@
//! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
//! The sort is stable, that is, the relative order of equivalent elements is preserved.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If comp throws.
//!
//! <b>Notes</b>: Iterators and references are not invalidated.
//!
@@ -1297,7 +1284,7 @@
//! <b>Complexity</b>: This function is linear time.
//!
//! <b>Note</b>: Iterators and references are not invalidated
- void reverse()
+ void reverse() BOOST_CONTAINER_NOEXCEPT
{ this->icont().reverse(); }
//////////////////////////////////////////////
@@ -1403,7 +1390,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements before p.
- iterator erase(const_iterator p)
+ iterator erase(const_iterator p) BOOST_CONTAINER_NOEXCEPT
{ return iterator(this->erase_after(previous(p))); }
//! <b>Requires</b>: first and last must be valid iterator to elements in *this.
@@ -1414,73 +1401,71 @@
//!
//! <b>Complexity</b>: Linear to the distance between first and last plus
//! linear to the elements before first.
- iterator erase(const_iterator first, const_iterator last)
+ iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
{ return iterator(this->erase_after(previous(first), last)); }
//! <b>Requires</b>: p must point to an element contained
- //! by the list. x != *this
+ //! by the list. x != *this. this' allocator and x's allocator shall compare equal
//!
//! <b>Effects</b>: Transfers all the elements of list x to this list, before the
//! the element pointed by p. No destructors or copy constructors are called.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size().
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of
//! this list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, slist& x)
+ void splice(const_iterator p, slist& x) BOOST_CONTAINER_NOEXCEPT
{ this->splice_after(this->previous(p), x); }
//! <b>Requires</b>: p must point to an element contained
- //! by the list. x != *this
+ //! by the list. x != *this. this' allocator and x's allocator shall compare equal
//!
//! <b>Effects</b>: Transfers all the elements of list x to this list, before the
//! the element pointed by p. No destructors or copy constructors are called.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size().
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of
//! this list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, BOOST_RV_REF(slist) x)
+ void splice(const_iterator p, BOOST_RV_REF(slist) x) BOOST_CONTAINER_NOEXCEPT
{ this->splice(p, static_cast<slist&>(x)); }
//! <b>Requires</b>: p must point to an element contained
//! by this list. i must point to an element contained in list x.
+ //! this' allocator and x's allocator shall compare equal
//!
//! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
//! before the the element pointed by p. No destructors or copy constructors are called.
//! If p == i or p == ++i, this function is a null operation.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i).
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, slist& x, const_iterator i)
+ void splice(const_iterator p, slist& x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
{ this->splice_after(this->previous(p), x, this->previous(i)); }
//! <b>Requires</b>: p must point to an element contained
//! by this list. i must point to an element contained in list x.
+ //! this' allocator and x's allocator shall compare equal.
//!
//! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
//! before the the element pointed by p. No destructors or copy constructors are called.
//! If p == i or p == ++i, this function is a null operation.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i).
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator i)
+ void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
{ this->splice(p, static_cast<slist&>(x), i); }
//! <b>Requires</b>: p must point to an element contained
@@ -1488,33 +1473,33 @@
//!
//! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
//! before the the element pointed by p. No destructors or copy constructors are called.
+ //! this' allocator and x's allocator shall compare equal.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first),
//! and in distance(first, last).
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, slist& x, const_iterator first, const_iterator last)
+ void splice(const_iterator p, slist& x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
{ this->splice_after(this->previous(p), x, this->previous(first), this->previous(last)); }
//! <b>Requires</b>: p must point to an element contained
//! by this list. first and last must point to elements contained in list x.
+ //! this' allocator and x's allocator shall compare equal
//!
//! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
//! before the the element pointed by p. No destructors or copy constructors are called.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
- //! are not equal.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first),
//! and in distance(first, last).
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator first, const_iterator last)
+ void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
{ this->splice(p, static_cast<slist&>(x), first, last); }
/// @cond
@@ -1658,15 +1643,14 @@
/// @cond
namespace boost {
-/*
+
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::slist<T, Allocator> >
-{
- static const bool value = has_trivial_destructor<Allocator>::value;
-};
-*/
+ : public ::boost::has_trivial_destructor_after_move<Allocator>
+{};
+
namespace container {
/// @endcond
Modified: branches/release/boost/container/stable_vector.hpp
==============================================================================
--- branches/release/boost/container/stable_vector.hpp (original)
+++ branches/release/boost/container/stable_vector.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -1,4 +1,4 @@
-//////////////////////////////////////////////////////////////////////////////
+
//
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
@@ -29,15 +29,16 @@
#include <boost/mpl/bool.hpp>
#include <boost/mpl/not.hpp>
#include <boost/assert.hpp>
-#include <boost/type_traits/is_integral.hpp>
-#include <boost/container/detail/version_type.hpp>
-#include <boost/container/detail/multiallocation_chain.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/intrusive/pointer_traits.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>
@@ -303,7 +304,7 @@
static const size_type ExtraPointers = 3;
//Stable vector stores metadata at the end of the index (node_base_ptr vector) with additional 3 pointers:
// back() is this->index.back() - ExtraPointers;
- // end node index is *(this->index.end() -3)
+ // end node index is *(this->index.end() - 3)
// Node cache first is *(this->index.end() - 2);
// Node cache last is this->index.back();
@@ -366,89 +367,6 @@
#endif //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
};
-template<class Allocator, unsigned Version = boost::container::container_detail::version<Allocator>::value>
-struct allocator_version_wrapper
-{
- typedef ::boost::container::container_detail::integral_constant
- <unsigned, Version> alloc_version;
-
- typedef typename Allocator::multiallocation_chain multiallocation_chain;
-
- typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
- typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
-
- static pointer allocate_one(Allocator &a)
- { return a.allocate_one(); }
-
- static void deallocate_one(Allocator &a, const pointer &p)
- { a.deallocate_one(p); }
-
- static multiallocation_chain allocate_individual(Allocator &a, size_type n)
- { return a.allocate_individual(n); }
-
- static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
- { a.deallocate_individual(::boost::move(holder)); }
-};
-
-template<class Allocator>
-struct allocator_version_wrapper<Allocator, 1>
-{
- typedef ::boost::container::container_detail::integral_constant
- <unsigned, 1> alloc_version;
-
- typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
- typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
- typedef typename boost::container::allocator_traits<Allocator>::value_type value_type;
-
- typedef typename boost::intrusive::pointer_traits<pointer>::
- template rebind_pointer<void>::type void_ptr;
- typedef container_detail::basic_multiallocation_chain
- <void_ptr> multialloc_cached_counted;
- typedef boost::container::container_detail::
- transform_multiallocation_chain
- < multialloc_cached_counted, value_type> multiallocation_chain;
-
- static pointer allocate_one(Allocator &a)
- { return a.allocate(1); }
-
- static void deallocate_one(Allocator &a, const pointer &p)
- { a.deallocate(p, 1); }
-
- static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
- {
- while(!holder.empty()){
- a.deallocate(holder.pop_front(), 1);
- }
- }
-
- struct allocate_individual_rollback
- {
- allocate_individual_rollback(Allocator &a, multiallocation_chain &chain)
- : mr_a(a), mr_chain(chain)
- {}
-
- ~allocate_individual_rollback()
- {
- allocator_version_wrapper::deallocate_individual(mr_a, mr_chain);
- }
-
- Allocator &mr_a;
- multiallocation_chain &mr_chain;
- };
-
- static multiallocation_chain allocate_individual(Allocator &a, size_type n)
- {
- multiallocation_chain m;
- multiallocation_chain m_ret;
- allocate_individual_rollback rollback(a, m);
- while(n--){
- m.push_front(a.allocate(1));
- }
- m.swap(m_ret);
- return ::boost::move(m_ret);
- }
-};
-
} //namespace stable_vector_detail
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -555,20 +473,21 @@
template portable_rebind_alloc
<node_type>::type node_allocator_type;
- typedef stable_vector_detail::allocator_version_wrapper<node_allocator_type> allocator_version_wrapper_t;
- typedef typename allocator_version_wrapper_t::multiallocation_chain multiallocation_chain;
+ typedef ::boost::container::container_detail::
+ allocator_version_traits<node_allocator_type> allocator_version_traits_t;
+ typedef typename allocator_version_traits_t::multiallocation_chain multiallocation_chain;
node_ptr allocate_one()
- { return allocator_version_wrapper_t::allocate_one(this->priv_node_alloc()); }
+ { return allocator_version_traits_t::allocate_one(this->priv_node_alloc()); }
void deallocate_one(const node_ptr &p)
- { allocator_version_wrapper_t::deallocate_one(this->priv_node_alloc(), p); }
+ { allocator_version_traits_t::deallocate_one(this->priv_node_alloc(), p); }
- multiallocation_chain allocate_individual(typename allocator_traits_type::size_type n)
- { return allocator_version_wrapper_t::allocate_individual(this->priv_node_alloc(), n); }
+ void allocate_individual(typename allocator_traits_type::size_type n, multiallocation_chain &m)
+ { allocator_version_traits_t::allocate_individual(this->priv_node_alloc(), n, m); }
void deallocate_individual(multiallocation_chain &holder)
- { allocator_version_wrapper_t::deallocate_individual(this->priv_node_alloc(), holder); }
+ { allocator_version_traits_t::deallocate_individual(this->priv_node_alloc(), holder); }
friend class stable_vector_detail::clear_on_destroy<stable_vector>;
typedef stable_vector_detail::iterator
@@ -633,10 +552,10 @@
//! <b>Effects</b>: Constructs a stable_vector taking the allocator as parameter.
//!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
- explicit stable_vector(const allocator_type& al)
+ explicit stable_vector(const allocator_type& al) BOOST_CONTAINER_NOEXCEPT
: internal_data(al), index(al)
{
STABLE_VECTOR_CHECK_INVARIANT;
@@ -904,7 +823,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin()
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
{ return (this->index.empty()) ? this->end(): iterator(node_ptr_traits::static_cast_from(this->index.front())); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the stable_vector.
@@ -912,7 +831,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin()const
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
{ return (this->index.empty()) ? this->cend() : const_iterator(node_ptr_traits::static_cast_from(this->index.front())) ; }
//! <b>Effects</b>: Returns an iterator to the end of the stable_vector.
@@ -920,7 +839,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end()
+ iterator end() BOOST_CONTAINER_NOEXCEPT
{ return iterator(this->priv_get_end_node()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the stable_vector.
@@ -928,7 +847,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
{ return const_iterator(this->priv_get_end_node()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -937,7 +856,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
{ return reverse_iterator(this->end()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -946,7 +865,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
{ return const_reverse_iterator(this->end()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -955,7 +874,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
{ return reverse_iterator(this->begin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -964,7 +883,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend()const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
{ return const_reverse_iterator(this->begin()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the stable_vector.
@@ -972,7 +891,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
{ return this->begin(); }
//! <b>Effects</b>: Returns a const_iterator to the end of the stable_vector.
@@ -980,7 +899,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend()const
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
{ return this->end(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -989,7 +908,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
{ return this->rbegin(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -998,7 +917,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend()const
+ const_reverse_iterator crend()const BOOST_CONTAINER_NOEXCEPT
{ return this->rend(); }
//////////////////////////////////////////////
@@ -1012,7 +931,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
{ return this->index.size() <= ExtraPointers; }
//! <b>Effects</b>: Returns the number of the elements contained in the stable_vector.
@@ -1020,7 +939,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
{
const size_type index_size = this->index.size();
return index_size ? (index_size - ExtraPointers) : 0;
@@ -1031,7 +950,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
{ return this->index.max_size() - ExtraPointers; }
//! <b>Effects</b>: Inserts or erases elements at the end such that
@@ -1071,7 +990,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type capacity() const
+ size_type capacity() const BOOST_CONTAINER_NOEXCEPT
{
const size_type index_size = this->index.size();
BOOST_ASSERT(!index_size || index_size >= ExtraPointers);
@@ -1094,7 +1013,7 @@
if(n > this->max_size())
throw std::bad_alloc();
- size_type size_ = this->size();
+ size_type sz = this->size();
size_type old_capacity = this->capacity();
if(n > old_capacity){
index_traits_type::initialize_end_node(this->index, this->internal_data.end_node, n);
@@ -1106,8 +1025,8 @@
index_traits_type::fix_up_pointers_from(this->index, this->index.begin());
}
//Now fill pool if data is not enough
- if((n - size_) > this->internal_data.pool_size){
- this->priv_increase_pool((n - size_) - this->internal_data.pool_size);
+ if((n - sz) > this->internal_data.pool_size){
+ this->priv_increase_pool((n - sz) - this->internal_data.pool_size);
}
}
}
@@ -1156,7 +1075,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference front()
+ reference front() BOOST_CONTAINER_NOEXCEPT
{ return static_cast<node_reference>(*this->index.front()).value; }
//! <b>Requires</b>: !empty()
@@ -1167,7 +1086,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference front() const
+ const_reference front() const BOOST_CONTAINER_NOEXCEPT
{ return static_cast<const_node_reference>(*this->index.front()).value; }
//! <b>Requires</b>: !empty()
@@ -1178,7 +1097,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference back()
+ reference back() BOOST_CONTAINER_NOEXCEPT
{ return static_cast<node_reference>(*this->index[this->size() - ExtraPointers]).value; }
//! <b>Requires</b>: !empty()
@@ -1189,7 +1108,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference back()const
+ const_reference back() const BOOST_CONTAINER_NOEXCEPT
{ return static_cast<const_node_reference>(*this->index[this->size() - ExtraPointers]).value; }
//! <b>Requires</b>: size() > n.
@@ -1200,7 +1119,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference operator[](size_type n)
+ reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT
{ return static_cast<node_reference>(*this->index[n]).value; }
//! <b>Requires</b>: size() > n.
@@ -1211,7 +1130,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference operator[](size_type n)const
+ const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
{ return static_cast<const_node_reference>(*this->index[n]).value; }
//! <b>Requires</b>: size() > n.
@@ -1400,7 +1319,7 @@
//!
//! <b>Complexity</b>: Linear to std::distance [first, last).
template <class InputIterator>
- iterator insert(const_iterator position,InputIterator first, InputIterator last
+ iterator insert(const_iterator position, InputIterator first, InputIterator last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename container_detail::enable_if_c
< !container_detail::is_convertible<InputIterator, size_type>::value
@@ -1426,8 +1345,8 @@
>::type * = 0
)
{
- const size_type num_new = (size_type)std::distance(first,last);
- const size_type pos = static_cast<size_type>(position - this->cbegin());
+ const size_type num_new = static_cast<size_type>(std::distance(first, last));
+ const size_type pos = static_cast<size_type>(position - this->cbegin());
if(num_new){
//Fills the node pool and inserts num_new null pointers in pos.
//If a new buffer was needed fixes up pointers up to pos so
@@ -1463,7 +1382,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant time.
- void pop_back()
+ void pop_back() BOOST_CONTAINER_NOEXCEPT
{ this->erase(--this->cend()); }
//! <b>Effects</b>: Erases the element at position pos.
@@ -1472,15 +1391,15 @@
//!
//! <b>Complexity</b>: Linear to the elements between pos and the
//! last element. Constant if pos is the last element.
- iterator erase(const_iterator position)
+ iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT
{
STABLE_VECTOR_CHECK_INVARIANT;
- difference_type d = position - this->cbegin();
- index_iterator it = this->index.begin() + d;
+ const size_type d = position - this->cbegin();
+ index_iterator it = this->index.begin() + d;
this->priv_delete_node(position.node_pointer());
it = this->index.erase(it);
index_traits_type::fix_up_pointers_from(this->index, it);
- return this->begin()+d;
+ return iterator(node_ptr_traits::static_cast_from(*it));
}
//! <b>Effects</b>: Erases the elements pointed by [first, last).
@@ -1489,19 +1408,30 @@
//!
//! <b>Complexity</b>: Linear to the distance between first and last
//! plus linear to the elements between pos and the last element.
- iterator erase(const_iterator first, const_iterator last)
+ iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
{
STABLE_VECTOR_CHECK_INVARIANT;
- difference_type d1 = first - this->cbegin(), d2 = last - this->cbegin();
- if(d1 != d2){
- index_iterator it1(this->index.begin() + d1), it2(it1 + (d2 - d1));
- for(index_iterator it = it1; it != it2; ++it){
- this->priv_delete_node(node_ptr_traits::static_cast_from(*it));
+ const const_iterator cbeg(this->cbegin());
+ const size_type d1 = static_cast<size_type>(first - cbeg),
+ d2 = static_cast<size_type>(last - cbeg);
+ size_type d_dif = d2 - d1;
+ if(d_dif){
+ multiallocation_chain holder;
+ const index_iterator it1(this->index.begin() + d1);
+ const index_iterator it2(it1 + d_dif);
+ index_iterator it(it1);
+ while(d_dif--){
+ node_base_ptr &nb = *it;
+ ++it;
+ node_type &n = *node_ptr_traits::static_cast_from(nb);
+ this->priv_destroy_node(n);
+ holder.push_back(node_ptr_traits::pointer_to(n));
}
+ this->priv_put_in_pool(holder);
const index_iterator e = this->index.erase(it1, it2);
index_traits_type::fix_up_pointers_from(this->index, e);
}
- return iterator(this->begin() + d1);
+ return iterator(last.node_pointer());
}
//! <b>Effects</b>: Swaps the contents of *this and x.
@@ -1524,7 +1454,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements in the stable_vector.
- void clear()
+ void clear() BOOST_CONTAINER_NOEXCEPT
{ this->erase(this->cbegin(),this->cend()); }
/// @cond
@@ -1666,7 +1596,8 @@
, node_ptr_traits::static_cast_from(pool_first_ref)
, node_ptr_traits::static_cast_from(pool_last_ref)
, internal_data.pool_size);
- multiallocation_chain m (this->allocate_individual(n));
+ multiallocation_chain m;
+ this->allocate_individual(n, m);
holder.splice_after(holder.before_begin(), m, m.before_begin(), m.last(), n);
this->internal_data.pool_size += n;
std::pair<node_ptr, node_ptr> data(holder.extract_data());
@@ -1690,11 +1621,25 @@
pool_last_ref = ret.second;
}
+ void priv_put_in_pool(multiallocation_chain &ch)
+ {
+ node_base_ptr &pool_first_ref = *(this->index.end()-(ExtraPointers-1));
+ node_base_ptr &pool_last_ref = this->index.back();
+ ch.incorporate_after( ch.before_begin()
+ , node_ptr_traits::static_cast_from(pool_first_ref)
+ , node_ptr_traits::static_cast_from(pool_last_ref)
+ , internal_data.pool_size);
+ this->internal_data.pool_size = ch.size();
+ const std::pair<node_ptr, node_ptr> ret(ch.extract_data());
+ pool_first_ref = ret.first;
+ pool_last_ref = ret.second;
+ }
+
node_ptr priv_get_from_pool()
{
//Precondition: index is not empty
BOOST_ASSERT(!this->index.empty());
- node_base_ptr &pool_first_ref = *(this->index.end() - 2);
+ node_base_ptr &pool_first_ref = *(this->index.end() - (ExtraPointers-1));
node_base_ptr &pool_last_ref = this->index.back();
multiallocation_chain holder;
holder.incorporate_after( holder.before_begin()
@@ -1707,9 +1652,9 @@
pool_first_ref = pool_last_ref = node_ptr();
}
else{
- std::pair<node_ptr, node_ptr> data(holder.extract_data());
+ const std::pair<node_ptr, node_ptr> data(holder.extract_data());
pool_first_ref = data.first;
- pool_last_ref = data.second;
+ pool_last_ref = data.second;
}
return ret;
}
@@ -1720,11 +1665,16 @@
(static_cast<node_type&>(const_cast<node_base_type&>(this->internal_data.end_node)));
}
- void priv_delete_node(const node_ptr &n)
+ void priv_destroy_node(const node_type &n)
{
allocator_traits<node_allocator_type>::
- destroy(this->priv_node_alloc(), container_detail::addressof(n->value));
- static_cast<node_base_type*>(container_detail::to_raw_pointer(n))->~node_base_type();
+ destroy(this->priv_node_alloc(), container_detail::addressof(n.value));
+ static_cast<const node_base_type*>(&n)->~node_base_type();
+ }
+
+ void priv_delete_node(const node_ptr &n)
+ {
+ this->priv_destroy_node(*n);
this->priv_put_in_pool(n);
}
@@ -1776,7 +1726,7 @@
}
size_type n = this->capacity() - this->size();
- node_base_ptr &pool_first_ref = *(index_ref.end() - 2);
+ node_base_ptr &pool_first_ref = *(index_ref.end() - (ExtraPointers-1));
node_base_ptr &pool_last_ref = index_ref.back();
multiallocation_chain holder;
holder.incorporate_after( holder.before_begin()
@@ -1886,6 +1836,17 @@
/// @endcond
+/*
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::stable_vector<T, Allocator> >
+ : public has_trivial_destructor_after_move<Allocator>::value
+{};
+
+*/
+
}}
#include <boost/container/detail/config_end.hpp>
Modified: branches/release/boost/container/string.hpp
==============================================================================
--- branches/release/boost/container/string.hpp (original)
+++ branches/release/boost/container/string.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -44,11 +44,13 @@
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/allocation_type.hpp>
#include <boost/container/allocator_traits.hpp>
+#include <boost/container/detail/allocator_version_traits.hpp>
#include <boost/container/detail/mpl.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include <boost/static_assert.hpp>
#include <boost/functional/hash.hpp>
#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
#include <functional>
#include <string>
@@ -81,8 +83,8 @@
// an exception-safe version of basic_string. The constructor allocates,
// but does not initialize, a block of memory. The destructor
// deallocates, but does not destroy elements within, a block of
-// memory. The destructor assumes that the memory either is the internal buffer,
-// or else points to a block of memory that was allocated using _String_base's
+// memory. The destructor assumes that the memory either is the internal buffer,
+// or else points to a block of memory that was allocated using string_base's
// allocator and whose size is this->m_storage.
template <class Allocator>
class basic_string_base
@@ -92,7 +94,6 @@
typedef allocator_traits<Allocator> allocator_traits_type;
public:
typedef Allocator allocator_type;
- //! The stored allocator type
typedef allocator_type stored_allocator_type;
typedef typename allocator_traits_type::pointer pointer;
typedef typename allocator_traits_type::value_type value_type;
@@ -284,36 +285,8 @@
reuse = pointer();
command &= ~(expand_fwd | expand_bwd);
}
- return this->allocation_command
- (command, limit_size, preferred_size, received_size, reuse, alloc_version());
- }
-
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
- size_type limit_size,
- size_type preferred_size,
- size_type &received_size,
- const pointer &reuse,
- allocator_v1)
- {
- (void)limit_size;
- (void)reuse;
- if(!(command & allocate_new))
- return std::pair<pointer, bool>(pointer(), false);
- received_size = preferred_size;
- return std::make_pair(this->alloc().allocate(received_size), false);
- }
-
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
- size_type limit_size,
- size_type preferred_size,
- size_type &received_size,
- pointer reuse,
- allocator_v2)
- {
- return this->alloc().allocation_command(command, limit_size, preferred_size,
- received_size, reuse);
+ return container_detail::allocator_version_traits<Allocator>::allocation_command
+ (this->alloc(), command, limit_size, preferred_size, received_size, reuse);
}
size_type next_capacity(size_type additional_objects) const
@@ -336,11 +309,9 @@
void destroy(pointer p, size_type n)
{
- for(; n--; ++p){
- allocator_traits_type::destroy
- ( this->alloc()
- , container_detail::to_raw_pointer(p)
- );
+ value_type *raw_p = container_detail::to_raw_pointer(p);
+ for(; n--; ++raw_p){
+ allocator_traits_type::destroy( this->alloc(), raw_p);
}
}
@@ -569,37 +540,26 @@
/// @endcond
public:
-
- //! The allocator type
- typedef Allocator allocator_type;
- //! The stored allocator type
- typedef allocator_type stored_allocator_type;
- //! The type of object, CharT, stored in the string
- typedef CharT value_type;
- //! The second template parameter Traits
- typedef Traits traits_type;
- //! Pointer to CharT
- typedef typename allocator_traits_type::pointer pointer;
- //! Const pointer to CharT
- typedef typename allocator_traits_type::const_pointer const_pointer;
- //! Reference to CharT
- typedef typename allocator_traits_type::reference reference;
- //! Const reference to CharT
- typedef typename allocator_traits_type::const_reference const_reference;
- //! An unsigned integral type
- typedef typename allocator_traits_type::size_type size_type;
- //! A signed integral type
- typedef typename allocator_traits_type::difference_type difference_type;
- //! Iterator used to iterate through a string. It's a Random Access Iterator
- typedef pointer iterator;
- //! Const iterator used to iterate through a string. It's a Random Access Iterator
- typedef const_pointer const_iterator;
- //! Iterator used to iterate backwards through a string
- typedef std::reverse_iterator<iterator> reverse_iterator;
- //! Const iterator used to iterate backwards through a string
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- //! The largest possible value of type size_type. That is, size_type(-1).
- static const size_type npos;
+ //////////////////////////////////////////////
+ //
+ // types
+ //
+ //////////////////////////////////////////////
+ typedef Traits traits_type;
+ typedef CharT value_type;
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
+ typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
+ typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
+ typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
+ typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
+ typedef Allocator allocator_type;
+ typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type;
+ typedef BOOST_CONTAINER_IMPDEF(pointer) iterator;
+ typedef BOOST_CONTAINER_IMPDEF(const_pointer) const_iterator;
+ typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
+ typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
+ static const size_type npos = size_type(-1);
/// @cond
private:
@@ -611,6 +571,11 @@
/// @endcond
public: // Constructor, destructor, assignment.
+ //////////////////////////////////////////////
+ //
+ // construct/copy/destroy
+ //
+ //////////////////////////////////////////////
/// @cond
struct reserve_t {};
@@ -634,8 +599,8 @@
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter.
//!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
- explicit basic_string(const allocator_type& a)
+ //! <b>Throws</b>: Nothing
+ explicit basic_string(const allocator_type& a) BOOST_CONTAINER_NOEXCEPT
: base_t(a)
{ this->priv_terminate_string(); }
@@ -653,10 +618,10 @@
//! <b>Effects</b>: Move constructor. Moves s's resources to *this.
//!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- basic_string(BOOST_RV_REF(basic_string) s)
+ basic_string(BOOST_RV_REF(basic_string) s) BOOST_CONTAINER_NOEXCEPT
: base_t(boost::move((base_t&)s))
{}
@@ -693,7 +658,7 @@
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
//! and is initialized by a specific number of characters of the s string.
basic_string(const basic_string& s, size_type pos, size_type n = npos,
- const allocator_type& a = allocator_type())
+ const allocator_type& a = allocator_type())
: base_t(a)
{
this->priv_terminate_string();
@@ -706,8 +671,7 @@
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
//! and is initialized by a specific number of characters of the s c-string.
- basic_string(const CharT* s, size_type n,
- const allocator_type& a = allocator_type())
+ basic_string(const CharT* s, size_type n, const allocator_type& a = allocator_type())
: base_t(a)
{
this->priv_terminate_string();
@@ -716,8 +680,7 @@
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
//! and is initialized by the null-terminated s c-string.
- basic_string(const CharT* s,
- const allocator_type& a = allocator_type())
+ basic_string(const CharT* s, const allocator_type& a = allocator_type())
: base_t(a)
{
this->priv_terminate_string();
@@ -726,8 +689,7 @@
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
//! and is initialized by n copies of c.
- basic_string(size_type n, CharT c,
- const allocator_type& a = allocator_type())
+ basic_string(size_type n, CharT c, const allocator_type& a = allocator_type())
: base_t(a)
{
this->priv_terminate_string();
@@ -737,8 +699,7 @@
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
//! and a range of iterators.
template <class InputIterator>
- basic_string(InputIterator f, InputIterator l,
- const allocator_type& a = allocator_type())
+ basic_string(InputIterator f, InputIterator l, const allocator_type& a = allocator_type())
: base_t(a)
{
this->priv_terminate_string();
@@ -750,7 +711,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- ~basic_string()
+ ~basic_string() BOOST_CONTAINER_NOEXCEPT
{}
//! <b>Effects</b>: Copy constructs a string.
@@ -784,7 +745,7 @@
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
- basic_string& operator=(BOOST_RV_REF(basic_string) x)
+ basic_string& operator=(BOOST_RV_REF(basic_string) x) BOOST_CONTAINER_NOEXCEPT
{
if (&x != this){
allocator_type &this_alloc = this->alloc();
@@ -815,44 +776,62 @@
basic_string& operator=(CharT c)
{ return this->assign(static_cast<size_type>(1), c); }
- //! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If allocator's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
- iterator begin()
- { return this->priv_addr(); }
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
+ { return this->alloc(); }
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+ //! <b>Effects</b>: Returns a reference to the internal allocator.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const
- { return this->priv_addr(); }
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
+ { return this->alloc(); }
- //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
+ //! <b>Effects</b>: Returns a reference to the internal allocator.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
+ { return this->alloc(); }
+
+ //////////////////////////////////////////////
+ //
+ // iterators
+ //
+ //////////////////////////////////////////////
+
+ //! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const
+ iterator begin() BOOST_CONTAINER_NOEXCEPT
{ return this->priv_addr(); }
- //! <b>Effects</b>: Returns an iterator to the end of the vector.
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end()
- { return this->priv_end_addr(); }
+ const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
+ { return this->priv_addr(); }
- //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
+ //! <b>Effects</b>: Returns an iterator to the end of the vector.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const
+ iterator end() BOOST_CONTAINER_NOEXCEPT
{ return this->priv_end_addr(); }
//! <b>Effects</b>: Returns a const_iterator to the end of the vector.
@@ -860,7 +839,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const
+ const_iterator end() const BOOST_CONTAINER_NOEXCEPT
{ return this->priv_end_addr(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -869,7 +848,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin()
+ reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
{ return reverse_iterator(this->priv_end_addr()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -878,25 +857,16 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const
+ const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
{ return this->crbegin(); }
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const
- { return const_reverse_iterator(this->priv_end_addr()); }
-
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
//! of the reversed vector.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend()
+ reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
{ return reverse_iterator(this->priv_addr()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -905,52 +875,63 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const
+ const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
{ return this->crend(); }
- //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
- //! of the reversed vector.
+ //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const
- { return const_reverse_iterator(this->priv_addr()); }
+ const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
+ { return this->priv_addr(); }
- //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
//!
- //! <b>Throws</b>: If allocator's copy constructor throws.
+ //! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
- { return this->alloc(); }
+ const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
+ { return this->priv_end_addr(); }
- //! <b>Effects</b>: Returns a reference to the internal allocator.
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
+ //! of the reversed vector.
//!
- //! <b>Throws</b>: Nothing
+ //! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- //!
- //! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
- { return this->alloc(); }
+ const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
+ { return const_reverse_iterator(this->priv_end_addr()); }
- //! <b>Effects</b>: Returns a reference to the internal allocator.
+ //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
+ //! of the reversed vector.
//!
- //! <b>Throws</b>: Nothing
+ //! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
+ const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
+ { return const_reverse_iterator(this->priv_addr()); }
+
+ //////////////////////////////////////////////
+ //
+ // capacity
+ //
+ //////////////////////////////////////////////
+
+ //! <b>Effects</b>: Returns true if the vector contains no elements.
//!
- //! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
- { return this->alloc(); }
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
+ { return !this->priv_size(); }
//! <b>Effects</b>: Returns the number of the elements contained in the vector.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
{ return this->priv_size(); }
//! <b>Effects</b>: Returns the number of the elements contained in the vector.
@@ -958,7 +939,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type length() const
+ size_type length() const BOOST_CONTAINER_NOEXCEPT
{ return this->size(); }
//! <b>Effects</b>: Returns the largest possible size of the vector.
@@ -966,7 +947,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
{ return base_t::max_size(); }
//! <b>Effects</b>: Inserts or erases elements at the end such that
@@ -990,7 +971,16 @@
//!
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
void resize(size_type n)
- { resize(n, CharT(0)); }
+ { resize(n, CharT()); }
+
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ size_type capacity() const BOOST_CONTAINER_NOEXCEPT
+ { return this->priv_capacity(); }
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
//! effect. Otherwise, it is a request for allocation of additional memory.
@@ -1023,28 +1013,6 @@
}
}
- //! <b>Effects</b>: Number of elements for which memory has been allocated.
- //! capacity() is always greater than or equal to size().
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type capacity() const
- { return this->priv_capacity(); }
-
- //! <b>Effects</b>: Erases all the elements of the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of elements in the vector.
- void clear()
- {
- if (!this->empty()) {
- Traits::assign(*this->priv_addr(), CharT(0));
- this->priv_size(0);
- }
- }
-
//! <b>Effects</b>: Tries to deallocate the excess of memory created
//! with previous allocations. The size of the string is unchanged
//!
@@ -1076,13 +1044,11 @@
}
}
- //! <b>Effects</b>: Returns true if the vector contains no elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- bool empty() const
- { return !this->priv_size(); }
+ //////////////////////////////////////////////
+ //
+ // element access
+ //
+ //////////////////////////////////////////////
//! <b>Requires</b>: size() > n.
//!
@@ -1092,7 +1058,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference operator[](size_type n)
+ reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT
{ return *(this->priv_addr() + n); }
//! <b>Requires</b>: size() > n.
@@ -1103,7 +1069,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference operator[](size_type n) const
+ const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
{ return *(this->priv_addr() + n); }
//! <b>Requires</b>: size() > n.
@@ -1135,6 +1101,12 @@
return *(this->priv_addr() + n);
}
+ //////////////////////////////////////////////
+ //
+ // modifiers
+ //
+ //////////////////////////////////////////////
+
//! <b>Effects</b>: Calls append(str.data, str.size()).
//!
//! <b>Returns</b>: *this
@@ -1240,7 +1212,7 @@
//! <b>Throws</b>: Nothing
//!
//! <b>Returns</b>: *this
- basic_string& assign(BOOST_RV_REF(basic_string) ms)
+ basic_string& assign(BOOST_RV_REF(basic_string) ms) BOOST_CONTAINER_NOEXCEPT
{ return this->swap_data(ms), *this; }
//! <b>Requires</b>: pos <= str.size()
@@ -1322,10 +1294,10 @@
//! <b>Returns</b>: *this
basic_string& insert(size_type pos, const basic_string& s)
{
- const size_type size_ = this->size();
- if (pos > size_)
+ const size_type sz = this->size();
+ if (pos > sz)
this->throw_out_of_range();
- if (size_ > this->max_size() - s.size())
+ if (sz > this->max_size() - s.size())
this->throw_length_error();
this->insert(this->priv_addr() + pos, s.begin(), s.end());
return *this;
@@ -1341,12 +1313,12 @@
//! <b>Returns</b>: *this
basic_string& insert(size_type pos1, const basic_string& s, size_type pos2, size_type n)
{
- const size_type size_ = this->size();
+ const size_type sz = this->size();
const size_type str_size = s.size();
- if (pos1 > size_ || pos2 > str_size)
+ if (pos1 > sz || pos2 > str_size)
this->throw_out_of_range();
size_type len = container_detail::min_value(n, str_size - pos2);
- if (size_ > this->max_size() - len)
+ if (sz > this->max_size() - len)
this->throw_length_error();
const CharT *beg_ptr = container_detail::to_raw_pointer(s.begin()) + pos2;
const CharT *end_ptr = beg_ptr + len;
@@ -1591,7 +1563,7 @@
//!
//! <b>Returns</b>: An iterator which points to the element immediately following p prior to the element being
//! erased. If no such element exists, end() is returned.
- iterator erase(const_iterator p)
+ iterator erase(const_iterator p) BOOST_CONTAINER_NOEXCEPT
{
// The move includes the terminating null.
CharT * const ptr = const_cast<CharT*>(container_detail::to_raw_pointer(p));
@@ -1611,7 +1583,7 @@
//!
//! <b>Returns</b>: An iterator which points to the element pointed to by last prior to
//! the other elements being erased. If no such element exists, end() is returned.
- iterator erase(const_iterator first, const_iterator last)
+ iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
{
CharT * f = const_cast<CharT*>(container_detail::to_raw_pointer(first));
if (first != last) { // The move includes the terminating null.
@@ -1631,13 +1603,26 @@
//! <b>Throws</b>: Nothing
//!
//! <b>Effects</b>: Equivalent to erase(size() - 1, 1).
- void pop_back()
+ void pop_back() BOOST_CONTAINER_NOEXCEPT
{
const size_type old_size = this->priv_size();
Traits::assign(this->priv_addr()[old_size-1], CharT(0));
this->priv_size(old_size-1);;
}
+ //! <b>Effects</b>: Erases all the elements of the vector.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in the vector.
+ void clear() BOOST_CONTAINER_NOEXCEPT
+ {
+ if (!this->empty()) {
+ Traits::assign(*this->priv_addr(), CharT(0));
+ this->priv_size(0);
+ }
+ }
+
//! <b>Requires</b>: pos1 <= size().
//!
//! <b>Effects</b>: Calls replace(pos1, n1, str.data(), str.size()).
@@ -1890,12 +1875,18 @@
container_detail::swap_alloc(this->alloc(), x.alloc(), flag);
}
+ //////////////////////////////////////////////
+ //
+ // data access
+ //
+ //////////////////////////////////////////////
+
//! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
//!
//! <b>Returns</b>: Allocator pointer p such that p + i == &operator[](i) for each i in [0,size()].
//!
//! <b>Complexity</b>: constant time.
- const CharT* c_str() const
+ const CharT* c_str() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::to_raw_pointer(this->priv_addr()); }
//! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
@@ -1903,9 +1894,15 @@
//! <b>Returns</b>: Allocator pointer p such that p + i == &operator[](i) for each i in [0,size()].
//!
//! <b>Complexity</b>: constant time.
- const CharT* data() const
+ const CharT* data() const BOOST_CONTAINER_NOEXCEPT
{ return container_detail::to_raw_pointer(this->priv_addr()); }
+ //////////////////////////////////////////////
+ //
+ // string operations
+ //
+ //////////////////////////////////////////////
+
//! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both
//! of the following conditions obtain: 19 pos <= xpos and xpos + str.size() <= size();
//! 2) traits::eq(at(xpos+I), str.at(I)) for all elements I of the string controlled by str.
@@ -1949,12 +1946,12 @@
//! <b>Returns</b>: find(basic_string<CharT,traits,Allocator>(1,c), pos).
size_type find(CharT c, size_type pos = 0) const
{
- const size_type size_ = this->size();
- if (pos >= size_)
+ const size_type sz = this->size();
+ if (pos >= sz)
return npos;
else {
- const pointer addr = this->priv_addr();
- pointer finish = addr + size_;
+ const pointer addr = this->priv_addr();
+ pointer finish = addr + sz;
const const_iterator result =
std::find_if(addr + pos, finish,
std::bind2nd(Eq_traits<Traits>(), c));
@@ -2039,12 +2036,12 @@
//! <b>Returns</b>: find_first_of(basic_string(s, n), pos).
size_type find_first_of(const CharT* s, size_type pos, size_type n) const
{
- const size_type size_ = this->size();
- if (pos >= size_)
+ const size_type sz = this->size();
+ if (pos >= sz)
return npos;
else {
- const pointer addr = this->priv_addr();
- pointer finish = addr + size_;
+ const pointer addr = this->priv_addr();
+ pointer finish = addr + sz;
const_iterator result = std::find_first_of
(addr + pos, finish, s, s + n, Eq_traits<Traits>());
return result != finish ? result - this->begin() : npos;
@@ -2282,8 +2279,8 @@
//! <b>Throws</b>: out_of_range if pos1 > size() or pos2 > str.size()
//!
//! <b>Returns</b>: basic_string(*this, pos1, n1).compare(basic_string(str, pos2, n2)).
- int compare(size_type pos1, size_type n1,
- const basic_string& str, size_type pos2, size_type n2) const {
+ 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();
const pointer addr = this->priv_addr();
@@ -2309,8 +2306,7 @@
//! <b>Throws</b>: out_of_range if pos1 > size()
//!
//! <b>Returns</b>: basic_string(*this, pos, n1).compare(basic_string(s, n2)).
- int compare(size_type pos1, size_type n1,
- const CharT* s, size_type n2) const
+ int compare(size_type pos1, size_type n1, const CharT* s, size_type n2) const
{
if (pos1 > this->size())
this->throw_out_of_range();
@@ -2352,7 +2348,7 @@
const size_type long_size = this->priv_long_size();
const size_type long_storage = this->priv_long_storage();
//We can make this nothrow as chars are always NoThrowCopyables
- try{
+ BOOST_TRY{
const std::pair<pointer, bool> ret = this->allocation_command
(allocate_new, long_size+1, long_size+1, real_cap, long_addr);
//Copy and update
@@ -2364,9 +2360,10 @@
//And release old buffer
this->alloc().deallocate(long_addr, long_storage);
}
- catch(...){
+ BOOST_CATCH(...){
return;
}
+ BOOST_CATCH_END
}
template<class AllocVersion>
@@ -2481,15 +2478,6 @@
,std::allocator<wchar_t> >
wstring;
-/// @cond
-
-template <class CharT, class Traits, class Allocator>
-const typename basic_string<CharT,Traits,Allocator>::size_type
-basic_string<CharT,Traits,Allocator>::npos
- = (typename basic_string<CharT,Traits,Allocator>::size_type) -1;
-
-/// @endcond
-
// ------------------------------------------------------------
// Non-member functions.
@@ -2857,15 +2845,14 @@
/// @cond
namespace boost {
-/*
+
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class C, class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, Allocator> >
-{
- static const bool value = has_trivial_destructor<Allocator>::value;
-};
-*/
+ : public ::boost::has_trivial_destructor_after_move<Allocator>
+{};
+
}
/// @endcond
Modified: branches/release/boost/container/vector.hpp
==============================================================================
--- branches/release/boost/container/vector.hpp (original)
+++ branches/release/boost/container/vector.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -32,6 +32,7 @@
#include <boost/type_traits/has_nothrow_copy.hpp>
#include <boost/type_traits/has_nothrow_assign.hpp>
#include <boost/type_traits/has_nothrow_constructor.hpp>
+#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/allocation_type.hpp>
#include <boost/container/detail/utilities.hpp>
@@ -39,9 +40,10 @@
#include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/destroyers.hpp>
#include <boost/container/allocator_traits.hpp>
-#include <boost/container/container_fwd.hpp>
-#include <boost/move/move.hpp>
-#include <boost/move/move_helpers.hpp>
+#include <boost/container/detail/allocator_version_traits.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/detail/move_helpers.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
@@ -213,8 +215,7 @@
typedef T value_type;
typedef Allocator allocator_type;
static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
- static const bool trivial_dctr_after_move = trivial_dctr;
- //::boost::has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
+ static const bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move<value_type>::value;
//static const bool trivial_copy = has_trivial_copy<value_type>::value;
//static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
//static const bool trivial_assign = has_trivial_assign<value_type>::value;
@@ -286,42 +287,17 @@
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0)
{
- return allocation_command(command, limit_size, preferred_size,
- received_size, reuse, alloc_version());
- }
-
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
- size_type limit_size,
- size_type preferred_size,
- size_type &received_size,
- const pointer &reuse,
- allocator_v1)
- {
- (void)limit_size;
- (void)reuse;
- if(!(command & allocate_new))
- return std::pair<pointer, bool>(pointer(0), false);
- received_size = preferred_size;
- return std::make_pair(this->alloc().allocate(received_size), false);
- }
-
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
- size_type limit_size,
- size_type preferred_size,
- size_type &received_size,
- const pointer &reuse,
- allocator_v2)
- {
- return this->alloc().allocation_command
- (command, limit_size, preferred_size, received_size, reuse);
+ return allocator_version_traits<Allocator>::allocation_command
+ (this->alloc(), command, limit_size, preferred_size, received_size, reuse);
}
size_type next_capacity(size_type additional_objects) const
{
+ std::size_t num_objects = this->members_.m_size + additional_objects;
+ std::size_t next_cap = this->members_.m_capacity + this->members_.m_capacity/2;
+ return num_objects > next_cap ? num_objects : next_cap;/*
return get_next_capacity( allocator_traits_type::max_size(this->alloc())
- , this->members_.m_capacity, additional_objects);
+ , this->members_.m_capacity, additional_objects);*/
}
struct members_holder
@@ -435,7 +411,6 @@
/// @cond
private:
BOOST_COPYABLE_AND_MOVABLE(vector)
- typedef container_detail::advanced_insert_aux_int<T*> advanced_insert_aux_int_t;
typedef container_detail::vector_value_traits<value_type, Allocator> value_traits;
typedef typename base_t::allocator_v1 allocator_v1;
@@ -443,8 +418,6 @@
typedef typename base_t::alloc_version alloc_version;
typedef constant_iterator<T, difference_type> cvalue_iterator;
- typedef repeat_iterator<T, difference_type> repeat_it;
- typedef boost::move_iterator<repeat_it> repeat_move_it;
/// @endcond
public:
@@ -857,7 +830,7 @@
else{
const size_type n = new_size - this->size();
this->reserve(new_size);
- container_detail::default_construct_aux_proxy<Allocator, T*> proxy(this->alloc(), n);
+ container_detail::insert_default_constructed_n_proxy<Allocator, T*> proxy(this->alloc());
this->priv_forward_range_insert(this->cend().get_ptr(), n, proxy);
}
}
@@ -920,11 +893,10 @@
//If there is no forward expansion, move objects
else{
//We will reuse insert code, so create a dummy input iterator
- T *dummy_it(container_detail::to_raw_pointer(this->members_.m_start));
- container_detail::advanced_insert_aux_proxy<Allocator, boost::move_iterator<T*>, T*>
- proxy(this->alloc(), ::boost::make_move_iterator(dummy_it), ::boost::make_move_iterator(dummy_it));
+ container_detail::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*>
+ proxy(this->alloc(), ::boost::make_move_iterator((T *)0));
//Backwards (and possibly forward) expansion
- if(ret.second){
+ if(alloc_version::value > 1 && ret.second){
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
++this->num_expand_bwd;
#endif
@@ -1018,7 +990,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference operator[](size_type n)
+ reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT
{ return this->members_.m_start[n]; }
//! <b>Requires</b>: size() > n.
@@ -1102,9 +1074,9 @@
++this->members_.m_size;
}
else{
- typedef container_detail::advanced_insert_aux_emplace<Allocator, T*, Args...> type;
- type &&proxy = type(this->alloc(), ::boost::forward<Args>(args)...);
- this->priv_forward_range_insert(back_pos, 1, proxy);
+ typedef container_detail::insert_emplace_proxy<Allocator, T*, Args...> type;
+ this->priv_forward_range_insert
+ (back_pos, 1, type(this->alloc(), ::boost::forward<Args>(args)...));
}
}
@@ -1122,11 +1094,9 @@
iterator emplace(const_iterator position, Args && ...args)
{
//Just call more general insert(pos, size, value) and return iterator
- size_type pos_n = position - cbegin();
- typedef container_detail::advanced_insert_aux_emplace<Allocator, T*, Args...> type;
- type &&proxy = type(this->alloc(), ::boost::forward<Args>(args)...);
- this->priv_forward_range_insert(position.get_ptr(), 1, proxy);
- return iterator(this->members_.m_start + pos_n);
+ typedef container_detail::insert_emplace_proxy<Allocator, T*, Args...> type;
+ return this->priv_forward_range_insert
+ (position.get_ptr(), 1, type(this->alloc(), ::boost::forward<Args>(args)...));
}
#else
@@ -1143,8 +1113,8 @@
++this->members_.m_size; \
} \
else{ \
- container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
- <Allocator, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
+ container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
+ <Allocator, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
this->priv_forward_range_insert(back_pos, 1, proxy); \
} \
@@ -1154,12 +1124,11 @@
iterator emplace(const_iterator pos \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
- size_type pos_n = pos - cbegin(); \
- container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
- <Allocator, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
+ container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
+ <Allocator, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- this->priv_forward_range_insert(container_detail::to_raw_pointer(pos.get_ptr()), 1,proxy);\
- return iterator(this->members_.m_start + pos_n); \
+ return this->priv_forward_range_insert \
+ (container_detail::to_raw_pointer(pos.get_ptr()), 1, proxy); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
@@ -1222,7 +1191,10 @@
//!
//! <b>Complexity</b>: Linear to n.
iterator insert(const_iterator p, size_type n, const T& x)
- { return this->insert(p, cvalue_iterator(x, n), cvalue_iterator()); }
+ {
+ container_detail::insert_n_copies_proxy<Allocator, T*> proxy(this->alloc(), x);
+ return this->priv_forward_range_insert(p.get_ptr(), n, proxy);
+ }
//! <b>Requires</b>: p must be a valid iterator of *this.
//!
@@ -1250,7 +1222,7 @@
it = this->emplace(it, *first);
++it;
}
- return this->begin() + n_pos;
+ return iterator(this->members_.m_start + n_pos);
}
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1262,11 +1234,8 @@
>::type * = 0
)
{
- const size_type n_pos = pos - this->cbegin();
- const size_type n = std::distance(first, last);
- container_detail::advanced_insert_aux_proxy<Allocator, FwdIt, T*> proxy(this->alloc(), first, last);
- this->priv_forward_range_insert(pos.get_ptr(), n, proxy);
- return this->begin() + n_pos;
+ container_detail::insert_range_proxy<Allocator, FwdIt, T*> proxy(this->alloc(), first);
+ return this->priv_forward_range_insert(pos.get_ptr(), std::distance(first, last), proxy);
}
#endif
@@ -1275,7 +1244,7 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant time.
- void pop_back()
+ void pop_back() BOOST_CONTAINER_NOEXCEPT
{
//Destroy last element
--this->members_.m_size;
@@ -1290,8 +1259,8 @@
//! last element. Constant if pos is the last element.
iterator erase(const_iterator position)
{
- T *pos = container_detail::to_raw_pointer(position.get_ptr());
- T *beg = container_detail::to_raw_pointer(this->members_.m_start);
+ T *const pos = container_detail::to_raw_pointer(position.get_ptr());
+ T *const beg = container_detail::to_raw_pointer(this->members_.m_start);
::boost::move(pos + 1, beg + this->members_.m_size, pos);
--this->members_.m_size;
//Destroy last element
@@ -1307,14 +1276,14 @@
//! plus linear to the elements between pos and the last element.
iterator erase(const_iterator first, const_iterator last)
{
- if (first != last){ // worth doing, copy down over hole
+ if (first != last){
T* end_pos = container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size;
T* ptr = container_detail::to_raw_pointer(boost::move
(container_detail::to_raw_pointer(last.get_ptr())
,end_pos
,container_detail::to_raw_pointer(first.get_ptr())
));
- size_type destroyed = (end_pos - ptr);
+ const size_type destroyed = (end_pos - ptr);
this->destroy_n(ptr, destroyed);
this->members_.m_size -= destroyed;
}
@@ -1361,26 +1330,15 @@
}
private:
- iterator priv_insert(const_iterator position, const T &x)
- {
- //Just call more general insert(pos, size, value) and return iterator
- size_type pos_n = position - cbegin();
- this->insert(position, (size_type)1, x);
- return iterator(this->members_.m_start + pos_n);
- }
-
- iterator priv_insert(const_iterator position, BOOST_RV_REF(T) x)
+ template<class U>
+ iterator priv_insert(const const_iterator &p, BOOST_FWD_REF(U) x)
{
- //Just call more general insert(pos, size, value) and return iterator
- size_type pos_n = position - cbegin();
- this->insert(position
- ,repeat_move_it(repeat_it(x, 1))
- ,repeat_move_it(repeat_it()));
- return iterator(this->members_.m_start + pos_n);
+ return this->priv_forward_range_insert
+ (p.get_ptr(), 1, container_detail::get_insert_value_proxy<T*>(this->alloc(), ::boost::forward<U>(x)));
}
template <class U>
- void priv_push_back(BOOST_MOVE_CATCH_FWD(U) x)
+ void priv_push_back(BOOST_FWD_REF(U) x)
{
if (this->members_.m_size < this->members_.m_capacity){
//There is more memory, just construct a new object at the end
@@ -1391,7 +1349,7 @@
++this->members_.m_size;
}
else{
- this->insert(this->cend(), ::boost::forward<U>(x));
+ this->priv_insert(this->cend(), ::boost::forward<U>(x));
}
}
@@ -1409,9 +1367,8 @@
(allocate_new, this->size(), this->size(), real_cap, this->members_.m_start);
if(real_cap < this->capacity()){
//We will reuse insert code, so create a dummy input iterator
- T *dummy_it(container_detail::to_raw_pointer(this->members_.m_start));
- container_detail::advanced_insert_aux_proxy<Allocator, boost::move_iterator<T*>, T*>
- proxy(this->alloc(), ::boost::make_move_iterator(dummy_it), ::boost::make_move_iterator(dummy_it));
+ container_detail::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*>
+ proxy(this->alloc(), ::boost::make_move_iterator((T *)0));
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
++this->num_alloc;
#endif
@@ -1450,65 +1407,79 @@
}
}
- void priv_forward_range_insert(pointer pos, const size_type n, advanced_insert_aux_int_t &interf)
+ template <class InsertionProxy>
+ iterator priv_forward_range_insert
+ (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy)
{
//Check if we have enough memory or try to expand current memory
- size_type remaining = this->members_.m_capacity - this->members_.m_size;
- bool same_buffer_start;
- std::pair<pointer, bool> ret;
- size_type real_cap = this->members_.m_capacity;
+ const size_type remaining = this->members_.m_capacity - this->members_.m_size;
+ const size_type n_pos = pos - this->members_.m_start;
+ T *const raw_pos = container_detail::to_raw_pointer(pos);
//Check if we already have room
- if (n <= remaining){
- same_buffer_start = true;
- }
- else{
- //There is not enough memory, allocate a new
- //buffer or expand the old one.
- size_type new_cap = this->next_capacity(n);
- ret = this->allocation_command
- (allocate_new | expand_fwd | expand_bwd,
- this->members_.m_size + n, new_cap, real_cap, this->members_.m_start);
+ if(alloc_version::value > 1){ //Version 2 allocator, compile time check
+ bool same_buffer_start = n <= remaining;
+ if (!same_buffer_start){
+ size_type real_cap = 0;
+ //There is not enough memory, allocate a new
+ //buffer or expand the old one.
+ std::pair<pointer, bool> ret = (this->allocation_command
+ (allocate_new | expand_fwd | expand_bwd,
+ this->members_.m_size + n, this->next_capacity(n), real_cap, this->members_.m_start));
- //Check for forward expansion
- same_buffer_start = ret.second && this->members_.m_start == ret.first;
- if(same_buffer_start){
- this->members_.m_capacity = real_cap;
+ //Buffer reallocated
+ if(ret.second){
+ //Forward expansion, delay insertion
+ if(this->members_.m_start == ret.first){
+ #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+ ++this->num_expand_fwd;
+ #endif
+ this->members_.m_capacity = real_cap;
+ //Expand forward
+ this->priv_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
+ }
+ //Backwards (and possibly forward) expansion
+ else{
+ #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+ ++this->num_expand_bwd;
+ #endif
+ this->priv_range_insert_expand_backwards
+ ( container_detail::to_raw_pointer(ret.first)
+ , real_cap, raw_pos, n, insert_range_proxy);
+ }
+ }
+ //New buffer
+ else{
+ #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+ ++this->num_alloc;
+ #endif
+ this->priv_range_insert_new_allocation
+ ( container_detail::to_raw_pointer(ret.first)
+ , real_cap, raw_pos, n, insert_range_proxy);
+ }
+ }
+ else{
+ //Expand forward
+ this->priv_range_insert_expand_forward
+ (raw_pos, n, insert_range_proxy);
}
}
-
- //If we had room or we have expanded forward
- if (same_buffer_start){
- #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
- ++this->num_expand_fwd;
- #endif
- this->priv_range_insert_expand_forward
- (container_detail::to_raw_pointer(pos), n, interf);
- }
- //Backwards (and possibly forward) expansion
- else if(ret.second){
- #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
- ++this->num_expand_bwd;
- #endif
- this->priv_range_insert_expand_backwards
- ( container_detail::to_raw_pointer(ret.first)
- , real_cap
- , container_detail::to_raw_pointer(pos)
- , n
- , interf);
- }
- //New buffer
- else{
- #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
- ++this->num_alloc;
- #endif
- this->priv_range_insert_new_allocation
- ( container_detail::to_raw_pointer(ret.first)
- , real_cap
- , container_detail::to_raw_pointer(pos)
- , n
- , interf);
+ else{ //Version 1 allocator
+ if (n <= remaining){
+ this->priv_range_insert_expand_forward
+ (raw_pos, n, insert_range_proxy);
+ }
+ else{
+ const size_type new_cap = this->next_capacity(n);
+ T * new_buf = container_detail::to_raw_pointer(this->alloc().allocate(new_cap));
+ #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+ ++this->num_alloc;
+ #endif
+ this->priv_range_insert_new_allocation
+ ( new_buf, new_cap, raw_pos, n, insert_range_proxy);
+ }
}
+ return iterator(this->members_.m_start + n_pos);
}
//Absolutely experimental. This function might change, disappear or simply crash!
@@ -1660,15 +1631,21 @@
}
private:
- void priv_range_insert_expand_forward(T* pos, size_type n, advanced_insert_aux_int_t &interf)
+ template <class InsertionProxy>
+ void priv_range_insert_expand_forward(T* const pos, const size_type n, InsertionProxy insert_range_proxy)
{
//n can't be 0, because there is nothing to do in that case
if(!n) return;
//There is enough memory
- T* old_finish = container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size;
+ T* const old_finish = container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size;
const size_type elems_after = old_finish - pos;
- if (elems_after >= n){
+ if (!elems_after){
+ //Copy first new elements in pos
+ insert_range_proxy.uninitialized_copy_n_and_update(pos, n);
+ this->members_.m_size += n;
+ }
+ else if (elems_after >= n){
//New elements can be just copied.
//Move to uninitialized memory last objects
::boost::container::uninitialized_move_alloc
@@ -1677,24 +1654,31 @@
//Copy previous to last objects to the initialized end
boost::move_backward(pos, old_finish - n, old_finish);
//Insert new objects in the pos
- interf.copy_remaining_to(pos);
+ insert_range_proxy.copy_n_and_update(pos, n);
}
else {
- //The new elements don't fit in the [pos, end()) range. Copy
- //to the beginning of the unallocated zone the last new elements.
- interf.uninitialized_copy_some_and_update(old_finish, elems_after, false);
- this->members_.m_size += n - elems_after;
- //Copy old [pos, end()) elements to the uninitialized memory
- ::boost::container::uninitialized_move_alloc
- (this->alloc(), pos, old_finish, container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size);
- this->members_.m_size += elems_after;
- //Copy first new elements in pos
- interf.copy_remaining_to(pos);
+ //The new elements don't fit in the [pos, end()) range.
+
+ //Copy old [pos, end()) elements to the uninitialized memory (a gap is created)
+ ::boost::container::uninitialized_move_alloc(this->alloc(), pos, old_finish, pos + n);
+ BOOST_TRY{
+ //Copy first new elements in pos (gap is still there)
+ insert_range_proxy.copy_n_and_update(pos, elems_after);
+ //Copy to the beginning of the unallocated zone the last new elements (the gap is closed).
+ insert_range_proxy.uninitialized_copy_n_and_update(old_finish, n - elems_after);
+ this->members_.m_size += n;
+ }
+ BOOST_CATCH(...){
+ this->destroy_n(pos + n, elems_after);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
}
}
+ template <class InsertionProxy>
void priv_range_insert_new_allocation
- (T* new_start, size_type new_cap, T* pos, size_type n, advanced_insert_aux_int_t &interf)
+ (T* const new_start, size_type new_cap, T* const pos, const size_type n, InsertionProxy insert_range_proxy)
{
//n can be zero, if we want to reallocate!
T *new_finish = new_start;
@@ -1712,7 +1696,7 @@
constructed_values_destroyer.increment_size(new_finish - old_finish);
}
//Initialize new objects, starting from previous point
- interf.uninitialized_copy_remaining_to(old_finish = new_finish);
+ insert_range_proxy.uninitialized_copy_n_and_update(old_finish = new_finish, n);
new_finish += n;
constructed_values_destroyer.increment_size(new_finish - old_finish);
//Initialize from the rest of the old buffer,
@@ -1734,19 +1718,21 @@
scoped_alloc.release();
}
+ template <class InsertionProxy>
void priv_range_insert_expand_backwards
- (T* new_start, size_type new_capacity,
- T* pos, const size_type n, advanced_insert_aux_int_t &interf)
+ (T* const new_start, const size_type new_capacity,
+ T* const pos, const size_type n, InsertionProxy insert_range_proxy)
{
//n can be zero to just expand capacity
//Backup old data
- T* old_start = container_detail::to_raw_pointer(this->members_.m_start);
- T* old_finish = old_start + this->members_.m_size;
- size_type old_size = this->members_.m_size;
+ T* const old_start = container_detail::to_raw_pointer(this->members_.m_start);
+ T* const old_finish = old_start + this->members_.m_size;
+ const size_type old_size = this->members_.m_size;
//We can have 8 possibilities:
- const size_type elemsbefore = (size_type)(pos - old_start);
- const size_type s_before = (size_type)(old_start - new_start);
+ const size_type elemsbefore = static_cast<size_type>(pos - old_start);
+ const size_type s_before = static_cast<size_type>(old_start - new_start);
+ const size_type before_plus_new = elemsbefore + n;
//Update the vector buffer information to a safe state
this->members_.m_start = new_start;
@@ -1757,15 +1743,16 @@
//all the old objects to fulfill previous vector state
typename value_traits::OldArrayDestructor old_values_destroyer(old_start, this->alloc(), old_size);
//Check if s_before is big enough to hold the beginning of old data + new data
- if(difference_type(s_before) >= difference_type(elemsbefore + n)){
+ if(s_before >= before_plus_new){
//Copy first old values before pos, after that the new objects
- ::boost::container::uninitialized_move_alloc(this->alloc(), old_start, pos, new_start);
+ T *const new_elem_pos = ::boost::container::uninitialized_move_alloc(this->alloc(), old_start, pos, new_start);
this->members_.m_size = elemsbefore;
- interf.uninitialized_copy_remaining_to(new_start + elemsbefore);
+ insert_range_proxy.uninitialized_copy_n_and_update(new_elem_pos, n);
this->members_.m_size += n;
//Check if s_before is so big that even copying the old data + new data
//there is a gap between the new data and the old data
- if(s_before >= (old_size + n)){
+ const size_type new_size = old_size + n;
+ if(s_before >= new_size){
//Old situation:
// _________________________________________________________
//| raw_mem | old_begin | old_end |
@@ -1778,9 +1765,9 @@
//
//Now initialize the rest of memory with the last old values
::boost::container::uninitialized_move_alloc
- (this->alloc(), pos, old_finish, new_start + elemsbefore + n);
+ (this->alloc(), pos, old_finish, new_start + before_plus_new);
//All new elements correctly constructed, avoid new element destruction
- this->members_.m_size = old_size + n;
+ this->members_.m_size = new_size;
//Old values destroyed automatically with "old_values_destroyer"
//when "old_values_destroyer" goes out of scope unless the have trivial
//destructor after move.
@@ -1801,17 +1788,17 @@
//
//Now initialize the rest of memory with the last old values
//All new elements correctly constructed, avoid new element destruction
- size_type raw_gap = s_before - (elemsbefore + n);
+ const size_type raw_gap = s_before - before_plus_new;
//Now initialize the rest of s_before memory with the
//first of elements after new values
- ::boost::container::uninitialized_move_alloc
- (this->alloc(), pos, pos + raw_gap, new_start + elemsbefore + n);
+ ::boost::container::uninitialized_move_alloc_n
+ (this->alloc(), pos, raw_gap, new_start + before_plus_new);
//Update size since we have a contiguous buffer
this->members_.m_size = old_size + s_before;
//All new elements correctly constructed, avoid old element destruction
old_values_destroyer.release();
//Now copy remaining last objects in the old buffer begin
- T *to_destroy = ::boost::move(pos + raw_gap, old_finish, old_start);
+ T * const to_destroy = ::boost::move(pos + raw_gap, old_finish, old_start);
//Now destroy redundant elements except if they were moved and
//they have trivial destructor after move
size_type n_destroy = old_finish - to_destroy;
@@ -1840,7 +1827,7 @@
//| old_begin + new + old_end | raw_mem |
//|____________________________|____________________|
//
- bool do_after = n > s_before;
+ const bool do_after = n > s_before;
//Now we can have two situations: the raw_mem of the
//beginning divides the old_begin, or the new elements:
@@ -1869,28 +1856,26 @@
//|___________|_____|_________|_____________________|
//
//Copy the first part of old_begin to raw_mem
- T *start_n = old_start + difference_type(s_before);
- ::boost::container::uninitialized_move_alloc
- (this->alloc(), old_start, start_n, new_start);
+ ::boost::container::uninitialized_move_alloc_n
+ (this->alloc(), old_start, s_before, new_start);
//The buffer is all constructed until old_end,
//release destroyer and update size
old_values_destroyer.release();
this->members_.m_size = old_size + s_before;
- //Now copy the second part of old_begin overwriting himself
- T* next = ::boost::move(start_n, pos, old_start);
+ //Now copy the second part of old_begin overwriting itself
+ T *const next = ::boost::move(old_start + s_before, pos, old_start);
if(do_after){
//Now copy the new_beg elements
- interf.copy_some_and_update(next, s_before, true);
+ insert_range_proxy.copy_n_and_update(next, s_before);
}
else{
//Now copy the all the new elements
- interf.copy_remaining_to(next);
- T* move_start = next + n;
+ insert_range_proxy.copy_n_and_update(next, n);
//Now displace old_end elements
- T* move_end = ::boost::move(pos, old_finish, move_start);
+ T* const move_end = ::boost::move(pos, old_finish, next + n);
//Destroy remaining moved elements from old_end except if
//they have trivial destructor after being moved
- difference_type n_destroy = s_before - n;
+ const size_type n_destroy = s_before - n;
if(!value_traits::trivial_dctr_after_move)
this->destroy_n(move_end, n_destroy);
this->members_.m_size -= n_destroy;
@@ -1923,30 +1908,30 @@
//|___________|_____|_________|__________________________|
//
//First copy whole old_begin and part of new to raw_mem
- ::boost::container::uninitialized_move_alloc
+ T * const new_pos = ::boost::container::uninitialized_move_alloc
(this->alloc(), old_start, pos, new_start);
this->members_.m_size = elemsbefore;
-
- const size_type mid_n = difference_type(s_before) - elemsbefore;
- interf.uninitialized_copy_some_and_update(new_start + elemsbefore, mid_n, true);
- this->members_.m_size = old_size + s_before;
+ const size_type mid_n = s_before - elemsbefore;
+ insert_range_proxy.uninitialized_copy_n_and_update(new_pos, mid_n);
//The buffer is all constructed until old_end,
- //release destroyer and update size
+ //release destroyer
+ this->members_.m_size = old_size + s_before;
old_values_destroyer.release();
if(do_after){
//Copy new_beg part
- interf.copy_some_and_update(old_start, s_before - mid_n, true);
+ insert_range_proxy.copy_n_and_update(old_start, elemsbefore);
}
else{
//Copy all new elements
- interf.copy_remaining_to(old_start);
- T* move_start = old_start + (n-mid_n);
+ const size_type rest_new = n - mid_n;
+ insert_range_proxy.copy_n_and_update(old_start, rest_new);
+ T* move_start = old_start + rest_new;
//Displace old_end
T* move_end = ::boost::move(pos, old_finish, move_start);
//Destroy remaining moved elements from old_end except if they
//have trivial destructor after being moved
- difference_type n_destroy = s_before - n;
+ size_type n_destroy = s_before - n;
if(!value_traits::trivial_dctr_after_move)
this->destroy_n(move_end, n_destroy);
this->members_.m_size -= n_destroy;
@@ -1954,9 +1939,6 @@
}
//This is only executed if two phase construction is needed
- //This can be executed without exception handling since we
- //have to just copy and append in raw memory and
- //old_values_destroyer has been released in phase 1.
if(do_after){
//The raw memory divides the new elements
//
@@ -1975,11 +1957,11 @@
//| old_begin + new | old_end |raw |
//|_______________________________________|_________|____|
//
- const size_type n_after = n - s_before;
- const difference_type elemsafter = old_size - elemsbefore;
+ const size_type n_after = n - s_before;
+ const size_type elemsafter = old_size - elemsbefore;
//We can have two situations:
- if (elemsafter > difference_type(n_after)){
+ if (elemsafter >= n_after){
//The raw_mem from end will divide displaced old_end
//
//Old situation:
@@ -1993,7 +1975,7 @@
//|__________________________|_________|________|_________|
//
//First copy the part of old_end raw_mem
- T* finish_n = old_finish - difference_type(n_after);
+ T* finish_n = old_finish - n_after;
::boost::container::uninitialized_move_alloc
(this->alloc(), finish_n, old_finish, old_finish);
this->members_.m_size += n_after;
@@ -2001,7 +1983,7 @@
boost::move_backward(pos, finish_n, old_finish);
//Now overwrite with new_end
//The new_end part is [first + (n - n_after), last)
- interf.copy_remaining_to(pos);
+ insert_range_proxy.copy_n_and_update(pos, n_after);
}
else {
//The raw_mem from end will divide new_end part
@@ -2016,16 +1998,38 @@
//| old_begin + new_beg | new_end |old_end | raw_mem |
//|__________________________|_______________|________|_________|
//
+
+ const size_type mid_last_dist = n_after - elemsafter;
+ //First initialize data in raw memory
+
+ //Copy to the old_end part to the uninitialized zone leaving a gap.
+ ::boost::container::uninitialized_move_alloc
+ (this->alloc(), pos, old_finish, old_finish + mid_last_dist);
+
+ BOOST_TRY{
+ //Copy the first part to the already constructed old_end zone
+ insert_range_proxy.copy_n_and_update(pos, elemsafter);
+ //Copy the rest to the uninitialized zone filling the gap
+ insert_range_proxy.uninitialized_copy_n_and_update(old_finish, mid_last_dist);
+ this->members_.m_size += n_after;
+ }
+ BOOST_CATCH(...){
+ this->destroy_n(pos, mid_last_dist);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+/*
size_type mid_last_dist = n_after - elemsafter;
//First initialize data in raw memory
+
//The new_end part is [first + (n - n_after), last)
- interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
+ insert_range_proxy.uninitialized_copy_last_and_update(old_finish, elemsafter);
this->members_.m_size += mid_last_dist;
::boost::container::uninitialized_move_alloc
(this->alloc(), pos, old_finish, old_finish + mid_last_dist);
this->members_.m_size += n_after - mid_last_dist;
//Now copy the part of new_end over constructed elements
- interf.copy_remaining_to(pos);
+ insert_range_proxy.copy_remaining_to(pos);*/
}
}
}
@@ -2083,17 +2087,14 @@
namespace boost {
-/*
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::vector<T, Allocator> >
-{
- static const bool value = has_trivial_destructor<Allocator>::value;
-};
+ : public ::boost::has_trivial_destructor_after_move<Allocator>
+{};
-*/
}
Modified: branches/release/libs/container/doc/container.qbk
==============================================================================
--- branches/release/libs/container/doc/container.qbk (original)
+++ branches/release/libs/container/doc/container.qbk 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -614,6 +614,16 @@
[section:release_notes Release Notes]
+[section:release_notes_boost_1_53_00 Boost 1.53 Release]
+
+* Improved `vector`'s insertion performance.
+* Changed again experimental multiallocation interface for better performance (still experimental).
+* Added no exception support for those willing to disable exceptions in their compilers.
+* Fixed GCC -Wshadow warnings.
+* Replaced deprecated BOOST_NO_XXXX with newer BOOST_NO_CXX11_XXX macros.
+
+[endsect]
+
[section:release_notes_boost_1_52_00 Boost 1.52 Release]
* Improved `stable_vector`'s template code bloat and type safety.
Modified: branches/release/libs/container/example/doc_move_containers.cpp
==============================================================================
--- branches/release/libs/container/example/doc_move_containers.cpp (original)
+++ branches/release/libs/container/example/doc_move_containers.cpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -11,7 +11,7 @@
#include <boost/container/detail/workaround.hpp>
//[doc_move_containers
#include <boost/container/vector.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include <cassert>
//Non-copyable class
Modified: branches/release/libs/container/proj/to-do.txt
==============================================================================
--- branches/release/libs/container/proj/to-do.txt (original)
+++ branches/release/libs/container/proj/to-do.txt 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -5,6 +5,10 @@
->Align with C++11 [multi]map::insert(P &&p) overload.
->Unify all allocator version traits in one class (starting from stable_vector_detail::allocator_version_wrapper)
maybe in allocator_traits?
+->Fix code marked with "//to-do: if possible, an efficient way to deallocate allocated blocks"
+->Add BOOST_CONTAINER_TRY, etc. macros to allow disabling exceptions only in this library (just like Boost.Intrusive)
+->Add macro to change the default allocator std::allocator to another one
+->Add front()/back() to string
Review allocator traits
@@ -56,97 +60,4 @@
Add std:: hashing support
-Fix trivial destructor after move and other optimizing traits
-
-Mark previous() in slist/and forward_list as non-standard
-
-Function order:
-
-----------type------------
-value_type;
-pointer;
-const_pointer;
-reference;
-const_reference;
-size_type;
-difference_type;
-allocator_type;
-stored_allocator_type;
-iterator;
-const_iterator;
-reverse_iterator;
-const_reverse_iterator;
-----------func------------
-container()
-container(allocator_type)
-container(size_type)
-container(size_type, value_type, allocator_type = ())
-container(InpIt, InpIt)
-container(const container &)
-container(container &&)
-container(const container &, allocator_type)
-container(container &&, allocator_type)
-container(initializer_list<T>, allocator)
-~container()
-container operator=(const container &)
-container operator=(container &&)
-container operator=(initializer_list<T>)
-assign(size_type, const T &)
-
-assign(InpIt, InptIt)
-assign(initializer_list)
-get_allocator()
-
-begin()
-begin() const
-end()
-end() const
-rbegin()
-rbegin() const
-rend()
-rend() const
-
-cbegin() const
-cend() const
-crbegin() const
-crend() const
-
-empty()
-size()
-max_size()
-resize(size_type)
-resize(size_type, cont T&)
-capacity()
-reserve(size_type)
-shrink_to_fit()
-
-front()
-front() const
-back()
-back() const
-operator[] ()
-operator[] ()const
-at()
-at() const
-
-
-data()
-data() const
-
-emplace_front()
-emplace_back()
-emplace()
-push_front(const T&)
-push_front(T&&)
-push_back(const T&)
-push_back(T&&)
-insert(iterator, const T &)
-insert(iterator, T &&)
-insert(size_type, const T &)
-insert(InpIt, InpIt)
-pop_front()
-pop_back()
-erase(const_iterator)
-erase(const_iterator, const_iterator)
-swap(container &)
-clear()
\ No newline at end of file
+Fix trivial destructor after move and other optimizing traits
\ No newline at end of file
Modified: branches/release/libs/container/proj/vc7ide/container.vcproj
==============================================================================
--- branches/release/libs/container/proj/vc7ide/container.vcproj (original)
+++ branches/release/libs/container/proj/vc7ide/container.vcproj 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -243,6 +243,9 @@
RelativePath="..\..\..\..\boost\container\detail\allocation_type.hpp">
</File>
<File
+ RelativePath="..\..\..\..\boost\container\detail\allocator_version_traits.hpp">
+ </File>
+ <File
RelativePath="..\..\..\..\boost\container\detail\config_begin.hpp">
</File>
<File
Modified: branches/release/libs/container/test/allocator_traits_test.cpp
==============================================================================
--- branches/release/libs/container/test/allocator_traits_test.cpp (original)
+++ branches/release/libs/container/test/allocator_traits_test.cpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -14,7 +14,7 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/container/detail/function_detector.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include <memory>
template<class T>
Modified: branches/release/libs/container/test/deque_test.cpp
==============================================================================
--- branches/release/libs/container/test/deque_test.cpp (original)
+++ branches/release/libs/container/test/deque_test.cpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -21,7 +21,8 @@
#include "check_equal_containers.hpp"
#include "dummy_test_allocator.hpp"
#include "movable_int.hpp"
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/iterator.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <string>
@@ -148,8 +149,7 @@
MyCntDeque *cntdeque = new MyCntDeque;
MyStdDeque *stddeque = new MyStdDeque;
//Compare several shared memory deque operations with std::deque
- int i;
- for(i = 0; i < max*100; ++i){
+ for(int i = 0; i < max*100; ++i){
IntType move_me(i);
cntdeque->insert(cntdeque->end(), boost::move(move_me));
stddeque->insert(stddeque->end(), i);
@@ -159,7 +159,7 @@
cntdeque->clear();
stddeque->clear();
- for(i = 0; i < max*100; ++i){
+ for(int i = 0; i < max*100; ++i){
IntType move_me(i);
cntdeque->push_back(boost::move(move_me));
stddeque->push_back(i);
@@ -169,7 +169,7 @@
cntdeque->clear();
stddeque->clear();
- for(i = 0; i < max*100; ++i){
+ for(int i = 0; i < max*100; ++i){
IntType move_me(i);
cntdeque->push_front(boost::move(move_me));
stddeque->push_front(i);
@@ -239,7 +239,7 @@
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
- for(i = 0; i < max; ++i){
+ for(int i = 0; i < max; ++i){
IntType move_me(i);
cntdeque->insert(cntdeque->begin(), boost::move(move_me));
stddeque->insert(stddeque->begin(), i);
Modified: branches/release/libs/container/test/dummy_test_allocator.hpp
==============================================================================
--- branches/release/libs/container/test/dummy_test_allocator.hpp (original)
+++ branches/release/libs/container/test/dummy_test_allocator.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -26,7 +26,7 @@
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/multiallocation_chain.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
@@ -55,7 +55,7 @@
{}
T* allocate(std::size_t n)
- { return (T*)::new char[sizeof(T)*n]; }
+ { return (T*)::new char[sizeof(T)*n]; }
void deallocate(T*p, std::size_t)
{ delete[] ((char*)p);}
@@ -168,8 +168,8 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- multiallocation_chain allocate_individual(size_type)
- { return multiallocation_chain(); }
+ void allocate_individual(size_type, multiallocation_chain &)
+ {}
//!Allocates many elements of size == 1 in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,
@@ -177,7 +177,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
- void deallocate_individual(multiallocation_chain)
+ void deallocate_individual(multiallocation_chain &)
{}
//!Allocates many elements of size elem_size in a contiguous block
@@ -186,7 +186,7 @@
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
- void deallocate_many(multiallocation_chain)
+ void deallocate_many(multiallocation_chain &)
{}
};
Modified: branches/release/libs/container/test/emplace_test.hpp
==============================================================================
--- branches/release/libs/container/test/emplace_test.hpp (original)
+++ branches/release/libs/container/test/emplace_test.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -15,7 +15,7 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/mpl.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/aligned_storage.hpp>
@@ -98,14 +98,20 @@
};
template<class Container>
-bool test_expected_container(const Container &ec, const EmplaceInt *Expected, unsigned int only_first_n)
+bool test_expected_container(const Container &ec, const EmplaceInt *Expected, unsigned int only_first_n, unsigned int cont_offset = 0)
{
typedef typename Container::const_iterator const_iterator;
const_iterator itb(ec.begin()), ite(ec.end());
unsigned int cur = 0;
- if(only_first_n > ec.size()){
+ if(cont_offset > ec.size()){
+ return false;
+ }
+ if(only_first_n > (ec.size() - cont_offset)){
return false;
}
+ while(cont_offset--){
+ ++itb;
+ }
for(; itb != ite && only_first_n--; ++itb, ++cur){
const EmplaceInt & cr = *itb;
if(cr != Expected[cur]){
@@ -163,33 +169,39 @@
<< typeid(Container).name() << std::endl;
{
- new(&expected [0]) EmplaceInt();
- new(&expected [1]) EmplaceInt(1);
- new(&expected [2]) EmplaceInt(1, 2);
- new(&expected [3]) EmplaceInt(1, 2, 3);
- new(&expected [4]) EmplaceInt(1, 2, 3, 4);
- new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
- Container c;
- c.emplace_back();
- if(!test_expected_container(c, &expected[0], 1))
- return false;
- c.emplace_back(1);
- if(!test_expected_container(c, &expected[0], 2))
- return false;
- c.emplace_back(1, 2);
- if(!test_expected_container(c, &expected[0], 3))
- return false;
- c.emplace_back(1, 2, 3);
- if(!test_expected_container(c, &expected[0], 4))
- return false;
- c.emplace_back(1, 2, 3, 4);
- if(!test_expected_container(c, &expected[0], 5))
- return false;
- c.emplace_back(1, 2, 3, 4, 5);
- if(!test_expected_container(c, &expected[0], 6))
- return false;
+ new(&expected [0]) EmplaceInt();
+ new(&expected [1]) EmplaceInt(1);
+ new(&expected [2]) EmplaceInt(1, 2);
+ new(&expected [3]) EmplaceInt(1, 2, 3);
+ new(&expected [4]) EmplaceInt(1, 2, 3, 4);
+ new(&expected [5]) EmplaceInt(1, 2, 3, 4, 5);
+ Container c;
+ c.emplace_back();
+ if(!test_expected_container(c, &expected[0], 1)){
+ return false;
+ }
+ c.emplace_back(1);
+ if(!test_expected_container(c, &expected[0], 2)){
+ return false;
+ }
+ c.emplace_back(1, 2);
+ if(!test_expected_container(c, &expected[0], 3)){
+ return false;
+ }
+ c.emplace_back(1, 2, 3);
+ if(!test_expected_container(c, &expected[0], 4)){
+ return false;
+ }
+ c.emplace_back(1, 2, 3, 4);
+ if(!test_expected_container(c, &expected[0], 5)){
+ return false;
+ }
+ c.emplace_back(1, 2, 3, 4, 5);
+ if(!test_expected_container(c, &expected[0], 6)){
+ return false;
+ }
}
-
+ std::cout << "...OK" << std::endl;
return true;
}
@@ -212,24 +224,31 @@
new(&expected [5]) EmplaceInt();
Container c;
c.emplace_front();
- if(!test_expected_container(c, &expected[0] + 5, 1))
+ if(!test_expected_container(c, &expected[0] + 5, 1)){
return false;
- c.emplace_front(1);/*
- if(!test_expected_container(c, &expected[0] + 4, 2))
+ }
+ c.emplace_front(1);
+ if(!test_expected_container(c, &expected[0] + 4, 2)){
return false;
+ }
c.emplace_front(1, 2);
- if(!test_expected_container(c, &expected[0] + 3, 3))
+ if(!test_expected_container(c, &expected[0] + 3, 3)){
return false;
+ }
c.emplace_front(1, 2, 3);
- if(!test_expected_container(c, &expected[0] + 2, 4))
+ if(!test_expected_container(c, &expected[0] + 2, 4)){
return false;
+ }
c.emplace_front(1, 2, 3, 4);
- if(!test_expected_container(c, &expected[0] + 1, 5))
+ if(!test_expected_container(c, &expected[0] + 1, 5)){
return false;
+ }
c.emplace_front(1, 2, 3, 4, 5);
- if(!test_expected_container(c, &expected[0] + 0, 6))
- return false;*/
+ if(!test_expected_container(c, &expected[0] + 0, 6)){
+ return false;
+ }
}
+ std::cout << "...OK" << std::endl;
return true;
}
@@ -250,11 +269,13 @@
Container c;
c.emplace(c.cend(), 1);
c.emplace(c.cbegin());
- if(!test_expected_container(c, &expected[0], 2))
+ if(!test_expected_container(c, &expected[0], 2)){
return false;
+ }
c.emplace(c.cend());
- if(!test_expected_container(c, &expected[0], 3))
+ if(!test_expected_container(c, &expected[0], 3)){
return false;
+ }
}
{
new(&expected [0]) EmplaceInt();
@@ -271,39 +292,74 @@
c.emplace(c.cbegin(), 1, 2);
c.emplace(c.cbegin(), 1);
c.emplace(c.cbegin());
- if(!test_expected_container(c, &expected[0], 6))
+ if(!test_expected_container(c, &expected[0], 6)){
return false;
+ }
c.clear();
//emplace_back-like
typename Container::const_iterator i = c.emplace(c.cend());
- if(!test_expected_container(c, &expected[0], 1))
+ if(!test_expected_container(c, &expected[0], 1)){
return false;
+ }
i = c.emplace(++i, 1);
- if(!test_expected_container(c, &expected[0], 2))
+ if(!test_expected_container(c, &expected[0], 2)){
return false;
+ }
i = c.emplace(++i, 1, 2);
- if(!test_expected_container(c, &expected[0], 3))
+ if(!test_expected_container(c, &expected[0], 3)){
return false;
+ }
i = c.emplace(++i, 1, 2, 3);
- if(!test_expected_container(c, &expected[0], 4))
+ if(!test_expected_container(c, &expected[0], 4)){
return false;
+ }
i = c.emplace(++i, 1, 2, 3, 4);
- if(!test_expected_container(c, &expected[0], 5))
+ if(!test_expected_container(c, &expected[0], 5)){
return false;
+ }
i = c.emplace(++i, 1, 2, 3, 4, 5);
- if(!test_expected_container(c, &expected[0], 6))
+ if(!test_expected_container(c, &expected[0], 6)){
return false;
+ }
c.clear();
//emplace in the middle
c.emplace(c.cbegin());
+ if(!test_expected_container(c, &expected[0], 1)){
+ return false;
+ }
i = c.emplace(c.cend(), 1, 2, 3, 4, 5);
+ if(!test_expected_container(c, &expected[0], 1)){
+ return false;
+ }
+ if(!test_expected_container(c, &expected[5], 1, 1)){
+ return false;
+ }
i = c.emplace(i, 1, 2, 3, 4);
+ if(!test_expected_container(c, &expected[0], 1)){
+ return false;
+ }
+ if(!test_expected_container(c, &expected[4], 2, 1)){
+ return false;
+ }
i = c.emplace(i, 1, 2, 3);
+ if(!test_expected_container(c, &expected[0], 1)){
+ return false;
+ }
+ if(!test_expected_container(c, &expected[3], 3, 1)){
+ return false;
+ }
i = c.emplace(i, 1, 2);
+ if(!test_expected_container(c, &expected[0], 1)){
+ return false;
+ }
+ if(!test_expected_container(c, &expected[2], 4, 1)){
+ return false;
+ }
i = c.emplace(i, 1);
-
- if(!test_expected_container(c, &expected[0], 6))
+ if(!test_expected_container(c, &expected[0], 6)){
return false;
+ }
+ std::cout << "...OK" << std::endl;
}
return true;
}
@@ -324,11 +380,13 @@
Container c;
typename Container::const_iterator i = c.emplace_after(c.cbefore_begin(), 1);
c.emplace_after(c.cbefore_begin());
- if(!test_expected_container(c, &expected[0], 2))
+ if(!test_expected_container(c, &expected[0], 2)){
return false;
+ }
c.emplace_after(i);
- if(!test_expected_container(c, &expected[0], 3))
+ if(!test_expected_container(c, &expected[0], 3)){
return false;
+ }
}
{
new(&expected [0]) EmplaceInt();
@@ -345,28 +403,35 @@
c.emplace_after(c.cbefore_begin(), 1, 2);
c.emplace_after(c.cbefore_begin(), 1);
c.emplace_after(c.cbefore_begin());
- if(!test_expected_container(c, &expected[0], 6))
+ if(!test_expected_container(c, &expected[0], 6)){
return false;
+ }
c.clear();
//emplace_back-like
typename Container::const_iterator i = c.emplace_after(c.cbefore_begin());
- if(!test_expected_container(c, &expected[0], 1))
+ if(!test_expected_container(c, &expected[0], 1)){
return false;
+ }
i = c.emplace_after(i, 1);
- if(!test_expected_container(c, &expected[0], 2))
+ if(!test_expected_container(c, &expected[0], 2)){
return false;
+ }
i = c.emplace_after(i, 1, 2);
- if(!test_expected_container(c, &expected[0], 3))
+ if(!test_expected_container(c, &expected[0], 3)){
return false;
+ }
i = c.emplace_after(i, 1, 2, 3);
- if(!test_expected_container(c, &expected[0], 4))
+ if(!test_expected_container(c, &expected[0], 4)){
return false;
+ }
i = c.emplace_after(i, 1, 2, 3, 4);
- if(!test_expected_container(c, &expected[0], 5))
+ if(!test_expected_container(c, &expected[0], 5)){
return false;
+ }
i = c.emplace_after(i, 1, 2, 3, 4, 5);
- if(!test_expected_container(c, &expected[0], 6))
+ if(!test_expected_container(c, &expected[0], 6)){
return false;
+ }
c.clear();
//emplace_after in the middle
i = c.emplace_after(c.cbefore_begin());
@@ -376,8 +441,10 @@
c.emplace_after(i, 1, 2);
c.emplace_after(i, 1);
- if(!test_expected_container(c, &expected[0], 6))
+ if(!test_expected_container(c, &expected[0], 6)){
return false;
+ }
+ std::cout << "...OK" << std::endl;
}
return true;
}
@@ -401,23 +468,30 @@
{
Container c;
c.emplace();
- if(!test_expected_container(c, &expected[0], 1))
+ if(!test_expected_container(c, &expected[0], 1)){
return false;
+ }
c.emplace(1);
- if(!test_expected_container(c, &expected[0], 2))
+ if(!test_expected_container(c, &expected[0], 2)){
return false;
+ }
c.emplace(1, 2);
- if(!test_expected_container(c, &expected[0], 3))
+ if(!test_expected_container(c, &expected[0], 3)){
return false;
+ }
c.emplace(1, 2, 3);
- if(!test_expected_container(c, &expected[0], 4))
+ if(!test_expected_container(c, &expected[0], 4)){
return false;
+ }
c.emplace(1, 2, 3, 4);
- if(!test_expected_container(c, &expected[0], 5))
+ if(!test_expected_container(c, &expected[0], 5)){
return false;
+ }
c.emplace(1, 2, 3, 4, 5);
- if(!test_expected_container(c, &expected[0], 6))
+ if(!test_expected_container(c, &expected[0], 6)){
return false;
+ }
+ std::cout << "...OK" << std::endl;
}
return true;
}
@@ -443,23 +517,30 @@
Container c;
typename Container::const_iterator it;
it = c.emplace_hint(c.begin());
- if(!test_expected_container(c, &expected[0], 1))
+ if(!test_expected_container(c, &expected[0], 1)){
return false;
+ }
it = c.emplace_hint(it, 1);
- if(!test_expected_container(c, &expected[0], 2))
+ if(!test_expected_container(c, &expected[0], 2)){
return false;
+ }
it = c.emplace_hint(it, 1, 2);
- if(!test_expected_container(c, &expected[0], 3))
+ if(!test_expected_container(c, &expected[0], 3)){
return false;
+ }
it = c.emplace_hint(it, 1, 2, 3);
- if(!test_expected_container(c, &expected[0], 4))
+ if(!test_expected_container(c, &expected[0], 4)){
return false;
+ }
it = c.emplace_hint(it, 1, 2, 3, 4);
- if(!test_expected_container(c, &expected[0], 5))
+ if(!test_expected_container(c, &expected[0], 5)){
return false;
+ }
it = c.emplace_hint(it, 1, 2, 3, 4, 5);
- if(!test_expected_container(c, &expected[0], 6))
+ if(!test_expected_container(c, &expected[0], 6)){
return false;
+ }
+ std::cout << "...OK" << std::endl;
}
return true;
@@ -498,6 +579,7 @@
std::cout << "Error after c.emplace(2, 2);\n";
return false;
}
+ std::cout << "...OK" << std::endl;
}
return true;
}
@@ -536,6 +618,7 @@
std::cout << "Error after c.emplace(it, 2, 2);\n";
return false;
}
+ std::cout << "...OK" << std::endl;
}
return true;
}
@@ -555,22 +638,30 @@
template<class Container, EmplaceOptions O>
bool test_emplace()
{
- if(!test_emplace_back<Container>(emplace_active<O, EMPLACE_BACK>()))
+ if(!test_emplace_back<Container>(emplace_active<O, EMPLACE_BACK>())){
return false;
- if(!test_emplace_front<Container>(emplace_active<O, EMPLACE_FRONT>()))
+ }
+ if(!test_emplace_front<Container>(emplace_active<O, EMPLACE_FRONT>())){
return false;
- if(!test_emplace_before<Container>(emplace_active<O, EMPLACE_BEFORE>()))
+ }
+ if(!test_emplace_before<Container>(emplace_active<O, EMPLACE_BEFORE>())){
return false;
- if(!test_emplace_after<Container>(emplace_active<O, EMPLACE_AFTER>()))
+ }
+ if(!test_emplace_after<Container>(emplace_active<O, EMPLACE_AFTER>())){
return false;
- if(!test_emplace_assoc<Container>(emplace_active<O, EMPLACE_ASSOC>()))
+ }
+ if(!test_emplace_assoc<Container>(emplace_active<O, EMPLACE_ASSOC>())){
return false;
- if(!test_emplace_hint<Container>(emplace_active<O, EMPLACE_HINT>()))
+ }
+ if(!test_emplace_hint<Container>(emplace_active<O, EMPLACE_HINT>())){
return false;
- if(!test_emplace_assoc_pair<Container>(emplace_active<O, EMPLACE_ASSOC_PAIR>()))
+ }
+ if(!test_emplace_assoc_pair<Container>(emplace_active<O, EMPLACE_ASSOC_PAIR>())){
return false;
- if(!test_emplace_hint_pair<Container>(emplace_active<O, EMPLACE_HINT_PAIR>()))
+ }
+ if(!test_emplace_hint_pair<Container>(emplace_active<O, EMPLACE_HINT_PAIR>())){
return false;
+ }
return true;
}
Modified: branches/release/libs/container/test/expand_bwd_test_allocator.hpp
==============================================================================
--- branches/release/libs/container/test/expand_bwd_test_allocator.hpp (original)
+++ branches/release/libs/container/test/expand_bwd_test_allocator.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -65,13 +65,16 @@
typedef boost::container::container_detail::version_type<expand_bwd_test_allocator, 2> version;
+ //Dummy multiallocation chain
+ struct multiallocation_chain{};
+
template<class T2>
struct rebind
{ typedef expand_bwd_test_allocator<T2> other; };
//!Constructor from the segment manager. Never throws
- expand_bwd_test_allocator(T *buffer, size_type size, difference_type offset)
- : mp_buffer(buffer), m_size(size)
+ expand_bwd_test_allocator(T *buffer, size_type sz, difference_type offset)
+ : mp_buffer(buffer), m_size(sz)
, m_offset(offset), m_allocations(0){ }
//!Constructor from other expand_bwd_test_allocator. Never throws
Modified: branches/release/libs/container/test/flat_tree_test.cpp
==============================================================================
--- branches/release/libs/container/test/flat_tree_test.cpp (original)
+++ branches/release/libs/container/test/flat_tree_test.cpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -627,3 +627,77 @@
}
#include <boost/container/detail/config_end.hpp>
+
+/*
+#include <boost/container/map.hpp>
+#include <boost/container/flat_map.hpp>
+#include <boost/container/vector.hpp>
+#include <boost/move/utility.hpp>
+#include <iostream>
+
+struct Request
+{
+ Request() {};
+
+ //Move semantics...
+ Request(BOOST_RV_REF(Request) r) : rvals() //Move constructor
+ {
+ rvals.swap(r.rvals);
+ };
+
+ Request& operator=(BOOST_RV_REF(Request) r) //Move assignment
+ {
+ if (this != &r){
+ rvals.swap(r.rvals);
+ }
+ return *this;
+ };
+
+ // Values I want to be moved, not copied.
+ boost::container::vector<int> rvals;
+
+ private:
+ // Mark this class movable but not copyable
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(Request)
+};
+
+typedef boost::container::flat_map<int, Request> Requests;
+//typedef boost::container::map<int, Request> Requests2;
+
+int
+main() {
+ Requests req;
+ std::pair<Requests::iterator, bool> ret = req.insert( Requests::value_type( 7, Request() ) );
+ std::cout << "Insert success for req: " << ret.second << std::endl;
+
+ //Requests2 req2;
+ //std::pair<Requests::iterator, bool> ret2 = req2.insert( Requests2::value_type( 7, Request() ) );
+ //std::cout << "Insert success for req2: " << ret2.second << std::endl;
+
+ return 0;
+}
+*/
+/*
+#include <cstdlib>
+#include <iostream>
+#include <boost/container/flat_set.hpp>
+
+using namespace std;
+
+int main(int , char *[])
+{
+ double d[] = {0, 0.2, 0.8, 1, 2, 3, 4};
+ boost::container::flat_set<double> set;
+
+ set.insert(0);
+ set.insert(set.end(), 1);
+ set.insert(set.end(), 3);
+ set.insert(boost::container::ordered_unique_range_t(), d, d + sizeof(d)/sizeof(*d));
+ boost::container::flat_set<double>::iterator it(set.begin());
+ boost::container::flat_set<double>::iterator const itend(set.end());
+ while(it != itend)
+ cout << *it++ << endl;
+
+ return 0;
+}
+*/
\ No newline at end of file
Modified: branches/release/libs/container/test/list_test.hpp
==============================================================================
--- branches/release/libs/container/test/list_test.hpp (original)
+++ branches/release/libs/container/test/list_test.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -19,7 +19,8 @@
#include <functional>
#include "print_container.hpp"
#include "input_from_forward_iterator.hpp"
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/iterator.hpp>
#include <string>
namespace boost{
Modified: branches/release/libs/container/test/map_test.hpp
==============================================================================
--- branches/release/libs/container/test/map_test.hpp (original)
+++ branches/release/libs/container/test/map_test.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -19,6 +19,8 @@
#include "print_container.hpp"
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/pair.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/utility.hpp>
#include <string>
template<class T1, class T2, class T3, class T4>
@@ -104,7 +106,6 @@
if(!CheckEqualContainers(boostmap2, stdmap2)) return 1;
if(!CheckEqualContainers(boostmultimap2, stdmultimap2)) return 1;
-/*
MyBoostMap *boostmap3 = new MyBoostMap
( ordered_unique_range
, boost::make_move_iterator(&aux_vect[0])
@@ -124,12 +125,14 @@
std::cout << "Error in construct<MyBoostMultiMap>(MyBoostMultiMap3)" << std::endl;
return 1;
}
-*/
- IntType i0(0);
- boostmap2->erase(i0);
- boostmultimap2->erase(i0);
- stdmap2->erase(0);
- stdmultimap2->erase(0);
+
+ {
+ IntType i0(0);
+ boostmap2->erase(i0);
+ boostmultimap2->erase(i0);
+ stdmap2->erase(0);
+ stdmultimap2->erase(0);
+ }
{
IntType i0(0);
IntType i1(1);
@@ -146,10 +149,10 @@
delete boostmultimap2;
delete stdmap2;
delete stdmultimap2;
- //delete boostmap3;
- //delete boostmultimap3;
- //delete stdmap3;
- //delete stdmultimap3;
+ delete boostmap3;
+ delete boostmultimap3;
+ delete stdmap3;
+ delete stdmultimap3;
}
{
//This is really nasty, but we have no other simple choice
Modified: branches/release/libs/container/test/movable_int.hpp
==============================================================================
--- branches/release/libs/container/test/movable_int.hpp (original)
+++ branches/release/libs/container/test/movable_int.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -13,7 +13,8 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
+#include <ostream>
namespace boost {
namespace container {
Modified: branches/release/libs/container/test/scoped_allocator_adaptor_test.cpp
==============================================================================
--- branches/release/libs/container/test/scoped_allocator_adaptor_test.cpp (original)
+++ branches/release/libs/container/test/scoped_allocator_adaptor_test.cpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -11,7 +11,7 @@
#include <boost/container/scoped_allocator_fwd.hpp>
#include <cstddef>
#include <boost/container/detail/mpl.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <memory>
Modified: branches/release/libs/container/test/scoped_allocator_usage_test.cpp
==============================================================================
--- branches/release/libs/container/test/scoped_allocator_usage_test.cpp (original)
+++ branches/release/libs/container/test/scoped_allocator_usage_test.cpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -1,7 +1,7 @@
#include <boost/container/detail/config_begin.hpp>
#include <memory>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include <boost/container/vector.hpp>
#include <boost/container/deque.hpp>
#include <boost/container/list.hpp>
Modified: branches/release/libs/container/test/set_test.hpp
==============================================================================
--- branches/release/libs/container/test/set_test.hpp (original)
+++ branches/release/libs/container/test/set_test.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -17,7 +17,8 @@
#include <set>
#include <functional>
#include "print_container.hpp"
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/iterator.hpp>
#include <string>
namespace boost{
@@ -119,8 +120,7 @@
delete stdmultiset3;
}
- int i, j;
- for(i = 0; i < max; ++i){
+ for(int i = 0; i < max; ++i){
IntType move_me(i);
boostset->insert(boost::move(move_me));
stdset->insert(i);
@@ -301,7 +301,7 @@
}
}
- for(i = 0; i < max; ++i){
+ for(int i = 0; i < max; ++i){
IntType move_me(i);
boostset->insert(boost::move(move_me));
stdset->insert(i);
@@ -319,37 +319,39 @@
return 1;
}
- for(i = 0; i < max; ++i){
- IntType move_me(i);
- boostset->insert(boostset->begin(), boost::move(move_me));
- stdset->insert(stdset->begin(), i);
- //PrintContainers(boostset, stdset);
- IntType move_me2(i);
- boostmultiset->insert(boostmultiset->begin(), boost::move(move_me2));
- stdmultiset->insert(stdmultiset->begin(), i);
- //PrintContainers(boostmultiset, stdmultiset);
- if(!CheckEqualContainers(boostset, stdset)){
- std::cout << "Error in boostset->insert(boostset->begin(), boost::move(move_me))" << std::endl;
- return 1;
- }
- if(!CheckEqualContainers(boostmultiset, stdmultiset)){
- std::cout << "Error in boostmultiset->insert(boostmultiset->begin(), boost::move(move_me2))" << std::endl;
- return 1;
- }
+ for(int i = 0; i < max; ++i){
+ {
+ IntType move_me(i);
+ boostset->insert(boostset->begin(), boost::move(move_me));
+ stdset->insert(stdset->begin(), i);
+ //PrintContainers(boostset, stdset);
+ IntType move_me2(i);
+ boostmultiset->insert(boostmultiset->begin(), boost::move(move_me2));
+ stdmultiset->insert(stdmultiset->begin(), i);
+ //PrintContainers(boostmultiset, stdmultiset);
+ if(!CheckEqualContainers(boostset, stdset)){
+ std::cout << "Error in boostset->insert(boostset->begin(), boost::move(move_me))" << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(boostmultiset, stdmultiset)){
+ std::cout << "Error in boostmultiset->insert(boostmultiset->begin(), boost::move(move_me2))" << std::endl;
+ return 1;
+ }
- IntType move_me3(i);
- boostset->insert(boostset->end(), boost::move(move_me3));
- stdset->insert(stdset->end(), i);
- IntType move_me4(i);
- boostmultiset->insert(boostmultiset->end(), boost::move(move_me4));
- stdmultiset->insert(stdmultiset->end(), i);
- if(!CheckEqualContainers(boostset, stdset)){
- std::cout << "Error in boostset->insert(boostset->end(), boost::move(move_me3))" << std::endl;
- return 1;
- }
- if(!CheckEqualContainers(boostmultiset, stdmultiset)){
- std::cout << "Error in boostmultiset->insert(boostmultiset->end(), boost::move(move_me4))" << std::endl;
- return 1;
+ IntType move_me3(i);
+ boostset->insert(boostset->end(), boost::move(move_me3));
+ stdset->insert(stdset->end(), i);
+ IntType move_me4(i);
+ boostmultiset->insert(boostmultiset->end(), boost::move(move_me4));
+ stdmultiset->insert(stdmultiset->end(), i);
+ if(!CheckEqualContainers(boostset, stdset)){
+ std::cout << "Error in boostset->insert(boostset->end(), boost::move(move_me3))" << std::endl;
+ return 1;
+ }
+ if(!CheckEqualContainers(boostmultiset, stdmultiset)){
+ std::cout << "Error in boostmultiset->insert(boostmultiset->end(), boost::move(move_me4))" << std::endl;
+ return 1;
+ }
}
{
IntType move_me(i);
@@ -372,10 +374,11 @@
}
{
IntType move_me(i);
+ IntType move_me2(i);
boostset->insert(boostset->lower_bound(move_me), boost::move(move_me2));
stdset->insert(stdset->lower_bound(i), i);
//PrintContainers(boostset, stdset);
- IntType move_me2(i);
+ move_me2 = i;
boostmultiset->insert(boostmultiset->lower_bound(move_me2), boost::move(move_me2));
stdmultiset->insert(stdmultiset->lower_bound(i), i);
//PrintContainers(boostmultiset, stdmultiset);
@@ -391,7 +394,7 @@
}
//Compare count with std containers
- for(i = 0; i < max; ++i){
+ for(int i = 0; i < max; ++i){
IntType count_me(i);
if(boostset->count(count_me) != stdset->count(i)){
return -1;
@@ -407,8 +410,8 @@
boostset->clear();
boostmultiset->clear();
- for(j = 0; j < 3; ++j)
- for(i = 0; i < 100; ++i){
+ for(int j = 0; j < 3; ++j)
+ for(int i = 0; i < 100; ++i){
IntType move_me(i);
boostset->insert(boost::move(move_me));
IntType move_me2(i);
@@ -448,8 +451,7 @@
MyBoostMultiSet *boostmultiset = new MyBoostMultiSet;
MyStdMultiSet *stdmultiset = new MyStdMultiSet;
- int i;
- for(i = 0; i < max; ++i){
+ for(int i = 0; i < max; ++i){
IntType move_me(i);
boostset->insert(boost::move(move_me));
stdset->insert(i);
Modified: branches/release/libs/container/test/string_test.cpp
==============================================================================
--- branches/release/libs/container/test/string_test.cpp (original)
+++ branches/release/libs/container/test/string_test.cpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -330,9 +330,6 @@
//Check addition
{
- typedef std::basic_string<CharType> StdString;
- typedef basic_string<CharType> BoostString;
-
BoostString bs2 = string_literals<CharType>::String();
StdString ss2 = string_literals<CharType>::String();
BoostString bs3 = string_literals<CharType>::Suffix();
Modified: branches/release/libs/container/test/vector_test.cpp
==============================================================================
--- branches/release/libs/container/test/vector_test.cpp (original)
+++ branches/release/libs/container/test/vector_test.cpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -15,7 +15,7 @@
#include <functional>
#include <boost/container/vector.hpp>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include "check_equal_containers.hpp"
#include "movable_int.hpp"
#include "expand_bwd_test_allocator.hpp"
@@ -148,12 +148,13 @@
v.push_back(Test());
const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_BEFORE);
- if(!boost::container::test::test_emplace
- < vector<test::EmplaceInt>, Options>())
+ if(!boost::container::test::test_emplace< vector<test::EmplaceInt>, Options>()){
return 1;
+ }
- if(!boost::container::test::test_propagate_allocator<vector>())
+ if(!boost::container::test::test_propagate_allocator<vector>()){
return 1;
+ }
return 0;
Modified: branches/release/libs/container/test/vector_test.hpp
==============================================================================
--- branches/release/libs/container/test/vector_test.hpp (original)
+++ branches/release/libs/container/test/vector_test.hpp 2012-12-01 18:01:47 EST (Sat, 01 Dec 2012)
@@ -19,7 +19,7 @@
#include <functional>
#include <list>
-#include <boost/move/move.hpp>
+#include <boost/move/utility.hpp>
#include <boost/container/detail/mpl.hpp>
#include "print_container.hpp"
#include "check_equal_containers.hpp"
@@ -28,6 +28,8 @@
#include <vector>
#include "emplace_test.hpp"
#include "input_from_forward_iterator.hpp"
+#include <boost/move/utility.hpp>
+#include <boost/move/iterator.hpp>
namespace boost{
namespace container {
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk