|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r80686 - in trunk: boost/container boost/container/detail libs/container/doc libs/container/proj
From: igaztanaga_at_[hidden]
Date: 2012-09-24 06:27:07
Author: igaztanaga
Date: 2012-09-24 06:27:02 EDT (Mon, 24 Sep 2012)
New Revision: 80686
URL: http://svn.boost.org/trac/boost/changeset/80686
Log:
Reordered sequence container types and functions to improve Doxygen documentation
Text files modified:
trunk/boost/container/allocator_traits.hpp | 24
trunk/boost/container/detail/iterators.hpp | 17
trunk/boost/container/detail/workaround.hpp | 4
trunk/boost/container/list.hpp | 938 ++++++++++++++++++-------------
trunk/boost/container/slist.hpp | 1171 +++++++++++++++++++++++----------------
trunk/boost/container/stable_vector.hpp | 451 ++++++++-------
trunk/boost/container/vector.hpp | 879 ++++++++++++-----------------
trunk/libs/container/doc/Jamfile.v2 | 2
trunk/libs/container/doc/container.qbk | 4
trunk/libs/container/proj/to-do.txt | 109 +++
10 files changed, 1987 insertions(+), 1612 deletions(-)
Modified: trunk/boost/container/allocator_traits.hpp
==============================================================================
--- trunk/boost/container/allocator_traits.hpp (original)
+++ trunk/boost/container/allocator_traits.hpp 2012-09-24 06:27:02 EDT (Mon, 24 Sep 2012)
@@ -70,41 +70,41 @@
typedef unspecified pointer;
//! Alloc::const_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<const
//!
- typedef unspecified const_pointer;
+ typedef see_documentation const_pointer;
//! Non-standard extension
//! Alloc::reference if such a type exists; otherwise, value_type&
- typedef unspecified reference;
+ typedef see_documentation reference;
//! Non-standard extension
//! Alloc::const_reference if such a type exists ; otherwise, const value_type&
- typedef unspecified const_reference;
+ typedef see_documentation const_reference;
//! Alloc::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>.
//!
- typedef unspecified void_pointer;
+ typedef see_documentation void_pointer;
//! Alloc::const_void_pointer if such a type exists ; otherwis e, pointer_traits<pointer>::rebind<const
//!
- typedef unspecified const_void_pointer;
+ typedef see_documentation const_void_pointer;
//! Alloc::difference_type if such a type exists ; otherwise, pointer_traits<pointer>::difference_type.
//!
- typedef unspecified difference_type;
+ typedef see_documentation difference_type;
//! Alloc::size_type if such a type exists ; otherwise, make_unsigned<difference_type>::type
//!
- typedef unspecified size_type;
+ typedef see_documentation size_type;
//! Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant
//! type with internal constant static member `value` == false.
- typedef unspecified propagate_on_container_copy_assignment;
+ typedef see_documentation propagate_on_container_copy_assignment;
//! Alloc::propagate_on_container_move_assignment if such a type exists, otherwise an integral_constant
//! type with internal constant static member `value` == false.
- typedef unspecified propagate_on_container_move_assignment;
+ typedef see_documentation propagate_on_container_move_assignment;
//! Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant
//! type with internal constant static member `value` == false.
- typedef unspecified propagate_on_container_swap;
+ typedef see_documentation propagate_on_container_swap;
//! Defines an allocator: Alloc::rebind<T>::other if such a type exists; otherwise, Alloc<T, Args>
//! if Alloc is a class template instantiation of the form Alloc<U, Args>, where Args is zero or
//! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed.
//!
//! In C++03 compilers `rebind_alloc` is a struct derived from an allocator
//! deduced by previously detailed rules.
- template <class T> using rebind_alloc = unspecified;
+ template <class T> using rebind_alloc = see_documentation;
//! In C++03 compilers `rebind_traits` is a struct derived from
//! `allocator_traits<OtherAlloc>`, where `OtherAlloc` is
@@ -115,7 +115,7 @@
//! `type` is an allocator related to Alloc deduced deduced by rules explained in `rebind_alloc`.
template <class T>
struct portable_rebind_alloc
- { typedef unspecified_type type; };
+ { typedef see_documentation type; };
#else
//pointer
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
Modified: trunk/boost/container/detail/iterators.hpp
==============================================================================
--- trunk/boost/container/detail/iterators.hpp (original)
+++ trunk/boost/container/detail/iterators.hpp 2012-09-24 06:27:02 EDT (Mon, 24 Sep 2012)
@@ -585,6 +585,22 @@
static const bool value = false;
};
+template<class T, class IIterator>
+struct iiterator_types
+{
+ typedef typename std::iterator_traits<IIterator>::pointer it_pointer;
+ typedef typename std::iterator_traits<IIterator>::difference_type difference_type;
+ typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
+ template rebind_pointer<T>::type pointer;
+ typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
+ template rebind_pointer<const T>::type const_pointer;
+ typedef typename ::boost::intrusive::
+ pointer_traits<pointer>::reference reference;
+ typedef typename ::boost::intrusive::
+ pointer_traits<const_pointer>::reference const_reference;
+};
+
+
} //namespace container_detail {
} //namespace container {
@@ -593,4 +609,3 @@
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
-
Modified: trunk/boost/container/detail/workaround.hpp
==============================================================================
--- trunk/boost/container/detail/workaround.hpp (original)
+++ trunk/boost/container/detail/workaround.hpp 2012-09-24 06:27:02 EDT (Mon, 24 Sep 2012)
@@ -31,6 +31,10 @@
#define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST
#endif
+//Macros for documentation purposes. For code, expands to the argument
+#define BOOST_CONTAINER_IMPDEF(TYPE) TYPE
+#define BOOST_CONTAINER_SEEDOC(TYPE) TYPE
+
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
Modified: trunk/boost/container/list.hpp
==============================================================================
--- trunk/boost/container/list.hpp (original)
+++ trunk/boost/container/list.hpp 2012-09-24 06:27:02 EDT (Mon, 24 Sep 2012)
@@ -94,6 +94,111 @@
typedef container_type type ;
};
+template<class T, class IIterator>
+class list_const_iterator
+ : public std::iterator< std::bidirectional_iterator_tag, T
+ , typename iiterator_types<T, IIterator>::difference_type
+ , typename iiterator_types<T, IIterator>::const_pointer
+ , typename iiterator_types<T, IIterator>::const_reference>
+{
+ protected:
+
+ IIterator m_it;
+
+ public:
+ typedef typename iiterator_types<T, IIterator>::const_pointer const_pointer;
+ typedef typename iiterator_types<T, IIterator>::const_reference const_reference;
+
+ //Constructors
+ list_const_iterator()
+ : m_it()
+ {}
+
+ explicit list_const_iterator(const IIterator &it)
+ : m_it(it)
+ {}
+
+ //Pointer like operators
+ const_reference operator*() const
+ { return this->m_it->m_data; }
+
+ const_pointer operator->() const
+ { return ::boost::intrusive::pointer_traits<const_pointer>::to_pointer(this->m_it->m_data); }
+
+ //Increment / Decrement
+ list_const_iterator& operator++()
+ { ++this->m_it; return *this; }
+
+ list_const_iterator operator++(int)
+ { IIterator tmp = this->m_it; ++*this; return list_const_iterator(tmp); }
+
+ list_const_iterator& operator--()
+ { --this->m_it; return *this; }
+
+ list_const_iterator operator--(int)
+ { IIterator tmp = this->m_it; --*this; return list_const_iterator(tmp); }
+
+ //Comparison operators
+ friend bool operator== (const list_const_iterator& l, const list_const_iterator& r)
+ { return l.m_it == r.m_it; }
+
+ friend bool operator!= (const list_const_iterator& l, const list_const_iterator& r)
+ { return l.m_it != r.m_it; }
+
+ IIterator &get()
+ { return this->m_it; }
+
+ const IIterator &get() const
+ { return this->m_it; }
+};
+
+template<class T, class IIterator>
+class list_iterator
+ : public list_const_iterator<T, IIterator>
+{
+ private:
+ typedef list_const_iterator<T, IIterator> const_iterator;
+
+ public:
+ typedef typename iiterator_types<T, IIterator>::pointer pointer;
+ typedef typename iiterator_types<T, IIterator>::reference reference;
+
+ //Constructors
+ list_iterator()
+ : const_iterator()
+ {}
+
+ explicit list_iterator(const IIterator &it)
+ : const_iterator(it)
+ {}
+
+ //Pointer like operators
+ reference operator*() const
+ { return this->m_it->m_data; }
+
+ pointer operator->() const
+ { return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->m_it->m_data); }
+
+ //Increment / Decrement
+ list_iterator& operator++()
+ { ++this->m_it; return *this; }
+
+ list_iterator operator++(int)
+ { IIterator tmp = this->m_it; ++*this; return list_iterator(tmp); }
+
+ list_iterator& operator--()
+ { --this->m_it; return *this; }
+
+ list_iterator operator--(int)
+ { IIterator tmp = this->m_it; --*this; return list_iterator(tmp); }
+
+ IIterator &get()
+ { return this->m_it; }
+
+ const IIterator &get() const
+ { return this->m_it; }
+};
+
} //namespace container_detail {
/// @endcond
@@ -119,7 +224,6 @@
/// @cond
typedef typename
container_detail::intrusive_list_type<A>::type Icont;
- typedef list <T, A> ThisType;
typedef container_detail::node_alloc_holder<A, Icont> AllocHolder;
typedef typename AllocHolder::NodePtr NodePtr;
typedef typename AllocHolder::NodeAlloc NodeAlloc;
@@ -159,141 +263,39 @@
bool operator()(const Node &a) const
{ return static_cast<const Pred&>(*this)(a.m_data); }
};
- /// @endcond
-
- public:
- //! The type of object, T, stored in the list
- typedef T value_type;
- //! Pointer to T
- typedef typename allocator_traits_type::pointer pointer;
- //! Const pointer to T
- typedef typename allocator_traits_type::const_pointer const_pointer;
- //! Reference to T
- typedef typename allocator_traits_type::reference reference;
- //! Const reference to T
- typedef typename allocator_traits_type::const_reference const_reference;
- //! An unsigned integral type
- typedef typename allocator_traits_type::size_type size_type;
- //! A signed integral type
- typedef typename allocator_traits_type::difference_type difference_type;
- //! The allocator type
- typedef A allocator_type;
- //! Non-standard extension: the stored allocator type
- typedef NodeAlloc stored_allocator_type;
- /// @cond
- private:
BOOST_COPYABLE_AND_MOVABLE(list)
- typedef difference_type list_difference_type;
- typedef pointer list_pointer;
- typedef const_pointer list_const_pointer;
- typedef reference list_reference;
- typedef const_reference list_const_reference;
- /// @endcond
-
- public:
- //! Const iterator used to iterate through a list.
- class const_iterator
- /// @cond
- : public std::iterator<std::bidirectional_iterator_tag,
- value_type, list_difference_type,
- list_const_pointer, list_const_reference>
- {
-
- protected:
- typename Icont::iterator m_it;
- explicit const_iterator(typename Icont::iterator it) : m_it(it){}
- void prot_incr() { ++m_it; }
- void prot_decr() { --m_it; }
-
- private:
- typename Icont::iterator get()
- { return this->m_it; }
-
- public:
- friend class list<T, A>;
- typedef list_difference_type difference_type;
-
- //Constructors
- const_iterator()
- : m_it()
- {}
-
- //Pointer like operators
- const_reference operator*() const
- { return m_it->m_data; }
-
- const_pointer operator->() const
- { return const_pointer(&m_it->m_data); }
-
- //Increment / Decrement
- const_iterator& operator++()
- { prot_incr(); return *this; }
-
- const_iterator operator++(int)
- { typename Icont::iterator tmp = m_it; ++*this; return const_iterator(tmp); }
-
- const_iterator& operator--()
- { prot_decr(); return *this; }
-
- const_iterator operator--(int)
- { typename Icont::iterator tmp = m_it; --*this; return const_iterator(tmp); }
-
- //Comparison operators
- bool operator== (const const_iterator& r) const
- { return m_it == r.m_it; }
-
- bool operator!= (const const_iterator& r) const
- { return m_it != r.m_it; }
- }
- /// @endcond
- ;
-
- //! Iterator used to iterate through a list
- class iterator
- /// @cond
- : public const_iterator
- {
-
- private:
- explicit iterator(typename Icont::iterator it)
- : const_iterator(it)
- {}
-
- typename Icont::iterator get()
- { return this->m_it; }
-
- public:
- friend class list<T, A>;
- typedef list_pointer pointer;
- typedef list_reference reference;
-
- //Constructors
- iterator(){}
-
- //Pointer like operators
- reference operator*() const { return this->m_it->m_data; }
- pointer operator->() const { return pointer(&this->m_it->m_data); }
-
- //Increment / Decrement
- iterator& operator++()
- { this->prot_incr(); return *this; }
-
- iterator operator++(int)
- { typename Icont::iterator tmp = this->m_it; ++*this; return iterator(tmp); }
-
- iterator& operator--()
- { this->prot_decr(); return *this; }
- iterator operator--(int)
- { iterator tmp = *this; --*this; return tmp; }
- };
+ typedef container_detail::list_iterator<T, typename Icont::iterator> iterator_impl;
+ typedef container_detail::list_const_iterator<T, typename Icont::iterator>const_iterator_impl;
/// @endcond
- //! Iterator used to iterate backwards through a list.
- typedef std::reverse_iterator<iterator> reverse_iterator;
- //! Const iterator used to iterate backwards through a list.
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ public:
+ //////////////////////////////////////////////
+ //
+ // types
+ //
+ //////////////////////////////////////////////
+
+ typedef T value_type;
+ typedef typename ::boost::container::allocator_traits<A>::pointer pointer;
+ typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer;
+ typedef typename ::boost::container::allocator_traits<A>::reference reference;
+ typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference;
+ typedef typename ::boost::container::allocator_traits<A>::size_type size_type;
+ typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type;
+ typedef A allocator_type;
+ typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type;
+ typedef BOOST_CONTAINER_IMPDEF(iterator_impl) 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<const_iterator>) const_reverse_iterator;
+
+ //////////////////////////////////////////////
+ //
+ // construct/copy/destroy
+ //
+ //////////////////////////////////////////////
//! <b>Effects</b>: Default constructs a list.
//!
@@ -404,6 +406,98 @@
~list()
{} //AllocHolder clears the list
+ //! <b>Effects</b>: Makes *this contain the same elements as x.
+ //!
+ //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+ //! of each of x's elements.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in x.
+ list& operator=(BOOST_COPY_ASSIGN_REF(list) x)
+ {
+ if (&x != this){
+ NodeAlloc &this_alloc = this->node_alloc();
+ const NodeAlloc &x_alloc = x.node_alloc();
+ container_detail::bool_<allocator_traits_type::
+ propagate_on_container_copy_assignment::value> flag;
+ if(flag && this_alloc != x_alloc){
+ this->clear();
+ }
+ this->AllocHolder::copy_assign_alloc(x);
+ this->assign(x.begin(), x.end());
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
+ //!
+ //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
+ //! before the function.
+ //!
+ //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ list& operator=(BOOST_RV_REF(list) x)
+ {
+ if (&x != this){
+ NodeAlloc &this_alloc = this->node_alloc();
+ NodeAlloc &x_alloc = x.node_alloc();
+ //If allocators are equal we can just swap pointers
+ if(this_alloc == x_alloc){
+ //Destroy and swap pointers
+ this->clear();
+ this->icont() = boost::move(x.icont());
+ //Move allocator if needed
+ this->AllocHolder::move_assign_alloc(x);
+ }
+ //If unequal allocators, then do a one by one move
+ else{
+ typedef typename std::iterator_traits<iterator>::iterator_category ItCat;
+ this->assign( boost::make_move_iterator(x.begin())
+ , boost::make_move_iterator(x.end()));
+ }
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Assigns the n copies of val to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void assign(size_type n, const T& val)
+ {
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+ return this->assign(cvalue_iterator(val, n), cvalue_iterator());
+ }
+
+ //! <b>Effects</b>: Assigns the the range [first, last) to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's constructor from dereferencing InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ template <class InpIt>
+ void assign(InpIt first, InpIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InpIt, size_type>::value
+ >::type * = 0
+ #endif
+ )
+ {
+ iterator first1 = this->begin();
+ const iterator last1 = this->end();
+ for ( ; first1 != last1 && first != last; ++first1, ++first)
+ *first1 = *first;
+ if (first == last)
+ this->erase(first1, last1);
+ else{
+ this->insert(last1, first, last);
+ }
+ }
+
//! <b>Effects</b>: Returns a copy of the internal allocator.
//!
//! <b>Throws</b>: If allocator's copy constructor throws.
@@ -412,19 +506,27 @@
allocator_type get_allocator() const
{ return allocator_type(this->node_alloc()); }
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //!
+ //! <b>Throws</b>: If allocator's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
const stored_allocator_type &get_stored_allocator() const
{ return this->node_alloc(); }
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //!
+ //! <b>Throws</b>: If allocator's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
stored_allocator_type &get_stored_allocator()
{ return this->node_alloc(); }
- //! <b>Effects</b>: Erases all the elements of the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of elements in the list.
- void clear()
- { AllocHolder::clear(alloc_version()); }
+ //////////////////////////////////////////////
+ //
+ // iterators
+ //
+ //////////////////////////////////////////////
//! <b>Effects</b>: Returns an iterator to the first element contained in the list.
//!
@@ -528,6 +630,12 @@
const_reverse_iterator crend() const
{ return const_reverse_iterator(this->cbegin()); }
+ //////////////////////////////////////////////
+ //
+ // capacity
+ //
+ //////////////////////////////////////////////
+
//! <b>Effects</b>: Returns true if the list contains no elements.
//!
//! <b>Throws</b>: Nothing.
@@ -552,61 +660,38 @@
size_type max_size() const
{ return AllocHolder::max_size(); }
- #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- //! <b>Effects</b>: Inserts a copy of x at the beginning of the list.
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- void push_front(const T &x);
-
- //! <b>Effects</b>: Constructs a new element in the beginning of the list
- //! and moves the resources of mx to this new element.
- //!
- //! <b>Throws</b>: If memory allocation throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- void push_front(T &&x);
- #else
- BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
- #endif
-
- #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- //! <b>Effects</b>: Inserts a copy of x at the end of the list.
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- void push_back(const T &x);
-
- //! <b>Effects</b>: Constructs a new element in the end of the list
- //! and moves the resources of mx to this new element.
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are default constructed.
//!
- //! <b>Throws</b>: If memory allocation throws.
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
//!
- //! <b>Complexity</b>: Amortized constant time.
- void push_back(T &&x);
- #else
- BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
- #endif
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size)
+ {
+ if(!priv_try_shrink(new_size)){
+ typedef default_construct_iterator<value_type, difference_type> default_iterator;
+ this->insert(this->cend(), default_iterator(new_size - this->size()), default_iterator());
+ }
+ }
- //! <b>Effects</b>: Removes the first element from the list.
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are copy constructed from x.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
//!
- //! <b>Complexity</b>: Amortized constant time.
- void pop_front()
- { this->erase(this->cbegin()); }
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size, const T& x)
+ {
+ if(!priv_try_shrink(new_size)){
+ this->insert(this->cend(), new_size - this->size(), x);
+ }
+ }
- //! <b>Effects</b>: Removes the last element from the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- void pop_back()
- { const_iterator tmp = this->cend(); this->erase(--tmp); }
+ //////////////////////////////////////////////
+ //
+ // element access
+ //
+ //////////////////////////////////////////////
//! <b>Requires</b>: !empty()
//!
@@ -652,95 +737,146 @@
const_reference back() const
{ return *(--this->end()); }
- //! <b>Effects</b>: Inserts or erases elements at the end such that
- //! the size becomes n. New elements are copy constructed from x.
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //////////////////////////////////////////////
+ //
+ // modifiers
+ //
+ //////////////////////////////////////////////
+
+ #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the end of the list.
//!
- //! <b>Complexity</b>: Linear to the difference between size() and new_size.
- void resize(size_type new_size, const T& x)
- {
- if(!priv_try_shrink(new_size)){
- this->insert(this->cend(), new_size - this->size(), x);
- }
- }
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant
+ template <class... Args>
+ void emplace_back(Args&&... args)
+ { this->emplace(this->cend(), boost::forward<Args>(args)...); }
- //! <b>Effects</b>: Inserts or erases elements at the end such that
- //! the size becomes n. New elements are default constructed.
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the beginning of the list.
//!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
//!
- //! <b>Complexity</b>: Linear to the difference between size() and new_size.
- void resize(size_type new_size)
+ //! <b>Complexity</b>: Constant
+ template <class... Args>
+ void emplace_front(Args&&... args)
+ { this->emplace(this->cbegin(), boost::forward<Args>(args)...); }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... before p.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant
+ template <class... Args>
+ iterator emplace(const_iterator p, Args&&... args)
{
- if(!priv_try_shrink(new_size)){
- typedef default_construct_iterator<value_type, difference_type> default_iterator;
- this->insert(this->cend(), default_iterator(new_size - this->size()), default_iterator());
- }
+ NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
+ return iterator(this->icont().insert(p.get(), *pnode));
}
- //! <b>Effects</b>: Swaps the contents of *this and x.
+ #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+ void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
+ { \
+ this->emplace(this->cend() \
+ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
+ } \
+ \
+ BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+ void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
+ { \
+ this->emplace(this->cbegin() \
+ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
+ } \
+ \
+ BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+ iterator emplace(const_iterator p \
+ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
+ { \
+ NodePtr pnode (AllocHolder::create_node \
+ (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
+ return iterator(this->icont().insert(p.get(), *pnode)); \
+ } \
//!
- //! <b>Throws</b>: Nothing.
+ #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+ #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ //! <b>Effects</b>: Inserts a copy of x at the beginning of the list.
//!
- //! <b>Complexity</b>: Constant.
- void swap(ThisType& x)
- { AllocHolder::swap(x); }
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_front(const T &x);
- //! <b>Effects</b>: Makes *this contain the same elements as x.
+ //! <b>Effects</b>: Constructs a new element in the beginning of the list
+ //! and moves the resources of mx to this new element.
//!
- //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
- //! of each of x's elements.
+ //! <b>Throws</b>: If memory allocation throws.
//!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_front(T &&x);
+ #else
+ BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
+ #endif
+
+ #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ //! <b>Effects</b>: Inserts a copy of x at the end of the list.
//!
- //! <b>Complexity</b>: Linear to the number of elements in x.
- ThisType& operator=(BOOST_COPY_ASSIGN_REF(ThisType) x)
- {
- if (&x != this){
- NodeAlloc &this_alloc = this->node_alloc();
- const NodeAlloc &x_alloc = x.node_alloc();
- container_detail::bool_<allocator_traits_type::
- propagate_on_container_copy_assignment::value> flag;
- if(flag && this_alloc != x_alloc){
- this->clear();
- }
- this->AllocHolder::copy_assign_alloc(x);
- this->assign(x.begin(), x.end());
- }
- return *this;
- }
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back(const T &x);
- //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
+ //! <b>Effects</b>: Constructs a new element in the end of the list
+ //! and moves the resources of mx to this new element.
//!
- //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
- //! before the function.
+ //! <b>Throws</b>: If memory allocation throws.
//!
- //! <b>Throws</b>: If allocator_type's copy constructor throws.
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back(T &&x);
+ #else
+ BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
+ #endif
+
+ #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ //! <b>Requires</b>: position must be a valid iterator of *this.
//!
- //! <b>Complexity</b>: Constant.
- ThisType& operator=(BOOST_RV_REF(ThisType) x)
- {
- if (&x != this){
- NodeAlloc &this_alloc = this->node_alloc();
- NodeAlloc &x_alloc = x.node_alloc();
- //If allocators are equal we can just swap pointers
- if(this_alloc == x_alloc){
- //Destroy and swap pointers
- this->clear();
- this->icont() = boost::move(x.icont());
- //Move allocator if needed
- this->AllocHolder::move_assign_alloc(x);
- }
- //If unequal allocators, then do a one by one move
- else{
- typedef typename std::iterator_traits<iterator>::iterator_category ItCat;
- this->assign( boost::make_move_iterator(x.begin())
- , boost::make_move_iterator(x.end()));
- }
- }
- return *this;
- }
+ //! <b>Effects</b>: Insert a copy of x before position.
+ //!
+ //! <b>Returns</b>: an iterator to the inserted element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ iterator insert(const_iterator position, const T &x);
+
+ //! <b>Requires</b>: position must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a new element before position with mx's resources.
+ //!
+ //! <b>Returns</b>: an iterator to the inserted element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ iterator insert(const_iterator position, T &&x);
+ #else
+ BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator)
+ #endif
//! <b>Requires</b>: p must be a valid iterator of *this.
//!
@@ -809,104 +945,21 @@
}
#endif
- #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- //! <b>Requires</b>: position must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Insert a copy of x before position.
- //!
- //! <b>Returns</b>: an iterator to the inserted element.
+ //! <b>Effects</b>: Removes the first element from the list.
//!
- //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
+ //! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Amortized constant time.
- iterator insert(const_iterator position, const T &x);
+ void pop_front()
+ { this->erase(this->cbegin()); }
- //! <b>Requires</b>: position must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Insert a new element before position with mx's resources.
- //!
- //! <b>Returns</b>: an iterator to the inserted element.
+ //! <b>Effects</b>: Removes the last element from the list.
//!
- //! <b>Throws</b>: If memory allocation throws.
+ //! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Amortized constant time.
- iterator insert(const_iterator position, T &&x);
- #else
- BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator)
- #endif
-
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the end of the list.
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's in-place constructor throws.
- //!
- //! <b>Complexity</b>: Constant
- template <class... Args>
- void emplace_back(Args&&... args)
- {
- this->emplace(this->cend(), boost::forward<Args>(args)...);
- }
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the beginning of the list.
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's in-place constructor throws.
- //!
- //! <b>Complexity</b>: Constant
- template <class... Args>
- void emplace_front(Args&&... args)
- {
- this->emplace(this->cbegin(), boost::forward<Args>(args)...);
- }
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... before p.
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's in-place constructor throws.
- //!
- //! <b>Complexity</b>: Constant
- template <class... Args>
- iterator emplace(const_iterator p, Args&&... args)
- {
- NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
- return iterator(this->icont().insert(p.get(), *pnode));
- }
-
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- this->emplace(this->cend() \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- this->emplace(this->cbegin() \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace(const_iterator p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- NodePtr pnode (AllocHolder::create_node \
- (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
- return iterator(this->icont().insert(p.get(), *pnode)); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ void pop_back()
+ { const_iterator tmp = this->cend(); this->erase(--tmp); }
//! <b>Requires</b>: p must be a valid iterator of *this.
//!
@@ -928,42 +981,27 @@
iterator erase(const_iterator first, const_iterator last)
{ return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
- //! <b>Effects</b>: Assigns the n copies of val to *this.
+ //! <b>Effects</b>: Swaps the contents of *this and x.
//!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //! <b>Throws</b>: Nothing.
//!
- //! <b>Complexity</b>: Linear to n.
- void assign(size_type n, const T& val)
- {
- typedef constant_iterator<value_type, difference_type> cvalue_iterator;
- return this->assign(cvalue_iterator(val, n), cvalue_iterator());
- }
+ //! <b>Complexity</b>: Constant.
+ void swap(list& x)
+ { AllocHolder::swap(x); }
- //! <b>Effects</b>: Assigns the the range [first, last) to *this.
+ //! <b>Effects</b>: Erases all the elements of the list.
//!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's constructor from dereferencing InpIt throws.
+ //! <b>Throws</b>: Nothing.
//!
- //! <b>Complexity</b>: Linear to n.
- template <class InpIt>
- void assign(InpIt first, InpIt last
- #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<InpIt, size_type>::value
- >::type * = 0
- #endif
- )
- {
- iterator first1 = this->begin();
- const iterator last1 = this->end();
- for ( ; first1 != last1 && first != last; ++first1, ++first)
- *first1 = *first;
- if (first == last)
- this->erase(first1, last1);
- else{
- this->insert(last1, first, last);
- }
- }
+ //! <b>Complexity</b>: Linear to the number of elements in the list.
+ void clear()
+ { AllocHolder::clear(alloc_version()); }
+
+ //////////////////////////////////////////////
+ //
+ // slist operations
+ //
+ //////////////////////////////////////////////
//! <b>Requires</b>: p must point to an element contained
//! by the list. x != *this
@@ -978,13 +1016,30 @@
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of
//! this list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, ThisType& x) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, list& x) BOOST_CONTAINER_NOEXCEPT
{
- BOOST_ASSERT((NodeAlloc&)*this == (NodeAlloc&)x);
+ BOOST_ASSERT(*this != x);
+ BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont());
}
//! <b>Requires</b>: p must point to an element contained
+ //! by the list. x != *this
+ //!
+ //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
+ //! the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
+ //! this list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, BOOST_RV_REF(list) x) BOOST_CONTAINER_NOEXCEPT
+ { this->splice(p, static_cast<list&>(x)); }
+
+ //! <b>Requires</b>: p must point to an element contained
//! by this list. i must point to an element contained in list x.
//!
//! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
@@ -998,13 +1053,31 @@
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, ThisType &x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, list &x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
{
- BOOST_ASSERT((NodeAlloc&)*this == (NodeAlloc&)x);
+ BOOST_ASSERT(*this != x);
+ BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont(), i.get());
}
//! <b>Requires</b>: p must point to an element contained
+ //! by this list. i must point to an element contained in list x.
+ //!
+ //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
+ //! If p == i or p == ++i, this function is a null operation.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
+ { this->splice(p, static_cast<list&>(x), i); }
+
+ //! <b>Requires</b>: p must point to an element contained
//! by this list. first and last must point to elements contained in list x.
//!
//! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
@@ -1017,14 +1090,31 @@
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, list &x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
{
- BOOST_ASSERT((NodeAlloc&)*this == (NodeAlloc&)x);
+ BOOST_ASSERT(*this != x);
+ BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont(), first.get(), last.get());
}
//! <b>Requires</b>: p must point to an element contained
//! by this list. first and last must point to elements contained in list x.
+ //!
+ //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements transferred.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
+ { this->splice(p, static_cast<list&>(x), first, last); }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by this list. first and last must point to elements contained in list x.
//! n == std::distance(first, last)
//!
//! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
@@ -1037,21 +1127,33 @@
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last, size_type n) BOOST_CONTAINER_NOEXCEPT
+ //!
+ //! <b>Note</b>: Non-standard extension
+ void splice(const_iterator p, list &x, const_iterator first, const_iterator last, size_type n) BOOST_CONTAINER_NOEXCEPT
{
- BOOST_ASSERT((NodeAlloc&)*this == (NodeAlloc&)x);
+ BOOST_ASSERT(*this != x);
+ BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
}
- //! <b>Effects</b>: Reverses the order of elements in the list.
+ //! <b>Requires</b>: p must point to an element contained
+ //! by this list. first and last must point to elements contained in list x.
+ //! n == std::distance(first, last)
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
//!
- //! <b>Complexity</b>: This function is linear time.
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
//!
- //! <b>Note</b>: Iterators and references are not invalidated
- void reverse()
- { this->icont().reverse(); }
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last, size_type n) BOOST_CONTAINER_NOEXCEPT
+ { this->splice(p, static_cast<list&>(x), first, last, n); }
//! <b>Effects</b>: Removes all the elements that compare equal to value.
//!
@@ -1062,7 +1164,7 @@
//! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
void remove(const T& value)
- { remove_if(equal_to_value(value)); }
+ { this->remove_if(equal_to_value(value)); }
//! <b>Effects</b>: Removes all the elements for which a specified
//! predicate is satisfied.
@@ -1119,9 +1221,23 @@
//!
//! <b>Complexity</b>: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons.
- void merge(list<T, A>& x)
+ void merge(list &x)
{ this->merge(x, value_less()); }
+ //! <b>Requires</b>: The lists x and *this must be distinct.
+ //!
+ //! <b>Effects</b>: This function removes all of x's elements and inserts them
+ //! in order into *this according to std::less<value_type>. The merge is stable;
+ //! that is, if an element from *this is equivalent to one from x, then the element
+ //! from *this will precede the one from x.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time: it performs at most
+ //! size() + x.size() - 1 comparisons.
+ void merge(BOOST_RV_REF(list) x)
+ { this->merge(static_cast<list&>(x)); }
+
//! <b>Requires</b>: p must be a comparison function that induces a strict weak
//! ordering and both *this and x must be sorted according to that ordering
//! The lists x and *this must be distinct.
@@ -1148,6 +1264,24 @@
}
}
+ //! <b>Requires</b>: p must be a comparison function that induces a strict weak
+ //! ordering and both *this and x must be sorted according to that ordering
+ //! The lists x and *this must be distinct.
+ //!
+ //! <b>Effects</b>: This function removes all of x's elements and inserts them
+ //! in order into *this. The merge is stable; that is, if an element from *this is
+ //! equivalent to one from x, then the element from *this will precede the one from x.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time: it performs at most
+ //! size() + x.size() - 1 comparisons.
+ //!
+ //! <b>Note</b>: Iterators and references to *this are not invalidated.
+ template <class StrictWeakOrdering>
+ void merge(BOOST_RV_REF(list) x, StrictWeakOrdering comp)
+ { this->merge(static_cast<list&>(x), comp); }
+
//! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
//! The sort is stable, that is, the relative order of equivalent elements is preserved.
//!
@@ -1178,6 +1312,16 @@
this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
}
+ //! <b>Effects</b>: Reverses the order of elements in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time.
+ //!
+ //! <b>Note</b>: Iterators and references are not invalidated
+ void reverse()
+ { this->icont().reverse(); }
+
/// @cond
private:
Modified: trunk/boost/container/slist.hpp
==============================================================================
--- trunk/boost/container/slist.hpp (original)
+++ trunk/boost/container/slist.hpp 2012-09-24 06:27:02 EDT (Mon, 24 Sep 2012)
@@ -20,6 +20,7 @@
#include <boost/container/container_fwd.hpp>
#include <boost/move/move.hpp>
+#include <boost/move/move_helpers.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/mpl.hpp>
@@ -53,6 +54,9 @@
/// @cond
+template <class T, class A>
+class slist;
+
namespace container_detail {
template<class VoidPointer>
@@ -96,6 +100,99 @@
typedef container_type type ;
};
+template<class T, class IIterator>
+class slist_const_iterator
+ : public std::iterator< std::forward_iterator_tag, T
+ , typename iiterator_types<T, IIterator>::difference_type
+ , typename iiterator_types<T, IIterator>::const_pointer
+ , typename iiterator_types<T, IIterator>::const_reference>
+{
+ protected:
+
+ IIterator m_it;
+
+ public:
+ typedef typename iiterator_types<T, IIterator>::const_pointer const_pointer;
+ typedef typename iiterator_types<T, IIterator>::const_reference const_reference;
+
+ //Constructors
+ slist_const_iterator()
+ : m_it()
+ {}
+
+ explicit slist_const_iterator(const IIterator &it)
+ : m_it(it)
+ {}
+
+ //Pointer like operators
+ const_reference operator*() const
+ { return this->m_it->m_data; }
+
+ const_pointer operator->() const
+ { return ::boost::intrusive::pointer_traits<const_pointer>::pointer_to(this->m_it->m_data); }
+
+ //Increment / Decrement
+ slist_const_iterator& operator++()
+ { ++this->m_it; return *this; }
+
+ slist_const_iterator operator++(int)
+ { IIterator tmp = this->m_it; ++*this; return slist_const_iterator(tmp); }
+
+ //Comparison operators
+ friend bool operator== (const slist_const_iterator& l, const slist_const_iterator& r)
+ { return l.m_it == r.m_it; }
+
+ friend bool operator!= (const slist_const_iterator& l, const slist_const_iterator& r)
+ { return l.m_it != r.m_it; }
+
+ IIterator &get()
+ { return this->m_it; }
+
+ const IIterator &get() const
+ { return this->m_it; }
+};
+
+template<class T, class IIterator>
+class slist_iterator
+ : public slist_const_iterator<T, IIterator>
+{
+ private:
+ typedef slist_const_iterator<T, IIterator> const_iterator;
+
+ public:
+ typedef typename iiterator_types<T, IIterator>::pointer pointer;
+ typedef typename iiterator_types<T, IIterator>::reference reference;
+
+ //Constructors
+ slist_iterator()
+ : const_iterator()
+ {}
+
+ explicit slist_iterator(const IIterator &it)
+ : const_iterator(it)
+ {}
+
+ //Pointer like operators
+ reference operator*() const
+ { return this->m_it->m_data; }
+
+ pointer operator->() const
+ { return ::boost::intrusive::pointer_traits<pointer>::to_pointer(this->m_it->m_data); }
+
+ //Increment / Decrement
+ slist_iterator& operator++()
+ { ++this->m_it; return *this; }
+
+ slist_iterator operator++(int)
+ { IIterator tmp = this->m_it; ++*this; return slist_iterator(tmp); }
+
+ IIterator &get()
+ { return this->m_it; }
+
+ const IIterator &get() const
+ { return this->m_it; }
+};
+
} //namespace container_detail {
/// @endcond
@@ -142,13 +239,10 @@
<A, typename container_detail::intrusive_slist_type<A>::type>
{
/// @cond
- typedef typename container_detail::
- move_const_ref_type<T>::type insert_const_ref_type;
typedef typename
container_detail::intrusive_slist_type<A>::type Icont;
typedef container_detail::node_alloc_holder<A, Icont> AllocHolder;
typedef typename AllocHolder::NodePtr NodePtr;
- typedef slist <T, A> ThisType;
typedef typename AllocHolder::NodeAlloc NodeAlloc;
typedef typename AllocHolder::ValAlloc ValAlloc;
typedef typename AllocHolder::Node Node;
@@ -186,126 +280,39 @@
bool operator()(const Node &a) const
{ return static_cast<const Pred&>(*this)(a.m_data); }
};
- /// @endcond
- public:
- //! The type of object, T, stored in the list
- typedef T value_type;
- //! Pointer to T
- typedef typename allocator_traits_type::pointer pointer;
- //! Const pointer to T
- typedef typename allocator_traits_type::const_pointer const_pointer;
- //! Reference to T
- typedef typename allocator_traits_type::reference reference;
- //! Const reference to T
- typedef typename allocator_traits_type::const_reference const_reference;
- //! An unsigned integral type
- typedef typename allocator_traits_type::size_type size_type;
- //! A signed integral type
- typedef typename allocator_traits_type::difference_type difference_type;
- //! The allocator type
- typedef A allocator_type;
- //! Non-standard extension: the stored allocator type
- typedef NodeAlloc stored_allocator_type;
- /// @cond
- private:
BOOST_COPYABLE_AND_MOVABLE(slist)
- typedef difference_type list_difference_type;
- typedef pointer list_pointer;
- typedef const_pointer list_const_pointer;
- typedef reference list_reference;
- typedef const_reference list_const_reference;
+ typedef container_detail::slist_iterator<T, typename Icont::iterator> iterator_impl;
+ typedef container_detail::slist_const_iterator<T, typename Icont::iterator>const_iterator_impl;
/// @endcond
public:
+ //////////////////////////////////////////////
+ //
+ // types
+ //
+ //////////////////////////////////////////////
+
+ typedef T value_type;
+ typedef typename ::boost::container::allocator_traits<A>::pointer pointer;
+ typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer;
+ typedef typename ::boost::container::allocator_traits<A>::reference reference;
+ typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference;
+ typedef typename ::boost::container::allocator_traits<A>::size_type size_type;
+ typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type;
+ typedef A allocator_type;
+ typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type;
+ typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
+ typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
- //! Const iterator used to iterate through a list.
- class const_iterator
- /// @cond
- : public std::iterator<std::forward_iterator_tag,
- value_type, list_difference_type,
- list_const_pointer, list_const_reference>
- {
-
- protected:
- typename Icont::iterator m_it;
- explicit const_iterator(typename Icont::iterator it) : m_it(it){}
- void prot_incr(){ ++m_it; }
-
- private:
- typename Icont::iterator get()
- { return this->m_it; }
-
- public:
- friend class slist<T, A>;
- typedef list_difference_type difference_type;
-
- //Constructors
- const_iterator()
- : m_it()
- {}
-
- //Pointer like operators
- const_reference operator*() const
- { return m_it->m_data; }
-
- const_pointer operator->() const
- { return const_pointer(&m_it->m_data); }
-
- //Increment / Decrement
- const_iterator& operator++()
- { prot_incr(); return *this; }
-
- const_iterator operator++(int)
- { typename Icont::iterator tmp = m_it; ++*this; return const_iterator(tmp); }
-
- //Comparison operators
- bool operator== (const const_iterator& r) const
- { return m_it == r.m_it; }
-
- bool operator!= (const const_iterator& r) const
- { return m_it != r.m_it; }
- }
- /// @endcond
- ;
-
- //! Iterator used to iterate through a list
- class iterator
- /// @cond
- : public const_iterator
- {
-
- private:
- explicit iterator(typename Icont::iterator it)
- : const_iterator(it)
- {}
-
- typename Icont::iterator get()
- { return this->m_it; }
-
- public:
- friend class slist<T, A>;
- typedef list_pointer pointer;
- typedef list_reference reference;
-
- //Constructors
- iterator(){}
-
- //Pointer like operators
- reference operator*() const { return this->m_it->m_data; }
- pointer operator->() const { return pointer(&this->m_it->m_data); }
-
- //Increment / Decrement
- iterator& operator++()
- { this->prot_incr(); return *this; }
+ public:
- iterator operator++(int)
- { typename Icont::iterator tmp = this->m_it; ++*this; return iterator(tmp); }
- }
- /// @endcond
- ;
+ //////////////////////////////////////////////
+ //
+ // construct/copy/destroy
+ //
+ //////////////////////////////////////////////
- public:
//! <b>Effects</b>: Constructs a list taking the allocator as parameter.
//!
//! <b>Throws</b>: If allocator_type's copy constructor throws.
@@ -347,8 +354,7 @@
//!
//! <b>Complexity</b>: Linear to the range [first, last).
template <class InpIt>
- slist(InpIt first, InpIt last,
- const allocator_type& a = allocator_type())
+ slist(InpIt first, InpIt last, const allocator_type& a = allocator_type())
: AllocHolder(a)
{ this->insert_after(this->cbefore_begin(), first, last); }
@@ -400,6 +406,15 @@
}
}
+ //! <b>Effects</b>: Destroys the list. All stored values are destroyed
+ //! and used memory is deallocated.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements.
+ ~slist()
+ {} //AllocHolder clears the slist
+
//! <b>Effects</b>: Makes *this contain the same elements as x.
//!
//! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
@@ -455,31 +470,6 @@
return *this;
}
- //! <b>Effects</b>: Destroys the list. All stored values are destroyed
- //! and used memory is deallocated.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of elements.
- ~slist()
- {} //AllocHolder clears the slist
-
- //! <b>Effects</b>: Returns a copy of the internal allocator.
- //!
- //! <b>Throws</b>: If allocator's copy constructor throws.
- //!
- //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const
- { return allocator_type(this->node_alloc()); }
-
- const stored_allocator_type &get_stored_allocator() const
- { return this->node_alloc(); }
-
- stored_allocator_type &get_stored_allocator()
- { return this->node_alloc(); }
-
- public:
-
//! <b>Effects</b>: Assigns the n copies of val to *this.
//!
//! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
@@ -521,6 +511,58 @@
this->erase_after(prev, end_n);
}
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //!
+ //! <b>Throws</b>: If allocator's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const
+ { return allocator_type(this->node_alloc()); }
+
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //!
+ //! <b>Throws</b>: If allocator's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const stored_allocator_type &get_stored_allocator() const
+ { return this->node_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.
+ stored_allocator_type &get_stored_allocator()
+ { return this->node_alloc(); }
+
+ //////////////////////////////////////////////
+ //
+ // iterators
+ //
+ //////////////////////////////////////////////
+
+ //! <b>Effects</b>: Returns a non-dereferenceable iterator that,
+ //! when incremented, yields begin(). This iterator may be used
+ //! as the argument to insert_after, erase_after, etc.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ iterator before_begin()
+ { return iterator(end()); }
+
+ //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
+ //! that, when incremented, yields begin(). This iterator may be used
+ //! as the argument to insert_after, erase_after, etc.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_iterator before_begin() const
+ { return this->cbefore_begin(); }
+
//! <b>Effects</b>: Returns an iterator to the first element contained in the list.
//!
//! <b>Throws</b>: Nothing.
@@ -553,16 +595,6 @@
const_iterator end() const
{ return this->cend(); }
- //! <b>Effects</b>: Returns a non-dereferenceable iterator that,
- //! when incremented, yields begin(). This iterator may be used
- //! as the argument to insert_after, erase_after, etc.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- iterator before_begin()
- { return iterator(end()); }
-
//! <b>Effects</b>: Returns a non-dereferenceable const_iterator
//! that, when incremented, yields begin(). This iterator may be used
//! as the argument to insert_after, erase_after, etc.
@@ -570,8 +602,8 @@
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator before_begin() const
- { return this->cbefore_begin(); }
+ const_iterator cbefore_begin() const
+ { return const_iterator(end()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
//!
@@ -589,15 +621,43 @@
const_iterator cend() const
{ return const_iterator(this->non_const_icont().end()); }
- //! <b>Effects</b>: Returns a non-dereferenceable const_iterator
- //! that, when incremented, yields begin(). This iterator may be used
- //! as the argument to insert_after, erase_after, etc.
+ //! <b>Returns</b>: The iterator to the element before i in the sequence.
+ //! Returns the end-iterator, if either i is the begin-iterator or the
+ //! sequence is empty.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements before i.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ iterator previous(iterator p)
+ { return iterator(this->icont().previous(p.get())); }
+
+ //! <b>Returns</b>: The const_iterator to the element before i in the sequence.
+ //! Returns the end-const_iterator, if either i is the begin-const_iterator or
+ //! the sequence is empty.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements before i.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ const_iterator previous(const_iterator p)
+ { return const_iterator(this->icont().previous(p.get())); }
+
+ //////////////////////////////////////////////
+ //
+ // capacity
+ //
+ //////////////////////////////////////////////
+
+ //! <b>Effects</b>: Returns true if the list contains no elements.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbefore_begin() const
- { return const_iterator(end()); }
+ bool empty() const
+ { return !this->size(); }
//! <b>Effects</b>: Returns the number of the elements contained in the list.
//!
@@ -615,21 +675,40 @@
size_type max_size() const
{ return AllocHolder::max_size(); }
- //! <b>Effects</b>: Returns true if the list contains no elements.
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are default constructed.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
//!
- //! <b>Complexity</b>: Constant.
- bool empty() const
- { return !this->size(); }
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size)
+ {
+ const_iterator last_pos;
+ if(!priv_try_shrink(new_size, last_pos)){
+ typedef default_construct_iterator<value_type, difference_type> default_iterator;
+ this->insert_after(last_pos, default_iterator(new_size - this->size()), default_iterator());
+ }
+ }
- //! <b>Effects</b>: Swaps the contents of *this and x.
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are copy constructed from x.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
//!
- //! <b>Complexity</b>: Linear to the number of elements on *this and x.
- void swap(slist& x)
- { AllocHolder::swap(x); }
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size, const T& x)
+ {
+ const_iterator last_pos;
+ if(!priv_try_shrink(new_size, last_pos)){
+ this->insert_after(last_pos, new_size, x);
+ }
+ }
+
+ //////////////////////////////////////////////
+ //
+ // element access
+ //
+ //////////////////////////////////////////////
//! <b>Requires</b>: !empty()
//!
@@ -653,64 +732,88 @@
const_reference front() const
{ return *this->begin(); }
- //! <b>Effects</b>: Inserts a copy of t in the beginning of the list.
+ //////////////////////////////////////////////
+ //
+ // modifiers
+ //
+ //////////////////////////////////////////////
+
+ #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the front of the list
//!
//! <b>Throws</b>: If memory allocation throws or
//! T's copy constructor throws.
//!
//! <b>Complexity</b>: Amortized constant time.
- void push_front(insert_const_ref_type x)
- { return priv_push_front(x); }
-
- #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- void push_front(T &x) { push_front(const_cast<const T &>(x)); }
-
- template<class U>
- void push_front(const U &u
- , typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
- { return priv_push_front(u); }
- #endif
+ template <class... Args>
+ void emplace_front(Args&&... args)
+ { this->emplace_after(this->cbefore_begin(), boost::forward<Args>(args)...); }
- //! <b>Effects</b>: Constructs a new element in the beginning of the list
- //! and moves the resources of t to this new element.
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... after prev
//!
- //! <b>Throws</b>: If memory allocation throws.
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
//!
- //! <b>Complexity</b>: Amortized constant time.
- void push_front(BOOST_RV_REF(T) x)
- { this->icont().push_front(*this->create_node(boost::move(x))); }
+ //! <b>Complexity</b>: Constant
+ template <class... Args>
+ iterator emplace_after(const_iterator prev, Args&&... args)
+ {
+ NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
+ return iterator(this->icont().insert_after(prev.get(), *pnode));
+ }
- //! <b>Effects</b>: Removes the first element from the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- void pop_front()
- { this->icont().pop_front_and_dispose(Destroyer(this->node_alloc())); }
+ #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
- //! <b>Returns</b>: The iterator to the element before i in the sequence.
- //! Returns the end-iterator, if either i is the begin-iterator or the
- //! sequence is empty.
- //!
- //! <b>Throws</b>: Nothing.
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+ void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
+ { \
+ this->emplace(this->cbegin() \
+ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
+ } \
+ \
+ BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+ iterator emplace_after(const_iterator prev \
+ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
+ { \
+ NodePtr pnode (AllocHolder::create_node \
+ (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
+ return iterator(this->icont().insert_after(prev.get(), *pnode)); \
+ } \
//!
- //! <b>Complexity</b>: Linear to the number of elements before i.
- iterator previous(iterator p)
- { return iterator(this->icont().previous(p.get())); }
+ #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
- //! <b>Returns</b>: The const_iterator to the element before i in the sequence.
- //! Returns the end-const_iterator, if either i is the begin-const_iterator or
- //! the sequence is empty.
+ #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+ #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ //! <b>Effects</b>: Inserts a copy of x at the beginning of the list.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy constructor throws.
//!
- //! <b>Complexity</b>: Linear to the number of elements before i.
- const_iterator previous(const_iterator p)
- { return const_iterator(this->icont().previous(p.get())); }
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_front(const T &x);
+
+ //! <b>Effects</b>: Constructs a new element in the beginning of the list
+ //! and moves the resources of mx to this new element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_front(T &&x);
+ #else
+ BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
+ #endif
+
+ #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Requires</b>: p must be a valid iterator of *this.
//!
- //! <b>Effects</b>: Inserts a copy of the value after the p pointed
+ //! <b>Effects</b>: Inserts a copy of the value after the position pointed
//! by prev_p.
//!
//! <b>Returns</b>: An iterator to the inserted element.
@@ -721,18 +824,7 @@
//!
//! <b>Note</b>: Does not affect the validity of iterators and references of
//! previous values.
- iterator insert_after(const_iterator prev_pos, insert_const_ref_type x)
- { return this->priv_insert_after(prev_pos, x); }
-
- #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- iterator insert_after(const_iterator position, T &x)
- { return this->insert_after(position, const_cast<const T &>(x)); }
-
- template<class U>
- iterator insert_after( const_iterator position, const U &u
- , typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
- { return this->priv_insert_after(position, u); }
- #endif
+ iterator insert_after(const_iterator prev_pos, const T &x);
//! <b>Requires</b>: prev_pos must be a valid iterator of *this.
//!
@@ -747,8 +839,10 @@
//!
//! <b>Note</b>: Does not affect the validity of iterators and references of
//! previous values.
- iterator insert_after(const_iterator prev_pos, BOOST_RV_REF(value_type) x)
- { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(boost::move(x)))); }
+ iterator insert_after(const_iterator prev_pos, T &&x);
+ #else
+ BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert_after, T, iterator, priv_insert_after, const_iterator)
+ #endif
//! <b>Requires</b>: prev_pos must be a valid iterator of *this.
//!
@@ -772,7 +866,7 @@
//! <b>Requires</b>: prev_pos must be a valid iterator of *this.
//!
//! <b>Effects</b>: Inserts the range pointed by [first, last)
- //! after the p prev_pos.
+ //! after the position prev_pos.
//!
//! <b>Returns</b>: an iterator to the last inserted element or prev_pos if first == last.
//!
@@ -820,145 +914,13 @@
}
#endif
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Insert a copy of x before p.
- //!
- //! <b>Returns</b>: an iterator to the inserted element.
- //!
- //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the elements before p.
- iterator insert(const_iterator position, insert_const_ref_type x)
- { return this->priv_insert(position, x); }
-
- #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- iterator insert(const_iterator position, T &x)
- { return this->insert(position, const_cast<const T &>(x)); }
-
- template<class U>
- iterator insert( const_iterator position, const U &u
- , typename container_detail::enable_if_c<container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
- { return this->priv_insert(position, u); }
- #endif
-
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Insert a new element before p with mx's resources.
- //!
- //! <b>Returns</b>: an iterator to the inserted element.
- //!
- //! <b>Throws</b>: If memory allocation throws.
- //!
- //! <b>Complexity</b>: Linear to the elements before p.
- iterator insert(const_iterator p, BOOST_RV_REF(value_type) x)
- { return this->insert_after(previous(p), boost::move(x)); }
-
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Inserts n copies of x before p.
- //!
- //! <b>Returns</b>: an iterator to the first inserted element or p if n == 0.
- //!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to n plus linear to the elements before p.
- iterator insert(const_iterator p, size_type n, const value_type& x)
- {
- const_iterator prev(this->previous(p));
- this->insert_after(prev, n, x);
- return ++iterator(prev.get());
- }
-
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
- //!
- //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
- //!
- //! <b>Throws</b>: If memory allocation throws, T's constructor from a
- //! dereferenced InpIt throws.
- //!
- //! <b>Complexity</b>: Linear to std::distance [first, last) plus
- //! linear to the elements before p.
- template <class InIter>
- iterator insert(const_iterator p, InIter first, InIter last)
- {
- const_iterator prev(this->previous(p));
- this->insert_after(prev, first, last);
- return ++iterator(prev.get());
- }
-
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the front of the list
+ //! <b>Effects</b>: Removes the first element from the list.
//!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's copy constructor throws.
+ //! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Amortized constant time.
- template <class... Args>
- void emplace_front(Args&&... args)
- { this->emplace_after(this->cbefore_begin(), boost::forward<Args>(args)...); }
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... before p
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's in-place constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the elements before p
- template <class... Args>
- iterator emplace(const_iterator p, Args&&... args)
- { return this->emplace_after(this->previous(p), boost::forward<Args>(args)...); }
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... after prev
- //!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's in-place constructor throws.
- //!
- //! <b>Complexity</b>: Constant
- template <class... Args>
- iterator emplace_after(const_iterator prev, Args&&... args)
- {
- NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
- return iterator(this->icont().insert_after(prev.get(), *pnode));
- }
-
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- this->emplace(this->cbegin() \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace (const_iterator p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- return this->emplace_after \
- (this->previous(p) \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace_after(const_iterator prev \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- NodePtr pnode (AllocHolder::create_node \
- (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
- return iterator(this->icont().insert_after(prev.get(), *pnode)); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ void pop_front()
+ { this->icont().pop_front_and_dispose(Destroyer(this->node_alloc())); }
//! <b>Effects</b>: Erases the element after the element pointed by prev_pos
//! of the list.
@@ -992,55 +954,13 @@
return iterator(this->icont().erase_after_and_dispose(before_first.get(), last.get(), Destroyer(this->node_alloc())));
}
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Erases the element at p p.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Linear to the number of elements before p.
- iterator erase(const_iterator p)
- { return iterator(this->erase_after(previous(p))); }
-
- //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
- //!
- //! <b>Effects</b>: Erases the elements pointed by [first, last).
+ //! <b>Effects</b>: Swaps the contents of *this and x.
//!
//! <b>Throws</b>: Nothing.
//!
- //! <b>Complexity</b>: Linear to the distance between first and last plus
- //! linear to the elements before first.
- iterator erase(const_iterator first, const_iterator last)
- { return iterator(this->erase_after(previous(first), last)); }
-
- //! <b>Effects</b>: Inserts or erases elements at the end such that
- //! the size becomes n. New elements are copy constructed from x.
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the difference between size() and new_size.
- void resize(size_type new_size, const T& x)
- {
- const_iterator last_pos;
- if(!priv_try_shrink(new_size, last_pos)){
- this->insert_after(last_pos, new_size, x);
- }
- }
-
- //! <b>Effects</b>: Inserts or erases elements at the end such that
- //! the size becomes n. New elements are default constructed.
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the difference between size() and new_size.
- void resize(size_type new_size)
- {
- const_iterator last_pos;
- if(!priv_try_shrink(new_size, last_pos)){
- typedef default_construct_iterator<value_type, difference_type> default_iterator;
- this->insert_after(last_pos, default_iterator(new_size - this->size()), default_iterator());
- }
- }
+ //! <b>Complexity</b>: Linear to the number of elements on *this and x.
+ void swap(slist& x)
+ { AllocHolder::swap(x); }
//! <b>Effects</b>: Erases all the elements of the list.
//!
@@ -1050,6 +970,12 @@
void clear()
{ this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
+ //////////////////////////////////////////////
+ //
+ // slist operations
+ //
+ //////////////////////////////////////////////
+
//! <b>Requires</b>: p must point to an element contained
//! by the list. x != *this
//!
@@ -1065,14 +991,27 @@
//! this list. Iterators of this list and all the references are not invalidated.
void splice_after(const_iterator prev_pos, slist& x)
{
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().splice_after(prev_pos.get(), x.icont());
- }
- else{
- throw std::runtime_error("slist::splice called with unequal allocators");
- }
+ BOOST_ASSERT(*this != x);
+ BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+ this->icont().splice_after(prev_pos.get(), x.icont());
}
+ //! <b>Requires</b>: p must point to an element contained
+ //! by the list. x != *this
+ //!
+ //! <b>Effects</b>: Transfers all the elements of list x to this list, after the
+ //! the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear to the elements in x.
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
+ //! this list. Iterators of this list and all the references are not invalidated.
+ void splice_after(const_iterator prev_pos, BOOST_RV_REF(slist) x)
+ { this->splice_after(prev_pos, static_cast<slist&>(x)); }
+
//! <b>Requires</b>: prev_pos must be a valid iterator of this.
//! i must point to an element contained in list x.
//!
@@ -1089,44 +1028,31 @@
//! list. Iterators of this list and all the references are not invalidated.
void splice_after(const_iterator prev_pos, slist& x, const_iterator prev)
{
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().splice_after(prev_pos.get(), x.icont(), prev.get());
- }
- else{
- throw std::runtime_error("slist::splice called with unequal allocators");
- }
+ BOOST_ASSERT(*this != x);
+ BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+ this->icont().splice_after(prev_pos.get(), x.icont(), prev.get());
}
//! <b>Requires</b>: prev_pos must be a valid iterator of this.
- //! before_first and before_last must be valid iterators of x.
- //! prev_pos must not be contained in [before_first, before_last) range.
- //!
- //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
- //! from list x to this list, after the element pointed by prev_pos.
+ //! i must point to an element contained in list x.
//!
- //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
+ //! after the element pointed by prev_pos.
+ //! If prev_pos == prev or prev_pos == ++prev, this function is a null operation.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
//! are not equal.
//!
- //! <b>Complexity</b>: Linear to the number of transferred elements.
+ //! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice_after(const_iterator prev_pos, slist& x,
- const_iterator before_first, const_iterator before_last)
- {
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().splice_after
- (prev_pos.get(), x.icont(), before_first.get(), before_last.get());
- }
- else{
- throw std::runtime_error("slist::splice called with unequal allocators");
- }
- }
+ void splice_after(const_iterator prev_pos, BOOST_RV_REF(slist) x, const_iterator prev)
+ { this->splice_after(prev_pos, static_cast<slist&>(x), prev); }
//! <b>Requires</b>: prev_pos must be a valid iterator of this.
//! before_first and before_last must be valid iterators of x.
//! prev_pos must not be contained in [before_first, before_last) range.
- //! n == std::distance(before_first, before_last)
//!
//! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
//! from list x to this list, after the element pointed by prev_pos.
@@ -1134,82 +1060,81 @@
//! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
//! are not equal.
//!
- //! <b>Complexity</b>: Constant.
+ //! <b>Complexity</b>: Linear to the number of transferred elements.
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void splice_after(const_iterator prev_pos, slist& x,
- const_iterator before_first, const_iterator before_last,
- size_type n)
+ const_iterator before_first, const_iterator before_last)
{
- if((NodeAlloc&)*this == (NodeAlloc&)x){
- this->icont().splice_after
- (prev_pos.get(), x.icont(), before_first.get(), before_last.get(), n);
- }
- else{
- throw std::runtime_error("slist::splice called with unequal allocators");
- }
+ BOOST_ASSERT(*this != x);
+ BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+ this->icont().splice_after
+ (prev_pos.get(), x.icont(), before_first.get(), before_last.get());
}
- //! <b>Requires</b>: p must point to an element contained
- //! by the list. x != *this
+ //! <b>Requires</b>: prev_pos must be a valid iterator of this.
+ //! before_first and before_last must be valid iterators of x.
+ //! prev_pos must not be contained in [before_first, before_last) range.
//!
- //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
- //! the element pointed by p. No destructors or copy constructors are called.
+ //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
+ //! from list x to this list, after the element pointed by prev_pos.
//!
//! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
//! are not equal.
//!
- //! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size().
+ //! <b>Complexity</b>: Linear to the number of transferred elements.
//!
- //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
- //! this list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, ThisType& x)
- { this->splice_after(this->previous(p), x); }
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice_after(const_iterator prev_pos, BOOST_RV_REF(slist) x,
+ const_iterator before_first, const_iterator before_last)
+ { this->splice_after(prev_pos, static_cast<slist&>(x), before_first, before_last); }
- //! <b>Requires</b>: p must point to an element contained
- //! by this list. i must point to an element contained in list x.
+ //! <b>Requires</b>: prev_pos must be a valid iterator of this.
+ //! before_first and before_last must be valid iterators of x.
+ //! prev_pos must not be contained in [before_first, before_last) range.
+ //! n == std::distance(before_first, before_last)
//!
- //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
- //! before the the element pointed by p. No destructors or copy constructors are called.
- //! If p == i or p == ++i, this function is a null operation.
+ //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
+ //! from list x to this list, after the element pointed by prev_pos.
//!
//! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
//! are not equal.
//!
- //! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i).
+ //! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, slist& x, const_iterator i)
- { this->splice_after(previous(p), x, i); }
+ void splice_after(const_iterator prev_pos, slist& x,
+ const_iterator before_first, const_iterator before_last,
+ size_type n)
+ {
+ BOOST_ASSERT(*this != x);
+ BOOST_ASSERT(this->node_alloc() == x.node_alloc());
+ this->icont().splice_after
+ (prev_pos.get(), x.icont(), before_first.get(), before_last.get(), n);
+ }
- //! <b>Requires</b>: p must point to an element contained
- //! by this list. first and last must point to elements contained in list x.
+ //! <b>Requires</b>: prev_pos must be a valid iterator of this.
+ //! before_first and before_last must be valid iterators of x.
+ //! prev_pos must not be contained in [before_first, before_last) range.
+ //! n == std::distance(before_first, before_last)
//!
- //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
- //! before the the element pointed by p. No destructors or copy constructors are called.
+ //! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
+ //! from list x to this list, after the element pointed by prev_pos.
//!
//! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
//! are not equal.
//!
- //! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first),
- //! and in distance(first, last).
+ //! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, slist& x, const_iterator first, const_iterator last)
- { this->splice_after(previous(p), x, previous(first), previous(last)); }
-
- //! <b>Effects</b>: Reverses the order of elements in the list.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: This function is linear time.
- //!
- //! <b>Note</b>: Iterators and references are not invalidated
- void reverse()
- { this->icont().reverse(); }
+ void splice_after(const_iterator prev_pos, BOOST_RV_REF(slist) x,
+ const_iterator before_first, const_iterator before_last,
+ size_type n)
+ { this->splice_after(prev_pos, static_cast<slist&>(x), before_first, before_last, n); }
//! <b>Effects</b>: Removes all the elements that compare equal to value.
//!
@@ -1220,7 +1145,7 @@
//! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
void remove(const T& value)
- { remove_if(equal_to_value(value)); }
+ { this->remove_if(equal_to_value(value)); }
//! <b>Effects</b>: Removes all the elements for which a specified
//! predicate is satisfied.
@@ -1280,6 +1205,20 @@
void merge(slist & x)
{ this->merge(x, value_less()); }
+ //! <b>Requires</b>: The lists x and *this must be distinct.
+ //!
+ //! <b>Effects</b>: This function removes all of x's elements and inserts them
+ //! in order into *this according to std::less<value_type>. The merge is stable;
+ //! that is, if an element from *this is equivalent to one from x, then the element
+ //! from *this will precede the one from x.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time: it performs at most
+ //! size() + x.size() - 1 comparisons.
+ void merge(BOOST_RV_REF(slist) x)
+ { this->merge(static_cast<slist&>(x)); }
+
//! <b>Requires</b>: p must be a comparison function that induces a strict weak
//! ordering and both *this and x must be sorted according to that ordering
//! The lists x and *this must be distinct.
@@ -1306,6 +1245,24 @@
}
}
+ //! <b>Requires</b>: p must be a comparison function that induces a strict weak
+ //! ordering and both *this and x must be sorted according to that ordering
+ //! The lists x and *this must be distinct.
+ //!
+ //! <b>Effects</b>: This function removes all of x's elements and inserts them
+ //! in order into *this. The merge is stable; that is, if an element from *this is
+ //! equivalent to one from x, then the element from *this will precede the one from x.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time: it performs at most
+ //! size() + x.size() - 1 comparisons.
+ //!
+ //! <b>Note</b>: Iterators and references to *this are not invalidated.
+ template <class StrictWeakOrdering>
+ void merge(BOOST_RV_REF(slist) x, StrictWeakOrdering comp)
+ { this->merge(static_cast<slist&>(x), comp); }
+
//! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
//! The sort is stable, that is, the relative order of equivalent elements is preserved.
//!
@@ -1336,9 +1293,242 @@
this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
}
+ //! <b>Effects</b>: Reverses the order of elements in the list.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: This function is linear time.
+ //!
+ //! <b>Note</b>: Iterators and references are not invalidated
+ void reverse()
+ { this->icont().reverse(); }
+
+ //////////////////////////////////////////////
+ //
+ // list compatibility interface
+ //
+ //////////////////////////////////////////////
+
+ #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... before p
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements before p
+ template <class... Args>
+ iterator emplace(const_iterator p, Args&&... args)
+ { return this->emplace_after(this->previous(p), boost::forward<Args>(args)...); }
+
+ #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+ iterator emplace (const_iterator p \
+ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
+ { \
+ return this->emplace_after \
+ (this->previous(p) \
+ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
+ } \
+ //!
+ #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+ #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+ #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of x before p.
+ //!
+ //! <b>Returns</b>: an iterator to the inserted element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements before p.
+ iterator insert(const_iterator position, const T &x);
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a new element before p with mx's resources.
+ //!
+ //! <b>Returns</b>: an iterator to the inserted element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Linear to the elements before p.
+ iterator insert(const_iterator prev_pos, T &&x);
+ #else
+ BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator)
+ #endif
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Inserts n copies of x before p.
+ //!
+ //! <b>Returns</b>: an iterator to the first inserted element or p if n == 0.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n plus linear to the elements before p.
+ iterator insert(const_iterator p, size_type n, const value_type& x)
+ {
+ const_iterator prev(this->previous(p));
+ this->insert_after(prev, n, x);
+ return ++iterator(prev.get());
+ }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Insert a copy of the [first, last) range before p.
+ //!
+ //! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
+ //!
+ //! <b>Throws</b>: If memory allocation throws, T's constructor from a
+ //! dereferenced InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to std::distance [first, last) plus
+ //! linear to the elements before p.
+ template <class InIter>
+ iterator insert(const_iterator p, InIter first, InIter last)
+ {
+ const_iterator prev(this->previous(p));
+ this->insert_after(prev, first, last);
+ return ++iterator(prev.get());
+ }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
+ //! <b>Effects</b>: Erases the element at p p.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements before p.
+ iterator erase(const_iterator p)
+ { return iterator(this->erase_after(previous(p))); }
+
+ //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
+ //!
+ //! <b>Effects</b>: Erases the elements pointed by [first, last).
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Linear to the distance between first and last plus
+ //! linear to the elements before first.
+ iterator erase(const_iterator first, const_iterator last)
+ { return iterator(this->erase_after(previous(first), last)); }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by the list. x != *this
+ //!
+ //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
+ //! the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size().
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
+ //! this list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, slist& x)
+ { this->splice_after(this->previous(p), x); }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by the list. x != *this
+ //!
+ //! <b>Effects</b>: Transfers all the elements of list x to this list, before the
+ //! the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear in distance(begin(), p), and linear in x.size().
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of
+ //! this list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, BOOST_RV_REF(slist) x)
+ { this->splice(p, static_cast<slist&>(x)); }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by this list. i must point to an element contained in list x.
+ //!
+ //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
+ //! If p == i or p == ++i, this function is a null operation.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i).
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, slist& x, const_iterator i)
+ { this->splice_after(this->previous(p), x, this->previous(i)); }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by this list. i must point to an element contained in list x.
+ //!
+ //! <b>Effects</b>: Transfers the value pointed by i, from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
+ //! If p == i or p == ++i, this function is a null operation.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear in distance(begin(), p), and in distance(x.begin(), i).
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator i)
+ { this->splice(p, static_cast<slist&>(x), i); }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by this list. first and last must point to elements contained in list x.
+ //!
+ //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first),
+ //! and in distance(first, last).
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, slist& x, const_iterator first, const_iterator last)
+ { this->splice_after(this->previous(p), x, this->previous(first), this->previous(last)); }
+
+ //! <b>Requires</b>: p must point to an element contained
+ //! by this list. first and last must point to elements contained in list x.
+ //!
+ //! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
+ //! before the the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! <b>Throws</b>: std::runtime_error if this' allocator and x's allocator
+ //! are not equal.
+ //!
+ //! <b>Complexity</b>: Linear in distance(begin(), p), in distance(x.begin(), first),
+ //! and in distance(first, last).
+ //!
+ //! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
+ //! list. Iterators of this list and all the references are not invalidated.
+ void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator first, const_iterator last)
+ { this->splice(p, static_cast<slist&>(x), first, last); }
+
/// @cond
private:
+ void priv_push_front (const T &x)
+ { this->insert(this->cbegin(), x); }
+
+ void priv_push_front (BOOST_RV_REF(T) x)
+ { this->insert(this->cbegin(), ::boost::move(x)); }
+
bool priv_try_shrink(size_type new_size, const_iterator &last_pos)
{
typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
@@ -1356,14 +1546,13 @@
}
}
- iterator priv_insert(const_iterator p, const value_type& x)
- { return this->insert_after(previous(p), x); }
-
- iterator priv_insert_after(const_iterator prev_pos, const value_type& x)
- { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(x))); }
+ template<class U>
+ iterator priv_insert(const_iterator p, BOOST_FWD_REF(U) x)
+ { return this->insert_after(previous(p), ::boost::forward<U>(x)); }
- void priv_push_front(const value_type &x)
- { this->icont().push_front(*this->create_node(x)); }
+ template<class U>
+ iterator priv_insert_after(const_iterator prev_pos, BOOST_FWD_REF(U) x)
+ { return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(::boost::forward<U>(x)))); }
class insertion_functor;
friend class insertion_functor;
Modified: trunk/boost/container/stable_vector.hpp
==============================================================================
--- trunk/boost/container/stable_vector.hpp (original)
+++ trunk/boost/container/stable_vector.hpp 2012-09-24 06:27:02 EDT (Mon, 24 Sep 2012)
@@ -466,9 +466,6 @@
typedef typename index_traits_type::index_iterator index_iterator;
typedef typename index_traits_type::
const_index_iterator const_index_iterator;
-
- typedef typename container_detail::
- move_const_ref_type<T>::type insert_const_ref_type;
typedef boost::intrusive::
pointer_traits
<typename allocator_traits_type::pointer> ptr_traits;
@@ -601,27 +598,35 @@
{ this->priv_node_alloc().deallocate_individual(boost::move(holder)); }
friend class stable_vector_detail::clear_on_destroy<stable_vector>;
+ typedef stable_vector_detail::iterator
+ < T
+ , typename allocator_traits<A>::reference
+ , typename allocator_traits<A>::pointer> iterator_impl;
+ typedef stable_vector_detail::iterator
+ < T
+ , typename allocator_traits<A>::const_reference
+ , typename allocator_traits<A>::const_pointer> const_iterator_impl;
///@endcond
public:
-
- // types:
-
- typedef typename allocator_traits_type::reference reference;
- typedef typename allocator_traits_type::const_reference const_reference;
- typedef typename allocator_traits_type::pointer pointer;
- typedef typename allocator_traits_type::const_pointer const_pointer;
- typedef stable_vector_detail::iterator
- <T,T&, pointer> iterator;
- typedef stable_vector_detail::iterator
- <T,const T&, const_pointer> const_iterator;
- typedef typename index_type::size_type size_type;
- typedef typename iterator::difference_type difference_type;
- typedef T value_type;
- typedef A allocator_type;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef node_allocator_type stored_allocator_type;
+ //////////////////////////////////////////////
+ //
+ // types
+ //
+ //////////////////////////////////////////////
+ typedef T value_type;
+ typedef typename ::boost::container::allocator_traits<A>::pointer pointer;
+ typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer;
+ typedef typename ::boost::container::allocator_traits<A>::reference reference;
+ typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference;
+ typedef typename ::boost::container::allocator_traits<A>::size_type size_type;
+ typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type;
+ typedef A allocator_type;
+ typedef node_allocator_type stored_allocator_type;
+ typedef BOOST_CONTAINER_IMPDEF(iterator_impl) 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<const_iterator>) const_reverse_iterator;
///@cond
private:
@@ -636,6 +641,11 @@
///@endcond
public:
+ //////////////////////////////////////////////
+ //
+ // construct/copy/destroy
+ //
+ //////////////////////////////////////////////
//! <b>Effects</b>: Default constructs a stable_vector.
//!
@@ -842,6 +852,18 @@
return *this;
}
+
+ //! <b>Effects</b>: Assigns the n copies of val to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void assign(size_type n, const T& t)
+ {
+ typedef constant_iterator<value_type, difference_type> cvalue_iterator;
+ this->assign(cvalue_iterator(t, n), cvalue_iterator());
+ }
+
//! <b>Effects</b>: Assigns the the range [first, last) to *this.
//!
//! <b>Throws</b>: If memory allocation throws or
@@ -870,17 +892,6 @@
}
}
- //! <b>Effects</b>: Assigns the n copies of val to *this.
- //!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to n.
- void assign(size_type n, const T& t)
- {
- typedef constant_iterator<value_type, difference_type> cvalue_iterator;
- this->assign(cvalue_iterator(t, n), cvalue_iterator());
- }
-
//! <b>Effects</b>: Returns a copy of the internal allocator.
//!
//! <b>Throws</b>: If allocator's copy constructor throws.
@@ -909,6 +920,12 @@
stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
{ return this->priv_node_alloc(); }
+ //////////////////////////////////////////////
+ //
+ // iterators
+ //
+ //////////////////////////////////////////////
+
//! <b>Effects</b>: Returns an iterator to the first element contained in the stable_vector.
//!
//! <b>Throws</b>: Nothing.
@@ -1011,6 +1028,20 @@
const_reverse_iterator crend()const
{ return this->rend(); }
+ //////////////////////////////////////////////
+ //
+ // capacity
+ //
+ //////////////////////////////////////////////
+
+ //! <b>Effects</b>: Returns true if the stable_vector contains no elements.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ bool empty() const
+ { return this->index.size() <= ExtraPointers; }
+
//! <b>Effects</b>: Returns the number of the elements contained in the stable_vector.
//!
//! <b>Throws</b>: Nothing.
@@ -1030,31 +1061,22 @@
size_type max_size() const
{ return this->index.max_size() - ExtraPointers; }
- //! <b>Effects</b>: Number of elements for which memory has been allocated.
- //! capacity() is always greater than or equal to size().
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are default constructed.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
//!
- //! <b>Complexity</b>: Constant.
- size_type capacity() const
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type n)
{
- const size_type index_size = this->index.size();
- BOOST_ASSERT(!index_size || index_size >= ExtraPointers);
- const size_type bucket_extra_capacity = this->index.capacity()- index_size;
- const size_type node_extra_capacity = this->internal_data.pool_size;
- const size_type extra_capacity = (bucket_extra_capacity < node_extra_capacity)
- ? bucket_extra_capacity : node_extra_capacity;
- return (index_size ? (index_size - ExtraPointers + extra_capacity) : index_size);
+ typedef default_construct_iterator<value_type, difference_type> default_iterator;
+ STABLE_VECTOR_CHECK_INVARIANT;
+ if(n > this->size())
+ this->insert(this->cend(), default_iterator(n - this->size()), default_iterator());
+ else if(n < this->size())
+ this->erase(this->cbegin() + n, this->cend());
}
- //! <b>Effects</b>: Returns true if the stable_vector contains no elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- bool empty() const
- { return this->index.size() <= ExtraPointers; }
-
//! <b>Effects</b>: Inserts or erases elements at the end such that
//! the size becomes n. New elements are copy constructed from x.
//!
@@ -1070,20 +1092,21 @@
this->erase(this->cbegin() + n, this->cend());
}
- //! <b>Effects</b>: Inserts or erases elements at the end such that
- //! the size becomes n. New elements are default constructed.
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
//!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //! <b>Throws</b>: Nothing.
//!
- //! <b>Complexity</b>: Linear to the difference between size() and new_size.
- void resize(size_type n)
+ //! <b>Complexity</b>: Constant.
+ size_type capacity() const
{
- typedef default_construct_iterator<value_type, difference_type> default_iterator;
- STABLE_VECTOR_CHECK_INVARIANT;
- if(n > this->size())
- this->insert(this->cend(), default_iterator(n - this->size()), default_iterator());
- else if(n < this->size())
- this->erase(this->cbegin() + n, this->cend());
+ const size_type index_size = this->index.size();
+ BOOST_ASSERT(!index_size || index_size >= ExtraPointers);
+ const size_type bucket_extra_capacity = this->index.capacity()- index_size;
+ const size_type node_extra_capacity = this->internal_data.pool_size;
+ const size_type extra_capacity = (bucket_extra_capacity < node_extra_capacity)
+ ? bucket_extra_capacity : node_extra_capacity;
+ return (index_size ? (index_size - ExtraPointers + extra_capacity) : index_size);
}
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
@@ -1116,6 +1139,86 @@
}
}
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ //! with previous allocations. The size of the stable_vector is unchanged
+ //!
+ //! <b>Throws</b>: If memory allocation throws.
+ //!
+ //! <b>Complexity</b>: Linear to size().
+ void shrink_to_fit()
+ {
+ if(this->capacity()){
+ //First empty allocated node pool
+ this->priv_clear_pool();
+ //If empty completely destroy the index, let's recover default-constructed state
+ if(this->empty()){
+ this->index.clear();
+ this->index.shrink_to_fit();
+ this->internal_data.end_node.up = node_base_ptr_ptr();
+ }
+ //Otherwise, try to shrink-to-fit the index and readjust pointers if necessary
+ else{
+ const void* old_ptr = &index[0];
+ this->index.shrink_to_fit();
+ bool realloced = &index[0] != old_ptr;
+ //Fix the pointers for the newly allocated buffer
+ if(realloced){
+ index_traits_type::fix_up_pointers_from(this->index, this->index.begin());
+ }
+ }
+ }
+ }
+
+ //////////////////////////////////////////////
+ //
+ // element access
+ //
+ //////////////////////////////////////////////
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a reference to the first
+ //! element of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference front()
+ { return static_cast<node_reference>(*this->index.front()).value; }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a const reference to the first
+ //! element of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference front() const
+ { return static_cast<const_node_reference>(*this->index.front()).value; }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a reference to the last
+ //! element of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference back()
+ { return static_cast<node_reference>(*this->index[this->size() - ExtraPointers]).value; }
+
+ //! <b>Requires</b>: !empty()
+ //!
+ //! <b>Effects</b>: Returns a const reference to the last
+ //! element of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference back()const
+ { return static_cast<const_node_reference>(*this->index[this->size() - ExtraPointers]).value; }
+
//! <b>Requires</b>: size() > n.
//!
//! <b>Effects</b>: Returns a reference to the nth element
@@ -1168,49 +1271,86 @@
return operator[](n);
}
- //! <b>Requires</b>: !empty()
- //!
- //! <b>Effects</b>: Returns a reference to the first
- //! element of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reference front()
- { return static_cast<node_reference>(*this->index.front()).value; }
+ //////////////////////////////////////////////
+ //
+ // modifiers
+ //
+ //////////////////////////////////////////////
- //! <b>Requires</b>: !empty()
- //!
- //! <b>Effects</b>: Returns a const reference to the first
- //! element of the container.
+ #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the end of the stable_vector.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
//!
- //! <b>Complexity</b>: Constant.
- const_reference front() const
- { return static_cast<const_node_reference>(*this->index.front()).value; }
+ //! <b>Complexity</b>: Amortized constant time.
+ template<class ...Args>
+ void emplace_back(Args &&...args)
+ {
+ typedef emplace_functor<Args...> EmplaceFunctor;
+ typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
+ EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
+ this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
+ }
- //! <b>Requires</b>: !empty()
+ //! <b>Requires</b>: position must be a valid iterator of *this.
//!
- //! <b>Effects</b>: Returns a reference to the last
- //! element of the container.
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... before position
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
//!
- //! <b>Complexity</b>: Constant.
- reference back()
- { return static_cast<node_reference>(*this->index[this->size() - ExtraPointers]).value; }
+ //! <b>Complexity</b>: If position is end(), amortized constant time
+ //! Linear time otherwise.
+ template<class ...Args>
+ iterator emplace(const_iterator position, Args && ...args)
+ {
+ //Just call more general insert(pos, size, value) and return iterator
+ size_type pos_n = position - cbegin();
+ typedef emplace_functor<Args...> EmplaceFunctor;
+ typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
+ EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
+ this->insert(position, EmplaceIterator(ef), EmplaceIterator());
+ return iterator(this->begin() + pos_n);
+ }
- //! <b>Requires</b>: !empty()
- //!
- //! <b>Effects</b>: Returns a const reference to the last
- //! element of the container.
- //!
- //! <b>Throws</b>: Nothing.
+ #else
+
+ #define BOOST_PP_LOCAL_MACRO(n) \
+ BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+ void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
+ { \
+ typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
+ BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
+ EmplaceFunctor; \
+ typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
+ EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
+ BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
+ BOOST_PP_RPAREN_IF(n); \
+ this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator()); \
+ } \
+ \
+ BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+ iterator emplace(const_iterator pos \
+ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
+ { \
+ typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
+ BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
+ EmplaceFunctor; \
+ typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
+ EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
+ BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
+ BOOST_PP_RPAREN_IF(n); \
+ size_type pos_n = pos - this->cbegin(); \
+ this->insert(pos, EmplaceIterator(ef), EmplaceIterator()); \
+ return iterator(this->begin() + pos_n); \
+ } \
//!
- //! <b>Complexity</b>: Constant.
- const_reference back()const
- { return static_cast<const_node_reference>(*this->index[this->size() - ExtraPointers]).value; }
+ #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+ #include BOOST_PP_LOCAL_ITERATE()
+
+ #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts a copy of x at the end of the stable_vector.
@@ -1232,16 +1372,6 @@
BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
#endif
- //! <b>Effects</b>: Removes the last element from the stable_vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant time.
- void pop_back()
- { this->erase(this->end()-1); }
-
-
-
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Requires</b>: position must be a valid iterator of *this.
//!
@@ -1355,80 +1485,13 @@
}
#endif
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the end of the stable_vector.
- //!
- //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- template<class ...Args>
- void emplace_back(Args &&...args)
- {
- typedef emplace_functor<Args...> EmplaceFunctor;
- typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
- EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
- this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
- }
-
- //! <b>Requires</b>: position must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... before position
- //!
- //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
+ //! <b>Effects</b>: Removes the last element from the stable_vector.
//!
- //! <b>Complexity</b>: If position is end(), amortized constant time
- //! Linear time otherwise.
- template<class ...Args>
- iterator emplace(const_iterator position, Args && ...args)
- {
- //Just call more general insert(pos, size, value) and return iterator
- size_type pos_n = position - cbegin();
- typedef emplace_functor<Args...> EmplaceFunctor;
- typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
- EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
- this->insert(position, EmplaceIterator(ef), EmplaceIterator());
- return iterator(this->begin() + pos_n);
- }
-
- #else
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
- BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
- EmplaceFunctor; \
- typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
- EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
- BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
- BOOST_PP_RPAREN_IF(n); \
- this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator()); \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace(const_iterator pos \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
- BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
- EmplaceFunctor; \
- typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
- EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
- BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
- BOOST_PP_RPAREN_IF(n); \
- size_type pos_n = pos - this->cbegin(); \
- this->insert(pos, EmplaceIterator(ef), EmplaceIterator()); \
- return iterator(this->begin() + pos_n); \
- } \
+ //! <b>Throws</b>: Nothing.
//!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ //! <b>Complexity</b>: Constant time.
+ void pop_back()
+ { this->erase(--this->cend()); }
//! <b>Effects</b>: Erases the element at position pos.
//!
@@ -1491,36 +1554,6 @@
void clear()
{ this->erase(this->cbegin(),this->cend()); }
- //! <b>Effects</b>: Tries to deallocate the excess of memory created
- //! with previous allocations. The size of the stable_vector is unchanged
- //!
- //! <b>Throws</b>: If memory allocation throws.
- //!
- //! <b>Complexity</b>: Linear to size().
- void shrink_to_fit()
- {
- if(this->capacity()){
- //First empty allocated node pool
- this->priv_clear_pool();
- //If empty completely destroy the index, let's recover default-constructed state
- if(this->empty()){
- this->index.clear();
- this->index.shrink_to_fit();
- this->internal_data.end_node.up = node_base_ptr_ptr();
- }
- //Otherwise, try to shrink-to-fit the index and readjust pointers if necessary
- else{
- const void* old_ptr = &index[0];
- this->index.shrink_to_fit();
- bool realloced = &index[0] != old_ptr;
- //Fix the pointers for the newly allocated buffer
- if(realloced){
- index_traits_type::fix_up_pointers_from(this->index, this->index.begin());
- }
- }
- }
- }
-
/// @cond
private:
Modified: trunk/boost/container/vector.hpp
==============================================================================
--- trunk/boost/container/vector.hpp (original)
+++ trunk/boost/container/vector.hpp 2012-09-24 06:27:02 EDT (Mon, 24 Sep 2012)
@@ -86,7 +86,7 @@
{ return *m_ptr; }
const value_type * operator->() const
- { return container_detail::to_raw_pointer(m_ptr); }
+ { return container_detail::to_raw_pointer(m_ptr); }
reference operator[](difference_type off) const
{ return m_ptr[off]; }
@@ -408,40 +408,29 @@
class vector : private container_detail::vector_alloc_holder<A>
{
/// @cond
- typedef vector<T, A> self_t;
typedef container_detail::vector_alloc_holder<A> base_t;
typedef allocator_traits<A> allocator_traits_type;
/// @endcond
public:
- //! The type of object, T, stored in the vector
- typedef T value_type;
- //! Pointer to T
- typedef typename allocator_traits_type::pointer pointer;
- //! Const pointer to T
- typedef typename allocator_traits_type::const_pointer const_pointer;
- //! Reference to T
- typedef typename allocator_traits_type::reference reference;
- //! Const reference to T
- typedef typename allocator_traits_type::const_reference const_reference;
- //! An unsigned integral type
- typedef typename allocator_traits_type::size_type size_type;
- //! A signed integral type
- typedef typename allocator_traits_type::difference_type difference_type;
- //! The allocator type
- typedef A allocator_type;
- //! The random access iterator
- typedef container_detail::vector_iterator<pointer> iterator;
- //! The random access const_iterator
- typedef container_detail::vector_const_iterator<pointer> const_iterator;
-
- //! Iterator used to iterate backwards through a vector.
- typedef std::reverse_iterator<iterator>
- reverse_iterator;
- //! Const iterator used to iterate backwards through a vector.
- typedef std::reverse_iterator<const_iterator>
- const_reverse_iterator;
- //! The stored allocator type
- typedef allocator_type stored_allocator_type;
+ //////////////////////////////////////////////
+ //
+ // types
+ //
+ //////////////////////////////////////////////
+
+ typedef T value_type;
+ typedef typename ::boost::container::allocator_traits<A>::pointer pointer;
+ typedef typename ::boost::container::allocator_traits<A>::const_pointer const_pointer;
+ typedef typename ::boost::container::allocator_traits<A>::reference reference;
+ typedef typename ::boost::container::allocator_traits<A>::const_reference const_reference;
+ typedef typename ::boost::container::allocator_traits<A>::size_type size_type;
+ typedef typename ::boost::container::allocator_traits<A>::difference_type difference_type;
+ typedef A allocator_type;
+ typedef allocator_type stored_allocator_type;
+ 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(std::reverse_iterator<iterator>) reverse_iterator;
+ typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
/// @cond
private:
@@ -459,6 +448,11 @@
/// @endcond
public:
+ //////////////////////////////////////////////
+ //
+ // construct/copy/destroy
+ //
+ //////////////////////////////////////////////
//! <b>Effects</b>: Constructs a vector taking the allocator as parameter.
//!
@@ -488,25 +482,7 @@
//! <b>Complexity</b>: Linear to n.
explicit vector(size_type n)
: base_t()
- {
- this->resize(n);
-/*
- //Allocate
- size_type real_cap = 0;
- std::pair<pointer, bool> ret =
- this->allocation_command(allocate_new, n, n, real_cap, this->members_.m_start);
- T *new_mem = container_detail::to_raw_pointer(ret.first);
- //Anti-exception rollback
- typename value_traits::ArrayDeallocator scoped_alloc(new_mem, this->alloc(), real_cap);
- //Default constructor
- container_detail::default_construct_aux_proxy<A, T*> proxy(this->alloc(), n);
- proxy.uninitialized_copy_remaining_to(new_mem);
- //All ok, commit
- this->members_.m_start = ret.first;
- this->members_.m_size = n;
- this->members_.m_capacity = real_cap;
- scoped_alloc.release();*/
- }
+ { this->resize(n); }
//! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
//! and inserts n copies of value.
@@ -517,10 +493,19 @@
//! <b>Complexity</b>: Linear to n.
vector(size_type n, const T& value, const allocator_type& a = allocator_type())
: base_t(a)
- {
- this->resize(n, value);
-// this->insert(this->cend(), n, value);
- }
+ { this->resize(n, value); }
+
+ //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
+ //! and inserts a copy of the range [first, last) in the vector.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor or allocation
+ //! throws or T's constructor taking an dereferenced InIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to the range [first, last).
+ template <class InIt>
+ vector(InIt first, InIt last, const allocator_type& a = allocator_type())
+ : base_t(a)
+ { this->assign(first, last); }
//! <b>Effects</b>: Copy constructs a vector.
//!
@@ -580,18 +565,6 @@
}
}
- //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
- //! and inserts a copy of the range [first, last) in the vector.
- //!
- //! <b>Throws</b>: If allocator_type's default constructor or allocation
- //! throws or T's constructor taking an dereferenced InIt throws.
- //!
- //! <b>Complexity</b>: Linear to the range [first, last).
- template <class InIt>
- vector(InIt first, InIt last, const allocator_type& a = allocator_type())
- : base_t(a)
- { this->assign(first, last); }
-
//! <b>Effects</b>: Destroys the vector. All stored values are destroyed
//! and used memory is deallocated.
//!
@@ -601,6 +574,141 @@
~vector() BOOST_CONTAINER_NOEXCEPT
{} //vector_alloc_holder clears the data
+ //! <b>Effects</b>: Makes *this contain the same elements as x.
+ //!
+ //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
+ //! of each of x's elements.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy/move constructor/assignment throws.
+ //!
+ //! <b>Complexity</b>: Linear to the number of elements in x.
+ vector& operator=(BOOST_COPY_ASSIGN_REF(vector) x)
+ {
+ if (&x != this){
+ allocator_type &this_alloc = this->alloc();
+ const allocator_type &x_alloc = x.alloc();
+ container_detail::bool_<allocator_traits_type::
+ propagate_on_container_copy_assignment::value> flag;
+ if(flag && this_alloc != x_alloc){
+ this->clear();
+ this->shrink_to_fit();
+ }
+ container_detail::assign_alloc(this_alloc, x_alloc, flag);
+ this->assign( container_detail::to_raw_pointer(x.members_.m_start)
+ , container_detail::to_raw_pointer(x.members_.m_start + x.members_.m_size));
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
+ //!
+ //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
+ //! before the function.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Complexity</b>: Linear.
+ vector& operator=(BOOST_RV_REF(vector) x)
+ //iG BOOST_CONTAINER_NOEXCEPT_IF(!allocator_type::propagate_on_container_move_assignment::value || is_nothrow_move_assignable<allocator_type>::value);)
+ BOOST_CONTAINER_NOEXCEPT
+ {
+ if (&x != this){
+ allocator_type &this_alloc = this->alloc();
+ allocator_type &x_alloc = x.alloc();
+ //If allocators are equal we can just swap pointers
+ if(this_alloc == x_alloc){
+ //Destroy objects but retain memory in case x reuses it in the future
+ this->clear();
+ this->swap_members(x);
+ //Move allocator if needed
+ container_detail::bool_<allocator_traits_type::
+ propagate_on_container_move_assignment::value> flag;
+ container_detail::move_alloc(this_alloc, x_alloc, flag);
+ }
+ //If unequal allocators, then do a one by one move
+ else{
+ this->assign( boost::make_move_iterator(container_detail::to_raw_pointer(x.members_.m_start))
+ , boost::make_move_iterator(container_detail::to_raw_pointer(x.members_.m_start + x.members_.m_size)));
+ }
+ }
+ return *this;
+ }
+
+ //! <b>Effects</b>: Assigns the the range [first, last) to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy/move constructor/assignment or
+ //! T's constructor/assignment from dereferencing InpIt throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ template <class InIt>
+ void assign(InIt first, InIt last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ , typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InIt, size_type>::value
+ //&& container_detail::is_input_iterator<InIt>::value
+ >::type * = 0
+ #endif
+ )
+ {
+ //Overwrite all elements we can from [first, last)
+ iterator cur = this->begin();
+ for ( ; first != last && cur != end(); ++cur, ++first){
+ *cur = *first;
+ }
+
+ if (first == last){
+ //There are no more elements in the sequence, erase remaining
+ this->erase(cur, this->cend());
+ }
+ else{
+ //There are more elements in the range, insert the remaining ones
+ this->insert(this->cend(), first, last);
+ }
+ }
+
+ //! <b>Effects</b>: Assigns the n copies of val to *this.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy/move constructor/assignment throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ void assign(size_type n, const value_type& val)
+ { this->assign(cvalue_iterator(val, n), cvalue_iterator()); }
+
+ //! <b>Effects</b>: Returns a copy of the internal allocator.
+ //!
+ //! <b>Throws</b>: If allocator's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant.
+ allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
+ { 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>Throws</b>: Nothing
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
+ { return this->alloc(); }
+
+ //////////////////////////////////////////////
+ //
+ // iterators
+ //
+ //////////////////////////////////////////////
+
//! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
//!
//! <b>Throws</b>: Nothing.
@@ -703,177 +811,88 @@
const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
{ return const_reverse_iterator(this->begin()); }
- //! <b>Requires</b>: !empty()
- //!
- //! <b>Effects</b>: Returns a reference to the first
- //! element of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reference front() BOOST_CONTAINER_NOEXCEPT
- { return *this->members_.m_start; }
+ //////////////////////////////////////////////
+ //
+ // capacity
+ //
+ //////////////////////////////////////////////
- //! <b>Requires</b>: !empty()
- //!
- //! <b>Effects</b>: Returns a const reference to the first
- //! element of the container.
+ //! <b>Effects</b>: Returns true if the vector contains no elements.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference front() const BOOST_CONTAINER_NOEXCEPT
- { return *this->members_.m_start; }
+ bool empty() const BOOST_CONTAINER_NOEXCEPT
+ { return !this->members_.m_size; }
- //! <b>Requires</b>: !empty()
- //!
- //! <b>Effects</b>: Returns a reference to the last
- //! element of the container.
+ //! <b>Effects</b>: Returns the number of the elements contained in the vector.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference back() BOOST_CONTAINER_NOEXCEPT
- { return this->members_.m_start[this->members_.m_size - 1]; }
+ size_type size() const BOOST_CONTAINER_NOEXCEPT
+ { return this->members_.m_size; }
- //! <b>Requires</b>: !empty()
- //!
- //! <b>Effects</b>: Returns a const reference to the last
- //! element of the container.
+ //! <b>Effects</b>: Returns the largest possible size of the vector.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference back() const BOOST_CONTAINER_NOEXCEPT
- { return this->members_.m_start[this->members_.m_size - 1]; }
+ size_type max_size() const BOOST_CONTAINER_NOEXCEPT
+ { return allocator_traits_type::max_size(this->alloc()); }
- //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
- //! For a non-empty vector, data() == &front().
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are default constructed.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
//!
- //! <b>Complexity</b>: Constant.
- pointer data() BOOST_CONTAINER_NOEXCEPT
- { return this->members_.m_start; }
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size)
+ {
+ if (new_size < this->size()){
+ //Destroy last elements
+ this->erase(const_iterator(this->members_.m_start + new_size), this->end());
+ }
+ else{
+ const size_type n = new_size - this->size();
+ this->reserve(new_size);
+ container_detail::default_construct_aux_proxy<A, T*> proxy(this->alloc(), n);
+ this->priv_forward_range_insert(this->cend().get_ptr(), n, proxy);
+ }
+ }
- //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
- //! For a non-empty vector, data() == &front().
+ //! <b>Effects</b>: Inserts or erases elements at the end such that
+ //! the size becomes n. New elements are copy constructed from x.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
//!
- //! <b>Complexity</b>: Constant.
- const_pointer data() const BOOST_CONTAINER_NOEXCEPT
- { return this->members_.m_start; }
+ //! <b>Complexity</b>: Linear to the difference between size() and new_size.
+ void resize(size_type new_size, const T& x)
+ {
+ pointer finish = this->members_.m_start + this->members_.m_size;
+ if (new_size < size()){
+ //Destroy last elements
+ this->erase(const_iterator(this->members_.m_start + new_size), this->end());
+ }
+ else{
+ //Insert new elements at the end
+ this->insert(const_iterator(finish), new_size - this->size(), x);
+ }
+ }
- //! <b>Effects</b>: Returns the number of the elements contained in the vector.
+ //! <b>Effects</b>: Number of elements for which memory has been allocated.
+ //! capacity() is always greater than or equal to size().
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const BOOST_CONTAINER_NOEXCEPT
- { return this->members_.m_size; }
+ size_type capacity() const BOOST_CONTAINER_NOEXCEPT
+ { return this->members_.m_capacity; }
- //! <b>Effects</b>: Returns the largest possible size of the vector.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type max_size() const BOOST_CONTAINER_NOEXCEPT
- { return allocator_traits_type::max_size(this->alloc()); }
-
- //! <b>Effects</b>: Number of elements for which memory has been allocated.
- //! capacity() is always greater than or equal to size().
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- size_type capacity() const BOOST_CONTAINER_NOEXCEPT
- { return this->members_.m_capacity; }
-
- //! <b>Effects</b>: Returns true if the vector contains no elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- bool empty() const BOOST_CONTAINER_NOEXCEPT
- { return !this->members_.m_size; }
-
- //! <b>Requires</b>: size() > n.
- //!
- //! <b>Effects</b>: Returns a reference to the nth element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- reference operator[](size_type n)
- { return this->members_.m_start[n]; }
-
- //! <b>Requires</b>: size() > n.
- //!
- //! <b>Effects</b>: Returns a const reference to the nth element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Complexity</b>: Constant.
- const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
- { return this->members_.m_start[n]; }
-
- //! <b>Requires</b>: size() > n.
- //!
- //! <b>Effects</b>: Returns a reference to the nth element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: std::range_error if n >= size()
- //!
- //! <b>Complexity</b>: Constant.
- reference at(size_type n)
- { this->priv_check_range(n); return this->members_.m_start[n]; }
-
- //! <b>Requires</b>: size() > n.
- //!
- //! <b>Effects</b>: Returns a const reference to the nth element
- //! from the beginning of the container.
- //!
- //! <b>Throws</b>: std::range_error if n >= size()
- //!
- //! <b>Complexity</b>: Constant.
- const_reference at(size_type n) const
- { this->priv_check_range(n); return this->members_.m_start[n]; }
-
- //! <b>Effects</b>: Returns a copy of the internal allocator.
- //!
- //! <b>Throws</b>: If allocator's copy constructor throws.
- //!
- //! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
- { 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>Throws</b>: Nothing
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
- { return this->alloc(); }
-
- //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
- //! effect. Otherwise, it is a request for allocation of additional memory.
- //! If the request is successful, then capacity() is greater than or equal to
- //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+ //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
+ //! effect. Otherwise, it is a request for allocation of additional memory.
+ //! If the request is successful, then capacity() is greater than or equal to
+ //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
//!
//! <b>Throws</b>: If memory allocation allocation throws or T's copy/move constructor throws.
void reserve(size_type new_cap)
@@ -931,251 +950,138 @@
}
}
- //! <b>Effects</b>: Makes *this contain the same elements as x.
+ //! <b>Effects</b>: Tries to deallocate the excess of memory created
+ //! with previous allocations. The size of the vector is unchanged
//!
- //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
- //! of each of x's elements.
+ //! <b>Throws</b>: If memory allocation throws, or T's copy/move constructor throws.
//!
- //! <b>Throws</b>: If memory allocation throws or T's copy/move constructor/assignment throws.
+ //! <b>Complexity</b>: Linear to size().
+ void shrink_to_fit()
+ { priv_shrink_to_fit(alloc_version()); }
+
+ //////////////////////////////////////////////
+ //
+ // element access
+ //
+ //////////////////////////////////////////////
+
+ //! <b>Requires</b>: !empty()
//!
- //! <b>Complexity</b>: Linear to the number of elements in x.
- vector& operator=(BOOST_COPY_ASSIGN_REF(vector) x)
- {
- if (&x != this){
- allocator_type &this_alloc = this->alloc();
- const allocator_type &x_alloc = x.alloc();
- container_detail::bool_<allocator_traits_type::
- propagate_on_container_copy_assignment::value> flag;
- if(flag && this_alloc != x_alloc){
- this->clear();
- this->shrink_to_fit();
- }
- container_detail::assign_alloc(this_alloc, x_alloc, flag);
- this->assign( container_detail::to_raw_pointer(x.members_.m_start)
- , container_detail::to_raw_pointer(x.members_.m_start + x.members_.m_size));
- }
- return *this;
- }
+ //! <b>Effects</b>: Returns a reference to the first
+ //! element of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference front() BOOST_CONTAINER_NOEXCEPT
+ { return *this->members_.m_start; }
- //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
+ //! <b>Requires</b>: !empty()
//!
- //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
- //! before the function.
+ //! <b>Effects</b>: Returns a const reference to the first
+ //! element of the container.
//!
- //! <b>Throws</b>: Nothing
+ //! <b>Throws</b>: Nothing.
//!
- //! <b>Complexity</b>: Linear.
- vector& operator=(BOOST_RV_REF(vector) x)
- //iG BOOST_CONTAINER_NOEXCEPT_IF(!allocator_type::propagate_on_container_move_assignment::value || is_nothrow_move_assignable<allocator_type>::value);)
- BOOST_CONTAINER_NOEXCEPT
- {
- if (&x != this){
- allocator_type &this_alloc = this->alloc();
- allocator_type &x_alloc = x.alloc();
- //If allocators are equal we can just swap pointers
- if(this_alloc == x_alloc){
- //Destroy objects but retain memory in case x reuses it in the future
- this->clear();
- this->swap_members(x);
- //Move allocator if needed
- container_detail::bool_<allocator_traits_type::
- propagate_on_container_move_assignment::value> flag;
- container_detail::move_alloc(this_alloc, x_alloc, flag);
- }
- //If unequal allocators, then do a one by one move
- else{
- this->assign( boost::make_move_iterator(container_detail::to_raw_pointer(x.members_.m_start))
- , boost::make_move_iterator(container_detail::to_raw_pointer(x.members_.m_start + x.members_.m_size)));
- }
- }
- return *this;
- }
+ //! <b>Complexity</b>: Constant.
+ const_reference front() const BOOST_CONTAINER_NOEXCEPT
+ { return *this->members_.m_start; }
- //! <b>Effects</b>: Assigns the n copies of val to *this.
+ //! <b>Requires</b>: !empty()
//!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's copy/move constructor/assignment throws.
+ //! <b>Effects</b>: Returns a reference to the last
+ //! element of the container.
//!
- //! <b>Complexity</b>: Linear to n.
- void assign(size_type n, const value_type& val)
- { this->assign(cvalue_iterator(val, n), cvalue_iterator()); }
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference back() BOOST_CONTAINER_NOEXCEPT
+ { return this->members_.m_start[this->members_.m_size - 1]; }
- //! <b>Effects</b>: Assigns the the range [first, last) to *this.
+ //! <b>Requires</b>: !empty()
//!
- //! <b>Throws</b>: If memory allocation throws or T's copy/move constructor/assignment or
- //! T's constructor/assignment from dereferencing InpIt throws.
+ //! <b>Effects</b>: Returns a const reference to the last
+ //! element of the container.
//!
- //! <b>Complexity</b>: Linear to n.
- template <class InIt>
- void assign(InIt first, InIt last
- #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<InIt, size_type>::value
- && container_detail::is_input_iterator<InIt>::value
- >::type * = 0
- #endif
- )
- {
- //Overwrite all elements we can from [first, last)
- iterator cur = begin();
- for ( ; first != last && cur != end(); ++cur, ++first){
- *cur = *first;
- }
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference back() const BOOST_CONTAINER_NOEXCEPT
+ { return this->members_.m_start[this->members_.m_size - 1]; }
- if (first == last){
- //There are no more elements in the sequence, erase remaining
- this->erase(cur, cend());
- }
- else{
- //There are more elements in the range, insert the remaining ones
- this->insert(this->cend(), first, last);
- }
- }
+ //! <b>Requires</b>: size() > n.
+ //!
+ //! <b>Effects</b>: Returns a reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference operator[](size_type n)
+ { return this->members_.m_start[n]; }
- #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- template <class FwdIt>
- void assign(FwdIt first, FwdIt last
- , typename container_detail::enable_if_c
- < !container_detail::is_convertible<FwdIt, size_type>::value
- && !container_detail::is_input_iterator<FwdIt>::value
- >::type * = 0
- )
- {
- const size_type n = std::distance(first, last);
-
- if(!n){
- this->prot_destroy_all();
- return;
- }
- //Check if we have enough memory or try to expand current memory
- size_type remaining = this->members_.m_capacity - this->members_.m_size;
- bool same_buffer_start;
- std::pair<pointer, bool> ret;
- size_type real_cap = this->members_.m_capacity;
+ //! <b>Requires</b>: size() > n.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
+ { return this->members_.m_start[n]; }
- if (n <= remaining){
- same_buffer_start = true;
- }
- else{
- //There is not enough memory, allocate a new buffer
- size_type new_cap = this->next_capacity(n);
- ret = this->allocation_command
- (allocate_new | expand_fwd | expand_bwd,
- this->size() + n, new_cap, real_cap, this->members_.m_start);
- same_buffer_start = ret.second && this->members_.m_start == ret.first;
- if(same_buffer_start){
- this->members_.m_capacity = real_cap;
- }
- }
-
- if(same_buffer_start){
- T *start = container_detail::to_raw_pointer(this->members_.m_start);
- if (this->size() >= n){
- //There is memory, but there are more old elements than new ones
- //Overwrite old elements with new ones
- std::copy(first, last, start);
- //Destroy remaining old elements
- this->destroy_n(start + n, this->members_.m_size - n);
- this->members_.m_size = n;
- }
- else{
- //There is memory, but there are less old elements than new ones
- //First overwrite some old elements with new ones
- FwdIt mid = first;
- std::advance(mid, this->size());
- T *end = std::copy(first, mid, start);
- //Initialize the remaining new elements in the uninitialized memory
- ::boost::container::uninitialized_copy_or_move_alloc(this->alloc(), mid, last, end);
- this->members_.m_size = n;
- }
- }
- else if(!ret.second){
- typename value_traits::ArrayDeallocator scoped_alloc(ret.first, this->alloc(), real_cap);
- ::boost::container::uninitialized_copy_or_move_alloc(this->alloc(), first, last, container_detail::to_raw_pointer(ret.first));
- scoped_alloc.release();
- //Destroy and deallocate old buffer
- if(this->members_.m_start != 0){
- this->destroy_n(container_detail::to_raw_pointer(this->members_.m_start), this->members_.m_size);
- this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
- }
- this->members_.m_start = ret.first;
- this->members_.m_size = n;
- this->members_.m_capacity = real_cap;
- }
- else{
- //Backwards expansion
- //If anything goes wrong, this object will destroy old objects
- T *old_start = container_detail::to_raw_pointer(this->members_.m_start);
- size_type old_size = this->members_.m_size;
- typename value_traits::OldArrayDestructor old_values_destroyer(old_start, this->alloc(), old_size);
- //If something goes wrong size will be 0
- //but holding the whole buffer
- this->members_.m_size = 0;
- this->members_.m_start = ret.first;
- this->members_.m_capacity = real_cap;
-
- //Backup old buffer data
- size_type old_offset = old_start - container_detail::to_raw_pointer(ret.first);
- size_type first_count = container_detail::min_value(n, old_offset);
-
- FwdIt mid = first;
- std::advance(mid, first_count);
- ::boost::container::uninitialized_copy_or_move_alloc
- (this->alloc(), first, mid, container_detail::to_raw_pointer(ret.first));
-
- if(old_offset > n){
- //All old elements will be destroyed by "old_values_destroyer"
- this->members_.m_size = n;
- }
- else{
- //We have constructed objects from the new begin until
- //the old end so release the rollback destruction
- old_values_destroyer.release();
- this->members_.m_start = ret.first;
- this->members_.m_size = first_count + old_size;
- //Now overwrite the old values
- size_type second_count = container_detail::min_value(old_size, n - first_count);
- FwdIt mid2 = mid;
- std::advance(mid2, second_count);
- std::copy(mid, mid2, old_start);
-
- //Check if we still have to append elements in the
- //uninitialized end
- if(second_count == old_size){
- std::copy(mid2, last, old_start + old_size);
- }
- else{
- //We have to destroy some old values
- this->destroy_n
- (old_start + second_count, old_size - second_count);
- this->members_.m_size = n;
- }
- this->members_.m_size = n;
- }
- }
- }
- #endif
+ //! <b>Requires</b>: size() > n.
+ //!
+ //! <b>Effects</b>: Returns a reference to the nth element
+ //! from the beginning of the container.
+ //!
+ //! <b>Throws</b>: std::range_error if n >= size()
+ //!
+ //! <b>Complexity</b>: Constant.
+ reference at(size_type n)
+ { this->priv_check_range(n); return this->members_.m_start[n]; }
- #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- //! <b>Effects</b>: Inserts a copy of x at the end of the vector.
+ //! <b>Requires</b>: size() > n.
//!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's copy/move constructor throws.
+ //! <b>Effects</b>: Returns a const reference to the nth element
+ //! from the beginning of the container.
//!
- //! <b>Complexity</b>: Amortized constant time.
- void push_back(const T &x);
+ //! <b>Throws</b>: std::range_error if n >= size()
+ //!
+ //! <b>Complexity</b>: Constant.
+ const_reference at(size_type n) const
+ { this->priv_check_range(n); return this->members_.m_start[n]; }
- //! <b>Effects</b>: Constructs a new element in the end of the vector
- //! and moves the resources of mx to this new element.
+ //////////////////////////////////////////////
+ //
+ // data access
+ //
+ //////////////////////////////////////////////
+
+ //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
+ //! For a non-empty vector, data() == &front().
//!
- //! <b>Throws</b>: If memory allocation throws or
- //! T's move constructor throws.
+ //! <b>Throws</b>: Nothing.
//!
- //! <b>Complexity</b>: Amortized constant time.
- void push_back(T &&x);
- #else
- BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
- #endif
+ //! <b>Complexity</b>: Constant.
+ T* data() BOOST_CONTAINER_NOEXCEPT
+ { return container_detail::to_raw_pointer(this->members_.m_start); }
+
+ //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
+ //! For a non-empty vector, data() == &front().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ const T * data() const BOOST_CONTAINER_NOEXCEPT
+ { return container_detail::to_raw_pointer(this->members_.m_start); }
+
+ //////////////////////////////////////////////
+ //
+ // modifiers
+ //
+ //////////////////////////////////////////////
#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -1259,21 +1165,28 @@
#include BOOST_PP_LOCAL_ITERATE()
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
- //! <b>Effects</b>: Swaps the contents of *this and x.
+
+ #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ //! <b>Effects</b>: Inserts a copy of x at the end of the vector.
//!
- //! <b>Throws</b>: Nothing.
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's copy/move constructor throws.
//!
- //! <b>Complexity</b>: Constant.
- void swap(vector& x)
- {
- //Just swap internals
- this->swap_members(x);
- //And now the allocator
- container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
- container_detail::swap_alloc(this->alloc(), x.alloc(), flag);
- }
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back(const T &x);
+ //! <b>Effects</b>: Constructs a new element in the end of the vector
+ //! and moves the resources of mx to this new element.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or
+ //! T's move constructor throws.
+ //!
+ //! <b>Complexity</b>: Amortized constant time.
+ void push_back(T &&x);
+ #else
+ BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
+ #endif
+
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Requires</b>: position must be a valid iterator of *this.
//!
@@ -1300,6 +1213,18 @@
//! <b>Requires</b>: p must be a valid iterator of *this.
//!
+ //! <b>Effects</b>: Insert n copies of x before pos.
+ //!
+ //! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
+ //!
+ //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ iterator insert(const_iterator p, size_type n, const T& x)
+ { return this->insert(p, cvalue_iterator(x, n), cvalue_iterator()); }
+
+ //! <b>Requires</b>: p must be a valid iterator of *this.
+ //!
//! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
//!
//! <b>Returns</b>: an iterator to the first inserted element or pos if first == last.
@@ -1344,18 +1269,6 @@
}
#endif
- //! <b>Requires</b>: p must be a valid iterator of *this.
- //!
- //! <b>Effects</b>: Insert n copies of x before pos.
- //!
- //! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
- //!
- //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to n.
- iterator insert(const_iterator p, size_type n, const T& x)
- { return this->insert(p, cvalue_iterator(x, n), cvalue_iterator()); }
-
//! <b>Effects</b>: Removes the last element from the vector.
//!
//! <b>Throws</b>: Nothing.
@@ -1407,43 +1320,18 @@
return iterator(first.get_ptr());
}
- //! <b>Effects</b>: Inserts or erases elements at the end such that
- //! the size becomes n. New elements are copy constructed from x.
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
- //!
- //! <b>Complexity</b>: Linear to the difference between size() and new_size.
- void resize(size_type new_size, const T& x)
- {
- pointer finish = this->members_.m_start + this->members_.m_size;
- if (new_size < size()){
- //Destroy last elements
- this->erase(const_iterator(this->members_.m_start + new_size), this->end());
- }
- else{
- //Insert new elements at the end
- this->insert(const_iterator(finish), new_size - this->size(), x);
- }
- }
-
- //! <b>Effects</b>: Inserts or erases elements at the end such that
- //! the size becomes n. New elements are default constructed.
+ //! <b>Effects</b>: Swaps the contents of *this and x.
//!
- //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
+ //! <b>Throws</b>: Nothing.
//!
- //! <b>Complexity</b>: Linear to the difference between size() and new_size.
- void resize(size_type new_size)
+ //! <b>Complexity</b>: Constant.
+ void swap(vector& x)
{
- if (new_size < this->size()){
- //Destroy last elements
- this->erase(const_iterator(this->members_.m_start + new_size), this->end());
- }
- else{
- const size_type n = new_size - this->size();
- this->reserve(new_size);
- container_detail::default_construct_aux_proxy<A, T*> proxy(this->alloc(), n);
- this->priv_forward_range_insert(this->cend().get_ptr(), n, proxy);
- }
+ //Just swap internals
+ this->swap_members(x);
+ //And now the allocator
+ container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
+ container_detail::swap_alloc(this->alloc(), x.alloc(), flag);
}
//! <b>Effects</b>: Erases all the elements of the vector.
@@ -1454,15 +1342,6 @@
void clear() BOOST_CONTAINER_NOEXCEPT
{ this->prot_destroy_all(); }
- //! <b>Effects</b>: Tries to deallocate the excess of memory created
- //! with previous allocations. The size of the vector is unchanged
- //!
- //! <b>Throws</b>: If memory allocation throws, or T's copy/move constructor throws.
- //!
- //! <b>Complexity</b>: Linear to size().
- void shrink_to_fit()
- { priv_shrink_to_fit(alloc_version()); }
-
/// @cond
//Absolutely experimental. This function might change, disappear or simply crash!
Modified: trunk/libs/container/doc/Jamfile.v2
==============================================================================
--- trunk/libs/container/doc/Jamfile.v2 (original)
+++ trunk/libs/container/doc/Jamfile.v2 2012-09-24 06:27:02 EDT (Mon, 24 Sep 2012)
@@ -27,6 +27,8 @@
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>"PREDEFINED=\"insert_const_ref_type= const T&\" \\
\"BOOST_CONTAINER_DOXYGEN_INVOKED\" \\
+ \"BOOST_CONTAINER_IMPDEF(T)=implementation_defined\" \\
+ \"BOOST_CONTAINER_SEEDOC(T)=see_documentation\" \\
\"BOOST_RV_REF(T)=T &&\" \\
\"BOOST_RV_REF_BEG=\" \\
\"BOOST_RV_REF_END=&&\" \\
Modified: trunk/libs/container/doc/container.qbk
==============================================================================
--- trunk/libs/container/doc/container.qbk (original)
+++ trunk/libs/container/doc/container.qbk 2012-09-24 06:27:02 EDT (Mon, 24 Sep 2012)
@@ -617,13 +617,15 @@
[section:release_notes_boost_1_52_00 Boost 1.52 Release]
* Improved `stable_vector`'s template code bloat and type safety.
-
+* Changed typedefs and reordered functions of sequence containers to improve doxygen documentation.
* Fixed bugs
[@https://svn.boost.org/trac/boost/ticket/6615 #6615],
[@https://svn.boost.org/trac/boost/ticket/7139 #7139],
[@https://svn.boost.org/trac/boost/ticket/7215 #7215],
[@https://svn.boost.org/trac/boost/ticket/7232 #7232],
[@https://svn.boost.org/trac/boost/ticket/7269 #7269].
+* Implemented LWG Issue #149 (range insertion now returns an iterator) & cleaned up insertion code in most containers
+* Corrected aliasing errors.
[endsect]
Modified: trunk/libs/container/proj/to-do.txt
==============================================================================
--- trunk/libs/container/proj/to-do.txt (original)
+++ trunk/libs/container/proj/to-do.txt 2012-09-24 06:27:02 EDT (Mon, 24 Sep 2012)
@@ -51,4 +51,111 @@
Add hash for containers
-Add std:: hashing support
\ No newline at end of file
+Add std:: hashing support
+
+Take out from class definition iterators in slist & list
+
+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
+
+Replace all insert_const_ref_type with BOOST_MOVE_CONVERSION_AWARE_CATCH_XXX
+
+
+
+Function order:
+
+----------type------------
+value_type;
+pointer;
+const_pointer;
+reference;
+const_reference;
+size_type;
+difference_type;
+allocator_type;
+stored_allocator_type;
+iterator;
+const_iterator;
+reverse_iterator;
+const_reverse_iterator;
+----------func------------
+container()
+container(allocator_type)
+container(size_type)
+container(size_type, value_type, allocator_type = ())
+container(InpIt, InpIt)
+container(const container &)
+container(container &&)
+container(const container &, allocator_type)
+container(container &&, allocator_type)
+container(initializer_list<T>, allocator)
+~container()
+container operator=(const container &)
+container operator=(container &&)
+container operator=(initializer_list<T>)
+assign(size_type, const T &)
+
+assign(InpIt, InptIt)
+assign(initializer_list)
+get_allocator()
+
+begin()
+begin() const
+end()
+end() const
+rbegin()
+rbegin() const
+rend()
+rend() const
+
+cbegin() const
+cend() const
+crbegin() const
+crend() const
+
+empty()
+size()
+max_size()
+resize(size_type)
+resize(size_type, cont T&)
+capacity()
+reserve(size_type)
+shrink_to_fit()
+
+front()
+front() const
+back()
+back() const
+operator[] ()
+operator[] ()const
+at()
+at() const
+
+
+data()
+data() const
+
+emplace_front()
+emplace_back()
+emplace()
+push_front(const T&)
+push_front(T&&)
+push_back(const T&)
+push_back(T&&)
+insert(iterator, const T &)
+insert(iterator, T &&)
+insert(size_type, const T &)
+insert(InpIt, InpIt)
+pop_front()
+pop_back()
+erase(const_iterator)
+erase(const_iterator, const_iterator)
+swap(container &)
+clear()
\ No newline at end of file
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk