From d3eb21000bf56f005fc920cc75d559df460655b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Fri, 3 Jan 2014 14:52:13 +0100 Subject: [PATCH] Derived flat_set from flat_tree to avoid redefining almost all functions and minimize instantiation of multiple function in debug mode. --- include/boost/container/detail/flat_tree.hpp | 25 +- include/boost/container/flat_set.hpp | 647 ++++++------------- test/flat_set_test.cpp | 53 ++ 3 files changed, 265 insertions(+), 460 deletions(-) diff --git a/include/boost/container/detail/flat_tree.hpp b/include/boost/container/detail/flat_tree.hpp index a07ba29..457b24c 100644 --- a/include/boost/container/detail/flat_tree.hpp +++ b/include/boost/container/detail/flat_tree.hpp @@ -270,6 +270,9 @@ class flat_tree Compare key_comp() const { return this->m_data.get_comp(); } + value_compare value_comp() const + { return this->m_data; } + allocator_type get_allocator() const { return this->m_data.m_vect.get_allocator(); } @@ -526,7 +529,7 @@ class flat_tree this->reserve(this->size()+len); const const_iterator b(this->cbegin()); const_iterator pos(b); - const value_compare &value_comp = this->m_data; + const value_compare &val_cmp = this->m_data; skips[0u] = 0u; //Loop in burst sizes while(len){ @@ -539,7 +542,7 @@ class flat_tree --len; pos = const_cast(*this).priv_lower_bound(pos, ce, KeyOfValue()(val)); //Check if already present - if(pos != ce && !value_comp(val, *pos)){ + if(pos != ce && !val_cmp(val, *pos)){ if(unique_burst > 0){ ++skips[unique_burst-1]; } @@ -790,10 +793,10 @@ class flat_tree // insert val before upper_bound(val) // else // insert val before lower_bound(val) - const value_compare &value_comp = this->m_data; + const value_compare &val_cmp = this->m_data; - if(pos == this->cend() || !value_comp(*pos, val)){ - if (pos == this->cbegin() || !value_comp(val, pos[-1])){ + if(pos == this->cend() || !val_cmp(*pos, val)){ + if (pos == this->cbegin() || !val_cmp(val, pos[-1])){ data.position = pos; } else{ @@ -810,9 +813,9 @@ class flat_tree bool priv_insert_unique_prepare (const_iterator b, const_iterator e, const value_type& val, insert_commit_data &commit_data) { - const value_compare &value_comp = this->m_data; + const value_compare &val_cmp = this->m_data; commit_data.position = this->priv_lower_bound(b, e, KeyOfValue()(val)); - return commit_data.position == e || value_comp(val, *commit_data.position); + return commit_data.position == e || val_cmp(val, *commit_data.position); } bool priv_insert_unique_prepare @@ -833,9 +836,9 @@ class flat_tree // insert val after pos //else // insert val before lower_bound(val) - const value_compare &value_comp = this->m_data; + const value_compare &val_cmp = this->m_data; const const_iterator cend_it = this->cend(); - if(pos == cend_it || value_comp(val, *pos)){ //Check if val should go before end + if(pos == cend_it || val_cmp(val, *pos)){ //Check if val should go before end const const_iterator cbeg = this->cbegin(); commit_data.position = pos; if(pos == cbeg){ //If container is empty then insert it in the beginning @@ -843,10 +846,10 @@ class flat_tree } const_iterator prev(pos); --prev; - if(value_comp(*prev, val)){ //If previous element was less, then it should go between prev and pos + if(val_cmp(*prev, val)){ //If previous element was less, then it should go between prev and pos return true; } - else if(!value_comp(val, *prev)){ //If previous was equal then insertion should fail + else if(!val_cmp(val, *prev)){ //If previous was equal then insertion should fail commit_data.position = prev; return false; } diff --git a/include/boost/container/flat_set.hpp b/include/boost/container/flat_set.hpp index bb1c2a9..e5a5269 100644 --- a/include/boost/container/flat_set.hpp +++ b/include/boost/container/flat_set.hpp @@ -42,18 +42,24 @@ namespace container { //! pointing to elements that come after (their keys are bigger) the erased element. //! //! This container provides random-access iterators. +//! +//! \tparam Key is the type to be inserted in the set, which is also the key_type +//! \tparam Compare is the comparison functor used to order keys +//! \tparam Allocator is the allocator to be used to allocate memory for this container #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED template , class Allocator = std::allocator > #else template #endif class flat_set + ///@cond + : public container_detail::flat_tree, Compare, Allocator> + ///@endcond { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(flat_set) - typedef container_detail::flat_tree, Compare, Allocator> tree_t; - tree_t m_flat_tree; // flat tree representing flat_set + typedef container_detail::flat_tree, Compare, Allocator> base_t; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -73,11 +79,11 @@ class flat_set typedef typename ::boost::container::allocator_traits::size_type size_type; typedef typename ::boost::container::allocator_traits::difference_type difference_type; typedef Allocator allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; public: ////////////////////////////////////////////// @@ -90,7 +96,7 @@ class flat_set //! //! Complexity: Constant. explicit flat_set() - : m_flat_tree() + : base_t() {} //! Effects: Constructs an empty flat_set using the specified @@ -99,14 +105,14 @@ class flat_set //! Complexity: Constant. explicit flat_set(const Compare& comp, const allocator_type& a = allocator_type()) - : m_flat_tree(comp, a) + : base_t(comp, a) {} //! Effects: Constructs an empty flat_set using the specified allocator. //! //! Complexity: Constant. explicit flat_set(const allocator_type& a) - : m_flat_tree(a) + : base_t(a) {} //! Effects: Constructs an empty set using the specified comparison object and @@ -118,7 +124,7 @@ class flat_set flat_set(InputIterator first, InputIterator last, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) - : m_flat_tree(true, first, last, comp, a) + : base_t(true, first, last, comp, a) {} //! Effects: Constructs an empty flat_set using the specified comparison object and @@ -135,14 +141,14 @@ class flat_set flat_set(ordered_unique_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) - : m_flat_tree(ordered_range, first, last, comp, a) + : base_t(ordered_range, first, last, comp, a) {} //! Effects: Copy constructs a set. //! //! Complexity: Linear in x.size(). flat_set(const flat_set& x) - : m_flat_tree(x.m_flat_tree) + : base_t(static_cast(x)) {} //! Effects: Move constructs a set. Constructs *this using x's resources. @@ -151,14 +157,14 @@ class flat_set //! //! Postcondition: x is emptied. flat_set(BOOST_RV_REF(flat_set) mx) - : m_flat_tree(boost::move(mx.m_flat_tree)) + : base_t(boost::move(static_cast(mx))) {} //! Effects: Copy constructs a set using the specified allocator. //! //! Complexity: Linear in x.size(). flat_set(const flat_set& x, const allocator_type &a) - : m_flat_tree(x.m_flat_tree, a) + : base_t(static_cast(x), a) {} //! Effects: Move constructs a set using the specified allocator. @@ -166,27 +172,27 @@ class flat_set //! //! Complexity: Constant if a == mx.get_allocator(), linear otherwise flat_set(BOOST_RV_REF(flat_set) mx, const allocator_type &a) - : m_flat_tree(boost::move(mx.m_flat_tree), a) + : base_t(boost::move(static_cast(mx)), a) {} //! Effects: Makes *this a copy of x. //! //! Complexity: Linear in x.size(). flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x) - { m_flat_tree = x.m_flat_tree; return *this; } + { return static_cast(this->base_t::operator=(x)); } //! Effects: Makes *this a copy of the previous value of xx. //! //! Complexity: Linear in x.size(). flat_set& operator=(BOOST_RV_REF(flat_set) mx) - { m_flat_tree = boost::move(mx.m_flat_tree); return *this; } + { return static_cast(this->base_t::operator=(boost::move(static_cast(mx)))); } + #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED //! Effects: Returns a copy of the Allocator that //! was passed to the object's constructor. //! //! Complexity: Constant. - allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.get_allocator(); } + allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a reference to the internal allocator. //! @@ -195,8 +201,7 @@ class flat_set //! Complexity: Constant. //! //! Note: Non-standard extension. - stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.get_stored_allocator(); } + stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a reference to the internal allocator. //! @@ -205,46 +210,35 @@ class flat_set //! Complexity: Constant. //! //! Note: Non-standard extension. - const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.get_stored_allocator(); } - - ////////////////////////////////////////////// - // - // iterators - // - ////////////////////////////////////////////// + const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns an iterator to the first element contained in the container. //! //! Throws: Nothing. //! //! Complexity: Constant. - iterator begin() BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.begin(); } + iterator begin() BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a const_iterator to the first element contained in the container. //! //! Throws: Nothing. //! //! Complexity: Constant. - const_iterator begin() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.begin(); } + const_iterator begin() const BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns an iterator to the end of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. - iterator end() BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.end(); } + iterator end() BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a const_iterator to the end of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. - const_iterator end() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.end(); } + const_iterator end() const BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a reverse_iterator pointing to the beginning //! of the reversed container. @@ -252,8 +246,7 @@ class flat_set //! Throws: Nothing. //! //! Complexity: Constant. - reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.rbegin(); } + reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a const_reverse_iterator pointing to the beginning //! of the reversed container. @@ -261,8 +254,7 @@ class flat_set //! Throws: Nothing. //! //! Complexity: Constant. - const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.rbegin(); } + const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a reverse_iterator pointing to the end //! of the reversed container. @@ -270,8 +262,7 @@ class flat_set //! Throws: Nothing. //! //! Complexity: Constant. - reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.rend(); } + reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed container. @@ -279,24 +270,21 @@ class flat_set //! Throws: Nothing. //! //! Complexity: Constant. - const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.rend(); } + const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a const_iterator to the first element contained in the container. //! //! Throws: Nothing. //! //! Complexity: Constant. - const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.cbegin(); } + const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a const_iterator to the end of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. - const_iterator cend() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.cend(); } + const_iterator cend() const BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a const_reverse_iterator pointing to the beginning //! of the reversed container. @@ -304,8 +292,7 @@ class flat_set //! Throws: Nothing. //! //! Complexity: Constant. - const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.crbegin(); } + const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed container. @@ -313,39 +300,28 @@ class flat_set //! Throws: Nothing. //! //! Complexity: Constant. - const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.crend(); } - - - ////////////////////////////////////////////// - // - // capacity - // - ////////////////////////////////////////////// + const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns true if the container contains no elements. //! //! Throws: Nothing. //! //! Complexity: Constant. - bool empty() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.empty(); } + bool empty() const BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns the number of the elements contained in the container. //! //! Throws: Nothing. //! //! Complexity: Constant. - size_type size() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.size(); } + size_type size() const BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns the largest possible size of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. - size_type max_size() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.max_size(); } + size_type max_size() const BOOST_CONTAINER_NOEXCEPT; //! Effects: Number of elements for which memory has been allocated. //! capacity() is always greater than or equal to size(). @@ -353,8 +329,7 @@ class flat_set //! Throws: Nothing. //! //! Complexity: Constant. - size_type capacity() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.capacity(); } + size_type capacity() const BOOST_CONTAINER_NOEXCEPT; //! Effects: If n is less than or equal to capacity(), this call has no //! effect. Otherwise, it is a request for allocation of additional memory. @@ -365,8 +340,7 @@ class flat_set //! //! Note: If capacity() is less than "cnt", iterators and references to //! to values might be invalidated. - void reserve(size_type cnt) - { m_flat_tree.reserve(cnt); } + void reserve(size_type cnt); //! Effects: Tries to deallocate the excess of memory created // with previous allocations. The size of the vector is unchanged @@ -374,8 +348,9 @@ class flat_set //! Throws: If memory allocation throws, or Key's copy constructor throws. //! //! Complexity: Linear to size(). - void shrink_to_fit() - { m_flat_tree.shrink_to_fit(); } + void shrink_to_fit(); + + #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) ////////////////////////////////////////////// // @@ -399,7 +374,7 @@ class flat_set //! Note: If an element is inserted it might invalidate elements. template std::pair emplace(Args&&... args) - { return m_flat_tree.emplace_unique(boost::forward(args)...); } + { return this->base_t::emplace_unique(boost::forward(args)...); } //! Effects: Inserts an object of type Key constructed with //! std::forward(args)... in the container if and only if there is @@ -415,19 +390,19 @@ class flat_set //! Note: If an element is inserted it might invalidate elements. template iterator emplace_hint(const_iterator hint, Args&&... args) - { return m_flat_tree.emplace_hint_unique(hint, boost::forward(args)...); } + { return this->base_t::emplace_hint_unique(hint, boost::forward(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, >) \ std::pair emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ + { return this->base_t::emplace_unique(BOOST_PP_ENUM(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_hint(const_iterator hint \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return m_flat_tree.emplace_hint_unique \ + { return this->base_t::emplace_hint_unique \ (hint BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ //! #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) @@ -507,7 +482,7 @@ class flat_set //! Note: If an element is inserted it might invalidate elements. template void insert(InputIterator first, InputIterator last) - { m_flat_tree.insert_unique(first, last); } + { this->base_t::insert_unique(first, last); } //! Requires: first, last are not iterators into *this and //! must be ordered according to the predicate and must be @@ -522,7 +497,9 @@ class flat_set //! Note: Non-standard extension. If an element is inserted it might invalidate elements. template void insert(ordered_unique_range_t, InputIterator first, InputIterator last) - { m_flat_tree.insert_unique(ordered_unique_range, first, last); } + { this->base_t::insert_unique(ordered_unique_range, first, last); } + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Erases the element pointed to by position. //! @@ -534,8 +511,7 @@ class flat_set //! //! Note: Invalidates elements with keys //! not less than the erased element. - iterator erase(const_iterator position) - { return m_flat_tree.erase(position); } + iterator erase(const_iterator position); //! Effects: Erases all elements in the container with key equivalent to x. //! @@ -543,8 +519,7 @@ class flat_set //! //! Complexity: Logarithmic search time plus erasure time //! linear to the elements with bigger keys. - size_type erase(const key_type& x) - { return m_flat_tree.erase(x); } + size_type erase(const key_type& x); //! Effects: Erases all the elements in the range [first, last). //! @@ -554,162 +529,135 @@ class flat_set //! //! Complexity: Logarithmic search time plus erasure time //! linear to the elements with bigger keys. - iterator erase(const_iterator first, const_iterator last) - { return m_flat_tree.erase(first, last); } + iterator erase(const_iterator first, const_iterator last); //! Effects: Swaps the contents of *this and x. //! //! Throws: Nothing. //! //! Complexity: Constant. - void swap(flat_set& x) - { m_flat_tree.swap(x.m_flat_tree); } + void swap(flat_set& x); //! Effects: erase(a.begin(),a.end()). //! //! Postcondition: size() == 0. //! //! Complexity: linear in size(). - void clear() BOOST_CONTAINER_NOEXCEPT - { m_flat_tree.clear(); } - - ////////////////////////////////////////////// - // - // observers - // - ////////////////////////////////////////////// + void clear() BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns the comparison object out //! of which a was constructed. //! //! Complexity: Constant. - key_compare key_comp() const - { return m_flat_tree.key_comp(); } + key_compare key_comp() const; //! Effects: Returns an object of value_compare constructed out //! of the comparison object. //! //! Complexity: Constant. - value_compare value_comp() const - { return m_flat_tree.key_comp(); } - - ////////////////////////////////////////////// - // - // set operations - // - ////////////////////////////////////////////// + value_compare value_comp() const; //! Returns: An iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! //! Complexity: Logarithmic. - iterator find(const key_type& x) - { return m_flat_tree.find(x); } + iterator find(const key_type& x); //! Returns: Allocator const_iterator pointing to an element with the key //! equivalent to x, or end() if such an element is not found. //! - //! Complexity: Logarithmic.s - const_iterator find(const key_type& x) const - { return m_flat_tree.find(x); } + //! Complexity: Logarithmic. + const_iterator find(const key_type& x) const; + + #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Returns: The number of elements with key equivalent to x. //! //! Complexity: log(size())+count(k) size_type count(const key_type& x) const - { return static_cast(m_flat_tree.find(x) != m_flat_tree.end()); } + { return static_cast(this->find(x) != this->cend()); } + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Returns: An iterator pointing to the first element with key not less //! than k, or a.end() if such an element is not found. //! //! Complexity: Logarithmic - iterator lower_bound(const key_type& x) - { return m_flat_tree.lower_bound(x); } + iterator lower_bound(const key_type& x); //! Returns: Allocator const iterator pointing to the first element with key not //! less than k, or a.end() if such an element is not found. //! //! Complexity: Logarithmic - const_iterator lower_bound(const key_type& x) const - { return m_flat_tree.lower_bound(x); } + const_iterator lower_bound(const key_type& x) const; //! Returns: An iterator pointing to the first element with key not less //! than x, or end() if such an element is not found. //! //! Complexity: Logarithmic - iterator upper_bound(const key_type& x) - { return m_flat_tree.upper_bound(x); } + iterator upper_bound(const key_type& x); //! Returns: Allocator const iterator pointing to the first element with key not //! less than x, or end() if such an element is not found. //! //! Complexity: Logarithmic - const_iterator upper_bound(const key_type& x) const - { return m_flat_tree.upper_bound(x); } + const_iterator upper_bound(const key_type& x) const; //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! Complexity: Logarithmic - std::pair equal_range(const key_type& x) const - { return m_flat_tree.equal_range(x); } + std::pair equal_range(const key_type& x) const; //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). //! //! Complexity: Logarithmic - std::pair equal_range(const key_type& x) - { return m_flat_tree.equal_range(x); } + std::pair equal_range(const key_type& x); //! Effects: Returns true if x and y are equal //! //! Complexity: Linear to the number of elements in the container. - friend bool operator==(const flat_set& x, const flat_set& y) - { return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); } + friend bool operator==(const flat_set& x, const flat_set& y); //! Effects: Returns true if x and y are unequal //! //! Complexity: Linear to the number of elements in the container. - friend bool operator!=(const flat_set& x, const flat_set& y) - { return !(x == y); } + friend bool operator!=(const flat_set& x, const flat_set& y); //! Effects: Returns true if x is less than y //! //! Complexity: Linear to the number of elements in the container. - friend bool operator<(const flat_set& x, const flat_set& y) - { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + friend bool operator<(const flat_set& x, const flat_set& y); //! Effects: Returns true if x is greater than y //! //! Complexity: Linear to the number of elements in the container. - friend bool operator>(const flat_set& x, const flat_set& y) - { return y < x; } + friend bool operator>(const flat_set& x, const flat_set& y); //! Effects: Returns true if x is equal or less than y //! //! Complexity: Linear to the number of elements in the container. - friend bool operator<=(const flat_set& x, const flat_set& y) - { return !(y < x); } + friend bool operator<=(const flat_set& x, const flat_set& y); //! Effects: Returns true if x is equal or greater than y //! //! Complexity: Linear to the number of elements in the container. - friend bool operator>=(const flat_set& x, const flat_set& y) - { return !(x < y); } + friend bool operator>=(const flat_set& x, const flat_set& y); //! Effects: x.swap(y) //! //! Complexity: Constant. - friend void swap(flat_set& x, flat_set& y) - { x.swap(y); } + friend void swap(flat_set& x, flat_set& y); + + #endif //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: template std::pair priv_insert(BOOST_FWD_REF(KeyType) x) - { return m_flat_tree.insert_unique(::boost::forward(x)); } + { return this->base_t::insert_unique(::boost::forward(x)); } template iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x) - { return m_flat_tree.insert_unique(p, ::boost::forward(x)); } + { return this->base_t::insert_unique(p, ::boost::forward(x)); } #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; @@ -741,18 +689,24 @@ namespace container { //! pointing to elements that come after (their keys are bigger) the erased element. //! //! This container provides random-access iterators. +//! +//! \tparam Key is the type to be inserted in the set, which is also the key_type +//! \tparam Compare is the comparison functor used to order keys +//! \tparam Allocator is the allocator to be used to allocate memory for this container #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED template , class Allocator = std::allocator > #else template #endif class flat_multiset + ///@cond + : public container_detail::flat_tree, Compare, Allocator> + ///@endcond { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(flat_multiset) - typedef container_detail::flat_tree, Compare, Allocator> tree_t; - tree_t m_flat_tree; // flat tree representing flat_multiset + typedef container_detail::flat_tree, Compare, Allocator> base_t; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -772,17 +726,17 @@ class flat_multiset typedef typename ::boost::container::allocator_traits::size_type size_type; typedef typename ::boost::container::allocator_traits::difference_type difference_type; typedef Allocator allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type) stored_allocator_type; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator) iterator; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator) const_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator) reverse_iterator; - typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator) const_reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::stored_allocator_type) stored_allocator_type; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::iterator) iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_iterator) const_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::reverse_iterator) reverse_iterator; + typedef typename BOOST_CONTAINER_IMPDEF(base_t::const_reverse_iterator) const_reverse_iterator; //! Effects: Default constructs an empty flat_multiset. //! //! Complexity: Constant. explicit flat_multiset() - : m_flat_tree() + : base_t() {} //! Effects: Constructs an empty flat_multiset using the specified @@ -791,21 +745,21 @@ class flat_multiset //! Complexity: Constant. explicit flat_multiset(const Compare& comp, const allocator_type& a = allocator_type()) - : m_flat_tree(comp, a) + : base_t(comp, a) {} //! Effects: Constructs an empty flat_multiset using the specified allocator. //! //! Complexity: Constant. explicit flat_multiset(const allocator_type& a) - : m_flat_tree(a) + : base_t(a) {} template flat_multiset(InputIterator first, InputIterator last, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) - : m_flat_tree(false, first, last, comp, a) + : base_t(false, first, last, comp, a) {} //! Effects: Constructs an empty flat_multiset using the specified comparison object and @@ -821,14 +775,14 @@ class flat_multiset flat_multiset(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) - : m_flat_tree(ordered_range, first, last, comp, a) + : base_t(ordered_range, first, last, comp, a) {} //! Effects: Copy constructs a flat_multiset. //! //! Complexity: Linear in x.size(). flat_multiset(const flat_multiset& x) - : m_flat_tree(x.m_flat_tree) + : base_t(static_cast(x)) {} //! Effects: Move constructs a flat_multiset. Constructs *this using x's resources. @@ -837,14 +791,14 @@ class flat_multiset //! //! Postcondition: x is emptied. flat_multiset(BOOST_RV_REF(flat_multiset) mx) - : m_flat_tree(boost::move(mx.m_flat_tree)) + : base_t(boost::move(static_cast(mx))) {} //! Effects: Copy constructs a flat_multiset using the specified allocator. //! //! Complexity: Linear in x.size(). flat_multiset(const flat_multiset& x, const allocator_type &a) - : m_flat_tree(x.m_flat_tree, a) + : base_t(static_cast(x), a) {} //! Effects: Move constructs a flat_multiset using the specified allocator. @@ -852,209 +806,87 @@ class flat_multiset //! //! Complexity: Constant if a == mx.get_allocator(), linear otherwise flat_multiset(BOOST_RV_REF(flat_multiset) mx, const allocator_type &a) - : m_flat_tree(boost::move(mx.m_flat_tree), a) + : base_t(boost::move(static_cast(mx)), a) {} //! Effects: Makes *this a copy of x. //! //! Complexity: Linear in x.size(). flat_multiset& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x) - { m_flat_tree = x.m_flat_tree; return *this; } + { return static_cast(this->base_t::operator=(x)); } //! Effects: Makes *this a copy of x. //! //! Complexity: Linear in x.size(). flat_multiset& operator=(BOOST_RV_REF(flat_multiset) mx) - { m_flat_tree = boost::move(mx.m_flat_tree); return *this; } + { return static_cast(this->base_t::operator=(boost::move(static_cast(mx)))); } - //! Effects: Returns a copy of the Allocator that - //! was passed to the object's constructor. - //! - //! Complexity: Constant. - allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.get_allocator(); } + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.get_stored_allocator(); } + //! @copydoc ::boost::container::flat_set::get_allocator() + allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.get_stored_allocator(); } + //! @copydoc ::boost::container::flat_set::get_stored_allocator() + stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns an iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - iterator begin() BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.begin(); } + //! @copydoc ::boost::container::flat_set::get_stored_allocator() const + const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator begin() const - { return m_flat_tree.begin(); } + //! @copydoc ::boost::container::flat_set::begin() + iterator begin() BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.cbegin(); } + //! @copydoc ::boost::container::flat_set::begin() const + const_iterator begin() const; - //! Effects: Returns an iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - iterator end() BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.end(); } + //! @copydoc ::boost::container::flat_set::cbegin() const + const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator end() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.end(); } + //! @copydoc ::boost::container::flat_set::end() + iterator end() BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cend() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.cend(); } + //! @copydoc ::boost::container::flat_set::end() const + const_iterator end() const BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns a reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.rbegin(); } + //! @copydoc ::boost::container::flat_set::cend() const + const_iterator cend() const BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.rbegin(); } + //! @copydoc ::boost::container::flat_set::rbegin() + reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.crbegin(); } + //! @copydoc ::boost::container::flat_set::rbegin() const + const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns a reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.rend(); } + //! @copydoc ::boost::container::flat_set::crbegin() const + const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.rend(); } + //! @copydoc ::boost::container::flat_set::rend() + reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns a const_reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.crend(); } + //! @copydoc ::boost::container::flat_set::rend() const + const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT; - ////////////////////////////////////////////// - // - // capacity - // - ////////////////////////////////////////////// + //! @copydoc ::boost::container::flat_set::crend() const + const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns true if the container contains no elements. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - bool empty() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.empty(); } + //! @copydoc ::boost::container::flat_set::empty() const + bool empty() const BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns the number of the elements contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type size() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.size(); } + //! @copydoc ::boost::container::flat_set::size() const + size_type size() const BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns the largest possible size of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type max_size() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.max_size(); } + //! @copydoc ::boost::container::flat_set::max_size() const + size_type max_size() const BOOST_CONTAINER_NOEXCEPT; - //! Effects: Number of elements for which memory has been allocated. - //! capacity() is always greater than or equal to size(). - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type capacity() const BOOST_CONTAINER_NOEXCEPT - { return m_flat_tree.capacity(); } + //! @copydoc ::boost::container::flat_set::capacity() const + size_type capacity() const BOOST_CONTAINER_NOEXCEPT; - //! Effects: 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. - //! - //! Throws: If memory allocation allocation throws or Key's copy constructor throws. - //! - //! Note: If capacity() is less than "cnt", iterators and references to - //! to values might be invalidated. - void reserve(size_type cnt) - { m_flat_tree.reserve(cnt); } + //! @copydoc ::boost::container::flat_set::reserve(size_type) + void reserve(size_type cnt); - //! Effects: Tries to deallocate the excess of memory created - // with previous allocations. The size of the vector is unchanged - //! - //! Throws: If memory allocation throws, or Key's copy constructor throws. - //! - //! Complexity: Linear to size(). - void shrink_to_fit() - { m_flat_tree.shrink_to_fit(); } + //! @copydoc ::boost::container::flat_set::shrink_to_fit() + void shrink_to_fit(); + + #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) ////////////////////////////////////////////// // @@ -1074,7 +906,7 @@ class flat_multiset //! Note: If an element is inserted it might invalidate elements. template iterator emplace(Args&&... args) - { return m_flat_tree.emplace_equal(boost::forward(args)...); } + { return this->base_t::emplace_equal(boost::forward(args)...); } //! Effects: Inserts an object of type Key constructed with //! std::forward(args)... in the container. @@ -1089,19 +921,19 @@ class flat_multiset //! Note: If an element is inserted it might invalidate elements. template iterator emplace_hint(const_iterator hint, Args&&... args) - { return m_flat_tree.emplace_hint_equal(hint, boost::forward(args)...); } + { return this->base_t::emplace_hint_equal(hint, boost::forward(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(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return m_flat_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ + { return this->base_t::emplace_equal(BOOST_PP_ENUM(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_hint(const_iterator hint \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ - { return m_flat_tree.emplace_hint_equal \ + { return this->base_t::emplace_hint_equal \ (hint BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \ //! #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) @@ -1169,7 +1001,7 @@ class flat_multiset //! Note: If an element is inserted it might invalidate elements. template void insert(InputIterator first, InputIterator last) - { m_flat_tree.insert_equal(first, last); } + { this->base_t::insert_equal(first, last); } //! Requires: first, last are not iterators into *this and //! must be ordered according to the predicate. @@ -1183,142 +1015,59 @@ class flat_multiset //! Note: Non-standard extension. If an element is inserted it might invalidate elements. template void insert(ordered_range_t, InputIterator first, InputIterator last) - { m_flat_tree.insert_equal(ordered_range, first, last); } + { this->base_t::insert_equal(ordered_range, first, last); } - //! Effects: Erases the element pointed to by position. - //! - //! Returns: Returns an iterator pointing to the element immediately - //! following q prior to the element being erased. If no such element exists, - //! returns end(). - //! - //! Complexity: Linear to the elements with keys bigger than position - //! - //! Note: Invalidates elements with keys - //! not less than the erased element. - iterator erase(const_iterator position) - { return m_flat_tree.erase(position); } + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: Erases all elements in the container with key equivalent to x. - //! - //! Returns: Returns the number of erased elements. - //! - //! Complexity: Logarithmic search time plus erasure time - //! linear to the elements with bigger keys. - size_type erase(const key_type& x) - { return m_flat_tree.erase(x); } + //! @copydoc ::boost::container::flat_set::erase(const_iterator) + iterator erase(const_iterator position); - //! Effects: Erases all the elements in the range [first, last). - //! - //! Returns: Returns last. - //! - //! Complexity: size()*N where N is the distance from first to last. - //! - //! Complexity: Logarithmic search time plus erasure time - //! linear to the elements with bigger keys. - iterator erase(const_iterator first, const_iterator last) - { return m_flat_tree.erase(first, last); } + //! @copydoc ::boost::container::flat_set::erase(const key_type&) + size_type erase(const key_type& x); - //! Effects: Swaps the contents of *this and x. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - void swap(flat_multiset& x) - { m_flat_tree.swap(x.m_flat_tree); } + //! @copydoc ::boost::container::flat_set::erase(const_iterator,const_iterator) + iterator erase(const_iterator first, const_iterator last); - //! Effects: erase(a.begin(),a.end()). - //! - //! Postcondition: size() == 0. - //! - //! Complexity: linear in size(). - void clear() BOOST_CONTAINER_NOEXCEPT - { m_flat_tree.clear(); } + //! @copydoc ::boost::container::flat_set::swap + void swap(flat_multiset& x); - ////////////////////////////////////////////// - // - // observers - // - ////////////////////////////////////////////// + //! @copydoc ::boost::container::flat_set::clear + void clear() BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns the comparison object out - //! of which a was constructed. - //! - //! Complexity: Constant. - key_compare key_comp() const - { return m_flat_tree.key_comp(); } + //! @copydoc ::boost::container::flat_set::key_comp + key_compare key_comp() const; - //! Effects: Returns an object of value_compare constructed out - //! of the comparison object. - //! - //! Complexity: Constant. - value_compare value_comp() const - { return m_flat_tree.key_comp(); } + //! @copydoc ::boost::container::flat_set::value_comp + value_compare value_comp() const; - ////////////////////////////////////////////// - // - // set operations - // - ////////////////////////////////////////////// + //! @copydoc ::boost::container::flat_set::find(const key_type& ) + iterator find(const key_type& x); - //! Returns: An iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic. - iterator find(const key_type& x) - { return m_flat_tree.find(x); } + //! @copydoc ::boost::container::flat_set::find(const key_type& ) const + const_iterator find(const key_type& x) const; - //! Returns: Allocator const_iterator pointing to an element with the key - //! equivalent to x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic.s - const_iterator find(const key_type& x) const - { return m_flat_tree.find(x); } + //! @copydoc ::boost::container::flat_set::count(const key_type& ) const + size_type count(const key_type& x) const; - //! Returns: The number of elements with key equivalent to x. - //! - //! Complexity: log(size())+count(k) - size_type count(const key_type& x) const - { return m_flat_tree.count(x); } + //! @copydoc ::boost::container::flat_set::lower_bound(const key_type& ) + iterator lower_bound(const key_type& x); - //! Returns: An iterator pointing to the first element with key not less - //! than k, or a.end() if such an element is not found. - //! - //! Complexity: Logarithmic - iterator lower_bound(const key_type& x) - { return m_flat_tree.lower_bound(x); } + //! @copydoc ::boost::container::flat_set::lower_bound(const key_type& ) const + const_iterator lower_bound(const key_type& x) const; - //! Returns: Allocator const iterator pointing to the first element with key not - //! less than k, or a.end() if such an element is not found. - //! - //! Complexity: Logarithmic - const_iterator lower_bound(const key_type& x) const - { return m_flat_tree.lower_bound(x); } + //! @copydoc ::boost::container::flat_set::upper_bound(const key_type& ) + iterator upper_bound(const key_type& x); - //! Returns: An iterator pointing to the first element with key not less - //! than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - iterator upper_bound(const key_type& x) - { return m_flat_tree.upper_bound(x); } + //! @copydoc ::boost::container::flat_set::upper_bound(const key_type& ) const + const_iterator upper_bound(const key_type& x) const; - //! Returns: Allocator const iterator pointing to the first element with key not - //! less than x, or end() if such an element is not found. - //! - //! Complexity: Logarithmic - const_iterator upper_bound(const key_type& x) const - { return m_flat_tree.upper_bound(x); } + //! @copydoc ::boost::container::flat_set::equal_range(const key_type& ) const + std::pair equal_range(const key_type& x) const; - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - std::pair equal_range(const key_type& x) const - { return m_flat_tree.equal_range(x); } + //! @copydoc ::boost::container::flat_set::equal_range(const key_type& ) + std::pair equal_range(const key_type& x); - //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)). - //! - //! Complexity: Logarithmic - std::pair equal_range(const key_type& x) - { return m_flat_tree.equal_range(x); } + #endif //! Effects: Returns true if x and y are equal //! @@ -1366,11 +1115,11 @@ class flat_multiset private: template iterator priv_insert(BOOST_FWD_REF(KeyType) x) - { return m_flat_tree.insert_equal(::boost::forward(x)); } + { return this->base_t::insert_equal(::boost::forward(x)); } template iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x) - { return m_flat_tree.insert_equal(p, ::boost::forward(x)); } + { return this->base_t::insert_equal(p, ::boost::forward(x)); } #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; diff --git a/test/flat_set_test.cpp b/test/flat_set_test.cpp index ac2a563..541fb27 100644 --- a/test/flat_set_test.cpp +++ b/test/flat_set_test.cpp @@ -105,6 +105,59 @@ template class flat_multiset , node_allocator >; +namespace container_detail { + +//Instantiate base class as previous instantiations don't instantiate inherited members +template class flat_tree + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , identity + , std::less + , test::dummy_test_allocator + >; + +template class flat_tree + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , identity + , std::less + , test::simple_allocator + >; + +template class flat_tree + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , identity + , std::less + , std::allocator + >; + +template class flat_tree + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , identity + , std::less + , allocator + >; + +template class flat_tree + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , identity + , std::less + , adaptive_pool + >; + +template class flat_tree + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , identity + , std::less + , node_allocator + >; + +} //container_detail { + //As flat container iterators are typedefs for vector::[const_]iterator, //no need to explicit instantiate them