diff --git a/include/boost/container/detail/tree.hpp b/include/boost/container/detail/tree.hpp index d15aada..735f49e 100644 --- a/include/boost/container/detail/tree.hpp +++ b/include/boost/container/detail/tree.hpp @@ -447,7 +447,7 @@ struct key_node_compare template + class Options = tree_assoc_defaults> class tree : protected container_detail::node_alloc_holder < A diff --git a/include/boost/container/map.hpp b/include/boost/container/map.hpp index 397369f..49a6cec 100644 --- a/include/boost/container/map.hpp +++ b/include/boost/container/map.hpp @@ -61,6 +61,12 @@ template < class Key, class T, class Compare = std::less template #endif class map + ///@cond + : public container_detail::tree + < Key, std::pair + , container_detail::select1st< std::pair > + , Compare, Allocator, MapOptions> + ///@endcond { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: @@ -68,12 +74,11 @@ class map typedef std::pair value_type_impl; typedef container_detail::tree - , Compare, Allocator, MapOptions> tree_t; + , Compare, Allocator, MapOptions> base_t; typedef container_detail::pair movable_value_type_impl; typedef container_detail::tree_value_compare < Key, value_type_impl, Compare, container_detail::select1st > value_compare_impl; - tree_t m_tree; // red-black tree representing map #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -93,13 +98,13 @@ class map 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(base_t::stored_allocator_type) stored_allocator_type; typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; typedef Compare key_compare; - 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::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; typedef std::pair nonconst_value_type; typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; @@ -113,7 +118,7 @@ class map //! //! Complexity: Constant. map() - : m_tree() + : base_t() { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -125,7 +130,7 @@ class map //! Complexity: Constant. explicit map(const Compare& comp, const allocator_type& a = allocator_type()) - : m_tree(comp, a) + : base_t(comp, a) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -135,7 +140,7 @@ class map //! //! Complexity: Constant. explicit map(const allocator_type& a) - : m_tree(a) + : base_t(a) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -149,7 +154,7 @@ class map template map(InputIterator first, InputIterator last, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) - : m_tree(true, first, last, comp, a) + : base_t(true, first, last, comp, a) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -168,7 +173,7 @@ class map template map( ordered_unique_range_t, InputIterator first, InputIterator last , const Compare& comp = Compare(), const allocator_type& a = allocator_type()) - : m_tree(ordered_range, first, last, comp, a) + : base_t(ordered_range, first, last, comp, a) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -178,7 +183,7 @@ class map //! //! Complexity: Linear in x.size(). map(const map& x) - : m_tree(x.m_tree) + : base_t(static_cast(x)) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -190,7 +195,7 @@ class map //! //! Postcondition: x is emptied. map(BOOST_RV_REF(map) x) - : m_tree(boost::move(x.m_tree)) + : base_t(boost::move(static_cast(x))) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -200,7 +205,7 @@ class map //! //! Complexity: Linear in x.size(). map(const map& x, const allocator_type &a) - : m_tree(x.m_tree, a) + : base_t(static_cast(x), a) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -213,7 +218,7 @@ class map //! //! Postcondition: x is emptied. map(BOOST_RV_REF(map) x, const allocator_type &a) - : m_tree(boost::move(x.m_tree), a) + : base_t(boost::move(static_cast(x)), a) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -223,20 +228,21 @@ class map //! //! Complexity: Linear in x.size(). map& operator=(BOOST_COPY_ASSIGN_REF(map) x) - { m_tree = x.m_tree; return *this; } + { return static_cast(this->base_t::operator=(static_cast(x))); } //! Effects: this->swap(x.get()). //! //! Complexity: Constant. map& operator=(BOOST_RV_REF(map) x) - { m_tree = boost::move(x.m_tree); return *this; } + { return static_cast(this->base_t::operator=(boost::move(static_cast(x)))); } + + #if defined(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_tree.get_allocator(); } + allocator_type get_allocator() const; //! Effects: Returns a reference to the internal allocator. //! @@ -245,8 +251,7 @@ class map //! Complexity: Constant. //! //! Note: Non-standard extension. - stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT - { return m_tree.get_stored_allocator(); } + stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a reference to the internal allocator. //! @@ -255,46 +260,49 @@ class map //! Complexity: Constant. //! //! Note: Non-standard extension. - const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT - { return m_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_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 this->cbegin(); } + const_iterator begin() 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; //! Effects: Returns an iterator to the end of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. - iterator end() BOOST_CONTAINER_NOEXCEPT - { return m_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 this->cend(); } + const_iterator end() 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; //! Effects: Returns a reverse_iterator pointing to the beginning //! of the reversed container. @@ -302,8 +310,7 @@ class map //! Throws: Nothing. //! //! Complexity: Constant. - reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT - { return m_tree.rbegin(); } + reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a const_reverse_iterator pointing to the beginning //! of the reversed container. @@ -311,8 +318,15 @@ class map //! Throws: Nothing. //! //! Complexity: Constant. - const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT - { return this->crbegin(); } + const_reverse_iterator rbegin() 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 crbegin() const BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a reverse_iterator pointing to the end //! of the reversed container. @@ -320,8 +334,7 @@ class map //! Throws: Nothing. //! //! Complexity: Constant. - reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT - { return m_tree.rend(); } + reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed container. @@ -329,33 +342,7 @@ class map //! Throws: Nothing. //! //! Complexity: Constant. - const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT - { return this->crend(); } - - //! 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_tree.begin(); } - - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cend() const BOOST_CONTAINER_NOEXCEPT - { return m_tree.end(); } - - //! 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_tree.rbegin(); } + const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT; //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed container. @@ -363,44 +350,30 @@ class map //! Throws: Nothing. //! //! Complexity: Constant. - const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT - { return m_tree.rend(); } - - ////////////////////////////////////////////// - // - // 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_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_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_tree.max_size(); } + size_type max_size() const BOOST_CONTAINER_NOEXCEPT; - ////////////////////////////////////////////// - // - // element access - // - ////////////////////////////////////////////// + #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: If there is no key equivalent to x in the map, inserts @@ -461,7 +434,7 @@ class map //! //! Complexity: Logarithmic. std::pair insert(const value_type& x) - { return m_tree.insert_unique(x); } + { return this->base_t::insert_unique(x); } //! Effects: Inserts a new value_type created from the pair if and only if //! there is no element in the container with key equivalent to the key of x. @@ -472,7 +445,7 @@ class map //! //! Complexity: Logarithmic. std::pair insert(const nonconst_value_type& x) - { return m_tree.insert_unique(x); } + { return this->base_t::insert_unique(x); } //! Effects: Inserts a new value_type move constructed from the pair if and //! only if there is no element in the container with key equivalent to the key of x. @@ -483,7 +456,7 @@ class map //! //! Complexity: Logarithmic. std::pair insert(BOOST_RV_REF(nonconst_value_type) x) - { return m_tree.insert_unique(boost::move(x)); } + { return this->base_t::insert_unique(boost::move(x)); } //! Effects: Inserts a new value_type move constructed from the pair if and //! only if there is no element in the container with key equivalent to the key of x. @@ -494,7 +467,7 @@ class map //! //! Complexity: Logarithmic. std::pair insert(BOOST_RV_REF(movable_value_type) x) - { return m_tree.insert_unique(boost::move(x)); } + { return this->base_t::insert_unique(boost::move(x)); } //! Effects: Move constructs a new value from x if and only if there is //! no element in the container with key equivalent to the key of x. @@ -505,7 +478,7 @@ class map //! //! Complexity: Logarithmic. std::pair insert(BOOST_RV_REF(value_type) x) - { return m_tree.insert_unique(boost::move(x)); } + { return this->base_t::insert_unique(boost::move(x)); } //! Effects: Inserts a copy of x in the container if and only if there is //! no element in the container with key equivalent to the key of x. @@ -517,7 +490,7 @@ class map //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. iterator insert(const_iterator position, const value_type& x) - { return m_tree.insert_unique(position, x); } + { return this->base_t::insert_unique(position, x); } //! Effects: Move constructs a new value from x if and only if there is //! no element in the container with key equivalent to the key of x. @@ -529,7 +502,7 @@ class map //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. iterator insert(const_iterator position, BOOST_RV_REF(nonconst_value_type) x) - { return m_tree.insert_unique(position, boost::move(x)); } + { return this->base_t::insert_unique(position, boost::move(x)); } //! Effects: Move constructs a new value from x if and only if there is //! no element in the container with key equivalent to the key of x. @@ -541,7 +514,7 @@ class map //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x) - { return m_tree.insert_unique(position, boost::move(x)); } + { return this->base_t::insert_unique(position, boost::move(x)); } //! Effects: Inserts a copy of x in the container. //! p is a hint pointing to where the insert should start to search. @@ -550,7 +523,7 @@ class map //! //! Complexity: Logarithmic. iterator insert(const_iterator position, const nonconst_value_type& x) - { return m_tree.insert_unique(position, x); } + { return this->base_t::insert_unique(position, x); } //! Effects: Inserts an element move constructed from x in the container. //! p is a hint pointing to where the insert should start to search. @@ -559,7 +532,7 @@ class map //! //! Complexity: Logarithmic. iterator insert(const_iterator position, BOOST_RV_REF(value_type) x) - { return m_tree.insert_unique(position, boost::move(x)); } + { return this->base_t::insert_unique(position, boost::move(x)); } //! Requires: first, last are not iterators into *this. //! @@ -569,7 +542,7 @@ class map //! Complexity: At most N log(size()+N) (N is the distance from first to last) template void insert(InputIterator first, InputIterator last) - { m_tree.insert_unique(first, last); } + { this->base_t::insert_unique(first, last); } #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -586,7 +559,7 @@ class map //! is inserted right before p. template std::pair emplace(Args&&... args) - { return m_tree.emplace_unique(boost::forward(args)...); } + { return this->base_t::emplace_unique(boost::forward(args)...); } //! Effects: Inserts an object of type T constructed with //! std::forward(args)... in the container if and only if there is @@ -600,19 +573,19 @@ class map //! is inserted right before p. template iterator emplace_hint(const_iterator hint, Args&&... args) - { return m_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_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_tree.emplace_hint_unique(hint \ + { 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) @@ -620,6 +593,8 @@ class map #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Effects: Erases the element pointed to by position. //! //! Returns: Returns an iterator pointing to the element immediately @@ -627,183 +602,154 @@ class map //! returns end(). //! //! Complexity: Amortized constant time - iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT - { return m_tree.erase(position); } + iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT; //! Effects: Erases all elements in the container with key equivalent to x. //! //! Returns: Returns the number of erased elements. //! //! Complexity: log(size()) + count(k) - size_type erase(const key_type& x) BOOST_CONTAINER_NOEXCEPT - { return m_tree.erase(x); } + size_type erase(const key_type& x) BOOST_CONTAINER_NOEXCEPT; //! Effects: Erases all the elements in the range [first, last). //! //! Returns: Returns last. //! //! Complexity: log(size())+N where N is the distance from first to last. - iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT - { return m_tree.erase(first, last); } + iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT; //! Effects: Swaps the contents of *this and x. //! //! Throws: Nothing. //! //! Complexity: Constant. - void swap(map& x) - { m_tree.swap(x.m_tree); } + void swap(map& x); //! Effects: erase(a.begin(),a.end()). //! //! Postcondition: size() == 0. //! //! Complexity: linear in size(). - void clear() BOOST_CONTAINER_NOEXCEPT - { m_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_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 value_compare(m_tree.key_comp()); } - - ////////////////////////////////////////////// - // - // map 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_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. - const_iterator find(const key_type& x) const - { return m_tree.find(x); } + 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_tree.find(x) != m_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_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_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_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_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) - { return m_tree.equal_range(x); } + 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) const - { return m_tree.equal_range(x); } + std::pair equal_range(const key_type& x) const; //! Effects: Rebalances the tree. It's a no-op for Red-Black and AVL trees. //! //! Complexity: Linear - void rebalance() - { return m_tree.rebalance(); } + void rebalance(); //! Effects: Returns true if x and y are equal //! //! Complexity: Linear to the number of elements in the container. - friend bool operator==(const map& x, const map& y) - { return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); } + friend bool operator==(const map& x, const map& y); //! Effects: Returns true if x and y are unequal //! //! Complexity: Linear to the number of elements in the container. - friend bool operator!=(const map& x, const map& y) - { return !(x == y); } + friend bool operator!=(const map& x, const map& y); //! Effects: Returns true if x is less than y //! //! Complexity: Linear to the number of elements in the container. - friend bool operator<(const map& x, const map& y) - { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + friend bool operator<(const map& x, const map& y); //! Effects: Returns true if x is greater than y //! //! Complexity: Linear to the number of elements in the container. - friend bool operator>(const map& x, const map& y) - { return y < x; } + friend bool operator>(const map& x, const map& 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 map& x, const map& y) - { return !(y < x); } + friend bool operator<=(const map& x, const map& 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 map& x, const map& y) - { return !(x < y); } + friend bool operator>=(const map& x, const map& y); //! Effects: x.swap(y) //! //! Complexity: Constant. - friend void swap(map& x, map& y) - { x.swap(y); } + friend void swap(map& x, map& y); + + #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: mapped_type& priv_subscript(const key_type &k) { //we can optimize this - iterator i = lower_bound(k); + iterator i = this->lower_bound(k); // i->first is greater than or equivalent to k. - if (i == end() || key_comp()(k, (*i).first)){ + if (i == this->end() || this->key_comp()(k, (*i).first)){ container_detail::value_init m; movable_value_type val(k, boost::move(m.m_t)); i = insert(i, boost::move(val)); @@ -815,9 +761,9 @@ class map { key_type &k = mk; //we can optimize this - iterator i = lower_bound(k); + iterator i = this->lower_bound(k); // i->first is greater than or equivalent to k. - if (i == end() || key_comp()(k, (*i).first)){ + if (i == this->end() || this->key_comp()(k, (*i).first)){ container_detail::value_init m; movable_value_type val(boost::move(k), boost::move(m.m_t)); i = insert(i, boost::move(val)); @@ -868,6 +814,12 @@ template < class Key, class T, class Compare = std::less template #endif class multimap + ///@cond + : public container_detail::tree + < Key, std::pair + , container_detail::select1st< std::pair > + , Compare, Allocator, MultiMapOptions> + ///@endcond { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: @@ -875,12 +827,11 @@ class multimap typedef std::pair value_type_impl; typedef container_detail::tree - , Compare, Allocator, MultiMapOptions> tree_t; + , Compare, Allocator, MultiMapOptions> base_t; typedef container_detail::pair movable_value_type_impl; typedef container_detail::tree_value_compare < Key, value_type_impl, Compare, container_detail::select1st > value_compare_impl; - tree_t m_tree; // red-black tree representing map #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -900,13 +851,13 @@ class multimap 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(base_t::stored_allocator_type) stored_allocator_type; typedef BOOST_CONTAINER_IMPDEF(value_compare_impl) value_compare; typedef Compare key_compare; - 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::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; typedef std::pair nonconst_value_type; typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl) movable_value_type; @@ -920,7 +871,7 @@ class multimap //! //! Complexity: Constant. multimap() - : m_tree() + : base_t() { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -930,7 +881,7 @@ class multimap //! //! Complexity: Constant. explicit multimap(const Compare& comp, const allocator_type& a = allocator_type()) - : m_tree(comp, a) + : base_t(comp, a) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -941,7 +892,7 @@ class multimap //! //! Complexity: Constant. explicit multimap(const allocator_type& a) - : m_tree(a) + : base_t(a) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -956,7 +907,7 @@ class multimap multimap(InputIterator first, InputIterator last, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) - : m_tree(false, first, last, comp, a) + : base_t(false, first, last, comp, a) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -974,14 +925,14 @@ class multimap template multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) - : m_tree(ordered_range, first, last, comp, a) + : base_t(ordered_range, first, last, comp, a) {} //! Effects: Copy constructs a multimap. //! //! Complexity: Linear in x.size(). multimap(const multimap& x) - : m_tree(x.m_tree) + : base_t(static_cast(x)) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -993,7 +944,7 @@ class multimap //! //! Postcondition: x is emptied. multimap(BOOST_RV_REF(multimap) x) - : m_tree(boost::move(x.m_tree)) + : base_t(boost::move(static_cast(x))) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -1003,7 +954,7 @@ class multimap //! //! Complexity: Linear in x.size(). multimap(const multimap& x, const allocator_type &a) - : m_tree(x.m_tree, a) + : base_t(static_cast(x), a) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -1015,7 +966,7 @@ class multimap //! //! Postcondition: x is emptied. multimap(BOOST_RV_REF(multimap) x, const allocator_type &a) - : m_tree(boost::move(x.m_tree), a) + : base_t(boost::move(static_cast(x)), a) { //Allocator type must be std::pair BOOST_STATIC_ASSERT((container_detail::is_same, typename Allocator::value_type>::value)); @@ -1025,184 +976,71 @@ class multimap //! //! Complexity: Linear in x.size(). multimap& operator=(BOOST_COPY_ASSIGN_REF(multimap) x) - { m_tree = x.m_tree; return *this; } + { return static_cast(this->base_t::operator=(static_cast(x))); } //! Effects: this->swap(x.get()). //! //! Complexity: Constant. multimap& operator=(BOOST_RV_REF(multimap) x) - { m_tree = boost::move(x.m_tree); return *this; } + { return static_cast(this->base_t::operator=(boost::move(static_cast(x)))); } - //! 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_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_tree.get_stored_allocator(); } + //! @copydoc ::boost::container::set::get_allocator() + allocator_type get_allocator() const; - //! 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_tree.get_stored_allocator(); } + //! @copydoc ::boost::container::set::get_stored_allocator() + stored_allocator_type &get_stored_allocator(); - ////////////////////////////////////////////// - // - // iterators - // - ////////////////////////////////////////////// + //! @copydoc ::boost::container::set::get_stored_allocator() const + const stored_allocator_type &get_stored_allocator() const; - //! Effects: Returns an iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - iterator begin() BOOST_CONTAINER_NOEXCEPT - { return m_tree.begin(); } + //! @copydoc ::boost::container::set::begin() + iterator begin(); - //! 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 this->cbegin(); } + //! @copydoc ::boost::container::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_tree.end(); } + //! @copydoc ::boost::container::set::cbegin() const + const_iterator cbegin() const; - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator end() const BOOST_CONTAINER_NOEXCEPT - { return this->cend(); } + //! @copydoc ::boost::container::set::end() + iterator end() 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_tree.rbegin(); } + //! @copydoc ::boost::container::set::end() const + const_iterator end() 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 this->crbegin(); } + //! @copydoc ::boost::container::set::cend() const + const_iterator cend() 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_tree.rend(); } + //! @copydoc ::boost::container::set::rbegin() + reverse_iterator rbegin() 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 this->crend(); } + //! @copydoc ::boost::container::set::rbegin() const + const_reverse_iterator rbegin() 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_tree.begin(); } + //! @copydoc ::boost::container::set::crbegin() const + const_reverse_iterator crbegin() 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_tree.end(); } + //! @copydoc ::boost::container::set::rend() + reverse_iterator rend() 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_tree.rbegin(); } + //! @copydoc ::boost::container::set::rend() const + const_reverse_iterator rend() 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 crend() const BOOST_CONTAINER_NOEXCEPT - { return m_tree.rend(); } + //! @copydoc ::boost::container::set::crend() const + const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT; - ////////////////////////////////////////////// - // - // capacity - // - ////////////////////////////////////////////// + //! @copydoc ::boost::container::set::empty() const + bool empty() const; - //! Effects: Returns true if the container contains no elements. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - bool empty() const BOOST_CONTAINER_NOEXCEPT - { return m_tree.empty(); } + //! @copydoc ::boost::container::set::size() const + size_type size() const; - //! Effects: Returns the number of the elements contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type size() const BOOST_CONTAINER_NOEXCEPT - { return m_tree.size(); } + //! @copydoc ::boost::container::set::max_size() const + size_type max_size() const; - //! Effects: Returns the largest possible size of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type max_size() const BOOST_CONTAINER_NOEXCEPT - { return m_tree.max_size(); } - - ////////////////////////////////////////////// - // - // modifiers - // - ////////////////////////////////////////////// + #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -1217,7 +1055,7 @@ class multimap //! is inserted right before p. template iterator emplace(Args&&... args) - { return m_tree.emplace_equal(boost::forward(args)...); } + { return this->base_t::emplace_equal(boost::forward(args)...); } //! Effects: Inserts an object of type T constructed with //! std::forward(args)... in the container. @@ -1230,19 +1068,19 @@ class multimap //! is inserted right before p. template iterator emplace_hint(const_iterator hint, Args&&... args) - { return m_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_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_tree.emplace_hint_equal(hint \ + { 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) @@ -1255,28 +1093,28 @@ class multimap //! //! Complexity: Logarithmic. iterator insert(const value_type& x) - { return m_tree.insert_equal(x); } + { return this->base_t::insert_equal(x); } //! Effects: Inserts a new value constructed from x and returns //! the iterator pointing to the newly inserted element. //! //! Complexity: Logarithmic. iterator insert(const nonconst_value_type& x) - { return m_tree.insert_equal(x); } + { return this->base_t::insert_equal(x); } //! Effects: Inserts a new value move-constructed from x and returns //! the iterator pointing to the newly inserted element. //! //! Complexity: Logarithmic. iterator insert(BOOST_RV_REF(nonconst_value_type) x) - { return m_tree.insert_equal(boost::move(x)); } + { return this->base_t::insert_equal(boost::move(x)); } //! Effects: Inserts a new value move-constructed from x and returns //! the iterator pointing to the newly inserted element. //! //! Complexity: Logarithmic. iterator insert(BOOST_RV_REF(movable_value_type) x) - { return m_tree.insert_equal(boost::move(x)); } + { return this->base_t::insert_equal(boost::move(x)); } //! Effects: Inserts a copy of x in the container. //! p is a hint pointing to where the insert should start to search. @@ -1287,7 +1125,7 @@ class multimap //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. iterator insert(const_iterator position, const value_type& x) - { return m_tree.insert_equal(position, x); } + { return this->base_t::insert_equal(position, x); } //! Effects: Inserts a new value constructed from x in the container. //! p is a hint pointing to where the insert should start to search. @@ -1298,7 +1136,7 @@ class multimap //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. iterator insert(const_iterator position, const nonconst_value_type& x) - { return m_tree.insert_equal(position, x); } + { return this->base_t::insert_equal(position, x); } //! Effects: Inserts a new value move constructed from x in the container. //! p is a hint pointing to where the insert should start to search. @@ -1309,7 +1147,7 @@ class multimap //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. iterator insert(const_iterator position, BOOST_RV_REF(nonconst_value_type) x) - { return m_tree.insert_equal(position, boost::move(x)); } + { return this->base_t::insert_equal(position, boost::move(x)); } //! Effects: Inserts a new value move constructed from x in the container. //! p is a hint pointing to where the insert should start to search. @@ -1320,7 +1158,7 @@ class multimap //! Complexity: Logarithmic in general, but amortized constant if t //! is inserted right before p. iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x) - { return m_tree.insert_equal(position, boost::move(x)); } + { return this->base_t::insert_equal(position, boost::move(x)); } //! Requires: first, last are not iterators into *this. //! @@ -1329,183 +1167,123 @@ class multimap //! Complexity: At most N log(size()+N) (N is the distance from first to last) template void insert(InputIterator first, InputIterator last) - { m_tree.insert_equal(first, last); } + { this->base_t::insert_equal(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: Amortized constant time - iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT - { return m_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: log(size()) + count(k) - size_type erase(const key_type& x) BOOST_CONTAINER_NOEXCEPT - { return m_tree.erase(x); } + //! @copydoc ::boost::container::set::erase(const_iterator) + iterator erase(const_iterator p); - //! Effects: Erases all the elements in the range [first, last). - //! - //! Returns: Returns last. - //! - //! Complexity: log(size())+N where N is the distance from first to last. - iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT - { return m_tree.erase(first, last); } + //! @copydoc ::boost::container::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(multimap& x) - { m_tree.swap(x.m_tree); } + //! @copydoc ::boost::container::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_tree.clear(); } + //! @copydoc ::boost::container::set::swap + void swap(flat_multiset& x); - ////////////////////////////////////////////// - // - // observers - // - ////////////////////////////////////////////// + //! @copydoc ::boost::container::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_tree.key_comp(); } + //! @copydoc ::boost::container::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 value_compare(m_tree.key_comp()); } - - ////////////////////////////////////////////// - // - // map operations - // - ////////////////////////////////////////////// + //! @copydoc ::boost::container::set::value_comp + 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_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. - const_iterator find(const key_type& x) const - { return m_tree.find(x); } + const_iterator find(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_tree.count(x); } + size_type count(const key_type& x) const; //! 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_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_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_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_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) - { return m_tree.equal_range(x); } + 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) const - { return m_tree.equal_range(x); } + std::pair equal_range(const key_type& x) const; //! Effects: Rebalances the tree. It's a no-op for Red-Black and AVL trees. //! //! Complexity: Linear - void rebalance() - { return m_tree.rebalance(); } + void rebalance(); //! Effects: Returns true if x and y are equal //! //! Complexity: Linear to the number of elements in the container. - friend bool operator==(const multimap& x, const multimap& y) - { return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); } + friend bool operator==(const multimap& x, const multimap& y); //! Effects: Returns true if x and y are unequal //! //! Complexity: Linear to the number of elements in the container. - friend bool operator!=(const multimap& x, const multimap& y) - { return !(x == y); } + friend bool operator!=(const multimap& x, const multimap& y); //! Effects: Returns true if x is less than y //! //! Complexity: Linear to the number of elements in the container. - friend bool operator<(const multimap& x, const multimap& y) - { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + friend bool operator<(const multimap& x, const multimap& y); //! Effects: Returns true if x is greater than y //! //! Complexity: Linear to the number of elements in the container. - friend bool operator>(const multimap& x, const multimap& y) - { return y < x; } + friend bool operator>(const multimap& x, const multimap& 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 multimap& x, const multimap& y) - { return !(y < x); } + friend bool operator<=(const multimap& x, const multimap& 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 multimap& x, const multimap& y) - { return !(x < y); } + friend bool operator>=(const multimap& x, const multimap& y); //! Effects: x.swap(y) //! //! Complexity: Constant. - friend void swap(multimap& x, multimap& y) - { x.swap(y); } + friend void swap(multimap& x, multimap& y); + + #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) }; #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED diff --git a/include/boost/container/set.hpp b/include/boost/container/set.hpp index 0edea92..99e195b 100644 --- a/include/boost/container/set.hpp +++ b/include/boost/container/set.hpp @@ -54,13 +54,16 @@ template , class Allocator = std::allo template #endif class set + ///@cond + : public container_detail::tree + < Key, Key, container_detail::identity, Compare, Allocator, SetOptions> + ///@endcond { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(set) typedef container_detail::tree - < Key, Key, container_detail::identity, Compare, Allocator, SetOptions> tree_t; - tree_t m_tree; // red-black tree representing set + < Key, Key, container_detail::identity, Compare, Allocator, SetOptions> base_t; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -80,11 +83,11 @@ class 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; ////////////////////////////////////////////// // @@ -96,7 +99,7 @@ class set //! //! Complexity: Constant. set() - : m_tree() + : base_t() {} //! Effects: Constructs an empty set using the specified comparison object @@ -105,14 +108,14 @@ class set //! Complexity: Constant. explicit set(const Compare& comp, const allocator_type& a = allocator_type()) - : m_tree(comp, a) + : base_t(comp, a) {} //! Effects: Constructs an empty set using the specified allocator object. //! //! Complexity: Constant. explicit set(const allocator_type& a) - : m_tree(a) + : base_t(a) {} //! Effects: Constructs an empty set using the specified comparison object and @@ -123,7 +126,7 @@ class set template set(InputIterator first, InputIterator last, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) - : m_tree(true, first, last, comp, a) + : base_t(true, first, last, comp, a) {} //! Effects: Constructs an empty set using the specified comparison object and @@ -139,14 +142,14 @@ class set template set( ordered_unique_range_t, InputIterator first, InputIterator last , const Compare& comp = Compare(), const allocator_type& a = allocator_type()) - : m_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(). set(const set& x) - : m_tree(x.m_tree) + : base_t(static_cast(x)) {} //! Effects: Move constructs a set. Constructs *this using x's resources. @@ -155,14 +158,14 @@ class set //! //! Postcondition: x is emptied. set(BOOST_RV_REF(set) x) - : m_tree(boost::move(x.m_tree)) + : base_t(boost::move(static_cast(x))) {} //! Effects: Copy constructs a set using the specified allocator. //! //! Complexity: Linear in x.size(). set(const set& x, const allocator_type &a) - : m_tree(x.m_tree, a) + : base_t(static_cast(x), a) {} //! Effects: Move constructs a set using the specified allocator. @@ -170,27 +173,28 @@ class set //! //! Complexity: Constant if a == x.get_allocator(), linear otherwise. set(BOOST_RV_REF(set) x, const allocator_type &a) - : m_tree(boost::move(x.m_tree), a) + : base_t(boost::move(static_cast(x)), a) {} //! Effects: Makes *this a copy of x. //! //! Complexity: Linear in x.size(). set& operator=(BOOST_COPY_ASSIGN_REF(set) x) - { m_tree = x.m_tree; return *this; } + { return static_cast(this->base_t::operator=(static_cast(x))); } //! Effects: this->swap(x.get()). //! //! Complexity: Constant. set& operator=(BOOST_RV_REF(set) x) - { m_tree = boost::move(x.m_tree); return *this; } + { return static_cast(this->base_t::operator=(boost::move(static_cast(x)))); } + + #if defined(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 - { return m_tree.get_allocator(); } + allocator_type get_allocator() const; //! Effects: Returns a reference to the internal allocator. //! @@ -199,8 +203,7 @@ class set //! Complexity: Constant. //! //! Note: Non-standard extension. - const stored_allocator_type &get_stored_allocator() const - { return m_tree.get_stored_allocator(); } + stored_allocator_type &get_stored_allocator(); //! Effects: Returns a reference to the internal allocator. //! @@ -209,46 +212,49 @@ class set //! Complexity: Constant. //! //! Note: Non-standard extension. - stored_allocator_type &get_stored_allocator() - { return m_tree.get_stored_allocator(); } - - ////////////////////////////////////////////// - // - // capacity - // - ////////////////////////////////////////////// + const stored_allocator_type &get_stored_allocator() const; //! Effects: Returns an iterator to the first element contained in the container. //! //! Throws: Nothing. //! //! Complexity: Constant - iterator begin() - { return m_tree.begin(); } + iterator begin(); //! Effects: Returns a const_iterator to the first element contained in the container. //! //! Throws: Nothing. //! //! Complexity: Constant. - const_iterator begin() const - { return m_tree.begin(); } + const_iterator begin() const; + + //! Effects: Returns a const_iterator to the first element contained in the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator cbegin() const; //! Effects: Returns an iterator to the end of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. - iterator end() - { return m_tree.end(); } + iterator end(); //! Effects: Returns a const_iterator to the end of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. - const_iterator end() const - { return m_tree.end(); } + const_iterator end() const; + + //! Effects: Returns a const_iterator to the end of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_iterator cend() const; //! Effects: Returns a reverse_iterator pointing to the beginning //! of the reversed container. @@ -256,8 +262,7 @@ class set //! Throws: Nothing. //! //! Complexity: Constant. - reverse_iterator rbegin() - { return m_tree.rbegin(); } + reverse_iterator rbegin(); //! Effects: Returns a const_reverse_iterator pointing to the beginning //! of the reversed container. @@ -265,8 +270,15 @@ class set //! Throws: Nothing. //! //! Complexity: Constant. - const_reverse_iterator rbegin() const - { return m_tree.rbegin(); } + const_reverse_iterator rbegin() const; + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reverse_iterator crbegin() const; //! Effects: Returns a reverse_iterator pointing to the end //! of the reversed container. @@ -274,8 +286,7 @@ class set //! Throws: Nothing. //! //! Complexity: Constant. - reverse_iterator rend() - { return m_tree.rend(); } + reverse_iterator rend(); //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed container. @@ -283,33 +294,7 @@ class set //! Throws: Nothing. //! //! Complexity: Constant. - const_reverse_iterator rend() const - { return m_tree.rend(); } - - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cbegin() const - { return m_tree.cbegin(); } - - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cend() const - { return m_tree.cend(); } - - //! Effects: Returns a const_reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_reverse_iterator crbegin() const - { return m_tree.crbegin(); } + const_reverse_iterator rend() const; //! Effects: Returns a const_reverse_iterator pointing to the end //! of the reversed container. @@ -317,44 +302,29 @@ class set //! Throws: Nothing. //! //! Complexity: Constant. - const_reverse_iterator crend() const - { return m_tree.crend(); } - - ////////////////////////////////////////////// - // - // capacity - // - ////////////////////////////////////////////// + const_reverse_iterator crend() const; //! Effects: Returns true if the container contains no elements. //! //! Throws: Nothing. //! //! Complexity: Constant. - bool empty() const - { return m_tree.empty(); } + bool empty() const; //! Effects: Returns the number of the elements contained in the container. //! //! Throws: Nothing. //! //! Complexity: Constant. - size_type size() const - { return m_tree.size(); } + size_type size() const; //! Effects: Returns the largest possible size of the container. //! //! Throws: Nothing. //! //! Complexity: Constant. - size_type max_size() const - { return m_tree.max_size(); } - - ////////////////////////////////////////////// - // - // modifiers - // - ////////////////////////////////////////////// + size_type max_size() const; + #endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -374,7 +344,7 @@ class set //! Complexity: Logarithmic. template std::pair emplace(Args&&... args) - { return m_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)... if and only if there is @@ -387,19 +357,19 @@ class set //! Complexity: Logarithmic. template iterator emplace_hint(const_iterator hint, Args&&... args) - { return m_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_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_tree.emplace_hint_unique(hint \ + { 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) @@ -465,7 +435,9 @@ class set //! Complexity: At most N log(size()+N) (N is the distance from first to last) template void insert(InputIterator first, InputIterator last) - { m_tree.insert_unique(first, last); } + { this->base_t::insert_unique(first, last); } + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Erases the element pointed to by p. //! @@ -474,184 +446,155 @@ class set //! returns end(). //! //! Complexity: Amortized constant time - iterator erase(const_iterator p) - { return m_tree.erase(p); } + iterator erase(const_iterator p); //! Effects: Erases all elements in the container with key equivalent to x. //! //! Returns: Returns the number of erased elements. //! //! Complexity: log(size()) + count(k) - size_type erase(const key_type& x) - { return m_tree.erase(x); } + size_type erase(const key_type& x); //! Effects: Erases all the elements in the range [first, last). //! //! Returns: Returns last. //! //! Complexity: log(size())+N where N is the distance from first to last. - iterator erase(const_iterator first, const_iterator last) - { return m_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(set& x) - { m_tree.swap(x.m_tree); } + void swap(set& x); //! Effects: erase(a.begin(),a.end()). //! //! Postcondition: size() == 0. //! //! Complexity: linear in size(). - void clear() - { m_tree.clear(); } - - ////////////////////////////////////////////// - // - // observers - // - ////////////////////////////////////////////// + void clear(); //! Effects: Returns the comparison object out //! of which a was constructed. //! //! Complexity: Constant. - key_compare key_comp() const - { return m_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_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_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. - const_iterator find(const key_type& x) const - { return m_tree.find(x); } + 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_tree.find(x) != m_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_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_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_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_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) - { return m_tree.equal_range(x); } + 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) const - { return m_tree.equal_range(x); } + std::pair equal_range(const key_type& x) const; //! Effects: Rebalances the tree. It's a no-op for Red-Black and AVL trees. //! //! Complexity: Linear - void rebalance() - { return m_tree.rebalance(); } + void rebalance(); //! Effects: Returns true if x and y are equal //! //! Complexity: Linear to the number of elements in the container. - friend bool operator==(const set& x, const set& y) - { return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); } + friend bool operator==(const set& x, const 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 set& x, const set& y) - { return !(x == y); } + friend bool operator!=(const set& x, const 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 set& x, const set& y) - { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + friend bool operator<(const set& x, const 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 set& x, const set& y) - { return y < x; } + friend bool operator>(const set& x, const 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 set& x, const set& y) - { return !(y < x); } + friend bool operator<=(const set& x, const 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 set& x, const set& y) - { return !(x < y); } + friend bool operator>=(const set& x, const set& y); //! Effects: x.swap(y) //! //! Complexity: Constant. - friend void swap(set& x, set& y) - { x.swap(y); } + friend void swap(set& x, set& y); + + #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: template std::pair priv_insert(BOOST_FWD_REF(KeyType) x) - { return m_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_tree.insert_unique(p, ::boost::forward(x)); } + { return this->base_t::insert_unique(p, ::boost::forward(x)); } #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; @@ -690,13 +633,16 @@ template , class Allocator = std::allo template #endif class multiset + /// @cond + : public container_detail::tree + , Compare, Allocator, MultiSetOptions> + /// @endcond { #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(multiset) typedef container_detail::tree - , Compare, Allocator, MultiSetOptions> tree_t; - tree_t m_tree; // red-black tree representing multiset + , Compare, Allocator, MultiSetOptions> base_t; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -717,11 +663,11 @@ class 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; ////////////////////////////////////////////// // @@ -729,40 +675,28 @@ class multiset // ////////////////////////////////////////////// - //! Effects: Constructs an empty multiset using the specified comparison - //! object and allocator. - //! - //! Complexity: Constant. + //! @copydoc ::boost::container::set::set() multiset() - : m_tree() + : base_t() {} - //! Effects: Constructs an empty multiset using the specified comparison - //! object and allocator. - //! - //! Complexity: Constant. + //! @copydoc ::boost::container::set::set(const Compare&, const allocator_type&) explicit multiset(const Compare& comp, const allocator_type& a = allocator_type()) - : m_tree(comp, a) + : base_t(comp, a) {} - //! Effects: Constructs an empty multiset using the specified allocator. - //! - //! Complexity: Constant. + //! @copydoc ::boost::container::set::set(const allocator_type&) explicit multiset(const allocator_type& a) - : m_tree(a) + : base_t(a) {} - //! Effects: Constructs an empty multiset using the specified comparison object - //! and allocator, and inserts elements from the range [first ,last ). - //! - //! Complexity: Linear in N if the range [first ,last ) is already sorted using - //! comp and otherwise N logN, where N is last - first. + //! @copydoc ::boost::container::set::set(InputIterator, InputIterator, const Compare& comp, const allocator_type&) template multiset(InputIterator first, InputIterator last, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) - : m_tree(false, first, last, comp, a) + : base_t(false, first, last, comp, a) {} //! Effects: Constructs an empty multiset using the specified comparison object and @@ -778,224 +712,94 @@ class multiset multiset( ordered_range_t, InputIterator first, InputIterator last , const Compare& comp = Compare() , const allocator_type& a = allocator_type()) - : m_tree(ordered_range, first, last, comp, a) + : base_t(ordered_range, first, last, comp, a) {} - //! Effects: Copy constructs a multiset. - //! - //! Complexity: Linear in x.size(). + //! @copydoc ::boost::container::set::set(const set &) multiset(const multiset& x) - : m_tree(x.m_tree) + : base_t(static_cast(x)) {} - //! Effects: Move constructs a multiset. Constructs *this using x's resources. - //! - //! Complexity: Constant. - //! - //! Postcondition: x is emptied. + //! @copydoc ::boost::container::set(set &&) multiset(BOOST_RV_REF(multiset) x) - : m_tree(boost::move(x.m_tree)) + : base_t(boost::move(static_cast(x))) {} - //! Effects: Copy constructs a multiset using the specified allocator. - //! - //! Complexity: Linear in x.size(). + //! @copydoc ::boost::container::set(const set &, const allocator_type &) multiset(const multiset& x, const allocator_type &a) - : m_tree(x.m_tree, a) + : base_t(static_cast(x), a) {} - //! Effects: Move constructs a multiset using the specified allocator. - //! Constructs *this using x's resources. - //! - //! Complexity: Constant if a == x.get_allocator(), linear otherwise. - //! - //! Postcondition: x is emptied. + //! @copydoc ::boost::container::set(set &&, const allocator_type &) multiset(BOOST_RV_REF(multiset) x, const allocator_type &a) - : m_tree(boost::move(x.m_tree), a) + : base_t(boost::move(static_cast(x)), a) {} - //! Effects: Makes *this a copy of x. - //! - //! Complexity: Linear in x.size(). + //! @copydoc ::boost::container::set::operator=(const set &) multiset& operator=(BOOST_COPY_ASSIGN_REF(multiset) x) - { m_tree = x.m_tree; return *this; } + { return static_cast(this->base_t::operator=(static_cast(x))); } - //! Effects: this->swap(x.get()). - //! - //! Complexity: Constant. + //! @copydoc ::boost::container::set::operator=(set &&) multiset& operator=(BOOST_RV_REF(multiset) x) - { m_tree = boost::move(x.m_tree); return *this; } + { return static_cast(this->base_t::operator=(boost::move(static_cast(x)))); } - //! Effects: Returns a copy of the Allocator that - //! was passed to the object's constructor. - //! - //! Complexity: Constant. - allocator_type get_allocator() const - { return m_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() - { return m_tree.get_stored_allocator(); } + //! @copydoc ::boost::container::set::get_allocator() + allocator_type get_allocator() const; - //! Effects: Returns a reference to the internal allocator. - //! - //! Throws: Nothing - //! - //! Complexity: Constant. - //! - //! Note: Non-standard extension. - const stored_allocator_type &get_stored_allocator() const - { return m_tree.get_stored_allocator(); } + //! @copydoc ::boost::container::set::get_stored_allocator() + stored_allocator_type &get_stored_allocator(); - ////////////////////////////////////////////// - // - // iterators - // - ////////////////////////////////////////////// + //! @copydoc ::boost::container::set::get_stored_allocator() const + const stored_allocator_type &get_stored_allocator() const; - //! Effects: Returns an iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - iterator begin() - { return m_tree.begin(); } + //! @copydoc ::boost::container::set::begin() + iterator begin(); - //! Effects: Returns a const_iterator to the first element contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator begin() const - { return m_tree.begin(); } + //! @copydoc ::boost::container::set::begin() const + const_iterator begin() const; - //! Effects: Returns an iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - iterator end() - { return m_tree.end(); } + //! @copydoc ::boost::container::set::cbegin() const + const_iterator cbegin() const; - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator end() const - { return m_tree.end(); } + //! @copydoc ::boost::container::set::end() + iterator end() BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns a reverse_iterator pointing to the beginning - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - reverse_iterator rbegin() - { return m_tree.rbegin(); } + //! @copydoc ::boost::container::set::end() const + const_iterator end() 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 - { return m_tree.rbegin(); } + //! @copydoc ::boost::container::set::cend() const + const_iterator cend() const BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns a reverse_iterator pointing to the end - //! of the reversed container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - reverse_iterator rend() - { return m_tree.rend(); } + //! @copydoc ::boost::container::set::rbegin() + reverse_iterator rbegin() 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 - { return m_tree.rend(); } + //! @copydoc ::boost::container::set::rbegin() const + const_reverse_iterator rbegin() 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 - { return m_tree.cbegin(); } + //! @copydoc ::boost::container::set::crbegin() const + const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT; - //! Effects: Returns a const_iterator to the end of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - const_iterator cend() const - { return m_tree.cend(); } + //! @copydoc ::boost::container::set::rend() + reverse_iterator rend() 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 - { return m_tree.crbegin(); } + //! @copydoc ::boost::container::set::rend() const + const_reverse_iterator rend() 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 crend() const - { return m_tree.crend(); } + //! @copydoc ::boost::container::set::crend() const + const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT; - ////////////////////////////////////////////// - // - // capacity - // - ////////////////////////////////////////////// + //! @copydoc ::boost::container::set::empty() const + bool empty() const; - //! Effects: Returns true if the container contains no elements. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - bool empty() const - { return m_tree.empty(); } + //! @copydoc ::boost::container::set::size() const + size_type size() const; - //! Effects: Returns the number of the elements contained in the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type size() const - { return m_tree.size(); } + //! @copydoc ::boost::container::set::max_size() const + size_type max_size() const; - //! Effects: Returns the largest possible size of the container. - //! - //! Throws: Nothing. - //! - //! Complexity: Constant. - size_type max_size() const - { return m_tree.max_size(); } - - ////////////////////////////////////////////// - // - // modifiers - // - ////////////////////////////////////////////// + #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -1006,7 +810,7 @@ class multiset //! Complexity: Logarithmic. template iterator emplace(Args&&... args) - { return m_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)... @@ -1018,19 +822,19 @@ class multiset //! is inserted right before p. template iterator emplace_hint(const_iterator hint, Args&&... args) - { return m_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_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_tree.emplace_hint_equal(hint \ + { 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) @@ -1038,9 +842,6 @@ class multiset #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING - - - #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: Inserts x and returns the iterator pointing to the //! newly inserted element. @@ -1091,193 +892,107 @@ class multiset //! Complexity: At most N log(size()+N) (N is the distance from first to last) template void insert(InputIterator first, InputIterator last) - { m_tree.insert_equal(first, last); } + { this->base_t::insert_equal(first, last); } - //! Effects: Erases the element pointed to by p. - //! - //! 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: Amortized constant time - iterator erase(const_iterator p) - { return m_tree.erase(p); } + #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: log(size()) + count(k) - size_type erase(const key_type& x) - { return m_tree.erase(x); } + //! @copydoc ::boost::container::set::erase(const_iterator) + iterator erase(const_iterator p); - //! Effects: Erases all the elements in the range [first, last). - //! - //! Returns: Returns last. - //! - //! Complexity: log(size())+N where N is the distance from first to last. - iterator erase(const_iterator first, const_iterator last) - { return m_tree.erase(first, last); } + //! @copydoc ::boost::container::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(multiset& x) - { m_tree.swap(x.m_tree); } + //! @copydoc ::boost::container::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() - { m_tree.clear(); } + //! @copydoc ::boost::container::set::swap + void swap(flat_multiset& x); - ////////////////////////////////////////////// - // - // observers - // - ////////////////////////////////////////////// + //! @copydoc ::boost::container::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_tree.key_comp(); } + //! @copydoc ::boost::container::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_tree.key_comp(); } + //! @copydoc ::boost::container::set::value_comp + value_compare value_comp() const; - ////////////////////////////////////////////// - // - // set operations - // - ////////////////////////////////////////////// + //! @copydoc ::boost::container::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_tree.find(x); } + //! @copydoc ::boost::container::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. - const_iterator find(const key_type& x) const - { return m_tree.find(x); } + //! @copydoc ::boost::container::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_tree.count(x); } + //! @copydoc ::boost::container::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_tree.lower_bound(x); } + //! @copydoc ::boost::container::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_tree.lower_bound(x); } + //! @copydoc ::boost::container::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_tree.upper_bound(x); } + //! @copydoc ::boost::container::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_tree.upper_bound(x); } + //! @copydoc ::boost::container::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) - { return m_tree.equal_range(x); } + //! @copydoc ::boost::container::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) const - { return m_tree.equal_range(x); } - - //! Effects: Rebalances the tree. It's a no-op for Red-Black and AVL trees. - //! - //! Complexity: Linear - void rebalance() - { return m_tree.rebalance(); } + //! @copydoc ::boost::container::set::rebalance() + void rebalance(); //! Effects: Returns true if x and y are equal //! //! Complexity: Linear to the number of elements in the container. - friend bool operator==(const multiset& x, const multiset& y) - { return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); } + friend bool operator==(const multiset& x, const multiset& y); //! Effects: Returns true if x and y are unequal //! //! Complexity: Linear to the number of elements in the container. - friend bool operator!=(const multiset& x, const multiset& y) - { return !(x == y); } + friend bool operator!=(const multiset& x, const multiset& y); //! Effects: Returns true if x is less than y //! //! Complexity: Linear to the number of elements in the container. - friend bool operator<(const multiset& x, const multiset& y) - { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + friend bool operator<(const multiset& x, const multiset& y); //! Effects: Returns true if x is greater than y //! //! Complexity: Linear to the number of elements in the container. - friend bool operator>(const multiset& x, const multiset& y) - { return y < x; } + friend bool operator>(const multiset& x, const multiset& 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 multiset& x, const multiset& y) - { return !(y < x); } + friend bool operator<=(const multiset& x, const multiset& 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 multiset& x, const multiset& y) - { return !(x < y); } + friend bool operator>=(const multiset& x, const multiset& y); //! Effects: x.swap(y) //! //! Complexity: Constant. - friend void swap(multiset& x, multiset& y) - { x.swap(y); } + friend void swap(multiset& x, multiset& y); + + #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: template iterator priv_insert(BOOST_FWD_REF(KeyType) x) - { return m_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_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/map_test.cpp b/test/map_test.cpp index 13d0503..565d2b1 100644 --- a/test/map_test.cpp +++ b/test/map_test.cpp @@ -126,6 +126,64 @@ template class multimap < std::pair > >; +namespace container_detail { + +template class tree + < const test::movable_and_copyable_int + , std::pair + , container_detail::select1st< std::pair > + , std::less + , test::dummy_test_allocator + < std::pair > + , tree_assoc_defaults >; + +template class tree + < const test::movable_and_copyable_int + , std::pair + , container_detail::select1st< std::pair > + , std::less + , test::simple_allocator + < std::pair > + , tree_assoc_defaults >; + +template class tree + < const test::movable_and_copyable_int + , std::pair + , container_detail::select1st< std::pair > + , std::less + , std::allocator + < std::pair > + , tree_assoc_defaults >; + +template class tree + < const test::movable_and_copyable_int + , std::pair + , container_detail::select1st< std::pair > + , std::less + , allocator + < std::pair > + , tree_assoc_defaults >; + +template class tree + < const test::movable_and_copyable_int + , std::pair + , container_detail::select1st< std::pair > + , std::less + , adaptive_pool + < std::pair > + , tree_assoc_defaults >; + +template class tree + < const test::movable_and_copyable_int + , std::pair + , container_detail::select1st< std::pair > + , std::less + , node_allocator + < std::pair > + , tree_assoc_defaults >; + +} //container_detail { + }} //boost::container class recursive_map diff --git a/test/set_test.cpp b/test/set_test.cpp index f5416ca..d613421 100644 --- a/test/set_test.cpp +++ b/test/set_test.cpp @@ -102,6 +102,65 @@ template class multiset , node_allocator >; +namespace container_detail { + +//Instantiate base class as previous instantiations don't instantiate inherited members +template class tree + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , identity + , std::less + , test::dummy_test_allocator + , tree_assoc_defaults + >; + +template class tree + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , identity + , std::less + , test::simple_allocator + , tree_assoc_defaults + >; + +template class tree + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , identity + , std::less + , std::allocator + , tree_assoc_defaults + >; + +template class tree + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , identity + , std::less + , allocator + , tree_assoc_defaults + >; + +template class tree + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , identity + , std::less + , adaptive_pool + , tree_assoc_defaults + >; + +template class tree + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , identity + , std::less + , node_allocator + , tree_assoc_defaults + >; + +} //container_detail { + }} //boost::container //Test recursive structures