Merge from trunk

[SVN r80806]
This commit is contained in:
Ion Gaztañaga
2012-10-01 11:32:04 +00:00
parent 0519b950f4
commit 4d8b2ed6a3
19 changed files with 2433 additions and 2245 deletions

View File

@@ -29,12 +29,12 @@ doxygen autodoc
\"BOOST_CONTAINER_DOXYGEN_INVOKED\" \\ \"BOOST_CONTAINER_DOXYGEN_INVOKED\" \\
\"BOOST_CONTAINER_IMPDEF(T)=implementation_defined\" \\ \"BOOST_CONTAINER_IMPDEF(T)=implementation_defined\" \\
\"BOOST_CONTAINER_SEEDOC(T)=see_documentation\" \\ \"BOOST_CONTAINER_SEEDOC(T)=see_documentation\" \\
\"BOOST_CONTAINER_NOEXCEPT=noexcept\" \\
\"BOOST_CONTAINER_NOEXCEPT_IF(T)=noexcept(T)\" \\
\"BOOST_RV_REF(T)=T &&\" \\ \"BOOST_RV_REF(T)=T &&\" \\
\"BOOST_RV_REF_BEG=\" \\ \"BOOST_RV_REF_BEG=\" \\
\"BOOST_RV_REF_END=&&\" \\ \"BOOST_RV_REF_END=&&\" \\
\"BOOST_COPY_ASSIGN_REF(T)=const T &\" \\ \"BOOST_COPY_ASSIGN_REF(T)=const T &\" \\
\"BOOST_RV_REF_2_TEMPL_ARGS(T,a,b)=T<a, b> &&\" \\
\"BOOST_RV_REF_3_TEMPL_ARGS(T,a,b,c)=T<a,b,c>T<a,b,c> &&\" \\
\"BOOST_FWD_REF(a)=a &&\"" \"BOOST_FWD_REF(a)=a &&\""
<xsl:param>"boost.doxygen.reftitle=Boost.Container Header Reference" <xsl:param>"boost.doxygen.reftitle=Boost.Container Header Reference"
; ;

View File

@@ -623,7 +623,8 @@ use [*Boost.Container]? There are several reasons for that:
[@https://svn.boost.org/trac/boost/ticket/7139 #7139], [@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/7215 #7215],
[@https://svn.boost.org/trac/boost/ticket/7232 #7232], [@https://svn.boost.org/trac/boost/ticket/7232 #7232],
[@https://svn.boost.org/trac/boost/ticket/7269 #7269]. [@https://svn.boost.org/trac/boost/ticket/7269 #7269],
[@https://svn.boost.org/trac/boost/ticket/7439 #7439].
* Implemented LWG Issue #149 (range insertion now returns an iterator) & cleaned up insertion code in most containers * Implemented LWG Issue #149 (range insertion now returns an iterator) & cleaned up insertion code in most containers
* Corrected aliasing errors. * Corrected aliasing errors.

View File

@@ -49,85 +49,85 @@ namespace container {
//vector class //vector class
template <class T template <class T
,class A = std::allocator<T> > ,class Allocator = std::allocator<T> >
class vector; class vector;
//vector class //vector class
template <class T template <class T
,class A = std::allocator<T> > ,class Allocator = std::allocator<T> >
class stable_vector; class stable_vector;
//vector class //vector class
template <class T template <class T
,class A = std::allocator<T> > ,class Allocator = std::allocator<T> >
class deque; class deque;
//list class //list class
template <class T template <class T
,class A = std::allocator<T> > ,class Allocator = std::allocator<T> >
class list; class list;
//slist class //slist class
template <class T template <class T
,class A = std::allocator<T> > ,class Allocator = std::allocator<T> >
class slist; class slist;
//set class //set class
template <class T template <class Key
,class Pred = std::less<T> ,class Compare = std::less<Key>
,class A = std::allocator<T> > ,class Allocator = std::allocator<Key> >
class set; class set;
//multiset class //multiset class
template <class T template <class Key
,class Pred = std::less<T> ,class Compare = std::less<Key>
,class A = std::allocator<T> > ,class Allocator = std::allocator<Key> >
class multiset; class multiset;
//map class //map class
template <class Key template <class Key
,class T ,class T
,class Pred = std::less<Key> ,class Compare = std::less<Key>
,class A = std::allocator<std::pair<const Key, T> > > ,class Allocator = std::allocator<std::pair<const Key, T> > >
class map; class map;
//multimap class //multimap class
template <class Key template <class Key
,class T ,class T
,class Pred = std::less<Key> ,class Compare = std::less<Key>
,class A = std::allocator<std::pair<const Key, T> > > ,class Allocator = std::allocator<std::pair<const Key, T> > >
class multimap; class multimap;
//flat_set class //flat_set class
template <class T template <class Key
,class Pred = std::less<T> ,class Compare = std::less<Key>
,class A = std::allocator<T> > ,class Allocator = std::allocator<Key> >
class flat_set; class flat_set;
//flat_multiset class //flat_multiset class
template <class T template <class Key
,class Pred = std::less<T> ,class Compare = std::less<Key>
,class A = std::allocator<T> > ,class Allocator = std::allocator<Key> >
class flat_multiset; class flat_multiset;
//flat_map class //flat_map class
template <class Key template <class Key
,class T ,class T
,class Pred = std::less<Key> ,class Compare = std::less<Key>
,class A = std::allocator<std::pair<Key, T> > > ,class Allocator = std::allocator<std::pair<Key, T> > >
class flat_map; class flat_map;
//flat_multimap class //flat_multimap class
template <class Key template <class Key
,class T ,class T
,class Pred = std::less<Key> ,class Compare = std::less<Key>
,class A = std::allocator<std::pair<Key, T> > > ,class Allocator = std::allocator<std::pair<Key, T> > >
class flat_multimap; class flat_multimap;
//basic_string class //basic_string class
template <class CharT template <class CharT
,class Traits = std::char_traits<CharT> ,class Traits = std::char_traits<CharT>
,class A = std::allocator<CharT> > ,class Allocator = std::allocator<CharT> >
class basic_string; class basic_string;
//! Type used to tag that the input range is //! Type used to tag that the input range is

View File

@@ -67,17 +67,17 @@ namespace container {
/// @cond /// @cond
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class A = std::allocator<T> > template <class T, class Allocator = std::allocator<T> >
#else #else
template <class T, class A> template <class T, class Allocator>
#endif #endif
class deque; class deque;
template <class T, class A> template <class T, class Allocator>
struct deque_value_traits struct deque_value_traits
{ {
typedef T value_type; typedef T value_type;
typedef A allocator_type; typedef Allocator allocator_type;
static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value; static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
static const bool trivial_dctr_after_move = false; static const bool trivial_dctr_after_move = false;
//::boost::has_trivial_destructor_after_move<value_type>::value || trivial_dctr; //::boost::has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
@@ -96,12 +96,12 @@ inline std::size_t deque_buf_size(std::size_t size)
// Deque base class. It has two purposes. First, its constructor // Deque base class. It has two purposes. First, its constructor
// and destructor allocate (but don't initialize) storage. This makes // and destructor allocate (but don't initialize) storage. This makes
// exception safety easier. // exception safety easier.
template <class T, class A> template <class T, class Allocator>
class deque_base class deque_base
{ {
BOOST_COPYABLE_AND_MOVABLE(deque_base) BOOST_COPYABLE_AND_MOVABLE(deque_base)
public: public:
typedef allocator_traits<A> val_alloc_traits_type; typedef allocator_traits<Allocator> val_alloc_traits_type;
typedef typename val_alloc_traits_type::value_type val_alloc_val; typedef typename val_alloc_traits_type::value_type val_alloc_val;
typedef typename val_alloc_traits_type::pointer val_alloc_ptr; typedef typename val_alloc_traits_type::pointer val_alloc_ptr;
typedef typename val_alloc_traits_type::const_pointer val_alloc_cptr; typedef typename val_alloc_traits_type::const_pointer val_alloc_cptr;
@@ -117,13 +117,13 @@ class deque_base
typedef typename ptr_alloc_traits_type::const_pointer ptr_alloc_cptr; typedef typename ptr_alloc_traits_type::const_pointer ptr_alloc_cptr;
typedef typename ptr_alloc_traits_type::reference ptr_alloc_ref; typedef typename ptr_alloc_traits_type::reference ptr_alloc_ref;
typedef typename ptr_alloc_traits_type::const_reference ptr_alloc_cref; typedef typename ptr_alloc_traits_type::const_reference ptr_alloc_cref;
typedef A allocator_type; typedef Allocator allocator_type;
typedef allocator_type stored_allocator_type; typedef allocator_type stored_allocator_type;
typedef val_alloc_size size_type; typedef val_alloc_size size_type;
protected: protected:
typedef deque_value_traits<T, A> traits_t; typedef deque_value_traits<T, Allocator> traits_t;
typedef ptr_alloc_t map_allocator_type; typedef ptr_alloc_t map_allocator_type;
static size_type s_buffer_size() { return deque_buf_size(sizeof(T)); } static size_type s_buffer_size() { return deque_buf_size(sizeof(T)); }
@@ -163,7 +163,7 @@ class deque_base
// [map, map + map_size) is a valid, non-empty range. // [map, map + map_size) is a valid, non-empty range.
// [start.node, finish.node] is a valid range contained within // [start.node, finish.node] is a valid range contained within
// [map, map + map_size). // [map, map + map_size).
// A pointer in the range [map, map + map_size) points to an allocated node // Allocator pointer in the range [map, map + map_size) points to an allocated node
// if and only if the pointer is in the range [start.node, finish.node]. // if and only if the pointer is in the range [start.node, finish.node].
class const_iterator class const_iterator
: public std::iterator<std::random_access_iterator_tag, : public std::iterator<std::random_access_iterator_tag,
@@ -171,7 +171,7 @@ class deque_base
val_alloc_cptr, val_alloc_cref> val_alloc_cptr, val_alloc_cref>
{ {
public: public:
static size_type s_buffer_size() { return deque_base<T, A>::s_buffer_size(); } static size_type s_buffer_size() { return deque_base<T, Allocator>::s_buffer_size(); }
typedef std::random_access_iterator_tag iterator_category; typedef std::random_access_iterator_tag iterator_category;
typedef val_alloc_val value_type; typedef val_alloc_val value_type;
@@ -182,8 +182,8 @@ class deque_base
typedef ptr_alloc_ptr index_pointer; typedef ptr_alloc_ptr index_pointer;
typedef const_iterator self_t; typedef const_iterator self_t;
friend class deque<T, A>; friend class deque<T, Allocator>;
friend class deque_base<T, A>; friend class deque_base<T, Allocator>;
protected: protected:
val_alloc_ptr m_cur; val_alloc_ptr m_cur;
@@ -323,8 +323,8 @@ class deque_base
typedef ptr_alloc_ptr index_pointer; typedef ptr_alloc_ptr index_pointer;
typedef const_iterator self_t; typedef const_iterator self_t;
friend class deque<T, A>; friend class deque<T, Allocator>;
friend class deque_base<T, A>; friend class deque_base<T, Allocator>;
private: private:
explicit iterator(const const_iterator& x) : const_iterator(x){} explicit iterator(const const_iterator& x) : const_iterator(x){}
@@ -525,15 +525,15 @@ class deque_base
//! Deque class //! Deque class
//! //!
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class A = std::allocator<T> > template <class T, class Allocator = std::allocator<T> >
#else #else
template <class T, class A> template <class T, class Allocator>
#endif #endif
class deque : protected deque_base<T, A> class deque : protected deque_base<T, Allocator>
{ {
/// @cond /// @cond
private: private:
typedef deque_base<T, A> Base; typedef deque_base<T, Allocator> Base;
/// @endcond /// @endcond
public: public:
@@ -544,19 +544,19 @@ class deque : protected deque_base<T, A>
// //
////////////////////////////////////////////// //////////////////////////////////////////////
typedef T value_type; typedef T value_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer; typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer; typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference; typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference; typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type; typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type; typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef A allocator_type; typedef Allocator allocator_type;
typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type; typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(typename Base::iterator) iterator; typedef BOOST_CONTAINER_IMPDEF(typename Base::iterator) iterator;
typedef BOOST_CONTAINER_IMPDEF(typename Base::const_iterator) const_iterator; typedef BOOST_CONTAINER_IMPDEF(typename Base::const_iterator) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator; typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator; typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
/// @cond /// @cond
@@ -568,7 +568,7 @@ class deque : protected deque_base<T, A>
typedef container_detail::advanced_insert_aux_int<iterator> advanced_insert_aux_int_t; typedef container_detail::advanced_insert_aux_int<iterator> advanced_insert_aux_int_t;
typedef repeat_iterator<T, difference_type> r_iterator; typedef repeat_iterator<T, difference_type> r_iterator;
typedef boost::move_iterator<r_iterator> move_it; typedef boost::move_iterator<r_iterator> move_it;
typedef allocator_traits<A> allocator_traits_type; typedef allocator_traits<Allocator> allocator_traits_type;
/// @endcond /// @endcond
@@ -607,7 +607,7 @@ class deque : protected deque_base<T, A>
explicit deque(size_type n) explicit deque(size_type n)
: Base(n, allocator_type()) : Base(n, allocator_type())
{ {
container_detail::default_construct_aux_proxy<A, iterator> proxy(this->alloc(), n); container_detail::default_construct_aux_proxy<Allocator, iterator> proxy(this->alloc(), n);
proxy.uninitialized_copy_remaining_to(this->begin()); proxy.uninitialized_copy_remaining_to(this->begin());
//deque_base will deallocate in case of exception... //deque_base will deallocate in case of exception...
} }
@@ -1020,7 +1020,7 @@ class deque : protected deque_base<T, A>
this->priv_erase_last_n(len - new_size); this->priv_erase_last_n(len - new_size);
else{ else{
const 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); container_detail::default_construct_aux_proxy<Allocator, iterator> proxy(this->alloc(), n);
priv_insert_back_aux_impl(n, proxy); priv_insert_back_aux_impl(n, proxy);
} }
} }
@@ -1176,7 +1176,7 @@ class deque : protected deque_base<T, A>
this->priv_push_front_simple_commit(); this->priv_push_front_simple_commit();
} }
else{ else{
typedef container_detail::advanced_insert_aux_non_movable_emplace<A, iterator, Args...> type; typedef container_detail::advanced_insert_aux_non_movable_emplace<Allocator, iterator, Args...> type;
type &&proxy = type(this->alloc(), boost::forward<Args>(args)...); type &&proxy = type(this->alloc(), boost::forward<Args>(args)...);
this->priv_insert_front_aux_impl(1, proxy); this->priv_insert_front_aux_impl(1, proxy);
} }
@@ -1199,7 +1199,7 @@ class deque : protected deque_base<T, A>
this->priv_push_back_simple_commit(); this->priv_push_back_simple_commit();
} }
else{ else{
typedef container_detail::advanced_insert_aux_non_movable_emplace<A, iterator, Args...> type; typedef container_detail::advanced_insert_aux_non_movable_emplace<Allocator, iterator, Args...> type;
type &&proxy = type(this->alloc(), boost::forward<Args>(args)...); type &&proxy = type(this->alloc(), boost::forward<Args>(args)...);
this->priv_insert_back_aux_impl(1, proxy); this->priv_insert_back_aux_impl(1, proxy);
} }
@@ -1226,7 +1226,7 @@ class deque : protected deque_base<T, A>
return (this->end()-1); return (this->end()-1);
} }
else{ else{
typedef container_detail::advanced_insert_aux_emplace<A, iterator, Args...> type; typedef container_detail::advanced_insert_aux_emplace<Allocator, iterator, Args...> type;
type &&proxy = type(this->alloc(), boost::forward<Args>(args)...); type &&proxy = type(this->alloc(), boost::forward<Args>(args)...);
return this->priv_insert_aux_impl(p, 1, proxy); return this->priv_insert_aux_impl(p, 1, proxy);
} }
@@ -1249,7 +1249,7 @@ class deque : protected deque_base<T, A>
else{ \ else{ \
container_detail::BOOST_PP_CAT(BOOST_PP_CAT \ container_detail::BOOST_PP_CAT(BOOST_PP_CAT \
(advanced_insert_aux_non_movable_emplace, n), arg) \ (advanced_insert_aux_non_movable_emplace, n), arg) \
<A, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \ <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
priv_insert_front_aux_impl(1, proxy); \ priv_insert_front_aux_impl(1, proxy); \
} \ } \
@@ -1268,7 +1268,7 @@ class deque : protected deque_base<T, A>
else{ \ else{ \
container_detail::BOOST_PP_CAT(BOOST_PP_CAT( \ container_detail::BOOST_PP_CAT(BOOST_PP_CAT( \
advanced_insert_aux_non_movable_emplace, n), arg) \ advanced_insert_aux_non_movable_emplace, n), arg) \
<A, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \ <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
priv_insert_back_aux_impl(1, proxy); \ priv_insert_back_aux_impl(1, proxy); \
} \ } \
@@ -1288,7 +1288,7 @@ class deque : protected deque_base<T, A>
} \ } \
else{ \ else{ \
container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \ container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
<A, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \ <Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
return this->priv_insert_aux_impl(p, 1, proxy); \ return this->priv_insert_aux_impl(p, 1, proxy); \
} \ } \
@@ -1424,7 +1424,7 @@ class deque : protected deque_base<T, A>
#endif #endif
) )
{ {
container_detail::advanced_insert_aux_proxy<A, FwdIt, iterator> proxy(this->alloc(), first, last); container_detail::advanced_insert_aux_proxy<Allocator, FwdIt, iterator> proxy(this->alloc(), first, last);
return priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy); return priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy);
} }
#endif #endif
@@ -1978,36 +1978,36 @@ class deque : protected deque_base<T, A>
}; };
// Nonmember functions. // Nonmember functions.
template <class T, class A> template <class T, class Allocator>
inline bool operator==(const deque<T, A>& x, const deque<T, A>& y) inline bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y)
{ {
return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
} }
template <class T, class A> template <class T, class Allocator>
inline bool operator<(const deque<T, A>& x, const deque<T, A>& y) inline bool operator<(const deque<T, Allocator>& x, const deque<T, Allocator>& y)
{ {
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
} }
template <class T, class A> template <class T, class Allocator>
inline bool operator!=(const deque<T, A>& x, const deque<T, A>& y) inline bool operator!=(const deque<T, Allocator>& x, const deque<T, Allocator>& y)
{ return !(x == y); } { return !(x == y); }
template <class T, class A> template <class T, class Allocator>
inline bool operator>(const deque<T, A>& x, const deque<T, A>& y) inline bool operator>(const deque<T, Allocator>& x, const deque<T, Allocator>& y)
{ return y < x; } { return y < x; }
template <class T, class A> template <class T, class Allocator>
inline bool operator>=(const deque<T, A>& x, const deque<T, A>& y) inline bool operator>=(const deque<T, Allocator>& x, const deque<T, Allocator>& y)
{ return !(x < y); } { return !(x < y); }
template <class T, class A> template <class T, class Allocator>
inline bool operator<=(const deque<T, A>& x, const deque<T, A>& y) inline bool operator<=(const deque<T, Allocator>& x, const deque<T, Allocator>& y)
{ return !(y < x); } { return !(y < x); }
template <class T, class A> template <class T, class Allocator>
inline void swap(deque<T, A>& x, deque<T, A>& y) inline void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
{ x.swap(y); } { x.swap(y); }
}} }}
@@ -2018,10 +2018,10 @@ namespace boost {
/* /*
//!has_trivial_destructor_after_move<> == true_type //!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations //!specialization for optimizations
template <class T, class A> template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::deque<T, A> > struct has_trivial_destructor_after_move<boost::container::deque<T, Allocator> >
{ {
enum { value = has_trivial_destructor<A>::value }; enum { value = has_trivial_destructor<Allocator>::value };
}; };
*/ */
} }

View File

@@ -414,7 +414,8 @@ class flat_tree
void insert_equal(ordered_range_t, FwdIt first, FwdIt last void insert_equal(ordered_range_t, FwdIt first, FwdIt last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename container_detail::enable_if_c , typename container_detail::enable_if_c
< container_detail::is_forward_iterator<FwdIt>::value < !container_detail::is_input_iterator<FwdIt>::value &&
container_detail::is_forward_iterator<FwdIt>::value
>::type * = 0 >::type * = 0
#endif #endif
) )
@@ -491,9 +492,9 @@ class flat_tree
const const_iterator beg(this->cbegin()); const const_iterator beg(this->cbegin());
const_iterator pos(beg); const_iterator pos(beg);
const value_compare &value_comp = this->m_data; const value_compare &value_comp = this->m_data;
skips[0u] = 0u;
//Loop in burst sizes //Loop in burst sizes
while(len){ while(len){
skips[0u] = 0u;
const size_type burst = len < BurstSize ? len : BurstSize; const size_type burst = len < BurstSize ? len : BurstSize;
size_type unique_burst = 0u; size_type unique_burst = 0u;
const const_iterator cend(this->cend()); const const_iterator cend(this->cend());
@@ -503,20 +504,23 @@ class flat_tree
--len; --len;
pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, cend, KeyOfValue()(val)); pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, cend, KeyOfValue()(val));
//Check if already present //Check if already present
if(pos != cend && !value_comp(*pos, val)){ if(pos != cend && !value_comp(val, *pos)){
++skips[unique_burst]; if(unique_burst > 0){
++skips[unique_burst-1];
}
continue; continue;
} }
//If not present, calculate position //If not present, calculate position
positions[unique_burst] = static_cast<size_type>(pos - beg); positions[unique_burst] = static_cast<size_type>(pos - beg);
if(++unique_burst < burst) skips[unique_burst++] = 0u;
skips[unique_burst] = 0u; }
if(unique_burst){
//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;
} }
//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;
} }
} }

View File

@@ -41,7 +41,7 @@ namespace container {
namespace container_detail { namespace container_detail {
template<class Key, class Value, class KeyCompare, class KeyOfValue> template<class Key, class Value, class KeyCompare, class KeyOfValue>
struct value_compare_impl struct tree_value_compare
: public KeyCompare : public KeyCompare
{ {
typedef Value value_type; typedef Value value_type;
@@ -49,7 +49,7 @@ struct value_compare_impl
typedef KeyOfValue key_of_value; typedef KeyOfValue key_of_value;
typedef Key key_type; typedef Key key_type;
value_compare_impl(const key_compare &kcomp) tree_value_compare(const key_compare &kcomp)
: key_compare(kcomp) : key_compare(kcomp)
{} {}
@@ -209,13 +209,13 @@ class rbtree
: protected container_detail::node_alloc_holder : protected container_detail::node_alloc_holder
< A < A
, typename container_detail::intrusive_rbtree_type , typename container_detail::intrusive_rbtree_type
<A, value_compare_impl<Key, Value, KeyCompare, KeyOfValue> <A, tree_value_compare<Key, Value, KeyCompare, KeyOfValue>
>::type >::type
, KeyCompare , KeyCompare
> >
{ {
typedef typename container_detail::intrusive_rbtree_type typedef typename container_detail::intrusive_rbtree_type
< A, value_compare_impl < A, tree_value_compare
<Key, Value, KeyCompare, KeyOfValue> <Key, Value, KeyCompare, KeyOfValue>
>::type Icont; >::type Icont;
typedef container_detail::node_alloc_holder typedef container_detail::node_alloc_holder
@@ -315,7 +315,7 @@ class rbtree
typedef Value value_type; typedef Value value_type;
typedef A allocator_type; typedef A allocator_type;
typedef KeyCompare key_compare; typedef KeyCompare key_compare;
typedef value_compare_impl< Key, Value typedef tree_value_compare< Key, Value
, KeyCompare, KeyOfValue> value_compare; , KeyCompare, KeyOfValue> value_compare;
typedef typename boost::container:: typedef typename boost::container::
allocator_traits<A>::pointer pointer; allocator_traits<A>::pointer pointer;

View File

@@ -122,36 +122,6 @@ struct ct_rounded_size
{ {
enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo }; enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo };
}; };
/*
template <class _TypeT>
struct __rw_is_enum
{
struct _C_no { };
struct _C_yes { int _C_dummy [2]; };
struct _C_indirect {
// prevent classes with user-defined conversions from matching
// use double to prevent float->int gcc conversion warnings
_C_indirect (double);
};
// nested struct gets rid of bogus gcc errors
struct _C_nest {
// supply first argument to prevent HP aCC warnings
static _C_no _C_is (int, ...);
static _C_yes _C_is (int, _C_indirect);
static _TypeT _C_make_T ();
};
enum {
_C_val = sizeof (_C_yes) == sizeof (_C_nest::_C_is (0, _C_nest::_C_make_T ()))
&& !::boost::is_fundamental<_TypeT>::value
};
};
*/
template<class T> template<class T>
struct move_const_ref_type struct move_const_ref_type

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -7,8 +7,8 @@
// See http://www.boost.org/libs/container for documentation. // See http://www.boost.org/libs/container for documentation.
// //
#ifndef BOOST_CONTAINER_LIST_HPP_ #ifndef BOOST_CONTAINER_LIST_HPP
#define BOOST_CONTAINER_LIST_HPP_ #define BOOST_CONTAINER_LIST_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once # pragma once
@@ -43,13 +43,8 @@
#include <algorithm> #include <algorithm>
#include <stdexcept> #include <stdexcept>
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace boost { namespace boost {
namespace container { namespace container {
#else
namespace boost {
namespace container {
#endif
/// @cond /// @cond
namespace container_detail { namespace container_detail {
@@ -73,10 +68,10 @@ struct list_node
T m_data; T m_data;
}; };
template<class A> template<class Allocator>
struct intrusive_list_type struct intrusive_list_type
{ {
typedef boost::container::allocator_traits<A> allocator_traits_type; typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type; typedef typename allocator_traits_type::value_type value_type;
typedef typename boost::intrusive::pointer_traits typedef typename boost::intrusive::pointer_traits
<typename allocator_traits_type::pointer>::template <typename allocator_traits_type::pointer>::template
@@ -213,27 +208,27 @@ class list_iterator
//! not be invalidated or made to point to different elements unless that invalidation //! not be invalidated or made to point to different elements unless that invalidation
//! or mutation is explicit. //! or mutation is explicit.
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class A = std::allocator<T> > template <class T, class Allocator = std::allocator<T> >
#else #else
template <class T, class A> template <class T, class Allocator>
#endif #endif
class list class list
: protected container_detail::node_alloc_holder : protected container_detail::node_alloc_holder
<A, typename container_detail::intrusive_list_type<A>::type> <Allocator, typename container_detail::intrusive_list_type<Allocator>::type>
{ {
/// @cond /// @cond
typedef typename typedef typename
container_detail::intrusive_list_type<A>::type Icont; container_detail::intrusive_list_type<Allocator>::type Icont;
typedef container_detail::node_alloc_holder<A, Icont> AllocHolder; typedef container_detail::node_alloc_holder<Allocator, Icont> AllocHolder;
typedef typename AllocHolder::NodePtr NodePtr; typedef typename AllocHolder::NodePtr NodePtr;
typedef typename AllocHolder::NodeAlloc NodeAlloc; typedef typename AllocHolder::NodeAlloc NodeAlloc;
typedef typename AllocHolder::ValAlloc ValAlloc; typedef typename AllocHolder::ValAlloc ValAlloc;
typedef typename AllocHolder::Node Node; typedef typename AllocHolder::Node Node;
typedef container_detail::allocator_destroyer<NodeAlloc> Destroyer; typedef container_detail::allocator_destroyer<NodeAlloc> Destroyer;
typedef typename AllocHolder::allocator_v1 allocator_v1; typedef typename AllocHolder::allocator_v1 allocator_v1;
typedef typename AllocHolder::allocator_v2 allocator_v2; typedef typename AllocHolder::allocator_v2 allocator_v2;
typedef typename AllocHolder::alloc_version alloc_version; typedef typename AllocHolder::alloc_version alloc_version;
typedef boost::container::allocator_traits<A> allocator_traits_type; typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
class equal_to_value class equal_to_value
{ {
@@ -277,19 +272,19 @@ class list
// //
////////////////////////////////////////////// //////////////////////////////////////////////
typedef T value_type; typedef T value_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer; typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer; typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference; typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference; typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type; typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type; typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef A allocator_type; typedef Allocator allocator_type;
typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type; typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator; typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator; typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
////////////////////////////////////////////// //////////////////////////////////////////////
// //
@@ -323,7 +318,7 @@ class list
//! //!
//! <b>Complexity</b>: Linear to n. //! <b>Complexity</b>: Linear to n.
explicit list(size_type n) explicit list(size_type n)
: AllocHolder(A()) : AllocHolder(Allocator())
{ this->resize(n); } { this->resize(n); }
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
@@ -333,7 +328,7 @@ class list
//! throws or T's default or copy constructor throws. //! throws or T's default or copy constructor throws.
//! //!
//! <b>Complexity</b>: Linear to n. //! <b>Complexity</b>: Linear to n.
list(size_type n, const T& value, const A& a = A()) list(size_type n, const T& value, const Allocator& a = Allocator())
: AllocHolder(a) : AllocHolder(a)
{ this->insert(this->cbegin(), n, value); } { this->insert(this->cbegin(), n, value); }
@@ -393,7 +388,7 @@ class list
//! //!
//! <b>Complexity</b>: Linear to the range [first, last). //! <b>Complexity</b>: Linear to the range [first, last).
template <class InpIt> template <class InpIt>
list(InpIt first, InpIt last, const A &a = A()) list(InpIt first, InpIt last, const Allocator &a = Allocator())
: AllocHolder(a) : AllocHolder(a)
{ this->insert(this->cbegin(), first, last); } { this->insert(this->cbegin(), first, last); }
@@ -506,20 +501,24 @@ class list
allocator_type get_allocator() const allocator_type get_allocator() const
{ return allocator_type(this->node_alloc()); } { return allocator_type(this->node_alloc()); }
//! <b>Effects</b>: Returns a copy of the internal allocator. //! <b>Effects</b>: Returns a reference to the internal allocator.
//! //!
//! <b>Throws</b>: If allocator's copy constructor throws. //! <b>Throws</b>: Nothing
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const stored_allocator_type &get_stored_allocator() const //!
//! <b>Note</b>: Non-standard extension.
stored_allocator_type &get_stored_allocator()
{ return this->node_alloc(); } { return this->node_alloc(); }
//! <b>Effects</b>: Returns a copy of the internal allocator. //! <b>Effects</b>: Returns a reference to the internal allocator.
//! //!
//! <b>Throws</b>: If allocator's copy constructor throws. //! <b>Throws</b>: Nothing
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
stored_allocator_type &get_stored_allocator() //!
//! <b>Note</b>: Non-standard extension.
const stored_allocator_type &get_stored_allocator() const
{ return this->node_alloc(); } { return this->node_alloc(); }
////////////////////////////////////////////// //////////////////////////////////////////////
@@ -1426,13 +1425,13 @@ class list
}; };
template <class T, class A> template <class T, class Allocator>
inline bool operator==(const list<T,A>& x, const list<T,A>& y) inline bool operator==(const list<T,Allocator>& x, const list<T,Allocator>& y)
{ {
if(x.size() != y.size()){ if(x.size() != y.size()){
return false; return false;
} }
typedef typename list<T,A>::const_iterator const_iterator; typedef typename list<T,Allocator>::const_iterator const_iterator;
const_iterator end1 = x.end(); const_iterator end1 = x.end();
const_iterator i1 = x.begin(); const_iterator i1 = x.begin();
@@ -1444,39 +1443,39 @@ inline bool operator==(const list<T,A>& x, const list<T,A>& y)
return i1 == end1; return i1 == end1;
} }
template <class T, class A> template <class T, class Allocator>
inline bool operator<(const list<T,A>& x, inline bool operator<(const list<T,Allocator>& x,
const list<T,A>& y) const list<T,Allocator>& y)
{ {
return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
} }
template <class T, class A> template <class T, class Allocator>
inline bool operator!=(const list<T,A>& x, const list<T,A>& y) inline bool operator!=(const list<T,Allocator>& x, const list<T,Allocator>& y)
{ {
return !(x == y); return !(x == y);
} }
template <class T, class A> template <class T, class Allocator>
inline bool operator>(const list<T,A>& x, const list<T,A>& y) inline bool operator>(const list<T,Allocator>& x, const list<T,Allocator>& y)
{ {
return y < x; return y < x;
} }
template <class T, class A> template <class T, class Allocator>
inline bool operator<=(const list<T,A>& x, const list<T,A>& y) inline bool operator<=(const list<T,Allocator>& x, const list<T,Allocator>& y)
{ {
return !(y < x); return !(y < x);
} }
template <class T, class A> template <class T, class Allocator>
inline bool operator>=(const list<T,A>& x, const list<T,A>& y) inline bool operator>=(const list<T,Allocator>& x, const list<T,Allocator>& y)
{ {
return !(x < y); return !(x < y);
} }
template <class T, class A> template <class T, class Allocator>
inline void swap(list<T, A>& x, list<T, A>& y) inline void swap(list<T, Allocator>& x, list<T, Allocator>& y)
{ {
x.swap(y); x.swap(y);
} }
@@ -1487,10 +1486,10 @@ inline void swap(list<T, A>& x, list<T, A>& y)
/* /*
//!has_trivial_destructor_after_move<> == true_type //!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations //!specialization for optimizations
template <class T, class A> template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::list<T, A> > struct has_trivial_destructor_after_move<boost::container::list<T, Allocator> >
{ {
static const bool value = has_trivial_destructor<A>::value; static const bool value = has_trivial_destructor<Allocator>::value;
}; };
*/ */
namespace container { namespace container {
@@ -1501,4 +1500,4 @@ namespace container {
#include <boost/container/detail/config_end.hpp> #include <boost/container/detail/config_end.hpp>
#endif // BOOST_CONTAINER_LIST_HPP_ #endif // BOOST_CONTAINER_LIST_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -47,10 +47,10 @@ namespace boost { namespace container {
//! ill-formed. //! ill-formed.
//! //!
//! [Example: //! [Example:
//! template <class T, class A = allocator<T> > //! template <class T, class Allocator = allocator<T> >
//! class Z { //! class Z {
//! public: //! public:
//! typedef A allocator_type; //! typedef Allocator allocator_type;
//! //!
//! // Default constructor with optional allocator suffix //! // Default constructor with optional allocator suffix
//! Z(const allocator_type& a = allocator_type()); //! Z(const allocator_type& a = allocator_type());
@@ -61,8 +61,8 @@ namespace boost { namespace container {
//! }; //! };
//! //!
//! // Specialize trait for class template Z //! // Specialize trait for class template Z
//! template <class T, class A = allocator<T> > //! template <class T, class Allocator = allocator<T> >
//! struct constructible_with_allocator_suffix<Z<T,A> > //! struct constructible_with_allocator_suffix<Z<T,Allocator> >
//! : ::boost::true_type { }; //! : ::boost::true_type { };
//! -- end example] //! -- end example]
//! //!
@@ -91,10 +91,10 @@ struct constructible_with_allocator_suffix
//! a constructor, then the program is ill-formed. //! a constructor, then the program is ill-formed.
//! //!
//! [Example: //! [Example:
//! template <class T, class A = allocator<T> > //! template <class T, class Allocator = allocator<T> >
//! class Y { //! class Y {
//! public: //! public:
//! typedef A allocator_type; //! typedef Allocator allocator_type;
//! //!
//! // Default constructor with and allocator-extended default constructor //! // Default constructor with and allocator-extended default constructor
//! Y(); //! Y();
@@ -111,8 +111,8 @@ struct constructible_with_allocator_suffix
//! }; //! };
//! //!
//! // Specialize trait for class template Y //! // Specialize trait for class template Y
//! template <class T, class A = allocator<T> > //! template <class T, class Allocator = allocator<T> >
//! struct constructible_with_allocator_prefix<Y<T,A> > //! struct constructible_with_allocator_prefix<Y<T,Allocator> >
//! : ::boost::true_type { }; //! : ::boost::true_type { };
//! //!
//! -- end example] //! -- end example]
@@ -1036,16 +1036,16 @@ class scoped_allocator_adaptor
typedef typename outer_traits_type::const_pointer const_pointer; typedef typename outer_traits_type::const_pointer const_pointer;
typedef typename outer_traits_type::void_pointer void_pointer; typedef typename outer_traits_type::void_pointer void_pointer;
typedef typename outer_traits_type::const_void_pointer const_void_pointer; typedef typename outer_traits_type::const_void_pointer const_void_pointer;
//! Type: `true_type` if `allocator_traits<A>::propagate_on_container_copy_assignment::value` is //! Type: `true_type` if `allocator_traits<Allocator>::propagate_on_container_copy_assignment::value` is
//! true for any `A` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type. //! true for any `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type.
typedef typename base_type:: typedef typename base_type::
propagate_on_container_copy_assignment propagate_on_container_copy_assignment; propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
//! Type: `true_type` if `allocator_traits<A>::propagate_on_container_move_assignment::value` is //! Type: `true_type` if `allocator_traits<Allocator>::propagate_on_container_move_assignment::value` is
//! true for any `A` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type. //! true for any `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type.
typedef typename base_type:: typedef typename base_type::
propagate_on_container_move_assignment propagate_on_container_move_assignment; propagate_on_container_move_assignment propagate_on_container_move_assignment;
//! Type: `true_type` if `allocator_traits<A>::propagate_on_container_swap::value` is true for any //! Type: `true_type` if `allocator_traits<Allocator>::propagate_on_container_swap::value` is true for any
//! `A` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type. //! `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type.
typedef typename base_type:: typedef typename base_type::
propagate_on_container_swap propagate_on_container_swap; propagate_on_container_swap propagate_on_container_swap;
@@ -1211,9 +1211,9 @@ class scoped_allocator_adaptor
outer_traits_type::deallocate(this->outer_allocator(), p, n); outer_traits_type::deallocate(this->outer_allocator(), p, n);
} }
//! <b>Returns</b>: A new scoped_allocator_adaptor object where each allocator //! <b>Returns</b>: Allocator new scoped_allocator_adaptor object where each allocator
//! A in the adaptor is initialized from the result of calling //! A in the adaptor is initialized from the result of calling
//! `allocator_traits<A>::select_on_container_copy_construction()` on //! `allocator_traits<Allocator>::select_on_container_copy_construction()` on
//! the corresponding allocator in *this. //! the corresponding allocator in *this.
scoped_allocator_adaptor select_on_container_copy_construction() const scoped_allocator_adaptor select_on_container_copy_construction() const
{ {

File diff suppressed because it is too large Load Diff

View File

@@ -44,17 +44,12 @@
#include <functional> #include <functional>
#include <algorithm> #include <algorithm>
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace boost { namespace boost {
namespace container { namespace container {
#else
namespace boost {
namespace container {
#endif
/// @cond /// @cond
template <class T, class A> template <class T, class Allocator>
class slist; class slist;
namespace container_detail { namespace container_detail {
@@ -78,10 +73,10 @@ struct slist_node
T m_data; T m_data;
}; };
template<class A> template<class Allocator>
struct intrusive_slist_type struct intrusive_slist_type
{ {
typedef boost::container::allocator_traits<A> allocator_traits_type; typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type; typedef typename allocator_traits_type::value_type value_type;
typedef typename boost::intrusive::pointer_traits typedef typename boost::intrusive::pointer_traits
<typename allocator_traits_type::pointer>::template <typename allocator_traits_type::pointer>::template
@@ -230,18 +225,18 @@ class slist_iterator
//! needs, and that you often need to use insert and erase in the middle of the list, //! needs, and that you often need to use insert and erase in the middle of the list,
//! then you should probably use list instead of slist. //! then you should probably use list instead of slist.
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class A = std::allocator<T> > template <class T, class Allocator = std::allocator<T> >
#else #else
template <class T, class A> template <class T, class Allocator>
#endif #endif
class slist class slist
: protected container_detail::node_alloc_holder : protected container_detail::node_alloc_holder
<A, typename container_detail::intrusive_slist_type<A>::type> <Allocator, typename container_detail::intrusive_slist_type<Allocator>::type>
{ {
/// @cond /// @cond
typedef typename typedef typename
container_detail::intrusive_slist_type<A>::type Icont; container_detail::intrusive_slist_type<Allocator>::type Icont;
typedef container_detail::node_alloc_holder<A, Icont> AllocHolder; typedef container_detail::node_alloc_holder<Allocator, Icont> AllocHolder;
typedef typename AllocHolder::NodePtr NodePtr; typedef typename AllocHolder::NodePtr NodePtr;
typedef typename AllocHolder::NodeAlloc NodeAlloc; typedef typename AllocHolder::NodeAlloc NodeAlloc;
typedef typename AllocHolder::ValAlloc ValAlloc; typedef typename AllocHolder::ValAlloc ValAlloc;
@@ -250,7 +245,7 @@ class slist
typedef typename AllocHolder::allocator_v1 allocator_v1; typedef typename AllocHolder::allocator_v1 allocator_v1;
typedef typename AllocHolder::allocator_v2 allocator_v2; typedef typename AllocHolder::allocator_v2 allocator_v2;
typedef typename AllocHolder::alloc_version alloc_version; typedef typename AllocHolder::alloc_version alloc_version;
typedef boost::container::allocator_traits<A> allocator_traits_type; typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
class equal_to_value class equal_to_value
{ {
@@ -294,13 +289,13 @@ class slist
////////////////////////////////////////////// //////////////////////////////////////////////
typedef T value_type; typedef T value_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer; typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer; typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference; typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference; typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type; typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type; typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef A allocator_type; typedef Allocator allocator_type;
typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type; typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
@@ -519,12 +514,14 @@ class slist
allocator_type get_allocator() const allocator_type get_allocator() const
{ return allocator_type(this->node_alloc()); } { return allocator_type(this->node_alloc()); }
//! <b>Effects</b>: Returns a copy of the internal allocator. //! <b>Effects</b>: Returns a reference to the internal allocator.
//! //!
//! <b>Throws</b>: If allocator's copy constructor throws. //! <b>Throws</b>: Nothing
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const stored_allocator_type &get_stored_allocator() const //!
//! <b>Note</b>: Non-standard extension.
stored_allocator_type &get_stored_allocator()
{ return this->node_alloc(); } { return this->node_alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator. //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -534,7 +531,7 @@ class slist
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
//! //!
//! <b>Note</b>: Non-standard extension. //! <b>Note</b>: Non-standard extension.
stored_allocator_type &get_stored_allocator() const stored_allocator_type &get_stored_allocator() const
{ return this->node_alloc(); } { return this->node_alloc(); }
////////////////////////////////////////////// //////////////////////////////////////////////
@@ -1605,14 +1602,14 @@ class slist
/// @endcond /// @endcond
}; };
template <class T, class A> template <class T, class Allocator>
inline bool inline bool
operator==(const slist<T,A>& x, const slist<T,A>& y) operator==(const slist<T,Allocator>& x, const slist<T,Allocator>& y)
{ {
if(x.size() != y.size()){ if(x.size() != y.size()){
return false; return false;
} }
typedef typename slist<T,A>::const_iterator const_iterator; typedef typename slist<T,Allocator>::const_iterator const_iterator;
const_iterator end1 = x.end(); const_iterator end1 = x.end();
const_iterator i1 = x.begin(); const_iterator i1 = x.begin();
@@ -1624,36 +1621,36 @@ operator==(const slist<T,A>& x, const slist<T,A>& y)
return i1 == end1; return i1 == end1;
} }
template <class T, class A> template <class T, class Allocator>
inline bool inline bool
operator<(const slist<T,A>& sL1, const slist<T,A>& sL2) operator<(const slist<T,Allocator>& sL1, const slist<T,Allocator>& sL2)
{ {
return std::lexicographical_compare return std::lexicographical_compare
(sL1.begin(), sL1.end(), sL2.begin(), sL2.end()); (sL1.begin(), sL1.end(), sL2.begin(), sL2.end());
} }
template <class T, class A> template <class T, class Allocator>
inline bool inline bool
operator!=(const slist<T,A>& sL1, const slist<T,A>& sL2) operator!=(const slist<T,Allocator>& sL1, const slist<T,Allocator>& sL2)
{ return !(sL1 == sL2); } { return !(sL1 == sL2); }
template <class T, class A> template <class T, class Allocator>
inline bool inline bool
operator>(const slist<T,A>& sL1, const slist<T,A>& sL2) operator>(const slist<T,Allocator>& sL1, const slist<T,Allocator>& sL2)
{ return sL2 < sL1; } { return sL2 < sL1; }
template <class T, class A> template <class T, class Allocator>
inline bool inline bool
operator<=(const slist<T,A>& sL1, const slist<T,A>& sL2) operator<=(const slist<T,Allocator>& sL1, const slist<T,Allocator>& sL2)
{ return !(sL2 < sL1); } { return !(sL2 < sL1); }
template <class T, class A> template <class T, class Allocator>
inline bool inline bool
operator>=(const slist<T,A>& sL1, const slist<T,A>& sL2) operator>=(const slist<T,Allocator>& sL1, const slist<T,Allocator>& sL2)
{ return !(sL1 < sL2); } { return !(sL1 < sL2); }
template <class T, class A> template <class T, class Allocator>
inline void swap(slist<T,A>& x, slist<T,A>& y) inline void swap(slist<T,Allocator>& x, slist<T,Allocator>& y)
{ x.swap(y); } { x.swap(y); }
}} }}
@@ -1664,10 +1661,10 @@ namespace boost {
/* /*
//!has_trivial_destructor_after_move<> == true_type //!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations //!specialization for optimizations
template <class T, class A> template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::slist<T, A> > struct has_trivial_destructor_after_move<boost::container::slist<T, Allocator> >
{ {
static const bool value = has_trivial_destructor<A>::value; static const bool value = has_trivial_destructor<Allocator>::value;
}; };
*/ */
namespace container { namespace container {
@@ -1685,11 +1682,11 @@ namespace container {
//there is no other way //there is no other way
namespace std { namespace std {
template <class T, class A> template <class T, class Allocator>
class insert_iterator<boost::container::slist<T, A> > class insert_iterator<boost::container::slist<T, Allocator> >
{ {
protected: protected:
typedef boost::container::slist<T, A> Container; typedef boost::container::slist<T, Allocator> Container;
Container* container; Container* container;
typename Container::iterator iter; typename Container::iterator iter;
public: public:
@@ -1722,4 +1719,4 @@ class insert_iterator<boost::container::slist<T, A> >
#include <boost/container/detail/config_end.hpp> #include <boost/container/detail/config_end.hpp>
#endif /* BOOST_CONTAINER_SLIST_HPP */ #endif // BOOST_CONTAINER_SLIST_HPP

View File

@@ -275,26 +275,6 @@ class iterator
node_ptr pn; node_ptr pn;
}; };
template<class A, unsigned int Version>
struct select_multiallocation_chain
{
typedef typename A::multiallocation_chain type;
};
template<class A>
struct select_multiallocation_chain<A, 1>
{
typedef typename boost::intrusive::pointer_traits
<typename allocator_traits<A>::pointer>::
template rebind_pointer<void>::type void_ptr;
typedef container_detail::basic_multiallocation_chain
<void_ptr> multialloc_cached_counted;
typedef boost::container::container_detail::
transform_multiallocation_chain
< multialloc_cached_counted
, typename allocator_traits<A>::value_type> type;
};
template<class VoidPtr, class VoidAllocator> template<class VoidPtr, class VoidAllocator>
struct index_traits struct index_traits
{ {
@@ -386,6 +366,89 @@ struct index_traits
#endif //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING #endif //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
}; };
template<class Allocator, unsigned Version = boost::container::container_detail::version<Allocator>::value>
struct allocator_version_wrapper
{
typedef ::boost::container::container_detail::integral_constant
<unsigned, Version> alloc_version;
typedef typename Allocator::multiallocation_chain multiallocation_chain;
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
static pointer allocate_one(Allocator &a)
{ return a.allocate_one(); }
static void deallocate_one(Allocator &a, const pointer &p)
{ a.deallocate_one(p); }
static multiallocation_chain allocate_individual(Allocator &a, size_type n)
{ return a.allocate_individual(n); }
static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
{ a.deallocate_individual(::boost::move(holder)); }
};
template<class Allocator>
struct allocator_version_wrapper<Allocator, 1>
{
typedef ::boost::container::container_detail::integral_constant
<unsigned, 1> alloc_version;
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename boost::container::allocator_traits<Allocator>::value_type value_type;
typedef typename boost::intrusive::pointer_traits<pointer>::
template rebind_pointer<void>::type void_ptr;
typedef container_detail::basic_multiallocation_chain
<void_ptr> multialloc_cached_counted;
typedef boost::container::container_detail::
transform_multiallocation_chain
< multialloc_cached_counted, value_type> multiallocation_chain;
static pointer allocate_one(Allocator &a)
{ return a.allocate(1); }
static void deallocate_one(Allocator &a, const pointer &p)
{ a.deallocate(p, 1); }
static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
{
while(!holder.empty()){
a.deallocate(holder.pop_front(), 1);
}
}
struct allocate_individual_rollback
{
allocate_individual_rollback(Allocator &a, multiallocation_chain &chain)
: mr_a(a), mr_chain(chain)
{}
~allocate_individual_rollback()
{
allocator_version_wrapper::deallocate_individual(mr_a, mr_chain);
}
Allocator &mr_a;
multiallocation_chain &mr_chain;
};
static multiallocation_chain allocate_individual(Allocator &a, size_type n)
{
multiallocation_chain m;
multiallocation_chain m_ret;
allocate_individual_rollback rollback(a, m);
while(n--){
m.push_front(a.allocate(1));
}
m.swap(m_ret);
return ::boost::move(m_ret);
}
};
} //namespace stable_vector_detail } //namespace stable_vector_detail
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -438,14 +501,14 @@ struct index_traits
//! Exception safety: As stable_vector does not internally copy elements around, some //! Exception safety: As stable_vector does not internally copy elements around, some
//! operations provide stronger exception safety guarantees than in std::vector. //! operations provide stronger exception safety guarantees than in std::vector.
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class A = std::allocator<T> > template <class T, class Allocator = std::allocator<T> >
#else #else
template <class T, class A> template <class T, class Allocator>
#endif #endif
class stable_vector class stable_vector
{ {
///@cond ///@cond
typedef allocator_traits<A> allocator_traits_type; typedef allocator_traits<Allocator> allocator_traits_type;
typedef typename boost::intrusive::pointer_traits typedef typename boost::intrusive::pointer_traits
<typename allocator_traits_type::pointer>:: <typename allocator_traits_type::pointer>::
template rebind_pointer<void>::type void_ptr; template rebind_pointer<void>::type void_ptr;
@@ -487,125 +550,35 @@ class stable_vector
integral_constant<unsigned, 2> allocator_v2; integral_constant<unsigned, 2> allocator_v2;
typedef ::boost::container::container_detail::integral_constant typedef ::boost::container::container_detail::integral_constant
<unsigned, boost::container::container_detail:: <unsigned, boost::container::container_detail::
version<A>::value> alloc_version; version<Allocator>::value> alloc_version;
typedef typename allocator_traits_type:: typedef typename allocator_traits_type::
template portable_rebind_alloc template portable_rebind_alloc
<node_type>::type node_allocator_type; <node_type>::type node_allocator_type;
typedef typename stable_vector_detail::
select_multiallocation_chain typedef stable_vector_detail::allocator_version_wrapper<node_allocator_type> allocator_version_wrapper_t;
< node_allocator_type typedef typename allocator_version_wrapper_t::multiallocation_chain multiallocation_chain;
, alloc_version::value
>::type multiallocation_chain;
node_ptr allocate_one() node_ptr allocate_one()
{ return this->allocate_one(alloc_version()); } { return allocator_version_wrapper_t::allocate_one(this->priv_node_alloc()); }
template<class AllocatorVersion> void deallocate_one(const node_ptr &p)
node_ptr allocate_one(AllocatorVersion, { allocator_version_wrapper_t::deallocate_one(this->priv_node_alloc(), p); }
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
{ return this->priv_node_alloc().allocate(1); }
template<class AllocatorVersion>
node_ptr allocate_one(AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<!boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
{ return this->priv_node_alloc().allocate_one(); }
void deallocate_one(node_ptr p)
{ return this->deallocate_one(p, alloc_version()); }
template<class AllocatorVersion>
void deallocate_one(node_ptr p, AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
{ this->priv_node_alloc().deallocate(p, 1); }
template<class AllocatorVersion>
void deallocate_one(node_ptr p, AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<!boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
{ this->priv_node_alloc().deallocate_one(p); }
multiallocation_chain allocate_individual(typename allocator_traits_type::size_type n) multiallocation_chain allocate_individual(typename allocator_traits_type::size_type n)
{ return this->allocate_individual(n, alloc_version()); } { return allocator_version_wrapper_t::allocate_individual(this->priv_node_alloc(), n); }
struct allocate_individual_rollback
{
allocate_individual_rollback(stable_vector &sv, multiallocation_chain &chain)
: mr_sv(sv), mr_chain(chain)
{}
~allocate_individual_rollback()
{
if(!mr_chain.empty()){
mr_sv.deallocate_individual(mr_chain);
}
}
stable_vector &mr_sv;
multiallocation_chain &mr_chain;
};
template<class AllocatorVersion>
multiallocation_chain allocate_individual
(typename allocator_traits_type::size_type n, AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
{
multiallocation_chain m;
multiallocation_chain m_ret;
allocate_individual_rollback rollback(*this, m);
while(n--){
m.push_front(this->allocate_one());
}
m.swap(m_ret);
return ::boost::move(m_ret);
}
template<class AllocatorVersion>
multiallocation_chain allocate_individual
(typename allocator_traits_type::size_type n, AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<!boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
{ return this->priv_node_alloc().allocate_individual(n); }
void deallocate_individual(multiallocation_chain &holder) void deallocate_individual(multiallocation_chain &holder)
{ this->deallocate_individual(holder, alloc_version()); } { allocator_version_wrapper_t::deallocate_individual(this->priv_node_alloc(), holder); }
template<class AllocatorVersion>
void deallocate_individual(multiallocation_chain & holder, AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
{
while(!holder.empty()){
this->deallocate_one(holder.pop_front());
}
}
template<class AllocatorVersion>
void deallocate_individual(multiallocation_chain & holder, AllocatorVersion,
typename boost::container::container_detail::enable_if_c
<!boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
::value>::type * = 0)
{ this->priv_node_alloc().deallocate_individual(boost::move(holder)); }
friend class stable_vector_detail::clear_on_destroy<stable_vector>; friend class stable_vector_detail::clear_on_destroy<stable_vector>;
typedef stable_vector_detail::iterator typedef stable_vector_detail::iterator
< T < T
, typename allocator_traits<A>::reference , typename allocator_traits<Allocator>::reference
, typename allocator_traits<A>::pointer> iterator_impl; , typename allocator_traits<Allocator>::pointer> iterator_impl;
typedef stable_vector_detail::iterator typedef stable_vector_detail::iterator
< T < T
, typename allocator_traits<A>::const_reference , typename allocator_traits<Allocator>::const_reference
, typename allocator_traits<A>::const_pointer> const_iterator_impl; , typename allocator_traits<Allocator>::const_pointer> const_iterator_impl;
///@endcond ///@endcond
public: public:
@@ -614,19 +587,19 @@ class stable_vector
// types // types
// //
////////////////////////////////////////////// //////////////////////////////////////////////
typedef T value_type; typedef T value_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer; typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer; typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference; typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference; typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type; typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type; typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef A allocator_type; typedef Allocator allocator_type;
typedef node_allocator_type stored_allocator_type; typedef node_allocator_type stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator; typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator; typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
///@cond ///@cond
private: private:
@@ -1863,46 +1836,46 @@ class stable_vector
/// @endcond /// @endcond
}; };
template <typename T,typename A> template <typename T,typename Allocator>
bool operator==(const stable_vector<T,A>& x,const stable_vector<T,A>& y) bool operator==(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
{ {
return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
} }
template <typename T,typename A> template <typename T,typename Allocator>
bool operator< (const stable_vector<T,A>& x,const stable_vector<T,A>& y) bool operator< (const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
{ {
return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
} }
template <typename T,typename A> template <typename T,typename Allocator>
bool operator!=(const stable_vector<T,A>& x,const stable_vector<T,A>& y) bool operator!=(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
{ {
return !(x==y); return !(x==y);
} }
template <typename T,typename A> template <typename T,typename Allocator>
bool operator> (const stable_vector<T,A>& x,const stable_vector<T,A>& y) bool operator> (const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
{ {
return y<x; return y<x;
} }
template <typename T,typename A> template <typename T,typename Allocator>
bool operator>=(const stable_vector<T,A>& x,const stable_vector<T,A>& y) bool operator>=(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
{ {
return !(x<y); return !(x<y);
} }
template <typename T,typename A> template <typename T,typename Allocator>
bool operator<=(const stable_vector<T,A>& x,const stable_vector<T,A>& y) bool operator<=(const stable_vector<T,Allocator>& x,const stable_vector<T,Allocator>& y)
{ {
return !(x>y); return !(x>y);
} }
// specialized algorithms: // specialized algorithms:
template <typename T, typename A> template <typename T, typename Allocator>
void swap(stable_vector<T,A>& x,stable_vector<T,A>& y) void swap(stable_vector<T,Allocator>& x,stable_vector<T,Allocator>& y)
{ {
x.swap(y); x.swap(y);
} }

View File

@@ -84,14 +84,14 @@ namespace container_detail {
// memory. The destructor assumes that the memory either is the internal buffer, // memory. The destructor assumes that the memory either is the internal buffer,
// or else points to a block of memory that was allocated using _String_base's // or else points to a block of memory that was allocated using _String_base's
// allocator and whose size is this->m_storage. // allocator and whose size is this->m_storage.
template <class A> template <class Allocator>
class basic_string_base class basic_string_base
{ {
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_string_base) BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_string_base)
typedef allocator_traits<A> allocator_traits_type; typedef allocator_traits<Allocator> allocator_traits_type;
public: public:
typedef A allocator_type; typedef Allocator allocator_type;
//! The stored allocator type //! The stored allocator type
typedef allocator_type stored_allocator_type; typedef allocator_type stored_allocator_type;
typedef typename allocator_traits_type::pointer pointer; typedef typename allocator_traits_type::pointer pointer;
@@ -211,24 +211,24 @@ class basic_string_base
}; };
struct members_holder struct members_holder
: public A : public Allocator
{ {
members_holder() members_holder()
: A() : Allocator()
{} {}
template<class AllocatorConvertible> template<class AllocatorConvertible>
explicit members_holder(BOOST_FWD_REF(AllocatorConvertible) a) explicit members_holder(BOOST_FWD_REF(AllocatorConvertible) a)
: A(boost::forward<AllocatorConvertible>(a)) : Allocator(boost::forward<AllocatorConvertible>(a))
{} {}
repr_t m_repr; repr_t m_repr;
} members_; } members_;
const A &alloc() const const Allocator &alloc() const
{ return members_; } { return members_; }
A &alloc() Allocator &alloc()
{ return members_; } { return members_; }
static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type); static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type);
@@ -272,7 +272,7 @@ class basic_string_base
typedef container_detail::integral_constant<unsigned, 1> allocator_v1; typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2; typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
typedef container_detail::integral_constant<unsigned, typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::version<A>::value> alloc_version; boost::container::container_detail::version<Allocator>::value> alloc_version;
std::pair<pointer, bool> std::pair<pointer, bool>
allocation_command(allocation_type command, allocation_command(allocation_type command,
@@ -521,22 +521,22 @@ class basic_string_base
//! In this implementation, iterators are only invalidated by member functions that //! In this implementation, iterators are only invalidated by member functions that
//! explicitly change the string's contents. //! explicitly change the string's contents.
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class CharT, class Traits = std::char_traits<CharT>, class A = std::allocator<CharT> > template <class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT> >
#else #else
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
#endif #endif
class basic_string class basic_string
: private container_detail::basic_string_base<A> : private container_detail::basic_string_base<Allocator>
{ {
/// @cond /// @cond
private: private:
typedef allocator_traits<A> allocator_traits_type; typedef allocator_traits<Allocator> allocator_traits_type;
BOOST_COPYABLE_AND_MOVABLE(basic_string) BOOST_COPYABLE_AND_MOVABLE(basic_string)
typedef container_detail::basic_string_base<A> base_t; typedef container_detail::basic_string_base<Allocator> base_t;
static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars; static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars;
protected: protected:
// A helper class to use a char_traits as a function object. // Allocator helper class to use a char_traits as a function object.
template <class Tr> template <class Tr>
struct Eq_traits struct Eq_traits
@@ -571,7 +571,7 @@ class basic_string
public: public:
//! The allocator type //! The allocator type
typedef A allocator_type; typedef Allocator allocator_type;
//! The stored allocator type //! The stored allocator type
typedef allocator_type stored_allocator_type; typedef allocator_type stored_allocator_type;
//! The type of object, CharT, stored in the string //! The type of object, CharT, stored in the string
@@ -932,7 +932,7 @@ class basic_string
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
//! //!
//! <b>Note</b>: Non-standard extension. //! <b>Note</b>: Non-standard extension.
const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
{ return this->alloc(); } { return this->alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator. //! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -942,7 +942,7 @@ class basic_string
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
//! //!
//! <b>Note</b>: Non-standard extension. //! <b>Note</b>: Non-standard extension.
stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return this->alloc(); } { return this->alloc(); }
//! <b>Effects</b>: Returns the number of the elements contained in the vector. //! <b>Effects</b>: Returns the number of the elements contained in the vector.
@@ -1892,7 +1892,7 @@ class basic_string
//! <b>Requires</b>: The program shall not alter any of the values stored in the character array. //! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
//! //!
//! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()]. //! <b>Returns</b>: Allocator pointer p such that p + i == &operator[](i) for each i in [0,size()].
//! //!
//! <b>Complexity</b>: constant time. //! <b>Complexity</b>: constant time.
const CharT* c_str() const const CharT* c_str() const
@@ -1900,7 +1900,7 @@ class basic_string
//! <b>Requires</b>: The program shall not alter any of the values stored in the character array. //! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
//! //!
//! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()]. //! <b>Returns</b>: Allocator pointer p such that p + i == &operator[](i) for each i in [0,size()].
//! //!
//! <b>Complexity</b>: constant time. //! <b>Complexity</b>: constant time.
const CharT* data() const const CharT* data() const
@@ -2483,10 +2483,10 @@ wstring;
/// @cond /// @cond
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
const typename basic_string<CharT,Traits,A>::size_type const typename basic_string<CharT,Traits,Allocator>::size_type
basic_string<CharT,Traits,A>::npos basic_string<CharT,Traits,Allocator>::npos
= (typename basic_string<CharT,Traits,A>::size_type) -1; = (typename basic_string<CharT,Traits,Allocator>::size_type) -1;
/// @endcond /// @endcond
@@ -2495,273 +2495,212 @@ basic_string<CharT,Traits,A>::npos
// Operator+ // Operator+
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator> inline
inline basic_string<CharT,Traits,A> basic_string<CharT,Traits,Allocator>
operator+(const basic_string<CharT,Traits,A>& x, operator+(const basic_string<CharT,Traits,Allocator>& x
const basic_string<CharT,Traits,A>& y) ,const basic_string<CharT,Traits,Allocator>& y)
{ {
typedef basic_string<CharT,Traits,A> str_t; typedef basic_string<CharT,Traits,Allocator> str_t;
typedef typename str_t::reserve_t reserve_t; typedef typename str_t::reserve_t reserve_t;
reserve_t reserve; reserve_t reserve;
str_t result(reserve, x.size() + y.size(), x.get_stored_allocator()); str_t result(reserve, x.size() + y.size(), x.get_stored_allocator());
result.append(x); result.append(x);
result.append(y); result.append(y);
return boost::move(result); return result;
} }
template <class CharT, class Traits, class A> inline template <class CharT, class Traits, class Allocator> inline
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) basic_string<CharT, Traits, Allocator> operator+
operator+( ( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END mx
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx , BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END my)
, BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
{ {
mx += my; mx += my;
return boost::move(mx); return boost::move(mx);
} }
template <class CharT, class Traits, class A> inline template <class CharT, class Traits, class Allocator> inline
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) basic_string<CharT, Traits, Allocator> operator+
operator+( ( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END mx
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx , const basic_string<CharT,Traits,Allocator>& y)
, const basic_string<CharT,Traits,A>& y)
{ {
mx += y; mx += y;
return boost::move(mx); return boost::move(mx);
} }
template <class CharT, class Traits, class A> inline template <class CharT, class Traits, class Allocator> inline
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) basic_string<CharT, Traits, Allocator> operator+
operator+(const basic_string<CharT,Traits,A>& x, (const basic_string<CharT,Traits,Allocator>& x
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my) ,BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END my)
{ {
typedef typename basic_string<CharT,Traits,A>::size_type size_type; my.insert(my.begin(), x.begin(), x.end());
my.replace(size_type(0), size_type(0), x);
return boost::move(my); return boost::move(my);
} }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator> inline
inline basic_string<CharT,Traits,A> basic_string<CharT, Traits, Allocator> operator+
operator+(const CharT* s, const basic_string<CharT,Traits,A>& y) (const CharT* s, basic_string<CharT, Traits, Allocator> y)
{ {
typedef basic_string<CharT, Traits, A> str_t; y.insert(y.begin(), s, s + Traits::length(s));
typedef typename str_t::reserve_t reserve_t; return y;
reserve_t reserve;
const typename str_t::size_type n = Traits::length(s);
str_t result(reserve, n + y.size());
result.append(s, s + n);
result.append(y);
return boost::move(result);
} }
template <class CharT, class Traits, class A> inline template <class CharT, class Traits, class Allocator> inline
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) basic_string<CharT,Traits,Allocator> operator+
operator+(const CharT* s, (basic_string<CharT,Traits,Allocator> x, const CharT* s)
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
{ {
typedef typename basic_string<CharT,Traits,A>::size_type size_type; x += s;
return boost::move(my.replace(size_type(0), size_type(0), s)); return x;
} }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator> inline
inline basic_string<CharT,Traits,A> basic_string<CharT,Traits,Allocator> operator+
operator+(CharT c, const basic_string<CharT,Traits,A>& y) (CharT c, basic_string<CharT,Traits,Allocator> y)
{ {
typedef basic_string<CharT,Traits,A> str_t; y.insert(y.begin(), c);
typedef typename str_t::reserve_t reserve_t; return y;
reserve_t reserve;
str_t result(reserve, 1 + y.size());
result.push_back(c);
result.append(y);
return boost::move(result);
} }
template <class CharT, class Traits, class A> inline template <class CharT, class Traits, class Allocator> inline
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) basic_string<CharT,Traits,Allocator> operator+
operator+(CharT c, (basic_string<CharT,Traits,Allocator> x, const CharT c)
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
{ {
typedef typename basic_string<CharT,Traits,A>::size_type size_type; x += c;
return boost::move(my.replace(size_type(0), size_type(0), &c, &c + 1)); return x;
}
template <class CharT, class Traits, class A>
inline basic_string<CharT,Traits,A>
operator+(const basic_string<CharT,Traits,A>& x, const CharT* s)
{
typedef basic_string<CharT,Traits,A> str_t;
typedef typename str_t::reserve_t reserve_t;
reserve_t reserve;
const typename str_t::size_type n = Traits::length(s);
str_t result(reserve, x.size() + n, x.get_stored_allocator());
result.append(x);
result.append(s, s + n);
return boost::move(result);
}
template <class CharT, class Traits, class A>
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
operator+(BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx
, const CharT* s)
{
mx += s;
return boost::move(mx);
}
template <class CharT, class Traits, class A>
inline basic_string<CharT,Traits,A>
operator+(const basic_string<CharT,Traits,A>& x, const CharT c)
{
typedef basic_string<CharT,Traits,A> str_t;
typedef typename str_t::reserve_t reserve_t;
reserve_t reserve;
str_t result(reserve, x.size() + 1, x.get_stored_allocator());
result.append(x);
result.push_back(c);
return boost::move(result);
}
template <class CharT, class Traits, class A>
BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
operator+( BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx
, const CharT c)
{
mx += c;
return boost::move(mx);
} }
// Operator== and operator!= // Operator== and operator!=
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator==(const basic_string<CharT,Traits,A>& x, operator==(const basic_string<CharT,Traits,Allocator>& x,
const basic_string<CharT,Traits,A>& y) const basic_string<CharT,Traits,Allocator>& y)
{ {
return x.size() == y.size() && return x.size() == y.size() &&
Traits::compare(x.data(), y.data(), x.size()) == 0; Traits::compare(x.data(), y.data(), x.size()) == 0;
} }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator==(const CharT* s, const basic_string<CharT,Traits,A>& y) operator==(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
{ {
typename basic_string<CharT,Traits,A>::size_type n = Traits::length(s); typename basic_string<CharT,Traits,Allocator>::size_type n = Traits::length(s);
return n == y.size() && Traits::compare(s, y.data(), n) == 0; return n == y.size() && Traits::compare(s, y.data(), n) == 0;
} }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator==(const basic_string<CharT,Traits,A>& x, const CharT* s) operator==(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
{ {
typename basic_string<CharT,Traits,A>::size_type n = Traits::length(s); typename basic_string<CharT,Traits,Allocator>::size_type n = Traits::length(s);
return x.size() == n && Traits::compare(x.data(), s, n) == 0; return x.size() == n && Traits::compare(x.data(), s, n) == 0;
} }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator!=(const basic_string<CharT,Traits,A>& x, operator!=(const basic_string<CharT,Traits,Allocator>& x,
const basic_string<CharT,Traits,A>& y) const basic_string<CharT,Traits,Allocator>& y)
{ return !(x == y); } { return !(x == y); }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator!=(const CharT* s, const basic_string<CharT,Traits,A>& y) operator!=(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
{ return !(s == y); } { return !(s == y); }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator!=(const basic_string<CharT,Traits,A>& x, const CharT* s) operator!=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
{ return !(x == s); } { return !(x == s); }
// Operator< (and also >, <=, and >=). // Operator< (and also >, <=, and >=).
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator<(const basic_string<CharT,Traits,A>& x, const basic_string<CharT,Traits,A>& y) operator<(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y)
{ {
return x.compare(y) < 0; return x.compare(y) < 0;
// return basic_string<CharT,Traits,A> // return basic_string<CharT,Traits,Allocator>
// ::s_compare(x.begin(), x.end(), y.begin(), y.end()) < 0; // ::s_compare(x.begin(), x.end(), y.begin(), y.end()) < 0;
} }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator<(const CharT* s, const basic_string<CharT,Traits,A>& y) operator<(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
{ {
return y.compare(s) > 0; return y.compare(s) > 0;
// basic_string<CharT,Traits,A>::size_type n = Traits::length(s); // basic_string<CharT,Traits,Allocator>::size_type n = Traits::length(s);
// return basic_string<CharT,Traits,A> // return basic_string<CharT,Traits,Allocator>
// ::s_compare(s, s + n, y.begin(), y.end()) < 0; // ::s_compare(s, s + n, y.begin(), y.end()) < 0;
} }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator<(const basic_string<CharT,Traits,A>& x, operator<(const basic_string<CharT,Traits,Allocator>& x,
const CharT* s) const CharT* s)
{ {
return x.compare(s) < 0; return x.compare(s) < 0;
// basic_string<CharT,Traits,A>::size_type n = Traits::length(s); // basic_string<CharT,Traits,Allocator>::size_type n = Traits::length(s);
// return basic_string<CharT,Traits,A> // return basic_string<CharT,Traits,Allocator>
// ::s_compare(x.begin(), x.end(), s, s + n) < 0; // ::s_compare(x.begin(), x.end(), s, s + n) < 0;
} }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator>(const basic_string<CharT,Traits,A>& x, operator>(const basic_string<CharT,Traits,Allocator>& x,
const basic_string<CharT,Traits,A>& y) { const basic_string<CharT,Traits,Allocator>& y) {
return y < x; return y < x;
} }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator>(const CharT* s, const basic_string<CharT,Traits,A>& y) { operator>(const CharT* s, const basic_string<CharT,Traits,Allocator>& y) {
return y < s; return y < s;
} }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator>(const basic_string<CharT,Traits,A>& x, const CharT* s) operator>(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
{ {
return s < x; return s < x;
} }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator<=(const basic_string<CharT,Traits,A>& x, operator<=(const basic_string<CharT,Traits,Allocator>& x,
const basic_string<CharT,Traits,A>& y) const basic_string<CharT,Traits,Allocator>& y)
{ {
return !(y < x); return !(y < x);
} }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator<=(const CharT* s, const basic_string<CharT,Traits,A>& y) operator<=(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
{ return !(y < s); } { return !(y < s); }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator<=(const basic_string<CharT,Traits,A>& x, const CharT* s) operator<=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
{ return !(s < x); } { return !(s < x); }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator>=(const basic_string<CharT,Traits,A>& x, operator>=(const basic_string<CharT,Traits,Allocator>& x,
const basic_string<CharT,Traits,A>& y) const basic_string<CharT,Traits,Allocator>& y)
{ return !(x < y); } { return !(x < y); }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator>=(const CharT* s, const basic_string<CharT,Traits,A>& y) operator>=(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
{ return !(s < y); } { return !(s < y); }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline bool inline bool
operator>=(const basic_string<CharT,Traits,A>& x, const CharT* s) operator>=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
{ return !(x < s); } { return !(x < s); }
// Swap. // Swap.
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline void swap(basic_string<CharT,Traits,A>& x, basic_string<CharT,Traits,A>& y) inline void swap(basic_string<CharT,Traits,Allocator>& x, basic_string<CharT,Traits,Allocator>& y)
{ x.swap(y); } { x.swap(y); }
/// @cond /// @cond
@@ -2786,17 +2725,17 @@ string_fill(std::basic_ostream<CharT, Traits>& os,
} //namespace container_detail { } //namespace container_detail {
/// @endcond /// @endcond
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
std::basic_ostream<CharT, Traits>& std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os, const basic_string<CharT,Traits,A>& s) operator<<(std::basic_ostream<CharT, Traits>& os, const basic_string<CharT,Traits,Allocator>& s)
{ {
typename std::basic_ostream<CharT, Traits>::sentry sentry(os); typename std::basic_ostream<CharT, Traits>::sentry sentry(os);
bool ok = false; bool ok = false;
if (sentry) { if (sentry) {
ok = true; ok = true;
typename basic_string<CharT,Traits,A>::size_type n = s.size(); typename basic_string<CharT,Traits,Allocator>::size_type n = s.size();
typename basic_string<CharT,Traits,A>::size_type pad_len = 0; typename basic_string<CharT,Traits,Allocator>::size_type pad_len = 0;
const bool left = (os.flags() & std::ios::left) != 0; const bool left = (os.flags() & std::ios::left) != 0;
const std::size_t w = os.width(0); const std::size_t w = os.width(0);
std::basic_streambuf<CharT, Traits>* buf = os.rdbuf(); std::basic_streambuf<CharT, Traits>* buf = os.rdbuf();
@@ -2821,9 +2760,9 @@ operator<<(std::basic_ostream<CharT, Traits>& os, const basic_string<CharT,Trait
} }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
std::basic_istream<CharT, Traits>& std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,A>& s) operator>>(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,Allocator>& s)
{ {
typename std::basic_istream<CharT, Traits>::sentry sentry(is); typename std::basic_istream<CharT, Traits>::sentry sentry(is);
@@ -2868,11 +2807,11 @@ operator>>(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,A>&
return is; return is;
} }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
std::basic_istream<CharT, Traits>& std::basic_istream<CharT, Traits>&
getline(std::istream& is, basic_string<CharT,Traits,A>& s,CharT delim) getline(std::istream& is, basic_string<CharT,Traits,Allocator>& s,CharT delim)
{ {
typename basic_string<CharT,Traits,A>::size_type nread = 0; typename basic_string<CharT,Traits,Allocator>::size_type nread = 0;
typename std::basic_istream<CharT, Traits>::sentry sentry(is, true); typename std::basic_istream<CharT, Traits>::sentry sentry(is, true);
if (sentry) { if (sentry) {
std::basic_streambuf<CharT, Traits>* buf = is.rdbuf(); std::basic_streambuf<CharT, Traits>* buf = is.rdbuf();
@@ -2900,15 +2839,15 @@ getline(std::istream& is, basic_string<CharT,Traits,A>& s,CharT delim)
return is; return is;
} }
template <class CharT, class Traits, class A> template <class CharT, class Traits, class Allocator>
inline std::basic_istream<CharT, Traits>& inline std::basic_istream<CharT, Traits>&
getline(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,A>& s) getline(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,Allocator>& s)
{ {
return getline(is, s, '\n'); return getline(is, s, '\n');
} }
template <class Ch, class A> template <class Ch, class Allocator>
inline std::size_t hash_value(basic_string<Ch, std::char_traits<Ch>, A> const& v) inline std::size_t hash_value(basic_string<Ch, std::char_traits<Ch>, Allocator> const& v)
{ {
return hash_range(v.begin(), v.end()); return hash_range(v.begin(), v.end());
} }
@@ -2921,10 +2860,10 @@ namespace boost {
/* /*
//!has_trivial_destructor_after_move<> == true_type //!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations //!specialization for optimizations
template <class C, class T, class A> template <class C, class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, A> > struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, Allocator> >
{ {
static const bool value = has_trivial_destructor<A>::value; static const bool value = has_trivial_destructor<Allocator>::value;
}; };
*/ */
} }

View File

@@ -207,11 +207,11 @@ class vector_iterator
{ return static_cast<const vector_const_iterator<Pointer>&>(*this) - right; } { return static_cast<const vector_const_iterator<Pointer>&>(*this) - right; }
}; };
template <class T, class A> template <class T, class Allocator>
struct vector_value_traits struct vector_value_traits
{ {
typedef T value_type; typedef T value_type;
typedef A allocator_type; typedef Allocator allocator_type;
static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value; static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
static const bool trivial_dctr_after_move = trivial_dctr; static const bool trivial_dctr_after_move = trivial_dctr;
//::boost::has_trivial_destructor_after_move<value_type>::value || trivial_dctr; //::boost::has_trivial_destructor_after_move<value_type>::value || trivial_dctr;
@@ -229,37 +229,37 @@ struct vector_value_traits
//to deallocate values already constructed //to deallocate values already constructed
typedef typename container_detail::if_c typedef typename container_detail::if_c
<trivial_dctr <trivial_dctr
,container_detail::null_scoped_destructor_n<A> ,container_detail::null_scoped_destructor_n<Allocator>
,container_detail::scoped_destructor_n<A> ,container_detail::scoped_destructor_n<Allocator>
>::type OldArrayDestructor; >::type OldArrayDestructor;
//This is the anti-exception array destructor //This is the anti-exception array destructor
//to destroy objects created with copy construction //to destroy objects created with copy construction
typedef typename container_detail::if_c typedef typename container_detail::if_c
<nothrow_copy <nothrow_copy
,container_detail::null_scoped_destructor_n<A> ,container_detail::null_scoped_destructor_n<Allocator>
,container_detail::scoped_destructor_n<A> ,container_detail::scoped_destructor_n<Allocator>
>::type ArrayDestructor; >::type ArrayDestructor;
//This is the anti-exception array deallocator //This is the anti-exception array deallocator
typedef typename container_detail::if_c typedef typename container_detail::if_c
<nothrow_copy <nothrow_copy
,container_detail::null_scoped_array_deallocator<A> ,container_detail::null_scoped_array_deallocator<Allocator>
,container_detail::scoped_array_deallocator<A> ,container_detail::scoped_array_deallocator<Allocator>
>::type ArrayDeallocator; >::type ArrayDeallocator;
}; };
//!This struct deallocates and allocated memory //!This struct deallocates and allocated memory
template <class A> template <class Allocator>
struct vector_alloc_holder struct vector_alloc_holder
{ {
typedef boost::container::allocator_traits<A> allocator_traits_type; typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::pointer pointer; typedef typename allocator_traits_type::pointer pointer;
typedef typename allocator_traits_type::size_type size_type; typedef typename allocator_traits_type::size_type size_type;
typedef typename allocator_traits_type::value_type value_type; typedef typename allocator_traits_type::value_type value_type;
typedef vector_value_traits<value_type, A> value_traits; typedef vector_value_traits<value_type, Allocator> value_traits;
//Constructor, does not throw //Constructor, does not throw
vector_alloc_holder() vector_alloc_holder()
BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor<A>::value) BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor<Allocator>::value)
: members_() : members_()
{} {}
@@ -279,7 +279,7 @@ struct vector_alloc_holder
typedef container_detail::integral_constant<unsigned, 1> allocator_v1; typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
typedef container_detail::integral_constant<unsigned, 2> allocator_v2; typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
typedef container_detail::integral_constant<unsigned, typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::version<A>::value> alloc_version; boost::container::container_detail::version<Allocator>::value> alloc_version;
std::pair<pointer, bool> std::pair<pointer, bool>
allocation_command(allocation_type command, allocation_command(allocation_type command,
size_type limit_size, size_type limit_size,
@@ -325,7 +325,7 @@ struct vector_alloc_holder
} }
struct members_holder struct members_holder
: public A : public Allocator
{ {
private: private:
members_holder(const members_holder&); members_holder(const members_holder&);
@@ -333,11 +333,11 @@ struct vector_alloc_holder
public: public:
template<class Alloc> template<class Alloc>
explicit members_holder(BOOST_FWD_REF(Alloc) alloc) explicit members_holder(BOOST_FWD_REF(Alloc) alloc)
: A(boost::forward<Alloc>(alloc)), m_start(0), m_size(0), m_capacity(0) : Allocator(boost::forward<Alloc>(alloc)), m_start(0), m_size(0), m_capacity(0)
{} {}
members_holder() members_holder()
: A(), m_start(0), m_size(0), m_capacity(0) : Allocator(), m_start(0), m_size(0), m_capacity(0)
{} {}
pointer m_start; pointer m_start;
@@ -352,10 +352,10 @@ struct vector_alloc_holder
container_detail::do_swap(this->members_.m_capacity, x.members_.m_capacity); container_detail::do_swap(this->members_.m_capacity, x.members_.m_capacity);
} }
A &alloc() Allocator &alloc()
{ return members_; } { return members_; }
const A &alloc() const const Allocator &alloc() const
{ return members_; } { return members_; }
protected: protected:
@@ -401,15 +401,15 @@ struct vector_alloc_holder
//! boost::container::vector is similar to std::vector but it's compatible //! boost::container::vector is similar to std::vector but it's compatible
//! with shared memory and memory mapped files. //! with shared memory and memory mapped files.
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class A = std::allocator<T> > template <class T, class Allocator = std::allocator<T> >
#else #else
template <class T, class A> template <class T, class Allocator>
#endif #endif
class vector : private container_detail::vector_alloc_holder<A> class vector : private container_detail::vector_alloc_holder<Allocator>
{ {
/// @cond /// @cond
typedef container_detail::vector_alloc_holder<A> base_t; typedef container_detail::vector_alloc_holder<Allocator> base_t;
typedef allocator_traits<A> allocator_traits_type; typedef allocator_traits<Allocator> allocator_traits_type;
/// @endcond /// @endcond
public: public:
////////////////////////////////////////////// //////////////////////////////////////////////
@@ -418,25 +418,25 @@ class vector : private container_detail::vector_alloc_holder<A>
// //
////////////////////////////////////////////// //////////////////////////////////////////////
typedef T value_type; typedef T value_type;
typedef typename ::boost::container::allocator_traits<A>::pointer pointer; typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer; typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename ::boost::container::allocator_traits<A>::reference reference; typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference; typedef typename ::boost::container::allocator_traits<Allocator>::const_reference const_reference;
typedef typename ::boost::container::allocator_traits<A>::size_type size_type; typedef typename ::boost::container::allocator_traits<Allocator>::size_type size_type;
typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type; typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
typedef A allocator_type; typedef Allocator allocator_type;
typedef allocator_type stored_allocator_type; typedef Allocator stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(container_detail::vector_iterator<pointer>) iterator; typedef BOOST_CONTAINER_IMPDEF(container_detail::vector_iterator<pointer>) iterator;
typedef BOOST_CONTAINER_IMPDEF(container_detail::vector_const_iterator<pointer>) const_iterator; typedef BOOST_CONTAINER_IMPDEF(container_detail::vector_const_iterator<pointer>) const_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator; typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator; typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
/// @cond /// @cond
private: private:
BOOST_COPYABLE_AND_MOVABLE(vector) BOOST_COPYABLE_AND_MOVABLE(vector)
typedef container_detail::advanced_insert_aux_int<T*> advanced_insert_aux_int_t; typedef container_detail::advanced_insert_aux_int<T*> advanced_insert_aux_int_t;
typedef container_detail::vector_value_traits<value_type, A> value_traits; typedef container_detail::vector_value_traits<value_type, Allocator> value_traits;
typedef typename base_t::allocator_v1 allocator_v1; typedef typename base_t::allocator_v1 allocator_v1;
typedef typename base_t::allocator_v2 allocator_v2; typedef typename base_t::allocator_v2 allocator_v2;
@@ -460,7 +460,7 @@ class vector : private container_detail::vector_alloc_holder<A>
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
vector() vector()
BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor<A>::value) BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor<Allocator>::value)
: base_t() : base_t()
{} {}
@@ -469,7 +469,7 @@ class vector : private container_detail::vector_alloc_holder<A>
//! <b>Throws</b>: Nothing //! <b>Throws</b>: Nothing
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
explicit vector(const A& a) BOOST_CONTAINER_NOEXCEPT explicit vector(const Allocator& a) BOOST_CONTAINER_NOEXCEPT
: base_t(a) : base_t(a)
{} {}
@@ -683,15 +683,6 @@ class vector : private container_detail::vector_alloc_holder<A>
allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return this->alloc(); } { return this->alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return this->alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator. //! <b>Effects</b>: Returns a reference to the internal allocator.
//! //!
@@ -703,6 +694,16 @@ class vector : private container_detail::vector_alloc_holder<A>
stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
{ return this->alloc(); } { return this->alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return this->alloc(); }
////////////////////////////////////////////// //////////////////////////////////////////////
// //
// iterators // iterators
@@ -856,7 +857,7 @@ class vector : private container_detail::vector_alloc_holder<A>
else{ else{
const size_type n = new_size - this->size(); const size_type n = new_size - this->size();
this->reserve(new_size); this->reserve(new_size);
container_detail::default_construct_aux_proxy<A, T*> proxy(this->alloc(), n); container_detail::default_construct_aux_proxy<Allocator, T*> proxy(this->alloc(), n);
this->priv_forward_range_insert(this->cend().get_ptr(), n, proxy); this->priv_forward_range_insert(this->cend().get_ptr(), n, proxy);
} }
} }
@@ -920,7 +921,7 @@ class vector : private container_detail::vector_alloc_holder<A>
else{ else{
//We will reuse insert code, so create a dummy input iterator //We will reuse insert code, so create a dummy input iterator
T *dummy_it(container_detail::to_raw_pointer(this->members_.m_start)); T *dummy_it(container_detail::to_raw_pointer(this->members_.m_start));
container_detail::advanced_insert_aux_proxy<A, boost::move_iterator<T*>, T*> container_detail::advanced_insert_aux_proxy<Allocator, boost::move_iterator<T*>, T*>
proxy(this->alloc(), ::boost::make_move_iterator(dummy_it), ::boost::make_move_iterator(dummy_it)); proxy(this->alloc(), ::boost::make_move_iterator(dummy_it), ::boost::make_move_iterator(dummy_it));
//Backwards (and possibly forward) expansion //Backwards (and possibly forward) expansion
if(ret.second){ if(ret.second){
@@ -957,7 +958,7 @@ class vector : private container_detail::vector_alloc_holder<A>
//! //!
//! <b>Complexity</b>: Linear to size(). //! <b>Complexity</b>: Linear to size().
void shrink_to_fit() void shrink_to_fit()
{ priv_shrink_to_fit(alloc_version()); } { this->priv_shrink_to_fit(alloc_version()); }
////////////////////////////////////////////// //////////////////////////////////////////////
// //
@@ -1059,7 +1060,7 @@ class vector : private container_detail::vector_alloc_holder<A>
// //
////////////////////////////////////////////// //////////////////////////////////////////////
//! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range. //! <b>Returns</b>: Allocator pointer such that [data(),data() + size()) is a valid range.
//! For a non-empty vector, data() == &front(). //! For a non-empty vector, data() == &front().
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
@@ -1068,7 +1069,7 @@ class vector : private container_detail::vector_alloc_holder<A>
T* data() BOOST_CONTAINER_NOEXCEPT T* data() BOOST_CONTAINER_NOEXCEPT
{ return container_detail::to_raw_pointer(this->members_.m_start); } { return container_detail::to_raw_pointer(this->members_.m_start); }
//! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range. //! <b>Returns</b>: Allocator pointer such that [data(),data() + size()) is a valid range.
//! For a non-empty vector, data() == &front(). //! For a non-empty vector, data() == &front().
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
@@ -1101,7 +1102,7 @@ class vector : private container_detail::vector_alloc_holder<A>
++this->members_.m_size; ++this->members_.m_size;
} }
else{ else{
typedef container_detail::advanced_insert_aux_emplace<A, T*, Args...> type; typedef container_detail::advanced_insert_aux_emplace<Allocator, T*, Args...> type;
type &&proxy = type(this->alloc(), ::boost::forward<Args>(args)...); type &&proxy = type(this->alloc(), ::boost::forward<Args>(args)...);
this->priv_forward_range_insert(back_pos, 1, proxy); this->priv_forward_range_insert(back_pos, 1, proxy);
} }
@@ -1122,7 +1123,7 @@ class vector : private container_detail::vector_alloc_holder<A>
{ {
//Just call more general insert(pos, size, value) and return iterator //Just call more general insert(pos, size, value) and return iterator
size_type pos_n = position - cbegin(); size_type pos_n = position - cbegin();
typedef container_detail::advanced_insert_aux_emplace<A, T*, Args...> type; typedef container_detail::advanced_insert_aux_emplace<Allocator, T*, Args...> type;
type &&proxy = type(this->alloc(), ::boost::forward<Args>(args)...); type &&proxy = type(this->alloc(), ::boost::forward<Args>(args)...);
this->priv_forward_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); return iterator(this->members_.m_start + pos_n);
@@ -1143,7 +1144,7 @@ class vector : private container_detail::vector_alloc_holder<A>
} \ } \
else{ \ else{ \
container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \ container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
<A, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \ <Allocator, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
this->priv_forward_range_insert(back_pos, 1, proxy); \ this->priv_forward_range_insert(back_pos, 1, proxy); \
} \ } \
@@ -1155,7 +1156,7 @@ class vector : private container_detail::vector_alloc_holder<A>
{ \ { \
size_type pos_n = pos - cbegin(); \ size_type pos_n = pos - cbegin(); \
container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \ container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg) \
<A, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \ <Allocator, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
this->priv_forward_range_insert(container_detail::to_raw_pointer(pos.get_ptr()), 1,proxy);\ this->priv_forward_range_insert(container_detail::to_raw_pointer(pos.get_ptr()), 1,proxy);\
return iterator(this->members_.m_start + pos_n); \ return iterator(this->members_.m_start + pos_n); \
@@ -1263,7 +1264,7 @@ class vector : private container_detail::vector_alloc_holder<A>
{ {
const size_type n_pos = pos - this->cbegin(); const size_type n_pos = pos - this->cbegin();
const size_type n = std::distance(first, last); const size_type n = std::distance(first, last);
container_detail::advanced_insert_aux_proxy<A, FwdIt, T*> proxy(this->alloc(), first, last); container_detail::advanced_insert_aux_proxy<Allocator, FwdIt, T*> proxy(this->alloc(), first, last);
this->priv_forward_range_insert(pos.get_ptr(), n, proxy); this->priv_forward_range_insert(pos.get_ptr(), n, proxy);
return this->begin() + n_pos; return this->begin() + n_pos;
} }
@@ -1394,10 +1395,7 @@ class vector : private container_detail::vector_alloc_holder<A>
} }
} }
template<class AllocVersion> void priv_shrink_to_fit(allocator_v1)
void priv_shrink_to_fit( AllocVersion
, typename container_detail::enable_if_c<
container_detail::is_same<AllocVersion, allocator_v1>::value >::type * = 0)
{ {
if(this->members_.m_capacity){ if(this->members_.m_capacity){
if(!this->size()){ if(!this->size()){
@@ -1412,7 +1410,7 @@ class vector : private container_detail::vector_alloc_holder<A>
if(real_cap < this->capacity()){ if(real_cap < this->capacity()){
//We will reuse insert code, so create a dummy input iterator //We will reuse insert code, so create a dummy input iterator
T *dummy_it(container_detail::to_raw_pointer(this->members_.m_start)); T *dummy_it(container_detail::to_raw_pointer(this->members_.m_start));
container_detail::advanced_insert_aux_proxy<A, boost::move_iterator<T*>, T*> container_detail::advanced_insert_aux_proxy<Allocator, boost::move_iterator<T*>, T*>
proxy(this->alloc(), ::boost::make_move_iterator(dummy_it), ::boost::make_move_iterator(dummy_it)); proxy(this->alloc(), ::boost::make_move_iterator(dummy_it), ::boost::make_move_iterator(dummy_it));
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
++this->num_alloc; ++this->num_alloc;
@@ -1431,10 +1429,7 @@ class vector : private container_detail::vector_alloc_holder<A>
} }
} }
template<class AllocVersion> void priv_shrink_to_fit(allocator_v2)
void priv_shrink_to_fit(AllocVersion
, typename container_detail::enable_if_c<
!container_detail::is_same<AllocVersion, allocator_v1>::value >::type * = 0)
{ {
if(this->members_.m_capacity){ if(this->members_.m_capacity){
if(!size()){ if(!size()){
@@ -1442,7 +1437,7 @@ class vector : private container_detail::vector_alloc_holder<A>
} }
else{ else{
size_type received_size; size_type received_size;
if(this->alloc().allocation_command if(this->allocation_command
( shrink_in_place | nothrow_allocation ( shrink_in_place | nothrow_allocation
, this->capacity(), this->size() , this->capacity(), this->size()
, received_size, this->members_.m_start).first){ , received_size, this->members_.m_start).first){
@@ -1535,6 +1530,10 @@ class vector : private container_detail::vector_alloc_holder<A>
//Loop for each insertion backwards, first moving the elements after the insertion point, //Loop for each insertion backwards, first moving the elements after the insertion point,
//then inserting the element. //then inserting the element.
while(insertions_left){ while(insertions_left){
if(do_skip){
size_type n = *(--last_skip_it);
std::advance(last_value_it, -difference_type(n));
}
const size_type pos = static_cast<size_type>(*(--last_position_it)); const size_type pos = static_cast<size_type>(*(--last_position_it));
BOOST_ASSERT(pos <= old_size_pos); BOOST_ASSERT(pos <= old_size_pos);
//If needed shift the range after the insertion point and the previous insertion point. //If needed shift the range after the insertion point and the previous insertion point.
@@ -1569,12 +1568,6 @@ class vector : private container_detail::vector_alloc_holder<A>
//Insert the new value in the already constructed range //Insert the new value in the already constructed range
begin_ptr[pos + insertions_left - 1] = *(--last_value_it); begin_ptr[pos + insertions_left - 1] = *(--last_value_it);
} }
if(do_skip){
size_type n = *(--last_skip_it);
while(n--){
--last_value_it;
}
}
--insertions_left; --insertions_left;
hole_size = new_hole_size; hole_size = new_hole_size;
next_pos = pos; next_pos = pos;
@@ -1599,7 +1592,7 @@ class vector : private container_detail::vector_alloc_holder<A>
//| prefix | range | suffix |raw_mem ~ //| prefix | range | suffix |raw_mem ~
//|____________|_______|__________________|_____________~ //|____________|_______|__________________|_____________~
// //
//New situation in Case A (hole_size == 0): //New situation in Case Allocator (hole_size == 0):
// range is moved through move assignments // range is moved through move assignments
// //
// first_pos last_pos limit_pos // first_pos last_pos limit_pos
@@ -1643,7 +1636,7 @@ class vector : private container_detail::vector_alloc_holder<A>
T* const last_ptr = begin_ptr + last_pos; T* const last_ptr = begin_ptr + last_pos;
size_type hole_size = 0; size_type hole_size = 0;
//Case A: //Case Allocator:
if((last_pos + shift_count) <= limit_pos){ if((last_pos + shift_count) <= limit_pos){
//All move assigned //All move assigned
boost::move_backward(first_ptr, last_ptr, last_ptr + shift_count); boost::move_backward(first_ptr, last_ptr, last_ptr + shift_count);
@@ -2057,31 +2050,31 @@ class vector : private container_detail::vector_alloc_holder<A>
/// @endcond /// @endcond
}; };
template <class T, class A> template <class T, class Allocator>
inline bool inline bool
operator==(const vector<T, A>& x, const vector<T, A>& y) operator==(const vector<T, Allocator>& x, const vector<T, Allocator>& y)
{ {
//Check first size and each element if needed //Check first size and each element if needed
return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin());
} }
template <class T, class A> template <class T, class Allocator>
inline bool inline bool
operator!=(const vector<T, A>& x, const vector<T, A>& y) operator!=(const vector<T, Allocator>& x, const vector<T, Allocator>& y)
{ {
//Check first size and each element if needed //Check first size and each element if needed
return x.size() != y.size() || !std::equal(x.begin(), x.end(), y.begin()); return x.size() != y.size() || !std::equal(x.begin(), x.end(), y.begin());
} }
template <class T, class A> template <class T, class Allocator>
inline bool inline bool
operator<(const vector<T, A>& x, const vector<T, A>& y) operator<(const vector<T, Allocator>& x, const vector<T, Allocator>& y)
{ {
return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
} }
template <class T, class A> template <class T, class Allocator>
inline void swap(vector<T, A>& x, vector<T, A>& y) inline void swap(vector<T, Allocator>& x, vector<T, Allocator>& y)
{ x.swap(y); } { x.swap(y); }
}} }}
@@ -2094,10 +2087,10 @@ namespace boost {
//!has_trivial_destructor_after_move<> == true_type //!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations //!specialization for optimizations
template <class T, class A> template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::vector<T, A> > struct has_trivial_destructor_after_move<boost::container::vector<T, Allocator> >
{ {
static const bool value = has_trivial_destructor<A>::value; static const bool value = has_trivial_destructor<Allocator>::value;
}; };
*/ */

View File

@@ -2,6 +2,9 @@
->Add an example with stateful allocators ->Add an example with stateful allocators
->Add test to check convertible types in push_back/insert ->Add test to check convertible types in push_back/insert
->Add SCARY iterators. ->Add SCARY iterators.
->Align with C++11 [multi]map::insert(P &&p) overload.
->Unify all allocator version traits in one class (starting from stable_vector_detail::allocator_version_wrapper)
maybe in allocator_traits?
Review allocator traits Review allocator traits
@@ -53,22 +56,10 @@ Add hash for containers
Add std:: hashing support Add std:: hashing support
Take out from class definition iterators in slist & list
Fix trivial destructor after move and other optimizing traits Fix trivial destructor after move and other optimizing traits
Define typedefs exactly like the standard to generate better documentation. for implementation defined types:
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#define BOOST_CONTAINER_IMPLDEF(TYPE) TYPE
#else
#define BOOST_CONTAINER_IMPLDEF(TYPE) implementation_defined
#endif
Mark previous() in slist/and forward_list as non-standard Mark previous() in slist/and forward_list as non-standard
Replace all insert_const_ref_type with BOOST_MOVE_CONVERSION_AWARE_CATCH_XXX
Function order: Function order:
----------type------------ ----------type------------

View File

@@ -85,7 +85,8 @@ struct string_literals<char>
{ return "Suffix"; } { return "Suffix"; }
static const char *LongString() static const char *LongString()
{ return "LongLongLongLongLongLongLongLongLongLongLongLongLongString"; } { return "LongLongLongLongLongLongLongLongLongLongLongLongLongString"; }
static char Char()
{ return 'C'; }
static void sprintf_number(char *buf, int number) static void sprintf_number(char *buf, int number)
{ {
std::sprintf(buf, "%i", number); std::sprintf(buf, "%i", number);
@@ -103,7 +104,8 @@ struct string_literals<wchar_t>
{ return L"Suffix"; } { return L"Suffix"; }
static const wchar_t *LongString() static const wchar_t *LongString()
{ return L"LongLongLongLongLongLongLongLongLongLongLongLongLongString"; } { return L"LongLongLongLongLongLongLongLongLongLongLongLongLongString"; }
static wchar_t Char()
{ return L'C'; }
static void sprintf_number(wchar_t *buffer, unsigned int number) static void sprintf_number(wchar_t *buffer, unsigned int number)
{ {
//For compilers without wsprintf, print it backwards //For compilers without wsprintf, print it backwards
@@ -398,6 +400,22 @@ int string_test()
if(!StringEqual()(bs4, ss4)){ if(!StringEqual()(bs4, ss4)){
return 1; return 1;
} }
bs2 = string_literals<CharType>::String();
ss2 = string_literals<CharType>::String();
bs4 = string_literals<CharType>::Char() + bs2;
ss4 = string_literals<CharType>::Char() + ss2;
if(!StringEqual()(bs4, ss4)){
return 1;
}
bs2 = string_literals<CharType>::String();
ss2 = string_literals<CharType>::String();
bs4 = bs2 + string_literals<CharType>::Char();
ss4 = ss2 + string_literals<CharType>::Char();
if(!StringEqual()(bs4, ss4)){
return 1;
}
} }
//When done, delete vector //When done, delete vector