From 6f1f162cb3862218b2813dde0bc4853141fd450e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sat, 1 Nov 2014 20:03:25 +0100 Subject: [PATCH] - Added nth and index_of. - Used BOOST_MOVE_BASE --- doc/container.qbk | 5 ++ include/boost/container/deque.hpp | 94 +++++++++++++++++--- include/boost/container/detail/flat_tree.hpp | 16 +++- include/boost/container/detail/tree.hpp | 28 +++--- include/boost/container/flat_map.hpp | 38 ++++++-- include/boost/container/flat_set.hpp | 93 +++++++++++++++---- include/boost/container/list.hpp | 12 +-- include/boost/container/map.hpp | 12 +-- include/boost/container/set.hpp | 12 +-- include/boost/container/slist.hpp | 8 +- include/boost/container/stable_vector.hpp | 79 ++++++++++++++-- include/boost/container/static_vector.hpp | 74 +++++++++++++-- include/boost/container/string.hpp | 20 ++--- include/boost/container/vector.hpp | 91 +++++++++++++++++-- proj/vc7ide/container.vcproj | 3 + test/check_equal_containers.hpp | 1 + test/container_common_tests.hpp | 86 ++++++++++++++++++ test/expand_bwd_test_template.hpp | 10 +-- test/flat_map_test.cpp | 17 ++++ test/flat_set_test.cpp | 17 ++++ test/vector_test.hpp | 5 ++ 21 files changed, 615 insertions(+), 106 deletions(-) create mode 100644 test/container_common_tests.hpp diff --git a/doc/container.qbk b/doc/container.qbk index 8208308..ea93dc1 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -1079,6 +1079,11 @@ use [*Boost.Container]? There are several reasons for that: [section:release_notes Release Notes] +[section:release_notes_boost_1_58_00 Boost 1.58 Release] +* Added `nth` and `index_of` functions to containers with random-access iterators (except `basic_string`). + +[endsect] + [section:release_notes_boost_1_57_00 Boost 1.57 Release] * Added support for `initializer_list`. Contributed by Robert Matusewicz. * Fixed double destruction bugs in vector and backward expansion capable allocators. diff --git a/include/boost/container/deque.hpp b/include/boost/container/deque.hpp index d8a546c..867af8a 100644 --- a/include/boost/container/deque.hpp +++ b/include/boost/container/deque.hpp @@ -639,13 +639,13 @@ class deque : protected deque_base } } - //! Effects: Move constructor. Moves mx's resources to *this. + //! Effects: Move constructor. Moves x's resources to *this. //! //! Throws: If allocator_type's copy constructor throws. //! //! Complexity: Constant. deque(BOOST_RV_REF(deque) x) - : Base(boost::move(static_cast(x))) + : Base(BOOST_MOVE_BASE(Base, x)) { this->swap_members(x); } //! Effects: Copy constructs a vector using the specified allocator. @@ -667,23 +667,23 @@ class deque : protected deque_base } //! Effects: Move constructor using the specified allocator. - //! Moves mx's resources to *this if a == allocator_type(). + //! Moves x's resources to *this if a == allocator_type(). //! Otherwise copies values from x to *this. //! //! Throws: If allocation or T's copy constructor throws. //! - //! Complexity: Constant if a == mx.get_allocator(), linear otherwise. - deque(BOOST_RV_REF(deque) mx, const allocator_type &a) + //! Complexity: Constant if a == x.get_allocator(), linear otherwise. + deque(BOOST_RV_REF(deque) x, const allocator_type &a) : Base(a) { - if(mx.alloc() == a){ - this->swap_members(mx); + if(x.alloc() == a){ + this->swap_members(x); } else{ - if(mx.size()){ - this->priv_initialize_map(mx.size()); + if(x.size()){ + this->priv_initialize_map(x.size()); boost::container::uninitialized_copy_alloc - (this->alloc(), mx.begin(), mx.end(), this->members_.m_start); + (this->alloc(), x.begin(), x.end(), this->members_.m_start); } } } @@ -1158,6 +1158,67 @@ class deque : protected deque_base const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT { return this->members_.m_start[difference_type(n)]; } + //! Requires: size() >= n. + //! + //! Effects: Returns an iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + iterator nth(size_type n) BOOST_CONTAINER_NOEXCEPT + { + BOOST_ASSERT(this->size() >= n); + return iterator(this->begin()+n); + } + + //! Requires: size() >= n. + //! + //! Effects: Returns a const_iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + const_iterator nth(size_type n) const BOOST_CONTAINER_NOEXCEPT + { + BOOST_ASSERT(this->size() >= n); + return const_iterator(this->cbegin()+n); + } + + //! Requires: size() >= n. + //! + //! Effects: Returns an iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + size_type index_of(iterator p) BOOST_CONTAINER_NOEXCEPT + { return this->priv_index_of(p); } + + //! Requires: begin() <= p <= end(). + //! + //! Effects: Returns the index of the element pointed by p + //! and size() if p == end(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + size_type index_of(const_iterator p) const BOOST_CONTAINER_NOEXCEPT + { return this->priv_index_of(p); } + //! Requires: size() > n. //! //! Effects: Returns a reference to the nth element @@ -1333,7 +1394,7 @@ class deque : protected deque_base void push_front(const T &x); //! Effects: Constructs a new element in the front of the deque - //! and moves the resources of mx to this new element. + //! and moves the resources of x to this new element. //! //! Throws: If memory allocation throws. //! @@ -1353,7 +1414,7 @@ class deque : protected deque_base void push_back(const T &x); //! Effects: Constructs a new element in the end of the deque - //! and moves the resources of mx to this new element. + //! and moves the resources of x to this new element. //! //! Throws: If memory allocation throws. //! @@ -1379,7 +1440,7 @@ class deque : protected deque_base //! Requires: p must be a valid iterator of *this. //! - //! Effects: Insert a new element before p with mx's resources. + //! Effects: Insert a new element before p with x's resources. //! //! Returns: an iterator to the inserted element. //! @@ -1648,6 +1709,13 @@ class deque : protected deque_base #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: + size_type priv_index_of(const_iterator p) const + { + BOOST_ASSERT(this->cbegin() <= p); + BOOST_ASSERT(p <= this->cend()); + return static_cast(p - this->cbegin()); + } + void priv_erase_last_n(size_type n) { if(n == this->size()) { diff --git a/include/boost/container/detail/flat_tree.hpp b/include/boost/container/detail/flat_tree.hpp index a6f7568..a2213d2 100644 --- a/include/boost/container/detail/flat_tree.hpp +++ b/include/boost/container/detail/flat_tree.hpp @@ -265,8 +265,8 @@ class flat_tree flat_tree& operator=(BOOST_COPY_ASSIGN_REF(flat_tree) x) { m_data = x.m_data; return *this; } - flat_tree& operator=(BOOST_RV_REF(flat_tree) mx) - { m_data = boost::move(mx.m_data); return *this; } + flat_tree& operator=(BOOST_RV_REF(flat_tree) x) + { m_data = boost::move(x.m_data); return *this; } public: // accessors: @@ -632,6 +632,18 @@ class flat_tree void shrink_to_fit() { this->m_data.m_vect.shrink_to_fit(); } + iterator nth(size_type n) BOOST_CONTAINER_NOEXCEPT + { return this->m_data.m_vect.nth(n); } + + const_iterator nth(size_type n) const BOOST_CONTAINER_NOEXCEPT + { return this->m_data.m_vect.nth(n); } + + size_type index_of(iterator p) BOOST_CONTAINER_NOEXCEPT + { return this->m_data.m_vect.index_of(p); } + + size_type index_of(const_iterator p) const BOOST_CONTAINER_NOEXCEPT + { return this->m_data.m_vect.index_of(p); } + // set operations: iterator find(const key_type& k) { diff --git a/include/boost/container/detail/tree.hpp b/include/boost/container/detail/tree.hpp index e59bca0..59e76cc 100644 --- a/include/boost/container/detail/tree.hpp +++ b/include/boost/container/detail/tree.hpp @@ -851,9 +851,9 @@ class tree template iterator insert_unique_commit - (BOOST_FWD_REF(MovableConvertible) mv, insert_commit_data &data) + (BOOST_FWD_REF(MovableConvertible) v, insert_commit_data &data) { - NodePtr tmp = AllocHolder::create_node(boost::forward(mv)); + NodePtr tmp = AllocHolder::create_node(boost::forward(v)); scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); iterator ret(this->icont().insert_unique_commit(*tmp, data)); destroy_deallocator.release(); @@ -872,13 +872,13 @@ class tree } template - std::pair insert_unique(BOOST_FWD_REF(MovableConvertible) mv) + std::pair insert_unique(BOOST_FWD_REF(MovableConvertible) v) { insert_commit_data data; std::pair ret = - this->insert_unique_check(KeyOfValue()(mv), data); + this->insert_unique_check(KeyOfValue()(v), data); if(ret.second){ - ret.first = this->insert_unique_commit(boost::forward(mv), data); + ret.first = this->insert_unique_commit(boost::forward(v), data); } return ret; } @@ -886,9 +886,9 @@ class tree private: template - void push_back_impl(BOOST_FWD_REF(MovableConvertible) mv) + void push_back_impl(BOOST_FWD_REF(MovableConvertible) v) { - NodePtr tmp(AllocHolder::create_node(boost::forward(mv))); + NodePtr tmp(AllocHolder::create_node(boost::forward(v))); //push_back has no-throw guarantee so avoid any deallocator/destroyer this->icont().push_back(*tmp); } @@ -1010,14 +1010,14 @@ class tree } template - iterator insert_unique(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv) + iterator insert_unique(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v) { insert_commit_data data; std::pair ret = - this->insert_unique_check(hint, KeyOfValue()(mv), data); + this->insert_unique_check(hint, KeyOfValue()(v), data); if(!ret.second) return ret.first; - return this->insert_unique_commit(boost::forward(mv), data); + return this->insert_unique_commit(boost::forward(v), data); } template @@ -1037,9 +1037,9 @@ class tree } template - iterator insert_equal(BOOST_FWD_REF(MovableConvertible) mv) + iterator insert_equal(BOOST_FWD_REF(MovableConvertible) v) { - NodePtr tmp(AllocHolder::create_node(boost::forward(mv))); + NodePtr tmp(AllocHolder::create_node(boost::forward(v))); scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); iterator ret(this->icont().insert_equal(this->icont().end(), *tmp)); destroy_deallocator.release(); @@ -1056,9 +1056,9 @@ class tree } template - iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv) + iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v) { - NodePtr tmp(AllocHolder::create_node(boost::forward(mv))); + NodePtr tmp(AllocHolder::create_node(boost::forward(v))); scoped_destroy_deallocator destroy_deallocator(tmp, this->node_alloc()); iterator ret(this->icont().insert_equal(hint.get(), *tmp)); destroy_deallocator.release(); diff --git a/include/boost/container/flat_map.hpp b/include/boost/container/flat_map.hpp index e7ff31a..f8b6ed4 100644 --- a/include/boost/container/flat_map.hpp +++ b/include/boost/container/flat_map.hpp @@ -115,6 +115,7 @@ class flat_map typedef typename impl_tree_t::value_type impl_value_type; typedef typename impl_tree_t::const_iterator impl_const_iterator; + typedef typename impl_tree_t::iterator impl_iterator; typedef typename impl_tree_t::allocator_type impl_allocator_type; typedef container_detail::flat_tree_value_compare < Compare @@ -556,6 +557,22 @@ class flat_map BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript) #endif + //! @copydoc ::boost::container::flat_set::nth(size_type) + iterator nth(size_type n) BOOST_CONTAINER_NOEXCEPT + { return container_detail::force_copy(m_flat_tree.nth(n)); } + + //! @copydoc ::boost::container::flat_set::nth(size_type) const + const_iterator nth(size_type n) const BOOST_CONTAINER_NOEXCEPT + { return container_detail::force_copy(m_flat_tree.nth(n)); } + + //! @copydoc ::boost::container::flat_set::index_of(iterator) + size_type index_of(iterator p) BOOST_CONTAINER_NOEXCEPT + { return m_flat_tree.index_of(container_detail::force_copy(p)); } + + //! @copydoc ::boost::container::flat_set::index_of(const_iterator) const + size_type index_of(const_iterator p) const BOOST_CONTAINER_NOEXCEPT + { return m_flat_tree.index_of(container_detail::force_copy(p)); } + //! Returns: Allocator reference to the element whose key is equivalent to x. //! //! Throws: An exception object of type out_of_range if no such element is present. @@ -1085,6 +1102,7 @@ class flat_multimap typedef typename impl_tree_t::value_type impl_value_type; typedef typename impl_tree_t::const_iterator impl_const_iterator; + typedef typename impl_tree_t::iterator impl_iterator; typedef typename impl_tree_t::allocator_type impl_allocator_type; typedef container_detail::flat_tree_value_compare < Compare @@ -1493,11 +1511,21 @@ class flat_multimap void shrink_to_fit() { m_flat_tree.shrink_to_fit(); } - ////////////////////////////////////////////// - // - // modifiers - // - ////////////////////////////////////////////// + //! @copydoc ::boost::container::flat_set::nth(size_type) + iterator nth(size_type n) BOOST_CONTAINER_NOEXCEPT + { return container_detail::force_copy(m_flat_tree.nth(n)); } + + //! @copydoc ::boost::container::flat_set::nth(size_type) const + const_iterator nth(size_type n) const BOOST_CONTAINER_NOEXCEPT + { return container_detail::force_copy(m_flat_tree.nth(n)); } + + //! @copydoc ::boost::container::flat_set::index_of(iterator) + size_type index_of(iterator p) BOOST_CONTAINER_NOEXCEPT + { return m_flat_tree.index_of(container_detail::force_copy(p)); } + + //! @copydoc ::boost::container::flat_set::index_of(const_iterator) const + size_type index_of(const_iterator p) const BOOST_CONTAINER_NOEXCEPT + { return m_flat_tree.index_of(container_detail::force_copy(p)); } #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) diff --git a/include/boost/container/flat_set.hpp b/include/boost/container/flat_set.hpp index 1307f34..631c99e 100644 --- a/include/boost/container/flat_set.hpp +++ b/include/boost/container/flat_set.hpp @@ -187,13 +187,13 @@ class flat_set : base_t(static_cast(x)) {} - //! Effects: Move constructs thecontainer. Constructs *this using mx's resources. + //! Effects: Move constructs thecontainer. Constructs *this using x's resources. //! //! Complexity: Constant. //! - //! Postcondition: mx is emptied. - flat_set(BOOST_RV_REF(flat_set) mx) - : base_t(boost::move(static_cast(mx))) + //! Postcondition: x is emptied. + flat_set(BOOST_RV_REF(flat_set) x) + : base_t(BOOST_MOVE_BASE(base_t, x)) {} //! Effects: Copy constructs a container using the specified allocator. @@ -204,11 +204,11 @@ class flat_set {} //! Effects: Move constructs a container using the specified allocator. - //! Constructs *this using mx's resources. + //! Constructs *this using x's resources. //! - //! Complexity: Constant if a == mx.get_allocator(), linear otherwise - flat_set(BOOST_RV_REF(flat_set) mx, const allocator_type &a) - : base_t(boost::move(static_cast(mx)), a) + //! Complexity: Constant if a == x.get_allocator(), linear otherwise + flat_set(BOOST_RV_REF(flat_set) x, const allocator_type &a) + : base_t(BOOST_MOVE_BASE(base_t, x), a) {} //! Effects: Makes *this a copy of x. @@ -225,7 +225,7 @@ class flat_set //! this->get>allocator() == x.get_allocator(). Linear otherwise. flat_set& operator=(BOOST_RV_REF(flat_set) x) BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value) - { return static_cast(this->base_t::operator=(boost::move(static_cast(x)))); } + { return static_cast(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! Effects: Copy all elements from il to *this. @@ -646,6 +646,57 @@ class flat_set //! Complexity: Logarithmic. const_iterator find(const key_type& x) const; + //! Requires: size() >= n. + //! + //! Effects: Returns an iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + iterator nth(size_type n) BOOST_CONTAINER_NOEXCEPT; + + //! Requires: size() >= n. + //! + //! Effects: Returns a const_iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + const_iterator nth(size_type n) const BOOST_CONTAINER_NOEXCEPT; + + //! Requires: size() >= n. + //! + //! Effects: Returns an iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + size_type index_of(iterator p) BOOST_CONTAINER_NOEXCEPT; + + //! Requires: begin() <= p <= end(). + //! + //! Effects: Returns the index of the element pointed by p + //! and size() if p == end(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + size_type index_of(const_iterator p) const BOOST_CONTAINER_NOEXCEPT; + #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Returns: The number of elements with key equivalent to x. @@ -876,8 +927,8 @@ class flat_multiset {} //! @copydoc ::boost::container::flat_set(flat_set &&) - flat_multiset(BOOST_RV_REF(flat_multiset) mx) - : base_t(boost::move(static_cast(mx))) + flat_multiset(BOOST_RV_REF(flat_multiset) x) + : base_t(boost::move(static_cast(x))) {} //! @copydoc ::boost::container::flat_set(const flat_set &, const allocator_type &) @@ -886,8 +937,8 @@ class flat_multiset {} //! @copydoc ::boost::container::flat_set(flat_set &&, const allocator_type &) - flat_multiset(BOOST_RV_REF(flat_multiset) mx, const allocator_type &a) - : base_t(boost::move(static_cast(mx)), a) + flat_multiset(BOOST_RV_REF(flat_multiset) x, const allocator_type &a) + : base_t(BOOST_MOVE_BASE(base_t, x), a) {} //! @copydoc ::boost::container::flat_set::operator=(const flat_set &) @@ -895,9 +946,9 @@ class flat_multiset { return static_cast(this->base_t::operator=(static_cast(x))); } //! @copydoc ::boost::container::flat_set::operator=(flat_set &&) - flat_multiset& operator=(BOOST_RV_REF(flat_multiset) mx) + flat_multiset& operator=(BOOST_RV_REF(flat_multiset) x) BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value) - { return static_cast(this->base_t::operator=(boost::move(static_cast(mx)))); } + { return static_cast(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! @copydoc ::boost::container::flat_set::operator=(std::initializer_list) @@ -1157,6 +1208,18 @@ class flat_multiset //! @copydoc ::boost::container::flat_set::find(const key_type& ) const const_iterator find(const key_type& x) const; + //! @copydoc ::boost::container::flat_set::nth(size_type) + iterator nth(size_type n) BOOST_CONTAINER_NOEXCEPT; + + //! @copydoc ::boost::container::flat_set::nth(size_type) const + const_iterator nth(size_type n) const BOOST_CONTAINER_NOEXCEPT; + + //! @copydoc ::boost::container::flat_set::index_of(iterator) + size_type index_of(iterator p) BOOST_CONTAINER_NOEXCEPT; + + //! @copydoc ::boost::container::flat_set::index_of(const_iterator) const + size_type index_of(const_iterator p) const BOOST_CONTAINER_NOEXCEPT; + //! @copydoc ::boost::container::flat_set::count(const key_type& ) const size_type count(const key_type& x) const; diff --git a/include/boost/container/list.hpp b/include/boost/container/list.hpp index 33cc6ee..79e0915 100644 --- a/include/boost/container/list.hpp +++ b/include/boost/container/list.hpp @@ -259,13 +259,13 @@ class list : AllocHolder(x) { this->insert(this->cbegin(), x.begin(), x.end()); } - //! Effects: Move constructor. Moves mx's resources to *this. + //! Effects: Move constructor. Moves x's resources to *this. //! //! Throws: If allocator_type's copy constructor throws. //! //! Complexity: Constant. list(BOOST_RV_REF(list) x) - : AllocHolder(boost::move(static_cast(x))) + : AllocHolder(BOOST_MOVE_BASE(AllocHolder, x)) {} //! Effects: Copy constructs a list using the specified allocator. @@ -280,7 +280,7 @@ class list { this->insert(this->cbegin(), x.begin(), x.end()); } //! Effects: Move constructor sing the specified allocator. - //! Moves mx's resources to *this. + //! Moves x's resources to *this. //! //! Throws: If allocation or value_type's copy constructor throws. //! @@ -786,7 +786,7 @@ class list void push_front(const T &x); //! Effects: Constructs a new element in the beginning of the list - //! and moves the resources of mx to this new element. + //! and moves the resources of x to this new element. //! //! Throws: If memory allocation throws. //! @@ -806,7 +806,7 @@ class list void push_back(const T &x); //! Effects: Constructs a new element in the end of the list - //! and moves the resources of mx to this new element. + //! and moves the resources of x to this new element. //! //! Throws: If memory allocation throws. //! @@ -830,7 +830,7 @@ class list //! Requires: p must be a valid iterator of *this. //! - //! Effects: Insert a new element before p with mx's resources. + //! Effects: Insert a new element before p with x's resources. //! //! Returns: an iterator to the inserted element. //! diff --git a/include/boost/container/map.hpp b/include/boost/container/map.hpp index 6abfa1a..6bbb1bc 100644 --- a/include/boost/container/map.hpp +++ b/include/boost/container/map.hpp @@ -223,7 +223,7 @@ class map //! //! Postcondition: x is emptied. map(BOOST_RV_REF(map) x) - : base_t(boost::move(static_cast(x))) + : base_t(BOOST_MOVE_BASE(base_t, x)) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -246,7 +246,7 @@ class map //! //! Postcondition: x is emptied. map(BOOST_RV_REF(map) x, const allocator_type &a) - : base_t(boost::move(static_cast(x)), a) + : base_t(BOOST_MOVE_BASE(base_t, x), a) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -268,7 +268,7 @@ class map //! this->get>allocator() == x.get_allocator(). Linear otherwise. map& operator=(BOOST_RV_REF(map) x) BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value) - { return static_cast(this->base_t::operator=(boost::move(static_cast(x)))); } + { return static_cast(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! Effects: Assign content of il to *this. @@ -1021,7 +1021,7 @@ class multimap //! //! Postcondition: x is emptied. multimap(BOOST_RV_REF(multimap) x) - : base_t(boost::move(static_cast(x))) + : base_t(BOOST_MOVE_BASE(base_t, x)) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -1043,7 +1043,7 @@ class multimap //! //! Postcondition: x is emptied. multimap(BOOST_RV_REF(multimap) x, const allocator_type &a) - : base_t(boost::move(static_cast(x)), a) + : base_t(BOOST_MOVE_BASE(base_t, x), a) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -1059,7 +1059,7 @@ class multimap //! //! Complexity: Constant. multimap& operator=(BOOST_RV_REF(multimap) x) - { return static_cast(this->base_t::operator=(boost::move(static_cast(x)))); } + { return static_cast(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! Effects: Assign content of il to *this. diff --git a/include/boost/container/set.hpp b/include/boost/container/set.hpp index 3e2c2aa..ee19704 100644 --- a/include/boost/container/set.hpp +++ b/include/boost/container/set.hpp @@ -188,7 +188,7 @@ class set //! //! Postcondition: x is emptied. set(BOOST_RV_REF(set) x) - : base_t(boost::move(static_cast(x))) + : base_t(BOOST_MOVE_BASE(base_t, x)) {} //! Effects: Copy constructs a set using the specified allocator. @@ -203,7 +203,7 @@ class set //! //! Complexity: Constant if a == x.get_allocator(), linear otherwise. set(BOOST_RV_REF(set) x, const allocator_type &a) - : base_t(boost::move(static_cast(x)), a) + : base_t(BOOST_MOVE_BASE(base_t, x), a) {} //! Effects: Makes *this a copy of x. @@ -222,7 +222,7 @@ class set //! this->get>allocator() == x.get_allocator(). Linear otherwise. set& operator=(BOOST_RV_REF(set) x) BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value) - { return static_cast(this->base_t::operator=(boost::move(static_cast(x)))); } + { return static_cast(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) set& operator=(std::initializer_list il) @@ -812,7 +812,7 @@ class multiset //! @copydoc ::boost::container::set(set &&) multiset(BOOST_RV_REF(multiset) x) - : base_t(boost::move(static_cast(x))) + : base_t(BOOST_MOVE_BASE(base_t, x)) {} //! @copydoc ::boost::container::set(const set &, const allocator_type &) @@ -822,7 +822,7 @@ class multiset //! @copydoc ::boost::container::set(set &&, const allocator_type &) multiset(BOOST_RV_REF(multiset) x, const allocator_type &a) - : base_t(boost::move(static_cast(x)), a) + : base_t(BOOST_MOVE_BASE(base_t, x), a) {} //! @copydoc ::boost::container::set::operator=(const set &) @@ -831,7 +831,7 @@ class multiset //! @copydoc ::boost::container::set::operator=(set &&) multiset& operator=(BOOST_RV_REF(multiset) x) - { return static_cast(this->base_t::operator=(boost::move(static_cast(x)))); } + { return static_cast(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); } #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) //! @copydoc ::boost::container::set::operator=(std::initializer_list) diff --git a/include/boost/container/slist.hpp b/include/boost/container/slist.hpp index b6b4c38..cc39043 100644 --- a/include/boost/container/slist.hpp +++ b/include/boost/container/slist.hpp @@ -307,13 +307,13 @@ class slist : AllocHolder(x) { this->insert_after(this->cbefore_begin(), x.begin(), x.end()); } - //! Effects: Move constructor. Moves mx's resources to *this. + //! Effects: Move constructor. Moves x's resources to *this. //! //! Throws: If allocator_type's copy constructor throws. //! //! Complexity: Constant. slist(BOOST_RV_REF(slist) x) - : AllocHolder(boost::move(static_cast(x))) + : AllocHolder(BOOST_MOVE_BASE(AllocHolder, x)) {} //! Effects: Copy constructs a list using the specified allocator. @@ -774,7 +774,7 @@ class slist void push_front(const T &x); //! Effects: Constructs a new element in the beginning of the list - //! and moves the resources of mx to this new element. + //! and moves the resources of x to this new element. //! //! Throws: If memory allocation throws. //! @@ -1337,7 +1337,7 @@ class slist //! Requires: p must be a valid iterator of *this. //! - //! Effects: Insert a new element before p with mx's resources. + //! Effects: Insert a new element before p with x's resources. //! //! Returns: an iterator to the inserted element. //! diff --git a/include/boost/container/stable_vector.hpp b/include/boost/container/stable_vector.hpp index b8b4157..59648a4 100644 --- a/include/boost/container/stable_vector.hpp +++ b/include/boost/container/stable_vector.hpp @@ -652,7 +652,7 @@ class stable_vector } #endif - //! Effects: Move constructor. Moves mx's resources to *this. + //! Effects: Move constructor. Moves x's resources to *this. //! //! Throws: If allocator_type's copy constructor throws. //! @@ -678,7 +678,7 @@ class stable_vector } //! Effects: Move constructor using the specified allocator. - //! Moves mx's resources to *this. + //! Moves x's resources to *this. //! //! Throws: If allocator_type's copy constructor throws. //! @@ -736,7 +736,7 @@ class stable_vector return *this; } - //! Effects: Move assignment. All mx's values are transferred to *this. + //! Effects: Move assignment. All x's values are transferred to *this. //! //! Postcondition: x.empty(). *this contains a the elements x had //! before the function. @@ -1217,6 +1217,67 @@ class stable_vector return static_cast(*this->index[n]).value; } + //! Requires: size() >= n. + //! + //! Effects: Returns an iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + iterator nth(size_type n) BOOST_CONTAINER_NOEXCEPT + { + BOOST_ASSERT(this->size() >= n); + return (this->index.empty()) ? this->end() : iterator(node_ptr_traits::static_cast_from(this->index[n])); + } + + //! Requires: size() >= n. + //! + //! Effects: Returns a const_iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + const_iterator nth(size_type n) const BOOST_CONTAINER_NOEXCEPT + { + BOOST_ASSERT(this->size() >= n); + return (this->index.empty()) ? this->cend() : iterator(node_ptr_traits::static_cast_from(this->index[n])); + } + + //! Requires: size() >= n. + //! + //! Effects: Returns an iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + size_type index_of(iterator p) BOOST_CONTAINER_NOEXCEPT + { return this->priv_index_of(p.node_pointer()); } + + //! Requires: begin() <= p <= end(). + //! + //! Effects: Returns the index of the element pointed by p + //! and size() if p == end(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + size_type index_of(const_iterator p) const BOOST_CONTAINER_NOEXCEPT + { return this->priv_index_of(p.node_pointer()); } + //! Requires: size() > n. //! //! Effects: Returns a reference to the nth element @@ -1339,7 +1400,7 @@ class stable_vector void push_back(const T &x); //! Effects: Constructs a new element in the end of the stable_vector - //! and moves the resources of mx to this new element. + //! and moves the resources of x to this new element. //! //! Throws: If memory allocation throws. //! @@ -1364,7 +1425,7 @@ class stable_vector //! Requires: p must be a valid iterator of *this. //! - //! Effects: Insert a new element before p with mx's resources. + //! Effects: Insert a new element before p with x's resources. //! //! Returns: an iterator to the inserted element. //! @@ -1603,6 +1664,14 @@ class stable_vector #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: + size_type priv_index_of(node_ptr p) const + { + //Check range + BOOST_ASSERT(this->index.empty() || (this->index.data() <= p->up)); + BOOST_ASSERT(this->index.empty() || p->up <= (this->index.data() + this->index.size())); + return this->index.empty() ? 0 : p->up - this->index.data(); + } + class insert_rollback { public: diff --git a/include/boost/container/static_vector.hpp b/include/boost/container/static_vector.hpp index 1ae8011..d3f8772 100644 --- a/include/boost/container/static_vector.hpp +++ b/include/boost/container/static_vector.hpp @@ -16,7 +16,7 @@ #endif #include - +#include #include #include @@ -265,7 +265,7 @@ public: //! @par Complexity //! Linear O(N). static_vector(BOOST_RV_REF(static_vector) other) - : base_t(boost::move(static_cast(other))) + : base_t(BOOST_MOVE_BASE(base_t, other)) {} //! @pre other.size() <= capacity() @@ -282,7 +282,7 @@ public: //! Linear O(N). template static_vector(BOOST_RV_REF_BEG static_vector BOOST_RV_REF_END other) - : base_t(boost::move(static_cast::base_t&>(other))) + : base_t(BOOST_MOVE_BASE(typename static_vector::base_t, other)) {} //! @brief Copy assigns Values stored in the other static_vector to this one. @@ -310,9 +310,7 @@ public: //! @par Complexity //! Linear O(N). static_vector & operator=(std::initializer_list il) - { - return static_cast(base_t::operator=(il)); - } + { return static_cast(base_t::operator=(il)); } #endif //! @pre other.size() <= capacity() @@ -345,7 +343,7 @@ public: //! Linear O(N). static_vector & operator=(BOOST_RV_REF(static_vector) other) { - return static_cast(base_t::operator=(boost::move(static_cast(other)))); + return static_cast(base_t::operator=(BOOST_MOVE_BASE(base_t, other))); } //! @pre other.size() <= capacity() @@ -364,7 +362,7 @@ public: static_vector & operator=(BOOST_RV_REF_BEG static_vector BOOST_RV_REF_END other) { return static_cast(base_t::operator= - (boost::move(static_cast::base_t&>(other)))); + (BOOST_MOVE_BASE(typename static_vector::base_t, other))); } #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -769,6 +767,66 @@ public: //! Constant O(1). const_reference operator[](size_type i) const; + //! @pre i =< size() + //! + //! @brief Returns a iterator to the i-th element. + //! + //! @param i The element's index. + //! + //! @return a iterator to the i-th element. + //! + //! @par Throws + //! Nothing by default. + //! + //! @par Complexity + //! Constant O(1). + iterator nth(size_type i); + + //! @pre i =< size() + //! + //! @brief Returns a const_iterator to the i-th element. + //! + //! @param i The element's index. + //! + //! @return a const_iterator to the i-th element. + //! + //! @par Throws + //! Nothing by default. + //! + //! @par Complexity + //! Constant O(1). + const_iterator nth(size_type i) const; + + //! @pre begin() <= p <= end() + //! + //! @brief Returns the index of the element pointed by p. + //! + //! @param i The element's index. + //! + //! @return The index of the element pointed by p. + //! + //! @par Throws + //! Nothing by default. + //! + //! @par Complexity + //! Constant O(1). + size_type index_of(iterator p); + + //! @pre begin() <= p <= end() + //! + //! @brief Returns the index of the element pointed by p. + //! + //! @param i The index of the element pointed by p. + //! + //! @return a const_iterator to the i-th element. + //! + //! @par Throws + //! Nothing by default. + //! + //! @par Complexity + //! Constant O(1). + size_type index_of(const_iterator p) const; + //! @pre \c !empty() //! //! @brief Returns reference to the first element. diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp index 1c3cf3b..3960f05 100644 --- a/include/boost/container/string.hpp +++ b/include/boost/container/string.hpp @@ -2552,29 +2552,29 @@ template inline template inline basic_string operator+ - ( BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END mx - , BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END my) + ( BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END x + , BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END y) { - mx += my; - return boost::move(mx); + x += y; + return boost::move(x); } template inline basic_string operator+ - ( BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END mx + ( BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END x , const basic_string& y) { - mx += y; - return boost::move(mx); + x += y; + return boost::move(x); } template inline basic_string operator+ (const basic_string& x - ,BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END my) + ,BOOST_RV_REF_BEG basic_string BOOST_RV_REF_END y) { - my.insert(my.begin(), x.begin(), x.end()); - return boost::move(my); + y.insert(y.begin(), x.begin(), x.end()); + return boost::move(y); } template inline diff --git a/include/boost/container/vector.hpp b/include/boost/container/vector.hpp index 765a2c6..9789cbd 100644 --- a/include/boost/container/vector.hpp +++ b/include/boost/container/vector.hpp @@ -310,7 +310,7 @@ struct vector_alloc_holder } vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) BOOST_CONTAINER_NOEXCEPT - : Allocator(boost::move(static_cast(holder))) + : Allocator(BOOST_MOVE_BASE(Allocator, holder)) , m_start(holder.m_start) , m_size(holder.m_size) , m_capacity(holder.m_capacity) @@ -439,7 +439,7 @@ struct vector_alloc_holder(holder))) + : Allocator(BOOST_MOVE_BASE(Allocator, holder)) , m_size(holder.m_size) //Size is initialized here so vector should only call uninitialized_xxx after this { ::boost::container::uninitialized_move_alloc_n @@ -1300,7 +1300,10 @@ class vector //! //! Complexity: Constant. reference back() BOOST_CONTAINER_NOEXCEPT - { return this->m_holder.start()[this->m_holder.m_size - 1]; } + { + BOOST_ASSERT(this->m_holder.m_size > 0); + return this->m_holder.start()[this->m_holder.m_size - 1]; + } //! Requires: !empty() //! @@ -1311,7 +1314,10 @@ class vector //! //! Complexity: Constant. const_reference back() const BOOST_CONTAINER_NOEXCEPT - { return this->m_holder.start()[this->m_holder.m_size - 1]; } + { + BOOST_ASSERT(this->m_holder.m_size > 0); + return this->m_holder.start()[this->m_holder.m_size - 1]; + } //! Requires: size() > n. //! @@ -1322,7 +1328,10 @@ class vector //! //! Complexity: Constant. reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT - { return this->m_holder.start()[n]; } + { + BOOST_ASSERT(this->m_holder.m_size > n); + return this->m_holder.start()[n]; + } //! Requires: size() > n. //! @@ -1333,7 +1342,70 @@ class vector //! //! Complexity: Constant. const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT - { return this->m_holder.start()[n]; } + { + return this->m_holder.start()[n]; + } + + //! Requires: size() >= n. + //! + //! Effects: Returns an iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + iterator nth(size_type n) BOOST_CONTAINER_NOEXCEPT + { + BOOST_ASSERT(this->m_holder.m_size >= n); + return iterator(this->m_holder.start()+n); + } + + //! Requires: size() >= n. + //! + //! Effects: Returns a const_iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + const_iterator nth(size_type n) const BOOST_CONTAINER_NOEXCEPT + { + BOOST_ASSERT(this->m_holder.m_size >= n); + return const_iterator(this->m_holder.start()+n); + } + + //! Requires: size() >= n. + //! + //! Effects: Returns an iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + size_type index_of(iterator p) BOOST_CONTAINER_NOEXCEPT + { return this->priv_index_of(vector_iterator_get_ptr(p)); } + + //! Requires: begin() <= p <= end(). + //! + //! Effects: Returns the index of the element pointed by p + //! and size() if p == end(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + size_type index_of(const_iterator p) const BOOST_CONTAINER_NOEXCEPT + { return this->priv_index_of(vector_iterator_get_ptr(p)); } //! Requires: size() > n. //! @@ -1901,6 +1973,13 @@ class vector private: + size_type priv_index_of(pointer p) const + { + BOOST_ASSERT(this->m_holder.start() <= p); + BOOST_ASSERT(p <= (this->m_holder.start()+size())); + return static_cast(p - this->m_holder.start()); + } + template void priv_move_assign(BOOST_RV_REF_BEG vector BOOST_RV_REF_END x , typename container_detail::enable_if_c diff --git a/proj/vc7ide/container.vcproj b/proj/vc7ide/container.vcproj index 291c603..008f37c 100644 --- a/proj/vc7ide/container.vcproj +++ b/proj/vc7ide/container.vcproj @@ -197,6 +197,9 @@ + + diff --git a/test/check_equal_containers.hpp b/test/check_equal_containers.hpp index b742891..1e09386 100644 --- a/test/check_equal_containers.hpp +++ b/test/check_equal_containers.hpp @@ -101,6 +101,7 @@ bool CheckEqualPairContainers(const MyBoostCont &boostcont, const MyStdCont &std } return true; } + } //namespace test{ } //namespace container { } //namespace boost{ diff --git a/test/container_common_tests.hpp b/test/container_common_tests.hpp new file mode 100644 index 0000000..394a860 --- /dev/null +++ b/test/container_common_tests.hpp @@ -0,0 +1,86 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_TEST_CONTAINER_COMMON_TESTS_HPP +#define BOOST_CONTAINER_TEST_CONTAINER_COMMON_TESTS_HPP + +#include + +namespace boost{ +namespace container { +namespace test{ + + +template +const Container &as_const(Container &c) +{ return c; } + +//nth, index_of +template +bool test_nth_index_of(Container &c) +{ + typename Container::iterator it; + typename Container::const_iterator cit; + typename Container::size_type sz, csz; + //index 0 + it = c.nth(0); + sz = c.index_of(it); + cit = as_const(c).nth(0); + csz = as_const(c).index_of(cit); + + if(it != c.begin()) + return false; + if(cit != c.cbegin()) + return false; + if(sz != 0) + return false; + if(csz != 0) + return false; + + //index size()/2 + const typename Container::size_type sz_div_2 = c.size()/2; + it = c.nth(sz_div_2); + sz = c.index_of(it); + cit = as_const(c).nth(sz_div_2); + csz = as_const(c).index_of(cit); + + if(it != (c.begin()+sz_div_2)) + return false; + if(cit != (c.cbegin()+sz_div_2)) + return false; + if(sz != sz_div_2) + return false; + if(csz != sz_div_2) + return false; + + //index size() + it = c.nth(c.size()); + sz = c.index_of(it); + cit = as_const(c).nth(c.size()); + csz = as_const(c).index_of(cit); + + if(it != c.end()) + return false; + if(cit != c.cend()) + return false; + if(sz != c.size()) + return false; + if(csz != c.size()) + return false; + return true; +} + +} //namespace test{ +} //namespace container { +} //namespace boost{ + +#include + +#endif //#ifndef BOOST_CONTAINER_TEST_CONTAINER_COMMON_TESTS_HPP diff --git a/test/expand_bwd_test_template.hpp b/test/expand_bwd_test_template.hpp index 7d6486d..bdb623e 100644 --- a/test/expand_bwd_test_template.hpp +++ b/test/expand_bwd_test_template.hpp @@ -55,8 +55,7 @@ template bool test_insert_with_expand_bwd() { typedef typename VectorWithExpandBwdAllocator::value_type value_type; - typedef typename boost::remove_volatile::type non_volatile_value_type; - typedef std::vector Vect; + typedef std::vector Vect; const unsigned int MemorySize = 1000; //Distance old and new buffer @@ -84,7 +83,7 @@ bool test_insert_with_expand_bwd() boost::movelib::unique_ptr memptr = boost::movelib::make_unique_definit(MemorySize*sizeof(value_type)); value_type *memory = (value_type*)memptr.get(); - std::vector initial_data; + std::vector initial_data; initial_data.resize(InitialSize[iteration]); for(unsigned int i = 0; i < InitialSize[iteration]; ++i){ initial_data[i] = i; @@ -133,7 +132,6 @@ template bool test_assign_with_expand_bwd() { typedef typename VectorWithExpandBwdAllocator::value_type value_type; - typedef typename boost::remove_volatile::type non_volatile_value_type; const unsigned int MemorySize = 200; const unsigned int Offset[] = { 50, 50, 50}; @@ -147,14 +145,14 @@ bool test_assign_with_expand_bwd() boost::movelib::make_unique_definit(MemorySize*sizeof(value_type)); value_type *memory = (value_type*)memptr.get(); //Create initial data - std::vector initial_data; + std::vector initial_data; initial_data.resize(InitialSize[iteration]); for(unsigned int i = 0; i < InitialSize[iteration]; ++i){ initial_data[i] = i; } //Create data to assign - std::vector data_to_insert; + std::vector data_to_insert; data_to_insert.resize(InsertSize[iteration]); for(unsigned int i = 0; i < InsertSize[iteration]; ++i){ data_to_insert[i] = -i; diff --git a/test/flat_map_test.cpp b/test/flat_map_test.cpp index b0ae330..1f189b2 100644 --- a/test/flat_map_test.cpp +++ b/test/flat_map_test.cpp @@ -19,6 +19,7 @@ #include "movable_int.hpp" #include "map_test.hpp" #include "propagate_allocator_test.hpp" +#include "container_common_tests.hpp" #include "emplace_test.hpp" #include #include @@ -445,6 +446,22 @@ int main() test_move >(); test_move >(); } + //Now test nth/index_of + { + flat_map map; + flat_multimap mmap; + + map.insert(std::pair(0, 0)); + map.insert(std::pair(1, 0)); + map.insert(std::pair(2, 0)); + mmap.insert(std::pair(0, 0)); + mmap.insert(std::pair(1, 0)); + mmap.insert(std::pair(2, 0)); + if(!boost::container::test::test_nth_index_of(map)) + return 1; + if(!boost::container::test::test_nth_index_of(mmap)) + return 1; + } //////////////////////////////////// // Ordered insertion test diff --git a/test/flat_set_test.cpp b/test/flat_set_test.cpp index 9e9e8c9..5949b8f 100644 --- a/test/flat_set_test.cpp +++ b/test/flat_set_test.cpp @@ -21,6 +21,7 @@ #include "set_test.hpp" #include "propagate_allocator_test.hpp" #include "emplace_test.hpp" +#include "container_common_tests.hpp" #include #include @@ -531,6 +532,22 @@ int main() test_move >(); test_move >(); } + //Now test nth/index_of + { + flat_set set; + flat_multiset mset; + + set.insert(0); + set.insert(1); + set.insert(2); + mset.insert(0); + mset.insert(1); + mset.insert(2); + if(!boost::container::test::test_nth_index_of(set)) + return 1; + if(!boost::container::test::test_nth_index_of(mset)) + return 1; + } //////////////////////////////////// // Ordered insertion test diff --git a/test/vector_test.hpp b/test/vector_test.hpp index 7112849..60f9783 100644 --- a/test/vector_test.hpp +++ b/test/vector_test.hpp @@ -34,6 +34,7 @@ #include #include #include "insert_test.hpp" +#include "container_common_tests.hpp" namespace boost{ namespace container { @@ -294,6 +295,10 @@ int vector_test() stdvector.assign(l.begin(), l.end()); if(!test::CheckEqualContainers(boostvector, stdvector)) return 1; } + + boostvector.resize(100); + if(!test_nth_index_of(boostvector)) + return 1; /* deque has no reserve or capacity std::size_t cap = boostvector.capacity(); boostvector.reserve(cap*2);