|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r80348 - in trunk: boost/container boost/container/detail libs/container/doc libs/container/proj libs/container/proj/vc7ide libs/container/test
From: igaztanaga_at_[hidden]
Date: 2012-09-01 07:01:06
Author: igaztanaga
Date: 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
New Revision: 80348
URL: http://svn.boost.org/trac/boost/changeset/80348
Log:
Implemented LWG Issue #149 (range insertion now returns an iterator) & cleaned up insertion code in most containers
Added:
trunk/libs/container/test/input_from_forward_iterator.hpp (contents, props changed)
Removed:
trunk/boost/container/detail/stored_ref.hpp
Text files modified:
trunk/boost/container/deque.hpp | 280 ++++++++++------------
trunk/boost/container/detail/advanced_insert_int.hpp | 15
trunk/boost/container/detail/algorithms.hpp | 24 +
trunk/boost/container/detail/flat_tree.hpp | 312 +++++++++++++++----------
trunk/boost/container/detail/iterators.hpp | 86 +++++-
trunk/boost/container/detail/preprocessor.hpp | 79 +++++-
trunk/boost/container/detail/tree.hpp | 165 ++++++-------
trunk/boost/container/flat_map.hpp | 8
trunk/boost/container/flat_set.hpp | 8
trunk/boost/container/list.hpp | 268 ++++++++++-----------
trunk/boost/container/map.hpp | 4
trunk/boost/container/set.hpp | 4
trunk/boost/container/slist.hpp | 283 ++++++++++------------
trunk/boost/container/stable_vector.hpp | 313 ++++++++++++-------------
trunk/boost/container/string.hpp | 482 +++++++++++++++++++--------------------
trunk/boost/container/vector.hpp | 414 ++++++++++++++++-----------------
trunk/libs/container/doc/container.qbk | 4
trunk/libs/container/proj/to-do.txt | 11
trunk/libs/container/proj/vc7ide/allocator_traits_test.vcproj | 3
trunk/libs/container/proj/vc7ide/container.sln | 8
trunk/libs/container/proj/vc7ide/container.vcproj | 5
trunk/libs/container/test/check_equal_containers.hpp | 27 ++
trunk/libs/container/test/deque_test.cpp | 2
trunk/libs/container/test/list_test.hpp | 44 +++
trunk/libs/container/test/movable_int.hpp | 25 ++
trunk/libs/container/test/set_test.hpp | 16
trunk/libs/container/test/vector_test.hpp | 45 +++
27 files changed, 1565 insertions(+), 1370 deletions(-)
Modified: trunk/boost/container/deque.hpp
==============================================================================
--- trunk/boost/container/deque.hpp (original)
+++ trunk/boost/container/deque.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -943,14 +943,18 @@
//! throws or T's constructor taking an dereferenced InIt throws.
//!
//! <b>Complexity</b>: Linear to the range [first, last).
- template <class InpIt>
- deque(InpIt first, InpIt last, const allocator_type& a = allocator_type())
+ template <class InIt>
+ deque(InIt first, InIt last, const allocator_type& a = allocator_type()
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InIt, size_type>::value
+ >::type * = 0
+ #endif
+ )
: Base(a)
{
- //Dispatch depending on integer/iterator
- const bool aux_boolean = container_detail::is_convertible<InpIt, size_type>::value;
- typedef container_detail::bool_<aux_boolean> Result;
- this->priv_initialize_dispatch(first, last, Result());
+ typedef typename std::iterator_traits<InIt>::iterator_category ItCat;
+ this->priv_range_initialize(first, last, ItCat());
}
//! <b>Effects</b>: Destroys the deque. All stored values are destroyed
@@ -1043,22 +1047,60 @@
//!
//! <b>Complexity</b>: Linear to n.
void assign(size_type n, const T& val)
- { this->priv_fill_assign(n, val); }
+ {
+ typedef constant_iterator<value_type, difference_type> c_it;
+ this->assign(c_it(val, n), c_it());
+ }
//! <b>Effects</b>: Assigns the the range [first, last) to *this.
//!
//! <b>Throws</b>: If memory allocation throws or
- //! T's constructor from dereferencing InpIt throws.
+ //! T's constructor from dereferencing InIt throws.
//!
//! <b>Complexity</b>: Linear to n.
- template <class InpIt>
- void assign(InpIt first, InpIt last)
+ template <class InIt>
+ void assign(InIt first, InIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InIt, size_type>::value
+ && container_detail::is_input_iterator<InIt>::value
+ >::type * = 0
+ #endif
+ )
+ {
+ iterator cur = begin();
+ for ( ; first != last && cur != end(); ++cur, ++first){
+ *cur = *first;
+ }
+ if (first == last){
+ this->erase(cur, cend());
+ }
+ else{
+ this->insert(cend(), first, last);
+ }
+ }
+
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ template <class FwdIt>
+ void assign(FwdIt first, FwdIt last
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<FwdIt, size_type>::value
+ && !container_detail::is_input_iterator<FwdIt>::value
+ >::type * = 0
+ )
{
- //Dispatch depending on integer/iterator
- const bool aux_boolean = container_detail::is_convertible<InpIt, size_type>::value;
- typedef container_detail::bool_<aux_boolean> Result;
- this->priv_assign_dispatch(first, last, Result());
+ const size_type len = std::distance(first, last);
+ if (len > size()) {
+ FwdIt mid = first;
+ std::advance(mid, size());
+ boost::copy_or_move(first, mid, begin());
+ this->insert(cend(), mid, last);
+ }
+ else{
+ this->erase(boost::copy_or_move(first, last, begin()), cend());
+ }
}
+ #endif
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts a copy of x at the end of the deque.
@@ -1142,6 +1184,8 @@
//!
//! <b>Effects</b>: Insert a copy of x before position.
//!
+ //! <b>Returns</b>: an iterator to the inserted element.
+ //!
//! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
//!
//! <b>Complexity</b>: If position is end(), amortized constant time
@@ -1152,6 +1196,8 @@
//!
//! <b>Effects</b>: Insert a new element before position with mx's resources.
//!
+ //! <b>Returns</b>: an iterator to the inserted element.
+ //!
//! <b>Throws</b>: If memory allocation throws.
//!
//! <b>Complexity</b>: If position is end(), amortized constant time
@@ -1165,28 +1211,62 @@
//!
//! <b>Effects</b>: Insert n copies of x before pos.
//!
+ //! <b>Returns</b>: an iterator to the first inserted element or pos if n is 0.
+ //!
//! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to n.
- void insert(const_iterator pos, size_type n, const value_type& x)
- { this->priv_fill_insert(pos, n, x); }
+ iterator insert(const_iterator pos, size_type n, const value_type& x)
+ {
+ typedef constant_iterator<value_type, difference_type> c_it;
+ return this->insert(pos, c_it(x, n), c_it());
+ }
//! <b>Requires</b>: pos must be a valid iterator of *this.
//!
//! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
//!
+ //! <b>Returns</b>: an iterator to the first inserted element or pos if first == last.
+ //!
//! <b>Throws</b>: If memory allocation throws, T's constructor from a
- //! dereferenced InpIt throws or T's copy constructor throws.
+ //! dereferenced InIt throws or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to std::distance [first, last).
- template <class InpIt>
- void insert(const_iterator pos, InpIt first, InpIt last)
+ template <class InIt>
+ iterator insert(const_iterator pos, InIt first, InIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InIt, size_type>::value
+ && container_detail::is_input_iterator<InIt>::value
+ >::type * = 0
+ #endif
+ )
+ {
+ size_type n = 0;
+ iterator it(pos);
+ for(;first != last; ++first, ++n){
+ it = this->emplace(it, *first);
+ ++it;
+ }
+ it -= n;
+ return it;
+ }
+
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ template <class FwdIt>
+ iterator insert(const_iterator p, FwdIt first, FwdIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<FwdIt, size_type>::value
+ && !container_detail::is_input_iterator<FwdIt>::value
+ >::type * = 0
+ #endif
+ )
{
- //Dispatch depending on integer/iterator
- const bool aux_boolean = container_detail::is_convertible<InpIt, size_type>::value;
- typedef container_detail::bool_<aux_boolean> Result;
- this->priv_insert_dispatch(pos, first, last, Result());
+ container_detail::advanced_insert_aux_proxy<A, FwdIt, iterator> proxy(this->alloc(), first, last);
+ return priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy);
}
+ #endif
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1257,11 +1337,9 @@
return (this->end()-1);
}
else{
- size_type n = p - this->cbegin();
typedef container_detail::advanced_insert_aux_emplace<A, iterator, Args...> type;
type &&proxy = type(this->alloc(), boost::forward<Args>(args)...);
- this->priv_insert_aux_impl(p, 1, proxy);
- return iterator(this->begin() + n);
+ return this->priv_insert_aux_impl(p, 1, proxy);
}
}
@@ -1320,12 +1398,10 @@
return (this->end()-1); \
} \
else{ \
- size_type pos_num = p - this->cbegin(); \
container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
<A, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- this->priv_insert_aux_impl(p, 1, proxy); \
- return iterator(this->begin() + pos_num); \
+ return this->priv_insert_aux_impl(p, 1, proxy); \
} \
} \
//!
@@ -1361,7 +1437,7 @@
if (new_size < len)
this->priv_erase_last_n(len - new_size);
else{
- size_type n = new_size - this->size();
+ const size_type n = new_size - this->size();
container_detail::default_construct_aux_proxy<A, iterator> proxy(this->alloc(), n);
priv_insert_back_aux_impl(n, proxy);
}
@@ -1500,9 +1576,7 @@
return (end()-1);
}
else {
- size_type n = position - cbegin();
- this->priv_insert_aux(position, size_type(1), x);
- return iterator(this->begin() + n);
+ return this->insert(position, size_type(1), x);
}
}
@@ -1517,10 +1591,7 @@
return(end()-1);
}
else {
- //Just call more general insert(pos, size, value) and return iterator
- size_type n = position - begin();
- this->priv_insert_aux(position, move_it(r_iterator(mx, 1)), move_it(r_iterator()));
- return iterator(this->begin() + n);
+ return this->insert(position, move_it(r_iterator(mx, 1)), move_it(r_iterator()));
}
}
@@ -1532,7 +1603,7 @@
this->priv_push_front_simple_commit();
}
else{
- this->priv_insert_aux(cbegin(), size_type(1), t);
+ this->insert(cbegin(), size_type(1), t);
}
}
@@ -1544,7 +1615,7 @@
this->priv_push_front_simple_commit();
}
else{
- this->priv_insert_aux(cbegin(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
+ this->insert(cbegin(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
}
}
@@ -1556,7 +1627,7 @@
this->priv_push_back_simple_commit();
}
else{
- this->priv_insert_aux(cend(), size_type(1), t);
+ this->insert(cend(), size_type(1), t);
}
}
@@ -1568,7 +1639,7 @@
this->priv_push_back_simple_commit();
}
else{
- this->priv_insert_aux(cend(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
+ this->insert(cend(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
}
}
@@ -1600,50 +1671,6 @@
void priv_push_front_simple_commit()
{ --this->members_.m_start.m_cur; }
- template <class InpIt>
- void priv_insert_aux(const_iterator pos, InpIt first, InpIt last, std::input_iterator_tag)
- {
- iterator it(pos);
- for(;first != last; ++first){
- it = this->emplace(it, *first);
- ++it;
- }
- }
-
- template <class FwdIt>
- void priv_insert_aux(const_iterator pos, FwdIt first, FwdIt last, std::forward_iterator_tag)
- { this->priv_insert_aux(pos, first, last); }
-
- // assign(), a generalized assignment member function. Two
- // versions: one that takes a count, and one that takes a range.
- // The range version is a member template, so we dispatch on whether
- // or not the type is an integer.
- void priv_fill_assign(size_type n, const T& val)
- {
- if (n > size()) {
- std::fill(begin(), end(), val);
- this->insert(cend(), n - size(), val);
- }
- else {
- this->erase(cbegin() + n, cend());
- std::fill(begin(), end(), val);
- }
- }
-
- template <class Integer>
- void priv_initialize_dispatch(Integer n, Integer x, container_detail::true_)
- {
- this->priv_initialize_map(n);
- this->priv_fill_initialize(x);
- }
-
- template <class InpIt>
- void priv_initialize_dispatch(InpIt first, InpIt last, container_detail::false_)
- {
- typedef typename std::iterator_traits<InpIt>::iterator_category ItCat;
- this->priv_range_initialize(first, last, ItCat());
- }
-
void priv_destroy_range(iterator p, iterator p2)
{
for(;p != p2; ++p){
@@ -1664,71 +1691,10 @@
}
}
- template <class Integer>
- void priv_assign_dispatch(Integer n, Integer val, container_detail::true_)
- { this->priv_fill_assign((size_type) n, (value_type)val); }
-
- template <class InpIt>
- void priv_assign_dispatch(InpIt first, InpIt last, container_detail::false_)
- {
- typedef typename std::iterator_traits<InpIt>::iterator_category ItCat;
- this->priv_assign_aux(first, last, ItCat());
- }
-
- template <class InpIt>
- void priv_assign_aux(InpIt first, InpIt last, std::input_iterator_tag)
- {
- iterator cur = begin();
- for ( ; first != last && cur != end(); ++cur, ++first)
- *cur = *first;
- if (first == last)
- this->erase(cur, cend());
- else
- this->insert(cend(), first, last);
- }
-
- template <class FwdIt>
- void priv_assign_aux(FwdIt first, FwdIt last, std::forward_iterator_tag)
- {
- size_type len = std::distance(first, last);
- if (len > size()) {
- FwdIt mid = first;
- std::advance(mid, size());
- boost::copy_or_move(first, mid, begin());
- this->insert(cend(), mid, last);
- }
- else
- this->erase(boost::copy_or_move(first, last, begin()), cend());
- }
-
- template <class Integer>
- void priv_insert_dispatch(const_iterator pos, Integer n, Integer x, container_detail::true_)
- { this->priv_fill_insert(pos, (size_type) n, (value_type)x); }
-
- template <class InpIt>
- void priv_insert_dispatch(const_iterator pos,InpIt first, InpIt last, container_detail::false_)
- {
- typedef typename std::iterator_traits<InpIt>::iterator_category ItCat;
- this->priv_insert_aux(pos, first, last, ItCat());
- }
-
- void priv_insert_aux(const_iterator pos, size_type n, const value_type& x)
- {
- typedef constant_iterator<value_type, difference_type> c_it;
- this->priv_insert_aux(pos, c_it(x, n), c_it());
- }
-
- //Just forward all operations to priv_insert_aux_impl
- template <class FwdIt>
- void priv_insert_aux(const_iterator p, FwdIt first, FwdIt last)
- {
- container_detail::advanced_insert_aux_proxy<A, FwdIt, iterator> proxy(this->alloc(), first, last);
- priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy);
- }
-
- void priv_insert_aux_impl(const_iterator p, size_type n, advanced_insert_aux_int_t &interf)
+ iterator priv_insert_aux_impl(const_iterator p, size_type n, advanced_insert_aux_int_t &interf)
{
iterator pos(p);
+ const size_type pos_n = p - this->cbegin();
if(!this->members_.m_map){
this->priv_initialize_map(0);
pos = this->begin();
@@ -1782,9 +1748,10 @@
interf.copy_remaining_to(pos);
}
}
+ return this->begin() + pos_n;
}
- void priv_insert_back_aux_impl(size_type n, advanced_insert_aux_int_t &interf)
+ iterator priv_insert_back_aux_impl(size_type n, advanced_insert_aux_int_t &interf)
{
if(!this->members_.m_map){
this->priv_initialize_map(0);
@@ -1794,9 +1761,10 @@
iterator old_finish = this->members_.m_finish;
interf.uninitialized_copy_some_and_update(old_finish, n, true);
this->members_.m_finish = new_finish;
+ return iterator(this->members_.m_finish - n);
}
- void priv_insert_front_aux_impl(size_type n, advanced_insert_aux_int_t &interf)
+ iterator priv_insert_front_aux_impl(size_type n, advanced_insert_aux_int_t &interf)
{
if(!this->members_.m_map){
this->priv_initialize_map(0);
@@ -1805,13 +1773,13 @@
iterator new_start = this->priv_reserve_elements_at_front(n);
interf.uninitialized_copy_some_and_update(new_start, difference_type(n), true);
this->members_.m_start = new_start;
+ return new_start;
}
-
- void priv_fill_insert(const_iterator pos, size_type n, const value_type& x)
+ iterator priv_fill_insert(const_iterator pos, size_type n, const value_type& x)
{
typedef constant_iterator<value_type, difference_type> c_it;
- this->insert(pos, c_it(x, n), c_it());
+ return this->insert(pos, c_it(x, n), c_it());
}
// Precondition: this->members_.m_start and this->members_.m_finish have already been initialized,
@@ -1834,13 +1802,13 @@
BOOST_CATCH_END
}
- template <class InpIt>
- void priv_range_initialize(InpIt first, InpIt last, std::input_iterator_tag)
+ template <class InIt>
+ void priv_range_initialize(InIt first, InIt last, std::input_iterator_tag)
{
this->priv_initialize_map(0);
BOOST_TRY {
for ( ; first != last; ++first)
- this->push_back(*first);
+ this->emplace_back(*first);
}
BOOST_CATCH(...){
this->clear();
Modified: trunk/boost/container/detail/advanced_insert_int.hpp
==============================================================================
--- trunk/boost/container/detail/advanced_insert_int.hpp (original)
+++ trunk/boost/container/detail/advanced_insert_int.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -173,7 +173,6 @@
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/variadic_templates_tools.hpp>
-#include <boost/container/detail/stored_ref.hpp>
#include <boost/move/move.hpp>
#include <typeinfo>
//#include <iostream> //For debugging purposes
@@ -227,8 +226,7 @@
if(!this->used_){
alloc_traits::construct( this->a_
, container_detail::to_raw_pointer(&*p)
- , ::boost::container::container_detail::
- stored_ref<Args>::forward(get<IdxPack>(this->args_))...
+ , ::boost::forward<Args>(get<IdxPack>(this->args_))...
);
this->used_ = true;
}
@@ -241,8 +239,7 @@
if(!this->used_){
alloc_traits::construct( this->a_
, container_detail::to_raw_pointer(&*p)
- , ::boost::container::container_detail::
- stored_ref<Args>::forward(get<IdxPack>(this->args_))...
+ , ::boost::forward<Args>(get<IdxPack>(this->args_))...
);
this->used_ = true;
}
@@ -288,7 +285,7 @@
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::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...);
+ ::boost::forward<Args>(get<IdxPack>(this->args_))...);
scoped_destructor<A> d(this->a_, vp);
*p = ::boost::move(*vp);
d.release();
@@ -305,7 +302,7 @@
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::container::container_detail::stored_ref<Args>::forward(get<IdxPack>(this->args_))...);
+ ::boost::forward<Args>(get<IdxPack>(this->args_))...);
try {
*p = ::boost::move(*vp);
} catch (...) {
@@ -413,7 +410,7 @@
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); \
+ *p = ::boost::move(*vp); \
d.release(); \
this->used_ = true; \
} \
@@ -430,7 +427,7 @@
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); \
+ *p = ::boost::move(*vp); \
d.release(); \
this->used_ = true; \
} \
Modified: trunk/boost/container/detail/algorithms.hpp
==============================================================================
--- trunk/boost/container/detail/algorithms.hpp (original)
+++ trunk/boost/container/detail/algorithms.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -34,6 +34,30 @@
namespace boost {
namespace container {
+template<class It>
+struct is_default_construct_iterator
+{
+ static const bool value = false;
+};
+
+template<class U, class D>
+struct is_default_construct_iterator<default_construct_iterator<U, D> >
+{
+ static const bool value = true;
+};
+
+template<class It>
+struct is_emplace_iterator
+{
+ static const bool value = false;
+};
+
+template<class U, class EF, class D>
+struct is_emplace_iterator<emplace_iterator<U, EF, D> >
+{
+ static const bool value = true;
+};
+
template<class A, class T, class InpIt>
inline void construct_in_place(A &a, T* dest, InpIt source)
{ boost::container::allocator_traits<A>::construct(a, dest, *source); }
Modified: trunk/boost/container/detail/flat_tree.hpp
==============================================================================
--- trunk/boost/container/detail/flat_tree.hpp (original)
+++ trunk/boost/container/detail/flat_tree.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -214,6 +214,21 @@
: m_data(comp, a)
{ this->m_data.m_vect.insert(this->m_data.m_vect.end(), first, last); }
+ template <class InputIterator>
+ flat_tree( bool unique_insertion
+ , InputIterator first, InputIterator last
+ , const Compare& comp = Compare()
+ , const allocator_type& a = allocator_type())
+ : m_data(comp, a)
+ {
+ if(unique_insertion){
+ this->insert_unique(first, last);
+ }
+ else{
+ this->insert_equal(first, last);
+ }
+ }
+
~flat_tree()
{ }
@@ -290,9 +305,9 @@
std::pair<iterator,bool> insert_unique(const value_type& val)
{
insert_commit_data data;
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data);
+ std::pair<iterator,bool> ret = this->priv_insert_unique_prepare(val, data);
if(ret.second){
- ret.first = priv_insert_commit(data, val);
+ ret.first = this->priv_insert_commit(data, val);
}
return ret;
}
@@ -300,9 +315,9 @@
std::pair<iterator,bool> insert_unique(BOOST_RV_REF(value_type) val)
{
insert_commit_data data;
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data);
+ std::pair<iterator,bool> ret = this->priv_insert_unique_prepare(val, data);
if(ret.second){
- ret.first = priv_insert_commit(data, boost::move(val));
+ ret.first = this->priv_insert_commit(data, boost::move(val));
}
return ret;
}
@@ -324,9 +339,9 @@
iterator insert_unique(const_iterator pos, const value_type& val)
{
insert_commit_data data;
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, val, data);
+ std::pair<iterator,bool> ret = this->priv_insert_unique_prepare(pos, val, data);
if(ret.second){
- ret.first = priv_insert_commit(data, val);
+ ret.first = this->priv_insert_commit(data, val);
}
return ret.first;
}
@@ -334,9 +349,9 @@
iterator insert_unique(const_iterator pos, BOOST_RV_REF(value_type) mval)
{
insert_commit_data data;
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(pos, mval, data);
+ std::pair<iterator,bool> ret = this->priv_insert_unique_prepare(pos, mval, data);
if(ret.second){
- ret.first = priv_insert_commit(data, boost::move(mval));
+ ret.first = this->priv_insert_commit(data, boost::move(mval));
}
return ret.first;
}
@@ -345,45 +360,164 @@
{
insert_commit_data data;
this->priv_insert_equal_prepare(pos, val, data);
- return priv_insert_commit(data, val);
+ return this->priv_insert_commit(data, val);
}
iterator insert_equal(const_iterator pos, BOOST_RV_REF(value_type) mval)
{
insert_commit_data data;
this->priv_insert_equal_prepare(pos, mval, data);
- return priv_insert_commit(data, boost::move(mval));
+ return this->priv_insert_commit(data, boost::move(mval));
}
template <class InIt>
void insert_unique(InIt first, InIt last)
+ { this->priv_insert_unique_loop(first, last); }
+
+ template <class InIt>
+ void insert_equal(InIt first, InIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < container_detail::is_input_iterator<InIt>::value
+ >::type * = 0
+ #endif
+ )
+ { this->priv_insert_equal_loop(first, last); }
+
+ template <class InIt>
+ void insert_equal(InIt first, InIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_input_iterator<InIt>::value
+ >::type * = 0
+ #endif
+ )
{
- for ( ; first != last; ++first)
- this->insert_unique(*first);
+ const size_type len = static_cast<size_type>(std::distance(first, last));
+ this->reserve(this->size()+len);
+ this->priv_insert_equal_loop(first, last);
}
+ //Ordered
+
template <class InIt>
- void insert_equal(InIt first, InIt last)
+ void insert_equal(ordered_range_t, InIt first, InIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < container_detail::is_input_iterator<InIt>::value
+ >::type * = 0
+ #endif
+ )
+ { this->priv_insert_equal_loop_ordered(first, last); }
+
+ template <class FwdIt>
+ void insert_equal(ordered_range_t, FwdIt first, FwdIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < container_detail::is_forward_iterator<FwdIt>::value
+ >::type * = 0
+ #endif
+ )
{
- typedef typename
- std::iterator_traits<InIt>::iterator_category ItCat;
- this->priv_insert_equal(first, last, ItCat());
+ const size_type len = static_cast<size_type>(std::distance(first, last));
+ this->reserve(this->size()+len);
+ this->priv_insert_equal_loop_ordered(first, last);
}
- template <class InIt>
- void insert_equal(ordered_range_t, InIt first, InIt last)
+ template <class BidirIt>
+ void insert_equal(ordered_range_t, BidirIt first, BidirIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_input_iterator<BidirIt>::value &&
+ !container_detail::is_forward_iterator<BidirIt>::value
+ >::type * = 0
+ #endif
+ )
{
- typedef typename
- std::iterator_traits<InIt>::iterator_category ItCat;
- this->priv_insert_equal(ordered_range_t(), first, last, ItCat());
+ size_type len = static_cast<size_type>(std::distance(first, last));
+ const size_type BurstSize = 16;
+ size_type positions[BurstSize];
+
+ //Prereserve all memory so that iterators are not invalidated
+ this->reserve(this->size()+len);
+ const const_iterator beg(this->cbegin());
+ const_iterator pos(beg);
+ //Loop in burst sizes
+ while(len){
+ const size_type burst = len < BurstSize ? len : BurstSize;
+ const const_iterator cend(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);
+ ++first;
+ }
+ //Insert all in a single step in the precalculated positions
+ this->m_data.m_vect.insert_ordered_at(burst, positions + burst, first);
+ //Next search position updated
+ pos += burst;
+ }
}
template <class InIt>
- void insert_unique(ordered_unique_range_t, InIt first, InIt last)
+ void insert_unique(ordered_unique_range_t, InIt first, InIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < container_detail::is_input_iterator<InIt>::value ||
+ container_detail::is_forward_iterator<InIt>::value
+ >::type * = 0
+ #endif
+ )
+ { this->priv_insert_unique_loop_hint(first, last); }
+
+ template <class BidirIt>
+ void insert_unique(ordered_unique_range_t, BidirIt first, BidirIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !(container_detail::is_input_iterator<BidirIt>::value ||
+ container_detail::is_forward_iterator<BidirIt>::value)
+ >::type * = 0
+ #endif
+ )
{
- typedef typename
- std::iterator_traits<InIt>::iterator_category ItCat;
- this->priv_insert_unique(ordered_unique_range_t(), first, last, ItCat());
+ size_type len = static_cast<size_type>(std::distance(first, last));
+ const size_type BurstSize = 16;
+ size_type positions[BurstSize];
+ size_type skips[BurstSize];
+
+ //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 value_compare &value_comp = this->m_data;
+ //Loop in burst sizes
+ while(len){
+ skips[0u] = 0u;
+ const size_type burst = len < BurstSize ? len : BurstSize;
+ size_type unique_burst = 0u;
+ const const_iterator cend(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));
+ //Check if already present
+ if(pos != cend && !value_comp(*pos, val)){
+ ++skips[unique_burst];
+ continue;
+ }
+
+ //If not present, calculate position
+ positions[unique_burst] = static_cast<size_type>(pos - beg);
+ if(++unique_burst < burst)
+ skips[unique_burst] = 0u;
+ }
+ //Insert all in a single step in the precalculated positions
+ this->m_data.m_vect.insert_ordered_at(unique_burst, positions + unique_burst, skips + unique_burst, first);
+ //Next search position updated
+ pos += unique_burst;
+ }
}
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
@@ -398,9 +532,9 @@
value_destructor<stored_allocator_type> d(a, val);
insert_commit_data data;
std::pair<iterator,bool> ret =
- priv_insert_unique_prepare(val, data);
+ this->priv_insert_unique_prepare(val, data);
if(ret.second){
- ret.first = priv_insert_commit(data, boost::move(val));
+ ret.first = this->priv_insert_commit(data, boost::move(val));
}
return ret;
}
@@ -414,9 +548,9 @@
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
value_destructor<stored_allocator_type> d(a, val);
insert_commit_data data;
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data);
+ std::pair<iterator,bool> ret = this->priv_insert_unique_prepare(hint, val, data);
if(ret.second){
- ret.first = priv_insert_commit(data, boost::move(val));
+ ret.first = this->priv_insert_commit(data, boost::move(val));
}
return ret.first;
}
@@ -444,7 +578,7 @@
value_destructor<stored_allocator_type> d(a, val);
insert_commit_data data;
this->priv_insert_equal_prepare(hint, val, data);
- iterator i = priv_insert_commit(data, boost::move(val));
+ iterator i = this->priv_insert_commit(data, boost::move(val));
return i;
}
@@ -462,9 +596,9 @@
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
value_destructor<stored_allocator_type> d(a, val); \
insert_commit_data data; \
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(val, data); \
+ std::pair<iterator,bool> ret = this->priv_insert_unique_prepare(val, data); \
if(ret.second){ \
- ret.first = priv_insert_commit(data, boost::move(val)); \
+ ret.first = this->priv_insert_commit(data, boost::move(val)); \
} \
return ret; \
} \
@@ -480,9 +614,9 @@
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
value_destructor<stored_allocator_type> d(a, val); \
insert_commit_data data; \
- std::pair<iterator,bool> ret = priv_insert_unique_prepare(hint, val, data); \
+ std::pair<iterator,bool> ret = this->priv_insert_unique_prepare(hint, val, data); \
if(ret.second){ \
- ret.first = priv_insert_commit(data, boost::move(val)); \
+ ret.first = this->priv_insert_commit(data, boost::move(val)); \
} \
return ret.first; \
} \
@@ -513,7 +647,7 @@
value_destructor<stored_allocator_type> d(a, val); \
insert_commit_data data; \
this->priv_insert_equal_prepare(hint, val, data); \
- iterator i = priv_insert_commit(data, boost::move(val)); \
+ iterator i = this->priv_insert_commit(data, boost::move(val)); \
return i; \
} \
@@ -653,7 +787,7 @@
std::pair<iterator,bool> priv_insert_unique_prepare
(const value_type& val, insert_commit_data &commit_data)
- { return priv_insert_unique_prepare(this->begin(), this->end(), val, commit_data); }
+ { return this->priv_insert_unique_prepare(this->begin(), this->end(), val, commit_data); }
std::pair<iterator,bool> priv_insert_unique_prepare
(const_iterator pos, const value_type& val, insert_commit_data &commit_data)
@@ -794,102 +928,38 @@
return std::pair<RanIt, RanIt>(first, first);
}
- template <class BidirIt>
- void priv_insert_equal(ordered_range_t, BidirIt first, BidirIt last, std::bidirectional_iterator_tag)
+ template<class InIt>
+ void priv_insert_equal_loop(InIt first, InIt last)
{
- size_type len = static_cast<size_type>(std::distance(first, last));
- const size_type BurstSize = 16;
- size_type positions[BurstSize];
-
- //Prereserve all memory so that iterators are not invalidated
- this->reserve(this->size()+len);
- const const_iterator beg(this->cbegin());
- const_iterator pos(beg);
- //Loop in burst sizes
- while(len){
- const size_type burst = len < BurstSize ? len : BurstSize;
- const const_iterator cend(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);
- ++first;
- }
- //Insert all in a single step in the precalculated positions
- this->m_data.m_vect.insert_ordered_at(burst, positions + burst, first);
- //Next search position updated
- pos += burst;
+ for ( ; first != last; ++first){
+ this->insert_equal(*first);
}
}
- template <class BidirIt>
- void priv_insert_unique(ordered_unique_range_t, BidirIt first, BidirIt last, std::bidirectional_iterator_tag)
+ template<class InIt>
+ void priv_insert_equal_loop_ordered(InIt first, InIt last)
{
- size_type len = static_cast<size_type>(std::distance(first, last));
- const size_type BurstSize = 16;
- size_type positions[BurstSize];
- size_type skips[BurstSize];
-
- //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 value_compare &value_comp = this->m_data;
- //Loop in burst sizes
- while(len){
- skips[0u] = 0u;
- const size_type burst = len < BurstSize ? len : BurstSize;
- size_type unique_burst = 0u;
- const const_iterator cend(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));
- //Check if already present
- if(pos != cend && !value_comp(*pos, val)){
- ++skips[unique_burst];
- continue;
- }
-
- //If not present, calculate position
- positions[unique_burst] = static_cast<size_type>(pos - beg);
- if(++unique_burst < burst)
- skips[unique_burst] = 0u;
- }
- //Insert all in a single step in the precalculated positions
- this->m_data.m_vect.insert_ordered_at(unique_burst, positions + unique_burst, skips + unique_burst, first);
- //Next search position updated
- pos += unique_burst;
+ const_iterator pos(this->cend());
+ for ( ; first != last; ++first){
+ pos = this->insert_equal(pos, *first);
}
}
-/*
- template <class FwdIt>
- void priv_insert_equal_forward(ordered_range_t, FwdIt first, FwdIt last, std::forward_iterator_tag)
- { this->priv_insert_equal(first, last, std::forward_iterator_tag()); }
-*/
- template <class InIt>
- void priv_insert_equal(ordered_range_t, InIt first, InIt last, std::input_iterator_tag)
- { this->priv_insert_equal(first, last, std::input_iterator_tag()); }
- template <class InIt>
- void priv_insert_unique(ordered_unique_range_t, InIt first, InIt last, std::input_iterator_tag)
- { this->priv_insert_unique(first, last, std::input_iterator_tag()); }
-/*
- template <class FwdIt>
- void priv_insert_equal_forward(FwdIt first, FwdIt last, std::forward_iterator_tag)
+ template<class InIt>
+ void priv_insert_unique_loop(InIt first, InIt last)
{
- const size_type len = static_cast<size_type>(std::distance(first, last));
- this->reserve(this->size()+len);
- this->priv_insert_equal(first, last, std::input_iterator_tag());
+ for ( ; first != last; ++first){
+ this->insert_unique(*first);
+ }
}
-*/
- template <class InIt>
- void priv_insert_equal(InIt first, InIt last, std::input_iterator_tag)
+
+ template<class InIt>
+ void priv_insert_unique_loop_ordered(InIt first, InIt last)
{
- for ( ; first != last; ++first)
- this->insert_equal(*first);
+ const_iterator pos(this->cend());
+ for ( ; first != last; ++first){
+ pos = this->insert_unique(pos, *first);
+ }
}
};
Modified: trunk/boost/container/detail/iterators.hpp
==============================================================================
--- trunk/boost/container/detail/iterators.hpp (original)
+++ trunk/boost/container/detail/iterators.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -22,10 +22,10 @@
#include <boost/container/detail/workaround.hpp>
#include <boost/move/move.hpp>
#include <boost/container/allocator_traits.hpp>
+#include <boost/container/detail/type_traits.hpp>
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/variadic_templates_tools.hpp>
-#include <boost/container/detail/stored_ref.hpp>
#else
#include <boost/container/detail/preprocessor.hpp>
#endif
@@ -222,14 +222,12 @@
default_construct_iterator operator-(Difference off) const
{ return *this + (-off); }
- const T& operator*() const
- { return dereference(); }
-
- const T* operator->() const
- { return &(dereference()); }
-
- const T& operator[] (Difference n) const
- { return dereference(); }
+ //This pseudo-iterator's dereference operations have no sense since value is not
+ //constructed until ::boost::container::construct_in_place is called.
+ //So comment them to catch bad uses
+ //const T& operator*() const;
+ //const T& operator[](difference_type) const;
+ //const T* operator->() const;
private:
Difference m_num;
@@ -445,14 +443,12 @@
this_type operator-(difference_type off) const
{ return *this + (-off); }
- const T& operator*() const
- { return dereference(); }
-
- const T& operator[](difference_type) const
- { return dereference(); }
-
- const T* operator->() const
- { return &(dereference()); }
+ //This pseudo-iterator's dereference operations have no sense since value is not
+ //constructed until ::boost::container::construct_in_place is called.
+ //So comment them to catch bad uses
+ //const T& operator*() const;
+ //const T& operator[](difference_type) const;
+ //const T* operator->() const;
template<class A>
void construct_in_place(A &a, T* ptr)
@@ -506,8 +502,7 @@
void inplace_impl(A &a, T* ptr, const container_detail::index_tuple<IdxPack...>&)
{
allocator_traits<A>::construct
- (a, ptr, container_detail::stored_ref<Args>::forward
- (container_detail::get<IdxPack>(args_))...);
+ (a, ptr, ::boost::forward<Args>(container_detail::get<IdxPack>(args_))...);
}
container_detail::tuple<Args&...> args_;
@@ -539,6 +534,59 @@
#endif
+namespace container_detail {
+
+template<class T>
+struct has_iterator_category
+{
+ template <typename X>
+ static char test(int, typename X::iterator_category*);
+
+ template <typename X>
+ static int test(int, ...);
+
+ static const bool value = (1 == sizeof(test<T>(0, 0)));
+};
+
+
+template<class T, bool = has_iterator_category<T>::value >
+struct is_input_iterator
+{
+ static const bool value = is_same<typename T::iterator_category, std::input_iterator_tag>::value;
+};
+
+template<class T>
+struct is_input_iterator<T, false>
+{
+ static const bool value = false;
+};
+
+template<class T, bool = has_iterator_category<T>::value >
+struct is_forward_iterator
+{
+ static const bool value = is_same<typename T::iterator_category, std::forward_iterator_tag>::value;
+};
+
+template<class T>
+struct is_forward_iterator<T, false>
+{
+ static const bool value = false;
+};
+
+template<class T, bool = has_iterator_category<T>::value >
+struct is_bidirectional_iterator
+{
+ static const bool value = is_same<typename T::iterator_category, std::bidirectional_iterator_tag>::value;
+};
+
+template<class T>
+struct is_bidirectional_iterator<T, false>
+{
+ static const bool value = false;
+};
+
+} //namespace container_detail {
+
} //namespace container {
} //namespace boost {
Modified: trunk/boost/container/detail/preprocessor.hpp
==============================================================================
--- trunk/boost/container/detail/preprocessor.hpp (original)
+++ trunk/boost/container/detail/preprocessor.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -16,11 +16,6 @@
#endif
#include <boost/container/detail/config_begin.hpp>
-
-#ifndef BOOST_NO_RVALUE_REFERENCES
-#include <boost/container/detail/stored_ref.hpp>
-#endif //#ifndef BOOST_NO_RVALUE_REFERENCES
-
#include <boost/container/detail/workaround.hpp>
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
@@ -78,19 +73,10 @@
#ifndef BOOST_NO_RVALUE_REFERENCES
- #if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
-
- #define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
- BOOST_PP_CAT(m_p, n) (static_cast<BOOST_PP_CAT(P, n)>( BOOST_PP_CAT(p, n) )) \
-
- #else //#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
-
#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) )) \
//!
- #endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
-
#else //BOOST_NO_RVALUE_REFERENCES
#define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
@@ -102,8 +88,68 @@
#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+ namespace boost {
+ namespace container {
+ namespace container_detail {
+ template<class T>
+ struct ref_holder;
+
+ template<class T>
+ struct ref_holder<T &>
+ {
+ ref_holder(T &t)
+ : t_(t)
+ {}
+ T &t_;
+ T & get() { return t_; }
+ };
+
+ template<class T>
+ struct ref_holder<const T>
+ {
+ ref_holder(const T &t)
+ : t_(t)
+ {}
+ const T &t_;
+ const T & get() { return t_; }
+ };
+
+ template<class T>
+ struct ref_holder<const T &&>
+ {
+ ref_holder(const T &t)
+ : t_(t)
+ {}
+ const T &t_;
+ const T & get() { return t_; }
+ };
+
+ template<class T>
+ struct ref_holder
+ {
+ ref_holder(T &&t)
+ : t_(t)
+ {}
+ T &t_;
+ T && get() { return ::boost::move(t_); }
+ };
+
+ template<class T>
+ struct ref_holder<T &&>
+ {
+ ref_holder(T &&t)
+ : t(t)
+ {}
+ T &t;
+ T && get() { return ::boost::move(t_); }
+ };
+
+ } //namespace container_detail {
+ } //namespace container {
+ } //namespace boost {
+
#define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data) \
- BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
+ ::boost::container::container_detail::ref_holder<BOOST_PP_CAT(P, n)> BOOST_PP_CAT(m_p, n); \
//!
#else //BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
@@ -123,8 +169,7 @@
#if !defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
- #define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) \
- ::boost::container::container_detail::stored_ref< BOOST_PP_CAT(P, n) >::forward( BOOST_PP_CAT(this->m_p, n) ) \
+ #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)
Deleted: trunk/boost/container/detail/stored_ref.hpp
==============================================================================
--- trunk/boost/container/detail/stored_ref.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
+++ (empty file)
@@ -1,92 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
-// Software License, Version 1.0. (See accompanying file
-// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-//
-// See http://www.boost.org/libs/container for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_CONTAINER_DETAIL_STORED_REF_HPP
-#define BOOST_CONTAINER_DETAIL_STORED_REF_HPP
-
-#include "config_begin.hpp"
-#include <boost/container/detail/workaround.hpp>
-
-#ifndef BOOST_NO_RVALUE_REFERENCES
-
-namespace boost{
-namespace container{
-namespace container_detail{
-
-template<class T>
-struct stored_ref
-{
-
- static T && forward(T &t)
- #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
- { return t; }
- #else
- { return boost::move(t); }
- #endif
-};
-
-template<class T>
-struct stored_ref<const T>
-{
- static const T && forward(const T &t)
- #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
- { return t; }
- #else
- { return static_cast<const T&&>(t); }
- #endif
-};
-
-template<class T>
-struct stored_ref<T&&>
-{
- static T && forward(T &t)
- #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
- { return t; }
- #else
- { return boost::move(t); }
- #endif
-};
-
-template<class T>
-struct stored_ref<const T&&>
-{
- static const T && forward(const T &t)
- #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
- { return t; }
- #else
- { return static_cast<const T &&>(t); }
- #endif
-};
-
-template<class T>
-struct stored_ref<const T&>
-{
- static const T & forward(const T &t)
- { return t; }
-};
-
-template<class T>
-struct stored_ref<T&>
-{
- static T & forward(T &t)
- { return t; }
-};
-
-} //namespace container_detail{
-} //namespace container{
-} //namespace boost{
-
-#else
-#error "This header can be included only for compiler with rvalue references"
-#endif //BOOST_NO_RVALUE_REFERENCES
-
-#include <boost/container/detail/config_end.hpp>
-
-#endif //BOOST_CONTAINER_DETAIL_STORED_REF_HPP
Modified: trunk/boost/container/detail/tree.hpp
==============================================================================
--- trunk/boost/container/detail/tree.hpp (original)
+++ trunk/boost/container/detail/tree.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -476,21 +476,77 @@
{}
template <class InputIterator>
- rbtree(InputIterator first, InputIterator last, const key_compare& comp,
- const allocator_type& a, bool unique_insertion)
+ rbtree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
+ const allocator_type& a
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < container_detail::is_input_iterator<InputIterator>::value
+ || container_detail::is_same<alloc_version, allocator_v1>::value
+ >::type * = 0
+ #endif
+ )
: AllocHolder(a, comp)
{
- typedef typename std::iterator_traits<InputIterator>::iterator_category ItCat;
- priv_create_and_insert_nodes(first, last, unique_insertion, alloc_version(), ItCat());
+ if(unique_insertion){
+ this->insert_unique(first, last);
+ }
+ else{
+ this->insert_equal(first, last);
+ }
+ }
+
+ template <class InputIterator>
+ rbtree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
+ const allocator_type& a
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !(container_detail::is_input_iterator<InputIterator>::value
+ || container_detail::is_same<alloc_version, allocator_v1>::value)
+ >::type * = 0
+ #endif
+ )
+ : AllocHolder(a, comp)
+ {
+ if(unique_insertion){
+ this->insert_unique(first, last);
+ }
+ else{
+ //Optimized allocation and construction
+ this->allocate_many_and_construct
+ (first, std::distance(first, last), insert_equal_end_hint_functor(this->icont()));
+ }
}
template <class InputIterator>
rbtree( ordered_range_t, InputIterator first, InputIterator last
- , const key_compare& comp = key_compare(), const allocator_type& a = allocator_type())
+ , const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < container_detail::is_input_iterator<InputIterator>::value
+ || container_detail::is_same<alloc_version, allocator_v1>::value
+ >::type * = 0
+ #endif
+ )
: AllocHolder(a, comp)
{
- typedef typename std::iterator_traits<InputIterator>::iterator_category ItCat;
- priv_create_and_insert_ordered_nodes(first, last, alloc_version(), ItCat());
+ this->insert_equal(first, last);
+ }
+
+ template <class InputIterator>
+ rbtree( ordered_range_t, InputIterator first, InputIterator last
+ , const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !(container_detail::is_input_iterator<InputIterator>::value
+ || container_detail::is_same<alloc_version, allocator_v1>::value)
+ >::type * = 0
+ #endif
+ )
+ : AllocHolder(a, comp)
+ {
+ //Optimized allocation and construction
+ this->allocate_many_and_construct
+ (first, std::distance(first, last), push_back_functor(this->icont()));
}
rbtree(const rbtree& x)
@@ -943,14 +999,14 @@
{ return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(value_comp()))); }
std::pair<iterator,iterator> equal_range(const key_type& k)
- {
+ {
std::pair<iiterator, iiterator> ret =
this->icont().equal_range(k, KeyNodeCompare(value_comp()));
return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second));
}
std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
- {
+ {
std::pair<iiterator, iiterator> ret =
this->non_const_icont().equal_range(k, KeyNodeCompare(value_comp()));
return std::pair<const_iterator,const_iterator>
@@ -958,108 +1014,39 @@
}
private:
- //Iterator range version
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (InpIterator beg, InpIterator end, bool unique, allocator_v1, std::input_iterator_tag)
- {
- if(unique){
- for (; beg != end; ++beg){
- this->insert_unique(*beg);
- }
- }
- else{
- for (; beg != end; ++beg){
- this->insert_equal(*beg);
- }
- }
- }
-
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (InpIterator beg, InpIterator end, bool unique, allocator_v2, std::input_iterator_tag)
- { //Just forward to the default one
- priv_create_and_insert_nodes(beg, end, unique, allocator_v1(), std::input_iterator_tag());
- }
- class insertion_functor;
- friend class insertion_functor;
+ class insert_equal_end_hint_functor;
+ friend class insert_equal_end_hint_functor;
- class insertion_functor
+ class insert_equal_end_hint_functor
{
Icont &icont_;
+ const iconst_iterator cend_;
public:
- insertion_functor(Icont &icont)
- : icont_(icont)
+ insert_equal_end_hint_functor(Icont &icont)
+ : icont_(icont), cend_(this->icont_.cend())
{}
void operator()(Node &n)
- { this->icont_.insert_equal(this->icont_.cend(), n); }
+ { this->icont_.insert_equal(cend_, n); }
};
+ class push_back_functor;
+ friend class push_back_functor;
- template<class FwdIterator>
- void priv_create_and_insert_nodes
- (FwdIterator beg, FwdIterator end, bool unique, allocator_v2, std::forward_iterator_tag)
- {
- if(beg != end){
- if(unique){
- priv_create_and_insert_nodes(beg, end, unique, allocator_v2(), std::input_iterator_tag());
- }
- else{
- //Optimized allocation and construction
- this->allocate_many_and_construct
- (beg, std::distance(beg, end), insertion_functor(this->icont()));
- }
- }
- }
-
- //Iterator range version
- template<class InpIterator>
- void priv_create_and_insert_ordered_nodes
- (InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
- {
- const_iterator cend_n(this->cend());
- for (; beg != end; ++beg){
- this->insert_before(cend_n, *beg);
- }
- }
-
- template<class InpIterator>
- void priv_create_and_insert_ordered_nodes
- (InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag)
- { //Just forward to the default one
- priv_create_and_insert_ordered_nodes(beg, end, allocator_v1(), std::input_iterator_tag());
- }
-
- class back_insertion_functor;
- friend class back_insertion_functor;
-
- class back_insertion_functor
+ class push_back_functor
{
Icont &icont_;
public:
- back_insertion_functor(Icont &icont)
+ push_back_functor(Icont &icont)
: icont_(icont)
{}
void operator()(Node &n)
{ this->icont_.push_back(n); }
};
-
-
- template<class FwdIterator>
- void priv_create_and_insert_ordered_nodes
- (FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
- {
- if(beg != end){
- //Optimized allocation and construction
- this->allocate_many_and_construct
- (beg, std::distance(beg, end), back_insertion_functor(this->icont()));
- }
- }
};
template <class Key, class Value, class KeyOfValue,
Modified: trunk/boost/container/flat_map.hpp
==============================================================================
--- trunk/boost/container/flat_map.hpp (original)
+++ trunk/boost/container/flat_map.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -190,8 +190,8 @@
template <class InputIterator>
flat_map(InputIterator first, InputIterator last, const Pred& comp = Pred(),
const allocator_type& a = allocator_type())
- : m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
- { m_flat_tree.insert_unique(first, last); }
+ : m_flat_tree(true, first, last, comp, container_detail::force<impl_allocator_type>(a))
+ {}
//! <b>Effects</b>: Constructs an empty flat_map using the specified comparison object and
//! allocator, and inserts elements from the ordered unique range [first ,last). This function
@@ -988,8 +988,8 @@
flat_multimap(InputIterator first, InputIterator last,
const Pred& comp = Pred(),
const allocator_type& a = allocator_type())
- : m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
- { m_flat_tree.insert_equal(first, last); }
+ : m_flat_tree(false, first, last, comp, container_detail::force<impl_allocator_type>(a))
+ {}
//! <b>Effects</b>: Constructs an empty flat_multimap using the specified comparison object and
//! allocator, and inserts elements from the ordered range [first ,last). This function
Modified: trunk/boost/container/flat_set.hpp
==============================================================================
--- trunk/boost/container/flat_set.hpp (original)
+++ trunk/boost/container/flat_set.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -125,8 +125,8 @@
flat_set(InputIterator first, InputIterator last,
const Pred& comp = Pred(),
const allocator_type& a = allocator_type())
- : m_flat_tree(comp, a)
- { m_flat_tree.insert_unique(first, last); }
+ : m_flat_tree(true, first, last, comp, a)
+ {}
//! <b>Effects</b>: Constructs an empty flat_set using the specified comparison object and
//! allocator, and inserts elements from the ordered unique range [first ,last). This function
@@ -777,8 +777,8 @@
flat_multiset(InputIterator first, InputIterator last,
const Pred& comp = Pred(),
const allocator_type& a = allocator_type())
- : m_flat_tree(comp, a)
- { m_flat_tree.insert_equal(first, last); }
+ : m_flat_tree(false, first, last, comp, a)
+ {}
//! <b>Effects</b>: Constructs an empty flat_multiset using the specified comparison object and
//! allocator, and inserts elements from the ordered range [first ,last ). This function
Modified: trunk/boost/container/list.hpp
==============================================================================
--- trunk/boost/container/list.hpp (original)
+++ trunk/boost/container/list.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -660,18 +660,8 @@
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
void resize(size_type new_size, const T& x)
{
- const_iterator iend = this->cend();
- size_type len = this->size();
-
- if(len > new_size){
- size_type to_erase = len - new_size;
- while(to_erase--){
- --iend;
- }
- this->erase(iend, this->cend());
- }
- else{
- this->priv_create_and_insert_nodes(iend, new_size - len, x);
+ if(!priv_try_shrink(new_size)){
+ this->insert(this->cend(), new_size - this->size(), x);
}
}
@@ -683,29 +673,9 @@
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
void resize(size_type new_size)
{
- const_iterator iend = this->end();
- size_type len = this->size();
-
- if(len > new_size){
- size_type to_erase = len - new_size;
- const_iterator ifirst;
- if(to_erase < len/2u){
- ifirst = iend;
- while(to_erase--){
- --ifirst;
- }
- }
- else{
- ifirst = this->begin();
- size_type to_skip = len - to_erase;
- while(to_skip--){
- ++ifirst;
- }
- }
- this->erase(ifirst, iend);
- }
- else{
- this->priv_create_and_insert_nodes(this->cend(), new_size - len);
+ if(!priv_try_shrink(new_size)){
+ typedef default_construct_iterator<value_type, difference_type> default_iterator;
+ this->insert(this->cend(), default_iterator(new_size - this->size()), default_iterator());
}
}
@@ -776,33 +746,76 @@
//!
//! <b>Effects</b>: Inserts n copies of x before p.
//!
+ //! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
+ //!
//! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to n.
- void insert(const_iterator p, size_type n, const T& x)
- { this->priv_create_and_insert_nodes(p, n, x); }
+ iterator insert(const_iterator p, size_type n, const T& x)
+ {
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+ return this->insert(p, cvalue_iterator(x, n), cvalue_iterator());
+ }
//! <b>Requires</b>: p must be a valid iterator of *this.
//!
//! <b>Effects</b>: Insert a copy of the [first, last) range before p.
//!
+ //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
+ //!
//! <b>Throws</b>: If memory allocation throws, T's constructor from a
//! dereferenced InpIt throws.
//!
//! <b>Complexity</b>: Linear to std::distance [first, last).
template <class InpIt>
- void insert(const_iterator p, InpIt first, InpIt last)
- {
- const bool aux_boolean = container_detail::is_convertible<InpIt, size_type>::value;
- typedef container_detail::bool_<aux_boolean> Result;
- this->priv_insert_dispatch(p, first, last, Result());
+ iterator insert(const_iterator p, InpIt first, InpIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InpIt, size_type>::value
+ && (container_detail::is_input_iterator<InpIt>::value
+ || container_detail::is_same<alloc_version, allocator_v1>::value
+ )
+ >::type * = 0
+ #endif
+ )
+ {
+ const typename Icont::iterator ipos(p.get());
+ iterator ret_it(ipos);
+ if(first != last){
+ ret_it = iterator(this->icont().insert(ipos, *this->create_node_from_it(first)));
+ ++first;
+ }
+ for (; first != last; ++first){
+ this->icont().insert(ipos, *this->create_node_from_it(first));
+ }
+ return ret_it;
+ }
+
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ template <class FwdIt>
+ iterator insert(const_iterator p, FwdIt first, FwdIt last
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<FwdIt, size_type>::value
+ && !(container_detail::is_input_iterator<FwdIt>::value
+ || container_detail::is_same<alloc_version, allocator_v1>::value
+ )
+ >::type * = 0
+ )
+ {
+ //Optimized allocation and construction
+ insertion_functor func(this->icont(), p.get());
+ this->allocate_many_and_construct(first, std::distance(first, last), func);
+ return iterator(func.inserted_first());
}
+ #endif
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Requires</b>: position must be a valid iterator of *this.
//!
//! <b>Effects</b>: Insert a copy of x before position.
//!
+ //! <b>Returns</b>: an iterator to the inserted element.
+ //!
//! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
//!
//! <b>Complexity</b>: Amortized constant time.
@@ -812,6 +825,8 @@
//!
//! <b>Effects</b>: Insert a new element before position with mx's resources.
//!
+ //! <b>Returns</b>: an iterator to the inserted element.
+ //!
//! <b>Throws</b>: If memory allocation throws.
//!
//! <b>Complexity</b>: Amortized constant time.
@@ -919,7 +934,10 @@
//!
//! <b>Complexity</b>: Linear to n.
void assign(size_type n, const T& val)
- { this->priv_fill_assign(n, val); }
+ {
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+ return this->assign(cvalue_iterator(val, n), cvalue_iterator());
+ }
//! <b>Effects</b>: Assigns the the range [first, last) to *this.
//!
@@ -928,11 +946,23 @@
//!
//! <b>Complexity</b>: Linear to n.
template <class InpIt>
- void assign(InpIt first, InpIt last)
- {
- const bool aux_boolean = container_detail::is_convertible<InpIt, size_type>::value;
- typedef container_detail::bool_<aux_boolean> Result;
- this->priv_assign_dispatch(first, last, Result());
+ void assign(InpIt first, InpIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InpIt, size_type>::value
+ >::type * = 0
+ #endif
+ )
+ {
+ iterator first1 = this->begin();
+ const iterator last1 = this->end();
+ for ( ; first1 != last1 && first != last; ++first1, ++first)
+ *first1 = *first;
+ if (first == last)
+ this->erase(first1, last1);
+ else{
+ this->insert(last1, first, last);
+ }
}
//! <b>Requires</b>: p must point to an element contained
@@ -1151,6 +1181,34 @@
/// @cond
private:
+ bool priv_try_shrink(size_type new_size)
+ {
+ const size_type len = this->size();
+ if(len > new_size){
+ const const_iterator iend = this->cend();
+ size_type to_erase = len - new_size;
+ const_iterator ifirst;
+ if(to_erase < len/2u){
+ ifirst = iend;
+ while(to_erase--){
+ --ifirst;
+ }
+ }
+ else{
+ ifirst = this->cbegin();
+ size_type to_skip = len - to_erase;
+ while(to_skip--){
+ ++ifirst;
+ }
+ }
+ this->erase(ifirst, iend);
+ return true;
+ }
+ else{
+ return false;
+ }
+ }
+
iterator priv_insert(const_iterator p, const T &x)
{
NodePtr tmp = AllocHolder::create_node(x);
@@ -1175,116 +1233,38 @@
void priv_push_front (BOOST_RV_REF(T) x)
{ this->insert(this->cbegin(), boost::move(x)); }
- //Iterator range version
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (const_iterator pos, InpIterator beg, InpIterator end)
- {
- typedef typename std::iterator_traits<InpIterator>::iterator_category ItCat;
- priv_create_and_insert_nodes(pos, beg, end, alloc_version(), ItCat());
- }
-
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (const_iterator pos, InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
- {
- for (; beg != end; ++beg){
- this->icont().insert(pos.get(), *this->create_node_from_it(beg));
- }
- }
-
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (const_iterator pos, InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag)
- { //Just forward to the default one
- priv_create_and_insert_nodes(pos, beg, end, allocator_v1(), std::input_iterator_tag());
- }
-
class insertion_functor;
friend class insertion_functor;
class insertion_functor
{
Icont &icont_;
- typename Icont::const_iterator pos_;
+ 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)
+ : icont_(icont), pos_(pos), ret_(pos.unconst()), first_(true)
{}
void operator()(Node &n)
- { this->icont_.insert(pos_, n); }
- };
-
-
- template<class FwdIterator>
- void priv_create_and_insert_nodes
- (const_iterator pos, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
- {
- if(beg != end){
- //Optimized allocation and construction
- this->allocate_many_and_construct
- (beg, std::distance(beg, end), insertion_functor(this->icont(), pos.get()));
- }
- }
-
- //Default constructed version
- void priv_create_and_insert_nodes(const_iterator pos, size_type n)
- {
- typedef default_construct_iterator<value_type, difference_type> default_iterator;
- this->priv_create_and_insert_nodes(pos, default_iterator(n), default_iterator());
- }
-
- //Copy constructed version
- void priv_create_and_insert_nodes(const_iterator pos, size_type n, const T& x)
- {
- typedef constant_iterator<value_type, difference_type> cvalue_iterator;
- this->priv_create_and_insert_nodes(pos, cvalue_iterator(x, n), cvalue_iterator());
- }
-
- //Dispatch to detect iterator range or integer overloads
- template <class InputIter>
- void priv_insert_dispatch(const_iterator p,
- InputIter first, InputIter last,
- container_detail::false_)
- { this->priv_create_and_insert_nodes(p, first, last); }
-
- template<class Integer>
- void priv_insert_dispatch(const_iterator p, Integer n, Integer x, container_detail::true_)
- { this->insert(p, (size_type)n, x); }
-
- void priv_fill_assign(size_type n, const T& val)
- {
- iterator i = this->begin(), iend = this->end();
-
- for ( ; i != iend && n > 0; ++i, --n)
- *i = val;
- if (n > 0){
- this->priv_create_and_insert_nodes(this->cend(), n, val);
- }
- else{
- this->erase(i, cend());
+ {
+ if(first_){
+ ret_ = this->icont_.insert(pos_, n);
+ first_ = false;
+ }
+ else{
+ this->icont_.insert(pos_, n);
+ }
}
- }
-
- template <class Integer>
- void priv_assign_dispatch(Integer n, Integer val, container_detail::true_)
- { this->priv_fill_assign((size_type) n, (T) val); }
- template <class InputIter>
- void priv_assign_dispatch(InputIter first2, InputIter last2, container_detail::false_)
- {
- iterator first1 = this->begin();
- iterator last1 = this->end();
- for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
- *first1 = *first2;
- if (first2 == last2)
- this->erase(first1, last1);
- else{
- this->priv_create_and_insert_nodes(last1, first2, last2);
- }
- }
+ iiterator inserted_first() const
+ { return ret_; }
+ };
//Functors for member algorithm defaults
struct value_less
Modified: trunk/boost/container/map.hpp
==============================================================================
--- trunk/boost/container/map.hpp (original)
+++ trunk/boost/container/map.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -155,7 +155,7 @@
template <class InputIterator>
map(InputIterator first, InputIterator last, const Pred& comp = Pred(),
const allocator_type& a = allocator_type())
- : m_tree(first, last, comp, a, true)
+ : m_tree(true, first, last, comp, a)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
@@ -902,7 +902,7 @@
multimap(InputIterator first, InputIterator last,
const Pred& comp = Pred(),
const allocator_type& a = allocator_type())
- : m_tree(first, last, comp, a, false)
+ : m_tree(false, first, last, comp, a)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename A::value_type>::value));
Modified: trunk/boost/container/set.hpp
==============================================================================
--- trunk/boost/container/set.hpp (original)
+++ trunk/boost/container/set.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -118,7 +118,7 @@
template <class InputIterator>
set(InputIterator first, InputIterator last, const Pred& comp = Pred(),
const allocator_type& a = allocator_type())
- : m_tree(first, last, comp, a, true)
+ : m_tree(true, first, last, comp, a)
{}
//! <b>Effects</b>: Constructs an empty set using the specified comparison object and
@@ -705,7 +705,7 @@
multiset(InputIterator first, InputIterator last,
const Pred& comp = Pred(),
const allocator_type& a = allocator_type())
- : m_tree(first, last, comp, a, false)
+ : m_tree(false, first, last, comp, a)
{}
//! <b>Effects</b>: Constructs an empty multiset using the specified comparison object and
Modified: trunk/boost/container/slist.hpp
==============================================================================
--- trunk/boost/container/slist.hpp (original)
+++ trunk/boost/container/slist.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -23,6 +23,7 @@
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/type_traits.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/container/detail/node_alloc_holder.hpp>
@@ -336,7 +337,7 @@
//! <b>Complexity</b>: Linear to n.
explicit slist(size_type n, const value_type& x, const allocator_type& a = allocator_type())
: AllocHolder(a)
- { this->priv_create_and_insert_nodes(this->before_begin(), n, x); }
+ { this->insert_after(this->cbefore_begin(), n, x); }
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a
//! and inserts a copy of the range [first, last) in the list.
@@ -349,7 +350,7 @@
slist(InpIt first, InpIt last,
const allocator_type& a = allocator_type())
: AllocHolder(a)
- { this->insert_after(this->before_begin(), first, last); }
+ { this->insert_after(this->cbefore_begin(), first, last); }
//! <b>Effects</b>: Copy constructs a list.
//!
@@ -360,7 +361,7 @@
//! <b>Complexity</b>: Linear to the elements x contains.
slist(const slist& x)
: AllocHolder(x)
- { this->insert_after(this->before_begin(), x.begin(), x.end()); }
+ { this->insert_after(this->cbefore_begin(), x.begin(), x.end()); }
//! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
//!
@@ -380,7 +381,7 @@
//! <b>Complexity</b>: Linear to the elements x contains.
slist(const slist& x, const allocator_type &a)
: AllocHolder(a)
- { this->insert_after(this->before_begin(), x.begin(), x.end()); }
+ { this->insert_after(this->cbefore_begin(), x.begin(), x.end()); }
//! <b>Effects</b>: Move constructor using the specified allocator.
//! Moves x's resources to *this.
@@ -485,7 +486,10 @@
//!
//! <b>Complexity</b>: Linear to n.
void assign(size_type n, const T& val)
- { this->priv_fill_assign(n, val); }
+ {
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+ return this->assign(cvalue_iterator(val, n), cvalue_iterator());
+ }
//! <b>Effects</b>: Assigns the range [first, last) to *this.
//!
@@ -494,11 +498,27 @@
//!
//! <b>Complexity</b>: Linear to n.
template <class InpIt>
- void assign(InpIt first, InpIt last)
+ void assign(InpIt first, InpIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InpIt, size_type>::value
+ >::type * = 0
+ #endif
+ )
{
- const bool aux_boolean = container_detail::is_convertible<InpIt, size_type>::value;
- typedef container_detail::bool_<aux_boolean> Result;
- this->priv_assign_dispatch(first, last, Result());
+ iterator end_n(this->end());
+ iterator prev(this->before_begin());
+ iterator node(this->begin());
+ while (node != end_n && first != last){
+ *node = *first;
+ prev = node;
+ ++node;
+ ++first;
+ }
+ if (first != last)
+ this->insert_after(prev, first, last);
+ else
+ this->erase_after(prev, end_n);
}
//! <b>Effects</b>: Returns an iterator to the first element contained in the list.
@@ -535,7 +555,7 @@
//! <b>Effects</b>: Returns a non-dereferenceable iterator that,
//! when incremented, yields begin(). This iterator may be used
- //! as the argument toinsert_after, erase_after, etc.
+ //! as the argument to insert_after, erase_after, etc.
//!
//! <b>Throws</b>: Nothing.
//!
@@ -545,7 +565,7 @@
//! <b>Effects</b>: Returns a non-dereferenceable const_iterator
//! that, when incremented, yields begin(). This iterator may be used
- //! as the argument toinsert_after, erase_after, etc.
+ //! as the argument to insert_after, erase_after, etc.
//!
//! <b>Throws</b>: Nothing.
//!
@@ -571,7 +591,7 @@
//! <b>Effects</b>: Returns a non-dereferenceable const_iterator
//! that, when incremented, yields begin(). This iterator may be used
- //! as the argument toinsert_after, erase_after, etc.
+ //! as the argument to insert_after, erase_after, etc.
//!
//! <b>Throws</b>: Nothing.
//!
@@ -734,20 +754,28 @@
//!
//! <b>Effects</b>: Inserts n copies of x after prev_pos.
//!
+ //! <b>Returns</b>: an iterator to the last inserted element or prev_pos if n is 0.
+ //!
//! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
//!
+ //!
//! <b>Complexity</b>: Linear to n.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references of
//! previous values.
- void insert_after(const_iterator prev_pos, size_type n, const value_type& x)
- { this->priv_create_and_insert_nodes(prev_pos, n, x); }
+ iterator insert_after(const_iterator prev_pos, size_type n, const value_type& x)
+ {
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+ return this->insert_after(prev_pos, cvalue_iterator(x, n), cvalue_iterator());
+ }
//! <b>Requires</b>: prev_pos must be a valid iterator of *this.
//!
//! <b>Effects</b>: Inserts the range pointed by [first, last)
//! after the p prev_pos.
//!
+ //! <b>Returns</b>: an iterator to the last inserted element or prev_pos if first == last.
+ //!
//! <b>Throws</b>: If memory allocation throws, T's constructor from a
//! dereferenced InpIt throws.
//!
@@ -755,18 +783,49 @@
//!
//! <b>Note</b>: Does not affect the validity of iterators and references of
//! previous values.
- template <class InIter>
- void insert_after(const_iterator prev_pos, InIter first, InIter last)
+ template <class InpIt>
+ iterator insert_after(const_iterator prev_pos, InpIt first, InpIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InpIt, size_type>::value
+ && (container_detail::is_input_iterator<InpIt>::value
+ || container_detail::is_same<alloc_version, allocator_v1>::value
+ )
+ >::type * = 0
+ #endif
+ )
+ {
+ iterator ret_it(prev_pos.get());
+ for (; first != last; ++first){
+ ret_it = iterator(this->icont().insert_after(ret_it.get(), *this->create_node_from_it(first)));
+ }
+ return ret_it;
+ }
+
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ template <class FwdIt>
+ iterator insert_after(const_iterator prev, FwdIt first, FwdIt last
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<FwdIt, size_type>::value
+ && !(container_detail::is_input_iterator<FwdIt>::value
+ || container_detail::is_same<alloc_version, allocator_v1>::value
+ )
+ >::type * = 0
+ )
{
- const bool aux_boolean = container_detail::is_convertible<InIter, size_type>::value;
- typedef container_detail::bool_<aux_boolean> Result;
- this->priv_insert_after_range_dispatch(prev_pos, first, last, Result());
+ //Optimized allocation and construction
+ insertion_functor func(this->icont(), prev.get());
+ this->allocate_many_and_construct(first, std::distance(first, last), func);
+ return iterator(func.inserted_first());
}
+ #endif
//! <b>Requires</b>: p must be a valid iterator of *this.
//!
//! <b>Effects</b>: Insert a copy of x before p.
//!
+ //! <b>Returns</b>: an iterator to the inserted element.
+ //!
//! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to the elements before p.
@@ -787,6 +846,8 @@
//!
//! <b>Effects</b>: Insert a new element before p with mx's resources.
//!
+ //! <b>Returns</b>: an iterator to the inserted element.
+ //!
//! <b>Throws</b>: If memory allocation throws.
//!
//! <b>Complexity</b>: Linear to the elements before p.
@@ -797,24 +858,36 @@
//!
//! <b>Effects</b>: Inserts n copies of x before p.
//!
+ //! <b>Returns</b>: an iterator to the first inserted element or p if n == 0.
+ //!
//! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to n plus linear to the elements before p.
- void insert(const_iterator p, size_type n, const value_type& x)
- { return this->insert_after(previous(p), n, x); }
+ iterator insert(const_iterator p, size_type n, const value_type& x)
+ {
+ const_iterator prev(this->previous(p));
+ this->insert_after(prev, n, x);
+ return ++iterator(prev.get());
+ }
//! <b>Requires</b>: p must be a valid iterator of *this.
//!
//! <b>Effects</b>: Insert a copy of the [first, last) range before p.
//!
+ //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
+ //!
//! <b>Throws</b>: If memory allocation throws, T's constructor from a
//! dereferenced InpIt throws.
//!
//! <b>Complexity</b>: Linear to std::distance [first, last) plus
//! linear to the elements before p.
template <class InIter>
- void insert(const_iterator p, InIter first, InIter last)
- { return this->insert_after(previous(p), first, last); }
+ iterator insert(const_iterator p, InIter first, InIter last)
+ {
+ const_iterator prev(this->previous(p));
+ this->insert_after(prev, first, last);
+ return ++iterator(prev.get());
+ }
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -948,15 +1021,10 @@
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
void resize(size_type new_size, const T& x)
{
- typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
- while (++(cur_next = cur) != end_n && new_size > 0){
- --new_size;
- cur = cur_next;
+ const_iterator last_pos;
+ if(!priv_try_shrink(new_size, last_pos)){
+ this->insert_after(last_pos, new_size, x);
}
- if (cur_next != end_n)
- this->erase_after(const_iterator(cur), const_iterator(end_n));
- else
- this->insert_after(const_iterator(cur), new_size, x);
}
//! <b>Effects</b>: Inserts or erases elements at the end such that
@@ -967,19 +1035,10 @@
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
void resize(size_type new_size)
{
- typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
- size_type len = this->size();
- size_type left = new_size;
-
- while (++(cur_next = cur) != end_n && left > 0){
- --left;
- cur = cur_next;
- }
- if (cur_next != end_n){
- this->erase_after(const_iterator(cur), const_iterator(end_n));
- }
- else{
- this->priv_create_and_insert_nodes(const_iterator(cur), new_size - len);
+ const_iterator last_pos;
+ if(!priv_try_shrink(new_size, last_pos)){
+ typedef default_construct_iterator<value_type, difference_type> default_iterator;
+ this->insert_after(last_pos, default_iterator(new_size - this->size()), default_iterator());
}
}
@@ -1279,6 +1338,24 @@
/// @cond
private:
+
+ bool priv_try_shrink(size_type new_size, const_iterator &last_pos)
+ {
+ typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
+ while (++(cur_next = cur) != end_n && new_size > 0){
+ --new_size;
+ cur = cur_next;
+ }
+ last_pos = const_iterator(cur);
+ if (cur_next != end_n){
+ this->erase_after(last_pos, const_iterator(end_n));
+ return true;
+ }
+ else{
+ return false;
+ }
+ }
+
iterator priv_insert(const_iterator p, const value_type& x)
{ return this->insert_after(previous(p), x); }
@@ -1288,128 +1365,30 @@
void priv_push_front(const value_type &x)
{ this->icont().push_front(*this->create_node(x)); }
- //Iterator range version
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (const_iterator prev, InpIterator beg, InpIterator end)
- {
- typedef typename std::iterator_traits<InpIterator>::iterator_category ItCat;
- priv_create_and_insert_nodes(prev, beg, end, alloc_version(), ItCat());
- }
-
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (const_iterator prev, InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
- {
- for (; beg != end; ++beg){
- this->icont().insert_after(prev.get(), *this->create_node_from_it(beg));
- ++prev;
- }
- }
-
- template<class InpIterator>
- void priv_create_and_insert_nodes
- (const_iterator prev, InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag)
- { //Just forward to the default one
- priv_create_and_insert_nodes(prev, beg, end, allocator_v1(), std::input_iterator_tag());
- }
-
class insertion_functor;
friend class insertion_functor;
class insertion_functor
{
Icont &icont_;
- typename Icont::const_iterator prev_;
+ typedef typename Icont::iterator iiterator;
+ typedef typename Icont::const_iterator iconst_iterator;
+ const iconst_iterator prev_;
+ iiterator ret_;
public:
insertion_functor(Icont &icont, typename Icont::const_iterator prev)
- : icont_(icont), prev_(prev)
+ : icont_(icont), prev_(prev), ret_(prev.unconst())
{}
void operator()(Node &n)
- { prev_ = this->icont_.insert_after(prev_, n); }
- };
-
- template<class FwdIterator>
- void priv_create_and_insert_nodes
- (const_iterator prev, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
- {
- //Optimized allocation and construction
- this->allocate_many_and_construct
- (beg, std::distance(beg, end), insertion_functor(this->icont(), prev.get()));
- }
-
- //Default constructed version
- void priv_create_and_insert_nodes(const_iterator prev, size_type n)
- {
- typedef default_construct_iterator<value_type, difference_type> default_iterator;
- this->priv_create_and_insert_nodes(prev, default_iterator(n), default_iterator());
- }
-
- //Copy constructed version
- void priv_create_and_insert_nodes(const_iterator prev, size_type n, const T& x)
- {
- typedef constant_iterator<value_type, difference_type> cvalue_iterator;
- this->priv_create_and_insert_nodes(prev, cvalue_iterator(x, n), cvalue_iterator());
- }
-
- //Dispatch to detect iterator range or integer overloads
- template <class InputIter>
- void priv_insert_dispatch(const_iterator prev,
- InputIter first, InputIter last,
- container_detail::false_)
- { this->priv_create_and_insert_nodes(prev, first, last); }
-
- template<class Integer>
- void priv_insert_dispatch(const_iterator prev, Integer n, Integer x, container_detail::true_)
- { this->priv_create_and_insert_nodes(prev, (size_type)n, x); }
-
- void priv_fill_assign(size_type n, const T& val)
- {
- iterator end_n(this->end());
- iterator prev(this->before_begin());
- iterator node(this->begin());
- for ( ; node != end_n && n > 0 ; --n){
- *node = val;
- prev = node;
- ++node;
+ {
+ ret_ = this->icont_.insert_after(prev_, n);
}
- if (n > 0)
- this->priv_create_and_insert_nodes(prev, n, val);
- else
- this->erase_after(prev, end_n);
- }
- template <class Int>
- void priv_assign_dispatch(Int n, Int val, container_detail::true_)
- { this->priv_fill_assign((size_type) n, (T)val); }
-
- template <class InpIt>
- void priv_assign_dispatch(InpIt first, InpIt last, container_detail::false_)
- {
- iterator end_n(this->end());
- iterator prev(this->before_begin());
- iterator node(this->begin());
- while (node != end_n && first != last){
- *node = *first;
- prev = node;
- ++node;
- ++first;
- }
- if (first != last)
- this->priv_create_and_insert_nodes(prev, first, last);
- else
- this->erase_after(prev, end_n);
- }
-
- template <class Int>
- void priv_insert_after_range_dispatch(const_iterator prev_pos, Int n, Int x, container_detail::true_)
- { this->priv_create_and_insert_nodes(prev_pos, (size_type)n, x); }
-
- template <class InIter>
- void priv_insert_after_range_dispatch(const_iterator prev_pos, InIter first, InIter last, container_detail::false_)
- { this->priv_create_and_insert_nodes(prev_pos, first, last); }
+ iiterator inserted_first() const
+ { return ret_; }
+ };
//Functors for member algorithm defaults
struct value_less
Modified: trunk/boost/container/stable_vector.hpp
==============================================================================
--- trunk/boost/container/stable_vector.hpp (original)
+++ trunk/boost/container/stable_vector.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -93,7 +93,7 @@
{
if(do_clear_){
c_.clear();
- c_.clear_pool();
+ c_.priv_clear_pool();
}
}
@@ -172,6 +172,9 @@
iterator(const iterator<T, T&, typename boost::intrusive::pointer_traits<Pointer>::template rebind_pointer<T>::type>& x)
: pn(x.pn)
{}
+
+ node_type_ptr_t node() const
+ { return pn; }
private:
static node_type_ptr_t node_ptr_cast(const void_ptr &p)
@@ -413,14 +416,14 @@
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
- { return node_alloc().allocate(1); }
+ { return this->priv_node_alloc().allocate(1); }
template<class AllocatorVersion>
node_type_ptr_t allocate_one(AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<!boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
- { return node_alloc().allocate_one(); }
+ { return this->priv_node_alloc().allocate_one(); }
void deallocate_one(node_type_ptr_t p)
{ return this->deallocate_one(p, alloc_version()); }
@@ -430,14 +433,14 @@
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
- { node_alloc().deallocate(p, 1); }
+ { this->priv_node_alloc().deallocate(p, 1); }
template<class AllocatorVersion>
void deallocate_one(node_type_ptr_t p, AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<!boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
- { node_alloc().deallocate_one(p); }
+ { this->priv_node_alloc().deallocate_one(p); }
friend class stable_vector_detail::clear_on_destroy<stable_vector>;
///@endcond
@@ -497,7 +500,7 @@
//!
//! <b>Complexity</b>: Constant.
explicit stable_vector(const allocator_type& al)
- : internal_data(al),impl(al)
+ : internal_data(al), impl(al)
{
STABLE_VECTOR_CHECK_INVARIANT;
}
@@ -510,7 +513,7 @@
//!
//! <b>Complexity</b>: Linear to n.
explicit stable_vector(size_type n)
- : internal_data(),impl()
+ : internal_data(), impl()
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->resize(n);
@@ -526,10 +529,10 @@
//!
//! <b>Complexity</b>: Linear to n.
stable_vector(size_type n, const T& t, const allocator_type& al = allocator_type())
- : internal_data(al),impl(al)
+ : internal_data(al), impl(al)
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
- this->insert(this->cbegin(), n, t);
+ this->insert(this->cend(), n, t);
STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
@@ -543,10 +546,10 @@
//! <b>Complexity</b>: Linear to the range [first, last).
template <class InputIterator>
stable_vector(InputIterator first,InputIterator last, const allocator_type& al = allocator_type())
- : internal_data(al),impl(al)
+ : internal_data(al), impl(al)
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
- this->insert(this->cbegin(), first, last);
+ this->insert(this->cend(), first, last);
STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
@@ -558,12 +561,12 @@
//! <b>Complexity</b>: Linear to the elements x contains.
stable_vector(const stable_vector& x)
: internal_data(allocator_traits<node_allocator_type>::
- select_on_container_copy_construction(x.node_alloc()))
+ select_on_container_copy_construction(x.priv_node_alloc()))
, impl(allocator_traits<allocator_type>::
select_on_container_copy_construction(x.impl.get_stored_allocator()))
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
- this->insert(this->cbegin(), x.begin(), x.end());
+ this->insert(this->cend(), x.begin(), x.end());
STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
@@ -574,7 +577,7 @@
//!
//! <b>Complexity</b>: Constant.
stable_vector(BOOST_RV_REF(stable_vector) x)
- : internal_data(boost::move(x.node_alloc())), impl(boost::move(x.impl))
+ : internal_data(boost::move(x.priv_node_alloc())), impl(boost::move(x.impl))
{
this->priv_swap_members(x);
}
@@ -588,7 +591,7 @@
: internal_data(a), impl(a)
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
- this->insert(this->cbegin(), x.begin(), x.end());
+ this->insert(this->cend(), x.begin(), x.end());
STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
@@ -602,12 +605,12 @@
stable_vector(BOOST_RV_REF(stable_vector) x, const allocator_type &a)
: internal_data(a), impl(a)
{
- if(this->node_alloc() == x.node_alloc()){
+ if(this->priv_node_alloc() == x.priv_node_alloc()){
this->priv_swap_members(x);
}
else{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
- this->insert(this->cbegin(), x.begin(), x.end());
+ this->insert(this->cend(), x.begin(), x.end());
STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
@@ -622,7 +625,7 @@
~stable_vector()
{
this->clear();
- clear_pool();
+ priv_clear_pool();
}
//! <b>Effects</b>: Makes *this contain the same elements as x.
@@ -637,15 +640,15 @@
{
STABLE_VECTOR_CHECK_INVARIANT;
if (&x != this){
- node_allocator_type &this_alloc = this->node_alloc();
- const node_allocator_type &x_alloc = x.node_alloc();
+ node_allocator_type &this_alloc = this->priv_node_alloc();
+ const node_allocator_type &x_alloc = x.priv_node_alloc();
container_detail::bool_<allocator_traits_type::
propagate_on_container_copy_assignment::value> flag;
if(flag && this_alloc != x_alloc){
this->clear();
this->shrink_to_fit();
}
- container_detail::assign_alloc(this->node_alloc(), x.node_alloc(), flag);
+ container_detail::assign_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag);
container_detail::assign_alloc(this->impl.get_stored_allocator(), x.impl.get_stored_allocator(), flag);
this->assign(x.begin(), x.end());
}
@@ -663,8 +666,8 @@
stable_vector& operator=(BOOST_RV_REF(stable_vector) x)
{
if (&x != this){
- node_allocator_type &this_alloc = this->node_alloc();
- node_allocator_type &x_alloc = x.node_alloc();
+ node_allocator_type &this_alloc = this->priv_node_alloc();
+ node_allocator_type &x_alloc = x.priv_node_alloc();
//If allocators are equal we can just swap pointers
if(this_alloc == x_alloc){
//Destroy objects but retain memory
@@ -674,7 +677,7 @@
//Move allocator if needed
container_detail::bool_<allocator_traits_type::
propagate_on_container_move_assignment::value> flag;
- container_detail::move_alloc(this->node_alloc(), x.node_alloc(), flag);
+ container_detail::move_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag);
}
//If unequal allocators, then do a one by one move
else{
@@ -693,9 +696,25 @@
//!
//! <b>Complexity</b>: Linear to n.
template<typename InputIterator>
- void assign(InputIterator first,InputIterator last)
+ void assign(InputIterator first,InputIterator last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InputIterator, size_type>::value
+ >::type * = 0
+ #endif
+ )
{
- assign_dispatch(first, last, boost::is_integral<InputIterator>());
+ STABLE_VECTOR_CHECK_INVARIANT;
+ iterator first1 = this->begin();
+ iterator last1 = this->end();
+ for ( ; first1 != last1 && first != last; ++first1, ++first)
+ *first1 = *first;
+ if (first == last){
+ this->erase(first1, last1);
+ }
+ else{
+ this->insert(last1, first, last);
+ }
}
@@ -707,7 +726,7 @@
void assign(size_type n,const T& t)
{
typedef constant_iterator<value_type, difference_type> cvalue_iterator;
- return assign_dispatch(cvalue_iterator(t, n), cvalue_iterator(), boost::mpl::false_());
+ this->assign(cvalue_iterator(t, n), cvalue_iterator());
}
//! <b>Effects</b>: Returns a copy of the internal allocator.
@@ -715,7 +734,8 @@
//! <b>Throws</b>: If allocator's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator()const {return this->node_alloc();}
+ allocator_type get_allocator()const
+ { return this->priv_node_alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
//!
@@ -725,7 +745,7 @@
//!
//! <b>Note</b>: Non-standard extension.
const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
- { return node_alloc(); }
+ { return this->priv_node_alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
//!
@@ -735,7 +755,7 @@
//!
//! <b>Note</b>: Non-standard extension.
stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
- { return node_alloc(); }
+ { return this->priv_node_alloc(); }
//! <b>Effects</b>: Returns an iterator to the first element contained in the stable_vector.
@@ -928,7 +948,7 @@
}
//Now fill pool if data is not enough
if((n - size) > this->internal_data.pool_size){
- this->add_to_pool((n - size) - this->internal_data.pool_size);
+ this->priv_add_to_pool((n - size) - this->internal_data.pool_size);
}
}
}
@@ -1066,6 +1086,8 @@
//!
//! <b>Effects</b>: Insert a copy of x before position.
//!
+ //! <b>Returns</b>: An iterator to the inserted element.
+ //!
//! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
//!
//! <b>Complexity</b>: If position is end(), amortized constant time
@@ -1086,6 +1108,8 @@
//!
//! <b>Effects</b>: Insert a new element before position with mx's resources.
//!
+ //! <b>Returns</b>: an iterator to the inserted element.
+ //!
//! <b>Throws</b>: If memory allocation throws.
//!
//! <b>Complexity</b>: If position is end(), amortized constant time
@@ -1104,33 +1128,70 @@
//! <b>Requires</b>: pos must be a valid iterator of *this.
//!
- //! <b>Effects</b>: Insert n copies of x before pos.
+ //! <b>Effects</b>: Insert n copies of x before position.
+ //!
+ //! <b>Returns</b>: an iterator to the first inserted element or position if n is 0.
//!
//! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to n.
- void insert(const_iterator position, size_type n, const T& t)
+ iterator insert(const_iterator position, size_type n, const T& t)
{
STABLE_VECTOR_CHECK_INVARIANT;
- this->insert_not_iter(position, n, t);
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+ return this->insert(position, cvalue_iterator(t, n), cvalue_iterator());
}
//! <b>Requires</b>: pos must be a valid iterator of *this.
//!
//! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
//!
+ //! <b>Returns</b>: an iterator to the first inserted element or position if first == last.
+ //!
//! <b>Throws</b>: If memory allocation throws, T's constructor from a
//! dereferenced InpIt throws or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to std::distance [first, last).
template <class InputIterator>
- void 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
+ && container_detail::is_input_iterator<InputIterator>::value
+ >::type * = 0
+ #endif
+ )
{
STABLE_VECTOR_CHECK_INVARIANT;
- this->insert_iter(position,first,last,
- boost::mpl::not_<boost::is_integral<InputIterator> >());
+ const size_type pos_n = position - this->cbegin();
+ for(; first != last; ++first){
+ this->emplace(position, *first);
+ }
+ return this->begin() + pos_n;
}
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ template <class FwdIt>
+ iterator insert(const_iterator position, FwdIt first, FwdIt last
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<FwdIt, size_type>::value
+ && !container_detail::is_input_iterator<FwdIt>::value
+ >::type * = 0
+ )
+ {
+ size_type n = (size_type)std::distance(first,last);
+ difference_type d = position - this->cbegin();
+ if(n){
+ this->insert_iter_prolog(n, d);
+ const impl_iterator it(impl.begin() + d);
+ this->priv_insert_iter_fwd(it, first, last, n);
+ //Fix the pointers for the newly allocated buffer
+ this->align_nodes(it + n, get_last_align());
+ }
+ return this->begin() + d;
+ }
+ #endif
+
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -1230,7 +1291,18 @@
//! <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)
- { return priv_erase(first, last, alloc_version()); }
+ {
+ STABLE_VECTOR_CHECK_INVARIANT;
+ difference_type d1 = first - this->cbegin(), d2 = last - this->cbegin();
+ if(d1 != d2){
+ impl_iterator it1(impl.begin() + d1), it2(impl.begin() + d2);
+ for(impl_iterator it = it1; it != it2; ++it)
+ this->delete_node(*it);
+ impl_iterator e = impl.erase(it1, it2);
+ this->align_nodes(e, get_last_align());
+ }
+ return iterator(this->begin() + d1);
+ }
//! <b>Effects</b>: Swaps the contents of *this and x.
//!
@@ -1241,7 +1313,7 @@
{
STABLE_VECTOR_CHECK_INVARIANT;
container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
- container_detail::swap_alloc(this->node_alloc(), x.node_alloc(), flag);
+ container_detail::swap_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag);
//vector's allocator is swapped here
this->impl.swap(x.impl);
this->priv_swap_members(x);
@@ -1265,7 +1337,7 @@
{
if(this->capacity()){
//First empty allocated node pool
- this->clear_pool();
+ this->priv_clear_pool();
//If empty completely destroy the index, let's recover default-constructed state
if(this->empty()){
this->impl.clear();
@@ -1291,14 +1363,14 @@
iterator priv_insert(const_iterator position, const value_type &t)
{
typedef constant_iterator<value_type, difference_type> cvalue_iterator;
- return this->insert_iter(position, cvalue_iterator(t, 1), cvalue_iterator(), std::forward_iterator_tag());
+ return this->insert(position, cvalue_iterator(t, 1), cvalue_iterator());
}
void priv_push_back(const value_type &t)
{ this->insert(end(), t); }
template<class AllocatorVersion>
- void clear_pool(AllocatorVersion,
+ void priv_clear_pool(AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
@@ -1320,7 +1392,7 @@
}
template<class AllocatorVersion>
- void clear_pool(AllocatorVersion,
+ void priv_clear_pool(AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<!boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
@@ -1330,24 +1402,24 @@
void_ptr &pool_last_ref = impl.back();
multiallocation_chain holder;
holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
- node_alloc().deallocate_individual(boost::move(holder));
+ this->priv_node_alloc().deallocate_individual(boost::move(holder));
pool_first_ref = pool_last_ref = 0;
this->internal_data.pool_size = 0;
}
}
- void clear_pool()
+ void priv_clear_pool()
{
- this->clear_pool(alloc_version());
+ this->priv_clear_pool(alloc_version());
}
- void add_to_pool(size_type n)
+ void priv_add_to_pool(size_type n)
{
- this->add_to_pool(n, alloc_version());
+ this->priv_add_to_pool(n, alloc_version());
}
template<class AllocatorVersion>
- void add_to_pool(size_type n, AllocatorVersion,
+ void priv_add_to_pool(size_type n, AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
@@ -1359,7 +1431,7 @@
}
template<class AllocatorVersion>
- void add_to_pool(size_type n, AllocatorVersion,
+ void priv_add_to_pool(size_type n, AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<!boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
@@ -1369,7 +1441,7 @@
multiallocation_chain holder;
holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
//BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled<multiallocation_chain>::value == true));
- multiallocation_chain m (node_alloc().allocate_individual(n));
+ multiallocation_chain m (this->priv_node_alloc().allocate_individual(n));
holder.splice_after(holder.before_begin(), m, m.before_begin(), m.last(), n);
this->internal_data.pool_size += n;
std::pair<void_ptr, void_ptr> data(holder.extract_data());
@@ -1390,7 +1462,7 @@
pool_last_ref = ret.second;
}
- node_type_ptr_t get_from_pool()
+ node_type_ptr_t priv_get_from_pool()
{
if(!impl.back()){
return node_type_ptr_t(0);
@@ -1429,43 +1501,6 @@
}
}
- template<typename InputIterator>
- void assign_dispatch(InputIterator first, InputIterator last, boost::mpl::false_)
- {
- STABLE_VECTOR_CHECK_INVARIANT;
- iterator first1 = this->begin();
- iterator last1 = this->end();
- for ( ; first1 != last1 && first != last; ++first1, ++first)
- *first1 = *first;
- if (first == last){
- this->erase(first1, last1);
- }
- else{
- this->insert(last1, first, last);
- }
- }
-
- template<typename Integer>
- void assign_dispatch(Integer n, Integer t, boost::mpl::true_)
- {
- typedef constant_iterator<value_type, difference_type> cvalue_iterator;
- this->assign_dispatch(cvalue_iterator(t, n), cvalue_iterator(), boost::mpl::false_());
- }
-
- iterator priv_erase(const_iterator first, const_iterator last, allocator_v1)
- {
- STABLE_VECTOR_CHECK_INVARIANT;
- difference_type d1 = first - this->cbegin(), d2 = last - this->cbegin();
- if(d1 != d2){
- impl_iterator it1(impl.begin() + d1), it2(impl.begin() + d2);
- for(impl_iterator it = it1; it != it2; ++it)
- this->delete_node(*it);
- impl_iterator e = impl.erase(it1, it2);
- this->align_nodes(e, get_last_align());
- }
- return iterator(this->begin() + d1);
- }
-
impl_iterator get_last_align()
{
return impl.end() - (ExtraPointers - 1);
@@ -1476,16 +1511,6 @@
return impl.cend() - (ExtraPointers - 1);
}
- template<class AllocatorVersion>
- iterator priv_erase(const_iterator first, const_iterator last, AllocatorVersion,
- typename boost::container::container_detail::enable_if_c
- <!boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
- ::value>::type * = 0)
- {
- STABLE_VECTOR_CHECK_INVARIANT;
- return priv_erase(first, last, allocator_v1());
- }
-
static node_type_ptr_t node_ptr_cast(const void_ptr &p)
{
return node_type_ptr_t(static_cast<node_type_t*>(container_detail::to_raw_pointer(p)));
@@ -1535,7 +1560,7 @@
{
node_type_ptr_t p = this->allocate_one();
try{
- boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), it);
+ boost::container::construct_in_place(this->priv_node_alloc(), container_detail::addressof(p->value), it);
//This does not throw
::new(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p))) node_type_base_t;
p->set_pointer(up);
@@ -1551,7 +1576,7 @@
{
node_type_ptr_t n(node_ptr_cast(p));
allocator_traits<node_allocator_type>::
- destroy(this->node_alloc(), container_detail::to_raw_pointer(n));
+ destroy(this->priv_node_alloc(), container_detail::to_raw_pointer(n));
this->put_in_pool(n);
}
@@ -1563,44 +1588,8 @@
}
}
- void insert_not_iter(const_iterator position, size_type n, const T& t)
- {
- typedef constant_iterator<value_type, difference_type> cvalue_iterator;
- this->insert_iter(position, cvalue_iterator(t, n), cvalue_iterator(), std::forward_iterator_tag());
- }
-
- template <class InputIterator>
- void insert_iter(const_iterator position,InputIterator first,InputIterator last, boost::mpl::true_)
- {
- typedef typename std::iterator_traits<InputIterator>::iterator_category category;
- this->insert_iter(position, first, last, category());
- }
-
- template <class InputIterator>
- void insert_iter(const_iterator position,InputIterator first,InputIterator last,std::input_iterator_tag)
- {
- for(; first!=last; ++first){
- this->insert(position, *first);
- }
- }
-
- template <class InputIterator>
- iterator insert_iter(const_iterator position, InputIterator first, InputIterator last, std::forward_iterator_tag)
- {
- size_type n = (size_type)std::distance(first,last);
- difference_type d = position-this->cbegin();
- if(n){
- this->insert_iter_prolog(n, d);
- const impl_iterator it(impl.begin() + d);
- this->insert_iter_fwd(it, first, last, n);
- //Fix the pointers for the newly allocated buffer
- this->align_nodes(it + n, get_last_align());
- }
- return this->begin() + d;
- }
-
template <class FwdIterator>
- void insert_iter_fwd_alloc(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n, allocator_v1)
+ void priv_insert_iter_fwd_alloc(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n, allocator_v1)
{
size_type i=0;
try{
@@ -1618,9 +1607,9 @@
}
template <class FwdIterator>
- void insert_iter_fwd_alloc(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n, allocator_v2)
+ void priv_insert_iter_fwd_alloc(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n, allocator_v2)
{
- multiallocation_chain mem(node_alloc().allocate_individual(n));
+ multiallocation_chain mem(this->priv_node_alloc().allocate_individual(n));
size_type i = 0;
node_type_ptr_t p = 0;
@@ -1629,7 +1618,7 @@
p = mem.front();
mem.pop_front();
//This can throw
- boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), first);
+ boost::container::construct_in_place(this->priv_node_alloc(), container_detail::addressof(p->value), first);
//This does not throw
::new(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p))) node_type_base_t;
p->set_pointer(void_ptr_ptr(&it[i]));
@@ -1639,8 +1628,8 @@
}
}
catch(...){
- node_alloc().deallocate_one(p);
- node_alloc().deallocate_many(boost::move(mem));
+ this->priv_node_alloc().deallocate_one(p);
+ this->priv_node_alloc().deallocate_many(boost::move(mem));
impl_iterator e = impl.erase(it+i, it+n);
this->align_nodes(e, get_last_align());
throw;
@@ -1648,19 +1637,19 @@
}
template <class FwdIterator>
- void insert_iter_fwd(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n)
+ void priv_insert_iter_fwd(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n)
{
size_type i = 0;
node_type_ptr_t p = 0;
try{
while(first != last){
- p = this->get_from_pool();
+ p = this->priv_get_from_pool();
if(!p){
- insert_iter_fwd_alloc(it+i, first, last, n-i, alloc_version());
+ this->priv_insert_iter_fwd_alloc(it+i, first, last, n-i, alloc_version());
break;
}
//This can throw
- boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->value), first);
+ boost::container::construct_in_place(this->priv_node_alloc(), container_detail::addressof(p->value), first);
//This does not throw
::new(static_cast<node_type_base_t*>(container_detail::to_raw_pointer(p))) node_type_base_t;
p->set_pointer(void_ptr_ptr(&it[i]));
@@ -1677,14 +1666,15 @@
}
}
- template <class InputIterator>
- void insert_iter(const_iterator position, InputIterator first, InputIterator last, boost::mpl::false_)
+ void priv_swap_members(stable_vector &x)
{
- this->insert_not_iter(position, first, last);
+ container_detail::do_swap(this->internal_data.pool_size, x.internal_data.pool_size);
+ this->readjust_end_node();
+ x.readjust_end_node();
}
#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
- bool invariant()const
+ bool priv_invariant()const
{
if(impl.empty())
return !capacity() && !size();
@@ -1715,7 +1705,7 @@
public:
invariant_checker(const stable_vector& v):p(&v){}
- ~invariant_checker(){BOOST_ASSERT(p->invariant());}
+ ~invariant_checker(){BOOST_ASSERT(p->priv_invariant());}
void touch(){}
};
#endif
@@ -1725,14 +1715,8 @@
{
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(ebo_holder)
+
public:
-/*
- explicit ebo_holder(BOOST_RV_REF(ebo_holder) x)
- : node_allocator_type(boost::move(static_cast<node_allocator_type&>(x)))
- , pool_size(0)
- , end_node()
- {}
-*/
template<class AllocatorRLValue>
explicit ebo_holder(BOOST_FWD_REF(AllocatorRLValue) a)
: node_allocator_type(boost::forward<AllocatorRLValue>(a))
@@ -1759,15 +1743,8 @@
node_type_base_t end_node;
} internal_data;
- void priv_swap_members(stable_vector &x)
- {
- container_detail::do_swap(this->internal_data.pool_size, x.internal_data.pool_size);
- this->readjust_end_node();
- x.readjust_end_node();
- }
-
- node_allocator_type &node_alloc() { return internal_data; }
- const node_allocator_type &node_alloc() const { return internal_data; }
+ node_allocator_type &priv_node_alloc() { return internal_data; }
+ const node_allocator_type &priv_node_alloc() const { return internal_data; }
impl_type impl;
/// @endcond
Modified: trunk/boost/container/string.hpp
==============================================================================
--- trunk/boost/container/string.hpp (original)
+++ trunk/boost/container/string.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -68,13 +68,8 @@
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/aligned_storage.hpp>
-#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace boost {
namespace container {
-#else
-namespace boost {
-namespace container {
-#endif
/// @cond
namespace container_detail {
@@ -624,7 +619,10 @@
//! <b>Throws</b>: If allocator_type's default constructor throws.
basic_string(const basic_string& s)
: base_t(allocator_traits_type::select_on_container_copy_construction(s.alloc()))
- { this->priv_range_initialize(s.begin(), s.end()); }
+ {
+ this->priv_terminate_string();
+ this->assign(s.begin(), s.end());
+ }
//! <b>Effects</b>: Move constructor. Moves s's resources to *this.
//!
@@ -642,7 +640,10 @@
//! <b>Throws</b>: If allocation throws.
basic_string(const basic_string& s, const allocator_type &a)
: base_t(a)
- { this->priv_range_initialize(s.begin(), s.end()); }
+ {
+ this->priv_terminate_string();
+ this->assign(s.begin(), s.end());
+ }
//! <b>Effects</b>: Move constructor using the specified allocator.
//! Moves s's resources to *this.
@@ -653,11 +654,12 @@
basic_string(BOOST_RV_REF(basic_string) s, const allocator_type &a)
: base_t(a)
{
+ this->priv_terminate_string();
if(a == this->alloc()){
this->swap_data(s);
}
else{
- this->priv_range_initialize(s.begin(), s.end());
+ this->assign(s.begin(), s.end());
}
}
@@ -667,10 +669,11 @@
const allocator_type& a = allocator_type())
: base_t(a)
{
+ this->priv_terminate_string();
if (pos > s.size())
this->throw_out_of_range();
else
- this->priv_range_initialize
+ this->assign
(s.begin() + pos, s.begin() + pos + container_detail::min_value(n, s.size() - pos));
}
@@ -679,23 +682,29 @@
basic_string(const CharT* s, size_type n,
const allocator_type& a = allocator_type())
: base_t(a)
- { this->priv_range_initialize(s, s + n); }
+ {
+ this->priv_terminate_string();
+ this->assign(s, s + n);
+ }
//! <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())
: base_t(a)
- { this->priv_range_initialize(s, s + Traits::length(s)); }
+ {
+ this->priv_terminate_string();
+ this->assign(s, s + Traits::length(s));
+ }
//! <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())
: base_t(a)
- {
- this->priv_range_initialize(cvalue_iterator(c, n),
- cvalue_iterator());
+ {
+ this->priv_terminate_string();
+ this->assign(n, c);
}
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
@@ -705,10 +714,8 @@
const allocator_type& a = allocator_type())
: base_t(a)
{
- //Dispatch depending on integer/iterator
- const bool aux_boolean = container_detail::is_convertible<InputIterator, size_type>::value;
- typedef container_detail::bool_<aux_boolean> Result;
- this->priv_initialize_dispatch(f, l, Result());
+ this->priv_terminate_string();
+ this->assign(f, l);
}
//! <b>Effects</b>: Destroys the basic_string. All used memory is deallocated.
@@ -1213,8 +1220,8 @@
//! <b>Throws</b>: If memory allocation throws or out_of_range if pos > str.size().
//!
//! <b>Returns</b>: *this
- basic_string& assign(const basic_string& s,
- size_type pos, size_type n) {
+ basic_string& assign(const basic_string& s, size_type pos, size_type n)
+ {
if (pos > s.size())
this->throw_out_of_range();
return this->assign(s.begin() + pos,
@@ -1250,12 +1257,28 @@
//!
//! <b>Returns</b>: *this
template <class InputIter>
- basic_string& assign(InputIter first, InputIter last)
+ basic_string& assign(InputIter first, InputIter last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InputIter, size_type>::value
+ >::type * = 0
+ #endif
+ )
{
- //Dispatch depending on integer/iterator
- const bool aux_boolean = container_detail::is_convertible<InputIter, size_type>::value;
- typedef container_detail::bool_<aux_boolean> Result;
- return this->priv_assign_dispatch(first, last, Result());
+ size_type cur = 0;
+ CharT *ptr = container_detail::to_raw_pointer(this->priv_addr());
+ const size_type old_size = this->priv_size();
+ while (first != last && cur != old_size) {
+ Traits::assign(*ptr, *first);
+ ++first;
+ ++cur;
+ ++ptr;
+ }
+ if (first == last)
+ this->erase(this->priv_addr() + cur, this->priv_addr() + old_size);
+ else
+ this->append(first, last);
+ return *this;
}
//! <b>Requires</b>: pos <= size().
@@ -1283,8 +1306,7 @@
//! <b>Throws</b>: If memory allocation throws or out_of_range if pos1 > size() or pos2 > str.size().
//!
//! <b>Returns</b>: *this
- basic_string& insert(size_type pos1, const basic_string& s,
- size_type pos2, size_type n)
+ basic_string& insert(size_type pos1, const basic_string& s, size_type pos2, size_type n)
{
if (pos1 > this->size() || pos2 > s.size())
this->throw_out_of_range();
@@ -1369,23 +1391,144 @@
//! <b>Requires</b>: p is a valid iterator on *this.
//!
//! <b>Effects</b>: Inserts n copies of c before the character referred to by p.
- void insert(const_iterator p, size_type n, CharT c)
- {
- this->insert(p, cvalue_iterator(c, n), cvalue_iterator());
- }
+ //!
+ //! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
+ iterator insert(const_iterator p, size_type n, CharT c)
+ { return this->insert(p, cvalue_iterator(c, n), cvalue_iterator()); }
//! <b>Requires</b>: p is a valid iterator on *this. [first,last) is a valid range.
//!
//! <b>Effects</b>: Equivalent to insert(p - begin(), basic_string(first, last)).
+ //!
+ //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
template <class InputIter>
- void insert(const_iterator p, InputIter first, InputIter last)
+ iterator insert(const_iterator p, InputIter first, InputIter last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InputIter, size_type>::value
+ && container_detail::is_input_iterator<InputIter>::value
+ >::type * = 0
+ #endif
+ )
{
- //Dispatch depending on integer/iterator
- const bool aux_boolean = container_detail::is_convertible<InputIter, size_type>::value;
- typedef container_detail::bool_<aux_boolean> Result;
- this->priv_insert_dispatch(p, first, last, Result());
+ const size_type n_pos = p - this->cbegin();
+ for ( ; first != last; ++first, ++p) {
+ p = this->insert(p, *first);
+ }
+ return this->begin() + n_pos;
}
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ template <class ForwardIter>
+ iterator insert(const_iterator p, ForwardIter first, ForwardIter last
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<ForwardIter, size_type>::value
+ && !container_detail::is_input_iterator<ForwardIter>::value
+ >::type * = 0
+ )
+ {
+ const size_type n_pos = p - this->cbegin();
+ if (first != last) {
+ const size_type n = std::distance(first, last);
+ const size_type old_size = this->priv_size();
+ const size_type remaining = this->capacity() - old_size;
+ const pointer old_start = this->priv_addr();
+ bool enough_capacity = false;
+ std::pair<pointer, bool> allocation_ret;
+ size_type new_cap = 0;
+
+ //Check if we have enough capacity
+ if (remaining >= n){
+ enough_capacity = true;
+ }
+ else {
+ //Otherwise expand current buffer or allocate new storage
+ new_cap = this->next_capacity(n);
+ allocation_ret = this->allocation_command
+ (allocate_new | expand_fwd | expand_bwd, old_size + n + 1,
+ new_cap, new_cap, old_start);
+
+ //Check forward expansion
+ if(old_start == allocation_ret.first){
+ enough_capacity = true;
+ this->priv_storage(new_cap);
+ }
+ }
+
+ //Reuse same buffer
+ if(enough_capacity){
+ const size_type elems_after = old_size - (p - this->priv_addr());
+ const size_type old_length = old_size;
+ if (elems_after >= n) {
+ const pointer pointer_past_last = this->priv_addr() + old_size + 1;
+ priv_uninitialized_copy(this->priv_addr() + (old_size - n + 1),
+ pointer_past_last, pointer_past_last);
+
+ this->priv_size(old_size+n);
+ Traits::move(const_cast<CharT*>(container_detail::to_raw_pointer(p + n)),
+ container_detail::to_raw_pointer(p),
+ (elems_after - n) + 1);
+ this->priv_copy(first, last, const_cast<CharT*>(container_detail::to_raw_pointer(p)));
+ }
+ else {
+ ForwardIter mid = first;
+ std::advance(mid, elems_after + 1);
+
+ priv_uninitialized_copy(mid, last, this->priv_addr() + old_size + 1);
+ this->priv_size(old_size + (n - elems_after));
+ priv_uninitialized_copy
+ (p, const_iterator(this->priv_addr() + old_length + 1),
+ this->priv_addr() + this->priv_size());
+ this->priv_size(this->priv_size() + elems_after);
+ this->priv_copy(first, mid, const_cast<CharT*>(container_detail::to_raw_pointer(p)));
+ }
+ }
+ else{
+ pointer new_start = allocation_ret.first;
+ if(!allocation_ret.second){
+ //Copy data to new buffer
+ size_type new_length = 0;
+ //This can't throw, since characters are POD
+ new_length += priv_uninitialized_copy
+ (const_iterator(this->priv_addr()), p, new_start);
+ new_length += priv_uninitialized_copy
+ (first, last, new_start + new_length);
+ new_length += priv_uninitialized_copy
+ (p, const_iterator(this->priv_addr() + old_size),
+ new_start + new_length);
+ this->priv_construct_null(new_start + new_length);
+
+ this->deallocate_block();
+ this->is_short(false);
+ this->priv_long_addr(new_start);
+ this->priv_long_size(new_length);
+ this->priv_long_storage(new_cap);
+ }
+ else{
+ //value_type is POD, so backwards expansion is much easier
+ //than with vector<T>
+ value_type * const oldbuf = container_detail::to_raw_pointer(old_start);
+ value_type * const newbuf = container_detail::to_raw_pointer(new_start);
+ const value_type *const pos = container_detail::to_raw_pointer(p);
+ const size_type before = pos - oldbuf;
+
+ //First move old data
+ Traits::move(newbuf, oldbuf, before);
+ Traits::move(newbuf + before + n, pos, old_size - before);
+ //Now initialize the new data
+ priv_uninitialized_copy(first, last, new_start + before);
+ this->priv_construct_null(new_start + (old_size + n));
+ this->is_short(false);
+ this->priv_long_addr(new_start);
+ this->priv_long_size(old_size + n);
+ this->priv_long_storage(new_cap);
+ }
+ }
+ }
+ return this->begin() + n_pos;
+ }
+ #endif
+
//! <b>Requires</b>: pos <= size()
//!
//! <b>Effects</b>: Determines the effective length xlen of the string to be removed as the smaller of n and size() - pos.
@@ -1472,8 +1615,9 @@
const size_type len = container_detail::min_value(n1, size() - pos1);
if (this->size() - len >= this->max_size() - str.size())
this->throw_length_error();
- return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len,
- str.begin(), str.end());
+ return this->replace( const_iterator(this->priv_addr() + pos1)
+ , const_iterator(this->priv_addr() + pos1 + len)
+ , str.begin(), str.end());
}
//! <b>Requires</b>: pos1 <= size() and pos2 <= str.size().
@@ -1512,16 +1656,14 @@
//! if the length of the resulting string would exceed max_size()
//!
//! <b>Returns</b>: *this
- basic_string& replace(size_type pos1, size_type n1,
- const CharT* s, size_type n2)
+ basic_string& replace(size_type pos1, size_type n1, const CharT* s, size_type n2)
{
if (pos1 > size())
this->throw_out_of_range();
const size_type len = container_detail::min_value(n1, size() - pos1);
if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
this->throw_length_error();
- return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len,
- s, s + n2);
+ return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len, s, s + n2);
}
//! <b>Requires</b>: pos1 <= size() and s points to an array of at least n2 elements of CharT.
@@ -1629,13 +1771,50 @@
//!
//! <b>Returns</b>: *this
template <class InputIter>
- basic_string& replace(const_iterator i1, const_iterator i2, InputIter j1, InputIter j2)
+ basic_string& replace(const_iterator i1, const_iterator i2, InputIter j1, InputIter j2
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InputIter, size_type>::value
+ && container_detail::is_input_iterator<InputIter>::value
+ >::type * = 0
+ #endif
+ )
+ {
+ for ( ; i1 != i2 && j1 != j2; ++i1, ++j1){
+ Traits::assign(*const_cast<CharT*>(container_detail::to_raw_pointer(i1)), *j1);
+ }
+
+ if (j1 == j2)
+ this->erase(i1, i2);
+ else
+ this->insert(i2, j1, j2);
+ return *this;
+ }
+
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ template <class ForwardIter>
+ basic_string& replace(const_iterator i1, const_iterator i2, ForwardIter j1, ForwardIter j2
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<ForwardIter, size_type>::value
+ && !container_detail::is_input_iterator<ForwardIter>::value
+ >::type * = 0
+ )
{
- //Dispatch depending on integer/iterator
- const bool aux_boolean = container_detail::is_convertible<InputIter, size_type>::value;
- typedef container_detail::bool_<aux_boolean> Result;
- return this->priv_replace_dispatch(i1, i2, j1, j2, Result());
+ difference_type n = std::distance(j1, j2);
+ const difference_type len = i2 - i1;
+ if (len >= n) {
+ this->priv_copy(j1, j2, const_cast<CharT*>(container_detail::to_raw_pointer(i1)));
+ this->erase(i1 + n, i2);
+ }
+ else {
+ ForwardIter m = j1;
+ std::advance(m, len);
+ this->priv_copy(j1, m, const_cast<CharT*>(container_detail::to_raw_pointer(i1)));
+ this->insert(i2, m, j2);
+ }
+ return *this;
}
+ #endif
//! <b>Requires</b>: pos <= size()
//!
@@ -2153,46 +2332,6 @@
void priv_terminate_string()
{ this->priv_construct_null(this->priv_addr() + this->priv_size()); }
- template <class InputIter>
- void priv_range_initialize(InputIter f, InputIter l,
- std::input_iterator_tag)
- {
- this->allocate_initial_block(InternalBufferChars);
- this->priv_construct_null(this->priv_addr() + this->priv_size());
- this->append(f, l);
- }
-
- template <class ForwardIter>
- void priv_range_initialize(ForwardIter f, ForwardIter l,
- std::forward_iterator_tag)
- {
- difference_type n = std::distance(f, l);
- this->allocate_initial_block(container_detail::max_value<difference_type>(n+1, InternalBufferChars));
- priv_uninitialized_copy(f, l, this->priv_addr());
- this->priv_size(n);
- this->priv_terminate_string();
- }
-
- template <class InputIter>
- void priv_range_initialize(InputIter f, InputIter l)
- {
- typedef typename std::iterator_traits<InputIter>::iterator_category Category;
- this->priv_range_initialize(f, l, Category());
- }
-
- template <class Integer>
- void priv_initialize_dispatch(Integer n, Integer x, container_detail::true_)
- {
- this->allocate_initial_block(container_detail::max_value<difference_type>(n+1, InternalBufferChars));
- priv_uninitialized_fill_n(this->priv_addr(), n, x);
- this->priv_size(n);
- this->priv_terminate_string();
- }
-
- template <class InputIter>
- void priv_initialize_dispatch(InputIter f, InputIter l, container_detail::false_)
- { this->priv_range_initialize(f, l); }
-
template<class FwdIt, class Count> inline
void priv_uninitialized_fill_n(FwdIt first, Count count, const CharT val)
{
@@ -2238,14 +2377,9 @@
BOOST_CATCH_END
return (constructed);
}
-
- template <class Integer>
- basic_string& priv_assign_dispatch(Integer n, Integer x, container_detail::true_)
- { return this->assign((size_type) n, (CharT) x); }
-
+/*
template <class InputIter>
- basic_string& priv_assign_dispatch(InputIter f, InputIter l,
- container_detail::false_)
+ basic_string& priv_assign_dispatch(InputIter f, InputIter l, container_detail::false_)
{
size_type cur = 0;
CharT *ptr = container_detail::to_raw_pointer(this->priv_addr());
@@ -2262,131 +2396,7 @@
this->append(f, l);
return *this;
}
-
- template <class InputIter>
- void priv_insert(const_iterator p, InputIter first, InputIter last, std::input_iterator_tag)
- {
- for ( ; first != last; ++first, ++p) {
- p = this->insert(p, *first);
- }
- }
-
- template <class ForwardIter>
- void priv_insert(const_iterator position, ForwardIter first,
- ForwardIter last, std::forward_iterator_tag)
- {
- if (first != last) {
- const size_type n = std::distance(first, last);
- const size_type old_size = this->priv_size();
- const size_type remaining = this->capacity() - old_size;
- const pointer old_start = this->priv_addr();
- bool enough_capacity = false;
- std::pair<pointer, bool> allocation_ret;
- size_type new_cap = 0;
-
- //Check if we have enough capacity
- if (remaining >= n){
- enough_capacity = true;
- }
- else {
- //Otherwise expand current buffer or allocate new storage
- new_cap = this->next_capacity(n);
- allocation_ret = this->allocation_command
- (allocate_new | expand_fwd | expand_bwd, old_size + n + 1,
- new_cap, new_cap, old_start);
-
- //Check forward expansion
- if(old_start == allocation_ret.first){
- enough_capacity = true;
- this->priv_storage(new_cap);
- }
- }
-
- //Reuse same buffer
- if(enough_capacity){
- const size_type elems_after = old_size - (position - this->priv_addr());
- const size_type old_length = old_size;
- if (elems_after >= n) {
- const pointer pointer_past_last = this->priv_addr() + old_size + 1;
- priv_uninitialized_copy(this->priv_addr() + (old_size - n + 1),
- pointer_past_last, pointer_past_last);
-
- this->priv_size(old_size+n);
- Traits::move(const_cast<CharT*>(container_detail::to_raw_pointer(position + n)),
- container_detail::to_raw_pointer(position),
- (elems_after - n) + 1);
- this->priv_copy(first, last, const_cast<CharT*>(container_detail::to_raw_pointer(position)));
- }
- else {
- ForwardIter mid = first;
- std::advance(mid, elems_after + 1);
-
- priv_uninitialized_copy(mid, last, this->priv_addr() + old_size + 1);
- this->priv_size(old_size + (n - elems_after));
- priv_uninitialized_copy
- (position, const_iterator(this->priv_addr() + old_length + 1),
- this->priv_addr() + this->priv_size());
- this->priv_size(this->priv_size() + elems_after);
- this->priv_copy(first, mid, const_cast<CharT*>(container_detail::to_raw_pointer(position)));
- }
- }
- else{
- pointer new_start = allocation_ret.first;
- if(!allocation_ret.second){
- //Copy data to new buffer
- size_type new_length = 0;
- //This can't throw, since characters are POD
- new_length += priv_uninitialized_copy
- (const_iterator(this->priv_addr()), position, new_start);
- new_length += priv_uninitialized_copy
- (first, last, new_start + new_length);
- new_length += priv_uninitialized_copy
- (position, const_iterator(this->priv_addr() + old_size),
- new_start + new_length);
- this->priv_construct_null(new_start + new_length);
-
- this->deallocate_block();
- this->is_short(false);
- this->priv_long_addr(new_start);
- this->priv_long_size(new_length);
- this->priv_long_storage(new_cap);
- }
- else{
- //value_type is POD, so backwards expansion is much easier
- //than with vector<T>
- value_type * const oldbuf = container_detail::to_raw_pointer(old_start);
- value_type * const newbuf = container_detail::to_raw_pointer(new_start);
- const value_type *const pos = container_detail::to_raw_pointer(position);
- const size_type before = pos - oldbuf;
-
- //First move old data
- Traits::move(newbuf, oldbuf, before);
- Traits::move(newbuf + before + n, pos, old_size - before);
- //Now initialize the new data
- priv_uninitialized_copy(first, last, new_start + before);
- this->priv_construct_null(new_start + (old_size + n));
- this->is_short(false);
- this->priv_long_addr(new_start);
- this->priv_long_size(old_size + n);
- this->priv_long_storage(new_cap);
- }
- }
- }
- }
-
- template <class Integer>
- void priv_insert_dispatch(const_iterator p, Integer n, Integer x,
- container_detail::true_)
- { insert(p, (size_type) n, (CharT) x); }
-
- template <class InputIter>
- void priv_insert_dispatch(const_iterator p, InputIter first, InputIter last,
- container_detail::false_)
- {
- typedef typename std::iterator_traits<InputIter>::iterator_category Category;
- priv_insert(p, first, last, Category());
- }
-
+*/
template <class InputIterator, class OutIterator>
void priv_copy(InputIterator first, InputIterator last, OutIterator result)
{
@@ -2412,40 +2422,6 @@
return this->priv_replace(first, last, f, l, Category());
}
-
- template <class InputIter>
- basic_string& priv_replace(const_iterator first, const_iterator last,
- InputIter f, InputIter l, std::input_iterator_tag)
- {
- for ( ; first != last && f != l; ++first, ++f)
- Traits::assign(*first, *f);
-
- if (f == l)
- this->erase(first, last);
- else
- this->insert(last, f, l);
- return *this;
- }
-
- template <class ForwardIter>
- basic_string& priv_replace(const_iterator first, const_iterator last,
- ForwardIter f, ForwardIter l,
- std::forward_iterator_tag)
- {
- difference_type n = std::distance(f, l);
- const difference_type len = last - first;
- if (len >= n) {
- this->priv_copy(f, l, const_cast<CharT*>(container_detail::to_raw_pointer(first)));
- this->erase(first + n, last);
- }
- else {
- ForwardIter m = f;
- std::advance(m, len);
- this->priv_copy(f, m, const_cast<CharT*>(container_detail::to_raw_pointer(first)));
- this->insert(last, m, l);
- }
- return *this;
- }
/// @endcond
};
Modified: trunk/boost/container/vector.hpp
==============================================================================
--- trunk/boost/container/vector.hpp (original)
+++ trunk/boost/container/vector.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -489,8 +489,10 @@
explicit vector(size_type n)
: base_t()
{
+ this->resize(n);
+/*
//Allocate
- size_type real_cap;
+ size_type real_cap = 0;
std::pair<pointer, bool> ret =
this->allocation_command(allocate_new, n, n, real_cap, this->members_.m_start);
T *new_mem = container_detail::to_raw_pointer(ret.first);
@@ -503,7 +505,7 @@
this->members_.m_start = ret.first;
this->members_.m_size = n;
this->members_.m_capacity = real_cap;
- scoped_alloc.release();
+ scoped_alloc.release();*/
}
//! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
@@ -515,7 +517,10 @@
//! <b>Complexity</b>: Linear to n.
vector(size_type n, const T& value, const allocator_type& a = allocator_type())
: base_t(a)
- { this->insert(this->cend(), n, value); }
+ {
+ this->resize(n, value);
+// this->insert(this->cend(), n, value);
+ }
//! <b>Effects</b>: Copy constructs a vector.
//!
@@ -571,7 +576,7 @@
}
else{
this->assign( container_detail::to_raw_pointer(mx.members_.m_start)
- , container_detail::to_raw_pointer(mx.members_.m_start + mx.members_.m_size));
+ , container_detail::to_raw_pointer(mx.members_.m_start) + mx.members_.m_size);
}
}
@@ -1002,13 +1007,154 @@
//!
//! <b>Complexity</b>: Linear to n.
template <class InIt>
- void assign(InIt first, InIt last)
+ void assign(InIt first, InIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InIt, size_type>::value
+ && container_detail::is_input_iterator<InIt>::value
+ >::type * = 0
+ #endif
+ )
+ {
+ //Overwrite all elements we can from [first, last)
+ iterator cur = begin();
+ for ( ; first != last && cur != end(); ++cur, ++first){
+ *cur = *first;
+ }
+
+ if (first == last){
+ //There are no more elements in the sequence, erase remaining
+ this->erase(cur, cend());
+ }
+ else{
+ //There are more elements in the range, insert the remaining ones
+ this->insert(this->cend(), first, last);
+ }
+ }
+
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ template <class FwdIt>
+ void assign(FwdIt first, FwdIt last
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<FwdIt, size_type>::value
+ && !container_detail::is_input_iterator<FwdIt>::value
+ >::type * = 0
+ )
{
- //Dispatch depending on integer/iterator
- const bool aux_boolean = container_detail::is_convertible<InIt, size_type>::value;
- typedef container_detail::bool_<aux_boolean> Result;
- this->priv_assign_dispatch(first, last, Result());
+ const size_type n = std::distance(first, last);
+
+ if(!n){
+ this->prot_destroy_all();
+ return;
+ }
+ //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;
+
+ if (n <= remaining){
+ same_buffer_start = true;
+ }
+ else{
+ //There is not enough memory, allocate a new buffer
+ size_type new_cap = this->next_capacity(n);
+ ret = this->allocation_command
+ (allocate_new | expand_fwd | expand_bwd,
+ this->size() + n, new_cap, real_cap, this->members_.m_start);
+ same_buffer_start = ret.second && this->members_.m_start == ret.first;
+ if(same_buffer_start){
+ this->members_.m_capacity = real_cap;
+ }
+ }
+
+ if(same_buffer_start){
+ T *start = container_detail::to_raw_pointer(this->members_.m_start);
+ if (this->size() >= n){
+ //There is memory, but there are more old elements than new ones
+ //Overwrite old elements with new ones
+ std::copy(first, last, start);
+ //Destroy remaining old elements
+ this->destroy_n(start + n, this->members_.m_size - n);
+ this->members_.m_size = n;
+ }
+ else{
+ //There is memory, but there are less old elements than new ones
+ //First overwrite some old elements with new ones
+ FwdIt mid = first;
+ std::advance(mid, this->size());
+ T *end = std::copy(first, mid, start);
+ //Initialize the remaining new elements in the uninitialized memory
+ ::boost::container::uninitialized_copy_or_move_alloc(this->alloc(), mid, last, end);
+ this->members_.m_size = n;
+ }
+ }
+ else if(!ret.second){
+ typename value_traits::ArrayDeallocator scoped_alloc(ret.first, this->alloc(), real_cap);
+ ::boost::container::uninitialized_copy_or_move_alloc(this->alloc(), first, last, container_detail::to_raw_pointer(ret.first));
+ scoped_alloc.release();
+ //Destroy and deallocate old buffer
+ if(this->members_.m_start != 0){
+ this->destroy_n(container_detail::to_raw_pointer(this->members_.m_start), this->members_.m_size);
+ this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
+ }
+ this->members_.m_start = ret.first;
+ this->members_.m_size = n;
+ this->members_.m_capacity = real_cap;
+ }
+ else{
+ //Backwards expansion
+ //If anything goes wrong, this object will destroy old objects
+ T *old_start = container_detail::to_raw_pointer(this->members_.m_start);
+ size_type old_size = this->members_.m_size;
+ typename value_traits::OldArrayDestructor old_values_destroyer(old_start, this->alloc(), old_size);
+ //If something goes wrong size will be 0
+ //but holding the whole buffer
+ this->members_.m_size = 0;
+ this->members_.m_start = ret.first;
+ this->members_.m_capacity = real_cap;
+
+ //Backup old buffer data
+ size_type old_offset = old_start - container_detail::to_raw_pointer(ret.first);
+ size_type first_count = container_detail::min_value(n, old_offset);
+
+ FwdIt mid = first;
+ std::advance(mid, first_count);
+ ::boost::container::uninitialized_copy_or_move_alloc
+ (this->alloc(), first, mid, container_detail::to_raw_pointer(ret.first));
+
+ if(old_offset > n){
+ //All old elements will be destroyed by "old_values_destroyer"
+ this->members_.m_size = n;
+ }
+ else{
+ //We have constructed objects from the new begin until
+ //the old end so release the rollback destruction
+ old_values_destroyer.release();
+ this->members_.m_start = ret.first;
+ this->members_.m_size = first_count + old_size;
+ //Now overwrite the old values
+ size_type second_count = container_detail::min_value(old_size, n - first_count);
+ FwdIt mid2 = mid;
+ std::advance(mid2, second_count);
+ std::copy(mid, mid2, old_start);
+
+ //Check if we still have to append elements in the
+ //uninitialized end
+ if(second_count == old_size){
+ std::copy(mid2, last, old_start + old_size);
+ }
+ else{
+ //We have to destroy some old values
+ this->destroy_n
+ (old_start + second_count, old_size - second_count);
+ this->members_.m_size = n;
+ }
+ this->members_.m_size = n;
+ }
+ }
}
+ #endif
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts a copy of x at the end of the vector.
@@ -1051,7 +1197,7 @@
else{
typedef container_detail::advanced_insert_aux_emplace<A, T*, Args...> type;
type &&proxy = type(this->alloc(), ::boost::forward<Args>(args)...);
- priv_range_insert(back_pos, 1, proxy);
+ this->priv_forward_range_insert(back_pos, 1, proxy);
}
}
@@ -1072,7 +1218,7 @@
size_type pos_n = position - cbegin();
typedef container_detail::advanced_insert_aux_emplace<A, T*, Args...> type;
type &&proxy = type(this->alloc(), ::boost::forward<Args>(args)...);
- priv_range_insert(position.get_ptr(), 1, proxy);
+ this->priv_forward_range_insert(position.get_ptr(), 1, proxy);
return iterator(this->members_.m_start + pos_n);
}
@@ -1093,7 +1239,7 @@
container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
<A, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- priv_range_insert(back_pos, 1, proxy); \
+ this->priv_forward_range_insert(back_pos, 1, proxy); \
} \
} \
\
@@ -1105,7 +1251,7 @@
container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
<A, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- priv_range_insert(container_detail::to_raw_pointer(pos.get_ptr()), 1, proxy); \
+ this->priv_forward_range_insert(container_detail::to_raw_pointer(pos.get_ptr()), 1,proxy);\
return iterator(this->members_.m_start + pos_n); \
} \
//!
@@ -1152,32 +1298,63 @@
BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator)
#endif
- //! <b>Requires</b>: pos must be a valid iterator of *this.
+ //! <b>Requires</b>: p must be a valid iterator of *this.
//!
//! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
//!
+ //! <b>Returns</b>: an iterator to the first inserted element or pos if first == last.
+ //!
//! <b>Throws</b>: If memory allocation throws, T's constructor from a
//! dereferenced InpIt throws or T's copy/move constructor/assignment throws.
//!
//! <b>Complexity</b>: Linear to std::distance [first, last).
template <class InIt>
- void insert(const_iterator pos, InIt first, InIt last)
+ iterator insert(const_iterator pos, InIt first, InIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InIt, size_type>::value
+ && container_detail::is_input_iterator<InIt>::value
+ >::type * = 0
+ #endif
+ )
{
- //Dispatch depending on integer/iterator
- const bool aux_boolean = container_detail::is_convertible<InIt, size_type>::value;
- typedef container_detail::bool_<aux_boolean> Result;
- this->priv_insert_dispatch(pos, first, last, Result());
+ const size_type n_pos = pos - this->cbegin();
+ iterator it(pos.get_ptr());
+ for(;first != last; ++first){
+ it = this->emplace(it, *first);
+ ++it;
+ }
+ return this->begin() + n_pos;
+ }
+
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ template <class FwdIt>
+ iterator insert(const_iterator pos, FwdIt first, FwdIt last
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<FwdIt, size_type>::value
+ && !container_detail::is_input_iterator<FwdIt>::value
+ >::type * = 0
+ )
+ {
+ const size_type n_pos = pos - this->cbegin();
+ const size_type n = std::distance(first, last);
+ container_detail::advanced_insert_aux_proxy<A, FwdIt, T*> proxy(this->alloc(), first, last);
+ this->priv_forward_range_insert(pos.get_ptr(), n, proxy);
+ return this->begin() + n_pos;
}
+ #endif
- //! <b>Requires</b>: pos must be a valid iterator of *this.
+ //! <b>Requires</b>: p must be a valid iterator of *this.
//!
//! <b>Effects</b>: Insert n copies of x before pos.
//!
+ //! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
+ //!
//! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to n.
- void insert(const_iterator p, size_type n, const T& x)
- { this->insert(p, cvalue_iterator(x, n), cvalue_iterator()); }
+ iterator insert(const_iterator p, size_type n, const T& x)
+ { return this->insert(p, cvalue_iterator(x, n), cvalue_iterator()); }
//! <b>Effects</b>: Removes the last element from the vector.
//!
@@ -1262,10 +1439,10 @@
this->erase(const_iterator(this->members_.m_start + new_size), this->end());
}
else{
- size_type n = new_size - this->size();
+ const size_type n = new_size - this->size();
this->reserve(new_size);
container_detail::default_construct_aux_proxy<A, T*> proxy(this->alloc(), n);
- priv_range_insert(this->cend().get_ptr(), n, proxy);
+ this->priv_forward_range_insert(this->cend().get_ptr(), n, proxy);
}
}
@@ -1399,27 +1576,7 @@
}
}
- template <class FwdIt>
- void priv_range_insert(const_iterator pos, FwdIt first, FwdIt last, std::forward_iterator_tag)
- {
- if(first != last){
- const size_type n = std::distance(first, last);
- container_detail::advanced_insert_aux_proxy<A, FwdIt, T*> proxy(this->alloc(), first, last);
- priv_range_insert(pos.get_ptr(), n, proxy);
- }
- }
-
- template <class InIt>
- void priv_range_insert(const_iterator pos, InIt first, InIt last, std::input_iterator_tag)
- {
- iterator it(pos.get_ptr());
- for(;first != last; ++first){
- it = this->emplace(it, *first);
- ++it;
- }
- }
-
- void priv_range_insert(pointer pos, const size_type n, advanced_insert_aux_int_t &interf)
+ void priv_forward_range_insert(pointer pos, const size_type n, advanced_insert_aux_int_t &interf)
{
//Check if we have enough memory or try to expand current memory
size_type remaining = this->members_.m_capacity - this->members_.m_size;
@@ -1575,7 +1732,7 @@
// |_>_>_>_>_>^
//
//
- //New situation in Case B (hole_size >= 0):
+ //New situation in Case B (hole_size > 0):
// range is moved through uninitialized moves
//
// first_pos last_pos old_limit
@@ -2001,173 +2158,10 @@
}
}
- template <class InIt>
- void priv_assign_aux(InIt first, InIt last, std::input_iterator_tag)
- {
- //Overwrite all elements we can from [first, last)
- iterator cur = begin();
- for ( ; first != last && cur != end(); ++cur, ++first){
- *cur = *first;
- }
-
- if (first == last){
- //There are no more elements in the sequence, erase remaining
- this->erase(cur, cend());
- }
- else{
- //There are more elements in the range, insert the remaining ones
- this->insert(this->cend(), first, last);
- }
- }
-
- template <class FwdIt>
- void priv_assign_aux(FwdIt first, FwdIt last, std::forward_iterator_tag)
- {
- size_type n = std::distance(first, last);
- if(!n){
- this->prot_destroy_all();
- return;
- }
- //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;
-
- if (n <= remaining){
- same_buffer_start = true;
- }
- else{
- //There is not enough memory, allocate a new buffer
- size_type new_cap = this->next_capacity(n);
- ret = this->allocation_command
- (allocate_new | expand_fwd | expand_bwd,
- this->size() + n, new_cap, real_cap, this->members_.m_start);
- same_buffer_start = ret.second && this->members_.m_start == ret.first;
- if(same_buffer_start){
- this->members_.m_capacity = real_cap;
- }
- }
-
- if(same_buffer_start){
- T *start = container_detail::to_raw_pointer(this->members_.m_start);
- if (this->size() >= n){
- //There is memory, but there are more old elements than new ones
- //Overwrite old elements with new ones
- std::copy(first, last, start);
- //Destroy remaining old elements
- this->destroy_n(start + n, this->members_.m_size - n);
- this->members_.m_size = n;
- }
- else{
- //There is memory, but there are less old elements than new ones
- //First overwrite some old elements with new ones
- FwdIt mid = first;
- std::advance(mid, this->size());
- // iG T *end = std::copy(first, mid, start);
- T *end = std::copy(first, mid, start);
- //Initialize the remaining new elements in the uninitialized memory
- ::boost::container::uninitialized_copy_or_move_alloc(this->alloc(), mid, last, end);
- this->members_.m_size = n;
- }
- }
- else if(!ret.second){
- typename value_traits::ArrayDeallocator scoped_alloc(ret.first, this->alloc(), real_cap);
- ::boost::container::uninitialized_copy_or_move_alloc(this->alloc(), first, last, container_detail::to_raw_pointer(ret.first));
- scoped_alloc.release();
- //Destroy and deallocate old buffer
- if(this->members_.m_start != 0){
- this->destroy_n(container_detail::to_raw_pointer(this->members_.m_start), this->members_.m_size);
- this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
- }
- this->members_.m_start = ret.first;
- this->members_.m_size = n;
- this->members_.m_capacity = real_cap;
- }
- else{
- //Backwards expansion
- //If anything goes wrong, this object will destroy old objects
- T *old_start = container_detail::to_raw_pointer(this->members_.m_start);
- size_type old_size = this->members_.m_size;
- typename value_traits::OldArrayDestructor old_values_destroyer(old_start, this->alloc(), old_size);
- //If something goes wrong size will be 0
- //but holding the whole buffer
- this->members_.m_size = 0;
- this->members_.m_start = ret.first;
- this->members_.m_capacity = real_cap;
-
- //Backup old buffer data
- size_type old_offset = old_start - container_detail::to_raw_pointer(ret.first);
- size_type first_count = container_detail::min_value(n, old_offset);
-
- FwdIt mid = first;
- std::advance(mid, first_count);
- ::boost::container::uninitialized_copy_or_move_alloc
- (this->alloc(), first, mid, container_detail::to_raw_pointer(ret.first));
-
- if(old_offset > n){
- //All old elements will be destroyed by "old_values_destroyer"
- this->members_.m_size = n;
- }
- else{
- //We have constructed objects from the new begin until
- //the old end so release the rollback destruction
- old_values_destroyer.release();
- this->members_.m_start = ret.first;
- this->members_.m_size = first_count + old_size;
- //Now overwrite the old values
- size_type second_count = container_detail::min_value(old_size, n - first_count);
- FwdIt mid2 = mid;
- std::advance(mid2, second_count);
- // iG std::copy(mid, mid2, old_start);
- std::copy(mid, mid2, old_start);
-
- //Check if we still have to append elements in the
- //uninitialized end
- if(second_count == old_size){
- // iG std::copy(mid2, last, old_start + old_size);
- std::copy(mid2, last, old_start + old_size);
- }
- else{
- //We have to destroy some old values
- this->destroy_n
- (old_start + second_count, old_size - second_count);
- this->members_.m_size = n;
- }
- this->members_.m_size = n;
- }
- }
- }
-
- template <class Integer>
- void priv_assign_dispatch(Integer n, Integer val, container_detail::true_)
- { this->assign((size_type) n, (value_type)val); }
-
- template <class InIt>
- void priv_assign_dispatch(InIt first, InIt last, container_detail::false_)
- {
- //Dispatch depending on integer/iterator
- typedef typename std::iterator_traits<InIt>::iterator_category ItCat;
- this->priv_assign_aux(first, last, ItCat());
- }
-
- template <class Integer>
- void priv_insert_dispatch(const_iterator pos, Integer n, Integer val, container_detail::true_)
- { this->insert(pos, (size_type)n, (T)val); }
-
- template <class InIt>
- void priv_insert_dispatch(const_iterator pos, InIt first,
- InIt last, container_detail::false_)
- {
- //Dispatch depending on integer/iterator
- typedef typename std::iterator_traits<InIt>::iterator_category ItCat;
- this->priv_range_insert(pos, first, last, ItCat());
- }
-
void priv_check_range(size_type n) const
{
//If n is out of range, throw an out_of_range exception
- if (n >= size())
+ if (n >= this->size())
throw std::out_of_range("vector::at");
}
Modified: trunk/libs/container/doc/container.qbk
==============================================================================
--- trunk/libs/container/doc/container.qbk (original)
+++ trunk/libs/container/doc/container.qbk 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -617,7 +617,7 @@
[section:release_notes_boost_1_52_00 Boost 1.52 Release]
* Fixed bugs
- [@https://svn.boost.org/trac/boost/ticket/6606 #6606],
+ [@https://svn.boost.org/trac/boost/ticket/6615 #6615],
[@https://svn.boost.org/trac/boost/ticket/7139 #7139],
[@https://svn.boost.org/trac/boost/ticket/7215 #7215],
[@https://svn.boost.org/trac/boost/ticket/7232 #7232],
@@ -641,11 +641,11 @@
* Added Scoped Allocator Model support.
* Fixed bugs
+ [@https://svn.boost.org/trac/boost/ticket/6606 #6606],
[@https://svn.boost.org/trac/boost/ticket/6533 #6533],
[@https://svn.boost.org/trac/boost/ticket/6536 #6536],
[@https://svn.boost.org/trac/boost/ticket/6566 #6566],
[@https://svn.boost.org/trac/boost/ticket/6575 #6575],
- [@https://svn.boost.org/trac/boost/ticket/6615 #6615],
[endsect]
Modified: trunk/libs/container/proj/to-do.txt
==============================================================================
--- trunk/libs/container/proj/to-do.txt (original)
+++ trunk/libs/container/proj/to-do.txt 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -34,6 +34,17 @@
check move if noexcept conditions in vector, deque and stable_vector
+Add noexcept testing using static_assert (Howard Hinnants's suggestion):
+
+ #include <type_traits>
+
+ struct A
+ {
+ void foo() noexcept;
+ };
+
+ static_assert(noexcept(std::declval<A&>().foo()), "A::foo() should be noexcept");
+
Detect always equal or unequal allocators at compiler time. operator== returns true_type or false_type
change virtual functions with pointers to avoid template instantiation for every type
Modified: trunk/libs/container/proj/vc7ide/allocator_traits_test.vcproj
==============================================================================
--- trunk/libs/container/proj/vc7ide/allocator_traits_test.vcproj (original)
+++ trunk/libs/container/proj/vc7ide/allocator_traits_test.vcproj 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -132,6 +132,9 @@
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93815995-89BD-b043-5E8B-65FBE52E2AFB}">
+ <File
+ RelativePath="..\..\..\..\boost\container\detail\node_alloc_holder.hpp">
+ </File>
</Filter>
</Files>
<Globals>
Modified: trunk/libs/container/proj/vc7ide/container.sln
==============================================================================
--- trunk/libs/container/proj/vc7ide/container.sln (original)
+++ trunk/libs/container/proj/vc7ide/container.sln 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -51,6 +51,10 @@
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hash_table_test", "hash_table_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792606}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@@ -111,6 +115,10 @@
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Debug.Build.0 = Debug|Win32
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.ActiveCfg = Release|Win32
{B4E9FB12-7D7C-4461-83A9-5EB2C78E608F}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
Modified: trunk/libs/container/proj/vc7ide/container.vcproj
==============================================================================
--- trunk/libs/container/proj/vc7ide/container.vcproj (original)
+++ trunk/libs/container/proj/vc7ide/container.vcproj 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -146,6 +146,9 @@
RelativePath="..\..\test\expand_bwd_test_template.hpp">
</File>
<File
+ RelativePath="..\..\test\forward_to_input_iterator.hpp">
+ </File>
+ <File
RelativePath="..\..\test\heap_allocator_v1.hpp">
</File>
<File
@@ -261,7 +264,7 @@
RelativePath="..\..\..\..\boost\container\detail\math_functions.hpp">
</File>
<File
- RelativePath="..\..\..\..\boost\container\allocator\memory_util.hpp">
+ RelativePath="..\..\..\..\boost\container\detail\memory_util.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\mpl.hpp">
Modified: trunk/libs/container/test/check_equal_containers.hpp
==============================================================================
--- trunk/libs/container/test/check_equal_containers.hpp (original)
+++ trunk/libs/container/test/check_equal_containers.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -12,6 +12,8 @@
#define BOOST_CONTAINER_TEST_CHECK_EQUAL_CONTAINER_HPP
#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/pair.hpp>
+#include <boost/container/detail/mpl.hpp>
#include <functional>
#include <iostream>
#include <algorithm>
@@ -20,6 +22,24 @@
namespace container {
namespace test{
+template< class T1, class T2>
+bool CheckEqual( const T1 &t1, const T2 &t2
+ , typename boost::container::container_detail::enable_if_c
+ <!boost::container::container_detail::is_pair<T1>::value &&
+ !boost::container::container_detail::is_pair<T2>::value
+ >::type* = 0)
+{ return t1 == t2; }
+
+template< class Pair1, class Pair2>
+bool CheckEqual( const Pair1 &pair1, const Pair2 &pair2
+ , typename boost::container::container_detail::enable_if_c
+ <boost::container::container_detail::is_pair<Pair1>::value &&
+ boost::container::container_detail::is_pair<Pair2>::value
+ >::type* = 0)
+{
+ return CheckEqual(pair1.first, pair2.first) && CheckEqual(pair1.second, pair2.second);
+}
+
//Function to check if both containers are equal
template<class MyBoostCont
,class MyStdCont>
@@ -38,10 +58,13 @@
}
std::size_t i = 0;
for(; itboost != itboostend; ++itboost, ++itstd, ++i){
- value_type val(*itstd);
+
+ if(!CheckEqual(*itstd, *itboost))
+ return false;
+/* value_type val(*itstd);
const value_type &v = *itboost;
if(v != val)
- return false;
+ return false;*/
}
return true;
}
Modified: trunk/libs/container/test/deque_test.cpp
==============================================================================
--- trunk/libs/container/test/deque_test.cpp (original)
+++ trunk/libs/container/test/deque_test.cpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -63,7 +63,7 @@
typedef typename V1::value_type IntType;
std::size_t size = cntdeque->size();
stddeque->insert(stddeque->end(), 50, 1);
- cntdeque->insert(cntdeque->end(), 50, 1);
+ cntdeque->insert(cntdeque->end(), 50, IntType(1));
if(!test::CheckEqualContainers(cntdeque, stddeque)) return false;
{
IntType move_me(1);
Added: trunk/libs/container/test/input_from_forward_iterator.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/container/test/input_from_forward_iterator.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -0,0 +1,80 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_TEST_FORWARD_TO_INPUT_ITERATOR_HPP
+#define BOOST_CONTAINER_TEST_FORWARD_TO_INPUT_ITERATOR_HPP
+
+#include <iterator>
+
+namespace boost{
+namespace container {
+namespace test{
+
+template<class FwdIterator>
+class input_iterator_wrapper
+ : public std::iterator< std::input_iterator_tag
+ , typename std::iterator_traits<FwdIterator>::value_type
+ , typename std::iterator_traits<FwdIterator>::difference_type
+ , typename std::iterator_traits<FwdIterator>::pointer
+ , typename std::iterator_traits<FwdIterator>::reference
+ >
+{
+ FwdIterator m_it;
+
+ public:
+ input_iterator_wrapper()
+ : m_it(0)
+ {}
+
+ explicit input_iterator_wrapper(FwdIterator it)
+ : m_it(it)
+ {}
+
+ //Default copy constructor...
+ //input_iterator_wrapper(const input_iterator_wrapper&);
+
+ //Default assignment...
+ //input_iterator_wrapper &operator=(const input_iterator_wrapper&);
+
+ //Default destructor...
+ //~input_iterator_wrapper();
+
+ typename std::iterator_traits<FwdIterator>::reference operator*() const
+ { return *m_it; }
+
+ typename std::iterator_traits<FwdIterator>::pointer operator->() const
+ { return m_it.operator->(); }
+
+ input_iterator_wrapper& operator++()
+ { ++m_it; return *this; }
+
+ input_iterator_wrapper operator++(int )
+ {
+ input_iterator_wrapper tmp(m_it);
+ ++m_it;
+ return tmp;
+ }
+
+ friend bool operator==(const input_iterator_wrapper &left, const input_iterator_wrapper &right)
+ { return left.m_it == right.m_it; }
+
+ friend bool operator!=(const input_iterator_wrapper &left, const input_iterator_wrapper &right)
+ { return left.m_it != right.m_it; }
+};
+
+template<class FwdIterator>
+input_iterator_wrapper<FwdIterator> make_input_from_forward_iterator(const FwdIterator &it)
+{ return input_iterator_wrapper<FwdIterator>(it); }
+
+} //namespace test{
+} //namespace container {
+} //namespace boost{
+
+#endif //BOOST_CONTAINER_TEST_FORWARD_TO_INPUT_ITERATOR_HPP
Modified: trunk/libs/container/test/list_test.hpp
==============================================================================
--- trunk/libs/container/test/list_test.hpp (original)
+++ trunk/libs/container/test/list_test.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -18,6 +18,7 @@
#include <vector>
#include <functional>
#include "print_container.hpp"
+#include "input_from_forward_iterator.hpp"
#include <boost/move/move.hpp>
#include <string>
@@ -177,7 +178,20 @@
aux_vect2[i] = -1;
}
boostlist->assign(boost::make_move_iterator(&aux_vect[0])
- ,boost::make_move_iterator(&aux_vect[50]));
+ ,boost::make_move_iterator(&aux_vect[50]));
+ stdlist->assign(&aux_vect2[0], &aux_vect2[50]);
+ if(!CheckEqualContainers(boostlist, stdlist)) return 1;
+
+ for(int i = 0; i < 50; ++i){
+ IntType move_me(-1);
+ aux_vect[i] = boost::move(move_me);
+ }
+
+ for(int i = 0; i < 50; ++i){
+ aux_vect2[i] = -1;
+ }
+ boostlist->assign(boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[0]))
+ ,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[50])));
stdlist->assign(&aux_vect2[0], &aux_vect2[50]);
if(!CheckEqualContainers(boostlist, stdlist)) return 1;
}
@@ -206,10 +220,36 @@
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
- boostlist->insert(boostlist->begin()
+ typename MyBoostList::iterator old_begin = boostlist->begin();
+ typename MyBoostList::iterator it_insert =
+ boostlist->insert(boostlist->begin()
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(&aux_vect[50]));
+ if(it_insert != boostlist->begin() || std::distance(it_insert, old_begin) != 50)
+ return 1;
+
stdlist->insert(stdlist->begin(), &aux_vect2[0], &aux_vect2[50]);
+ if(!CheckEqualContainers(boostlist, stdlist))
+ return 1;
+
+ for(int i = 0; i < 50; ++i){
+ IntType move_me(-1);
+ aux_vect[i] = boost::move(move_me);
+ }
+
+ for(int i = 0; i < 50; ++i){
+ aux_vect2[i] = -1;
+ }
+
+ old_begin = boostlist->begin();
+ it_insert = boostlist->insert(boostlist->end()
+ ,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[0]))
+ ,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[50])));
+ if(std::distance(it_insert, boostlist->end()) != 50)
+ return 1;
+ stdlist->insert(stdlist->end(), &aux_vect2[0], &aux_vect2[50]);
+ if(!CheckEqualContainers(boostlist, stdlist))
+ return 1;
}
boostlist->unique();
Modified: trunk/libs/container/test/movable_int.hpp
==============================================================================
--- trunk/libs/container/test/movable_int.hpp (original)
+++ trunk/libs/container/test/movable_int.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -73,6 +73,12 @@
int get_int() const
{ return m_int; }
+ friend bool operator==(const movable_int &l, int r)
+ { return l.get_int() == r; }
+
+ friend bool operator==(int l, const movable_int &r)
+ { return l == r.get_int(); }
+
private:
int m_int;
};
@@ -144,6 +150,12 @@
int get_int() const
{ return m_int; }
+ friend bool operator==(const movable_and_copyable_int &l, int r)
+ { return l.get_int() == r; }
+
+ friend bool operator==(int l, const movable_and_copyable_int &r)
+ { return l == r.get_int(); }
+
private:
int m_int;
};
@@ -202,6 +214,12 @@
int get_int() const
{ return m_int; }
+ friend bool operator==(const copyable_int &l, int r)
+ { return l.get_int() == r; }
+
+ friend bool operator==(int l, const copyable_int &r)
+ { return l == r.get_int(); }
+
private:
int m_int;
};
@@ -256,10 +274,17 @@
int get_int() const
{ return m_int; }
+ friend bool operator==(const non_copymovable_int &l, int r)
+ { return l.get_int() == r; }
+
+ friend bool operator==(int l, const non_copymovable_int &r)
+ { return l == r.get_int(); }
+
private:
int m_int;
};
+
} //namespace test {
} //namespace container {
} //namespace boost {
Modified: trunk/libs/container/test/set_test.hpp
==============================================================================
--- trunk/libs/container/test/set_test.hpp (original)
+++ trunk/libs/container/test/set_test.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -88,13 +88,13 @@
IntType move_me(i);
aux_vect3[i] = boost::move(move_me);
}
-/*
- MyBoostSet *boostset3 = MyBoostSet
+
+ MyBoostSet *boostset3 = new MyBoostSet
( ordered_unique_range
, boost::make_move_iterator(&aux_vect[0])
, boost::make_move_iterator(aux_vect + 50));
MyStdSet *stdset3 = new MyStdSet(aux_vect2, aux_vect2 + 50);
- MyBoostMultiSet *boostmultiset3 = MyBoostMultiSet
+ MyBoostMultiSet *boostmultiset3 = new MyBoostMultiSet
( ordered_range
, boost::make_move_iterator(&aux_vect3[0])
, boost::make_move_iterator(aux_vect3 + 50));
@@ -108,15 +108,15 @@
std::cout << "Error in construct<MyBoostMultiSet>(MyBoostMultiSet3)" << std::endl;
return 1;
}
-*/
+
delete boostset2;
delete boostmultiset2;
delete stdset2;
delete stdmultiset2;
- //delete boostset3;
- //delete boostmultiset3;
- //delete stdset3;
- //delete stdmultiset3;
+ delete boostset3;
+ delete boostmultiset3;
+ delete stdset3;
+ delete stdmultiset3;
}
int i, j;
Modified: trunk/libs/container/test/vector_test.hpp
==============================================================================
--- trunk/libs/container/test/vector_test.hpp (original)
+++ trunk/libs/container/test/vector_test.hpp 2012-09-01 07:01:03 EDT (Sat, 01 Sep 2012)
@@ -8,6 +8,9 @@
//
//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_CONTAINER_TEST_VECTOR_TEST_HEADER
+#define BOOST_CONTAINER_TEST_VECTOR_TEST_HEADER
+
#include <boost/container/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
@@ -24,6 +27,7 @@
#include <string>
#include <vector>
#include "emplace_test.hpp"
+#include "input_from_forward_iterator.hpp"
namespace boost{
namespace container {
@@ -133,10 +137,11 @@
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
-
- boostvector->insert(boostvector->end()
+ typename MyBoostVector::iterator insert_it =
+ boostvector->insert(boostvector->end()
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(aux_vect + 50));
+ if(std::size_t(std::distance(insert_it, boostvector->end())) != 50) return 1;
stdvector->insert(stdvector->end(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
@@ -156,9 +161,30 @@
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
- boostvector->insert(boostvector->begin()
+ typename MyBoostVector::iterator insert_it =
+ boostvector->insert(boostvector->begin()
,boost::make_move_iterator(&aux_vect[0])
,boost::make_move_iterator(aux_vect + 50));
+ if(boostvector->begin() != insert_it) return 1;
+ stdvector->insert(stdvector->begin(), aux_vect2, aux_vect2 + 50);
+ if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
+
+ for(int i = 0; i < 50; ++i){
+ IntType new_int(-1);
+ aux_vect[i] = boost::move(new_int);
+ }
+
+ for(int i = 0; i < 50; ++i){
+ aux_vect2[i] = -1;
+ }
+ //Now try with input iterators instead
+ insert_it = boostvector->insert(boostvector->begin()
+// ,boost::make_move_iterator(make_input_from_forward_iterator(&aux_vect[0]))
+// ,boost::make_move_iterator(make_input_from_forward_iterator(aux_vect + 50))
+ ,boost::make_move_iterator(&aux_vect[0])
+ ,boost::make_move_iterator(aux_vect + 50)
+ );
+ if(boostvector->begin() != insert_it) return 1;
stdvector->insert(stdvector->begin(), aux_vect2, aux_vect2 + 50);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
}
@@ -204,12 +230,20 @@
//Test insertion from list
{
std::list<int> l(50, int(1));
- boostvector->insert(boostvector->begin(), l.begin(), l.end());
+ typename MyBoostVector::iterator it_insert =
+ boostvector->insert(boostvector->begin(), l.begin(), l.end());
+ if(boostvector->begin() != it_insert) return 1;
stdvector->insert(stdvector->begin(), l.begin(), l.end());
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector->assign(l.begin(), l.end());
stdvector->assign(l.begin(), l.end());
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
+
+ boostvector->clear();
+ stdvector->clear();
+ boostvector->assign(make_input_from_forward_iterator(l.begin()), make_input_from_forward_iterator(l.end()));
+ stdvector->assign(l.begin(), l.end());
+ if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
}
/*
std::size_t cap = boostvector->capacity();
@@ -252,3 +286,6 @@
} //namespace boost{
#include <boost/container/detail/config_end.hpp>
+
+#endif //BOOST_CONTAINER_TEST_VECTOR_TEST_HEADER
+
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