diff --git a/include/boost/intrusive/avl_set.hpp b/include/boost/intrusive/avl_set.hpp index b70fd89..ce2d178 100644 --- a/include/boost/intrusive/avl_set.hpp +++ b/include/boost/intrusive/avl_set.hpp @@ -304,21 +304,29 @@ class avl_set_impl template const_iterator find(const KeyType& key, KeyValueCompare comp) const; - //! @copydoc ::boost::intrusive::avltree::equal_range(const_reference) - std::pair equal_range(const_reference value); + #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyValueCompare) + //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference) + std::pair equal_range(const_reference value) + { return this->tree_type::lower_bound_range(value); } + + //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare) template - std::pair equal_range(const KeyType& key, KeyValueCompare comp); + std::pair equal_range(const KeyType& key, KeyValueCompare comp) + { return this->tree_type::lower_bound_range(key, comp); } - //! @copydoc ::boost::intrusive::avltree::equal_range(const_reference)const + //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const std::pair - equal_range(const_reference value) const; + equal_range(const_reference value) const + { return this->tree_type::lower_bound_range(value); } - //! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyValueCompare)const + //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const template std::pair - equal_range(const KeyType& key, KeyValueCompare comp) const; + equal_range(const KeyType& key, KeyValueCompare comp) const + { return this->tree_type::lower_bound_range(key, comp); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::avltree::bounded_range(const_reference,const_reference,bool,bool) std::pair bounded_range diff --git a/include/boost/intrusive/bs_set.hpp b/include/boost/intrusive/bs_set.hpp index ce3c490..9768382 100644 --- a/include/boost/intrusive/bs_set.hpp +++ b/include/boost/intrusive/bs_set.hpp @@ -302,21 +302,29 @@ class bs_set_impl template const_iterator find(const KeyType& key, KeyValueCompare comp) const; - //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference) - std::pair equal_range(const_reference value); + #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare) + //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference) + std::pair equal_range(const_reference value) + { return this->tree_type::lower_bound_range(value); } + + //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare) template - std::pair equal_range(const KeyType& key, KeyValueCompare comp); + std::pair equal_range(const KeyType& key, KeyValueCompare comp) + { return this->tree_type::lower_bound_range(key, comp); } - //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const + //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const std::pair - equal_range(const_reference value) const; + equal_range(const_reference value) const + { return this->tree_type::lower_bound_range(value); } - //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const + //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const template std::pair - equal_range(const KeyType& key, KeyValueCompare comp) const; + equal_range(const KeyType& key, KeyValueCompare comp) const + { return this->tree_type::lower_bound_range(key, comp); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool) std::pair bounded_range diff --git a/include/boost/intrusive/bstree.hpp b/include/boost/intrusive/bstree.hpp index c880731..19b50de 100644 --- a/include/boost/intrusive/bstree.hpp +++ b/include/boost/intrusive/bstree.hpp @@ -238,6 +238,7 @@ struct bstbase2 key_compare key_comp() const { return this->comp(); } + //lower_bound iterator lower_bound(const_reference value) { return this->lower_bound(value, this->comp()); } @@ -262,6 +263,7 @@ struct bstbase2 (this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr()); } + //upper_bound iterator upper_bound(const_reference value) { return this->upper_bound(value, this->comp()); } @@ -286,6 +288,7 @@ struct bstbase2 (this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr()); } + //find iterator find(const_reference value) { return this->find(value, this->comp()); } @@ -310,6 +313,7 @@ struct bstbase2 (node_algorithms::find(this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr()); } + //equal_range std::pair equal_range(const_reference value) { return this->equal_range(value, this->comp()); } @@ -340,6 +344,38 @@ struct bstbase2 , const_iterator(ret.second, this->real_value_traits_ptr())); } + //lower_bound_range + std::pair lower_bound_range(const_reference value) + { return this->lower_bound_range(value, this->comp()); } + + template + std::pair lower_bound_range(const KeyType &key, KeyValueCompare comp) + { + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_real_value_traits()); + std::pair ret + (node_algorithms::lower_bound_range(this->header_ptr(), key, key_node_comp)); + return std::pair( iterator(ret.first, this->real_value_traits_ptr()) + , iterator(ret.second, this->real_value_traits_ptr())); + } + + std::pair + lower_bound_range(const_reference value) const + { return this->lower_bound_range(value, this->comp()); } + + template + std::pair + lower_bound_range(const KeyType &key, KeyValueCompare comp) const + { + detail::key_nodeptr_comp + key_node_comp(comp, &this->get_real_value_traits()); + std::pair ret + (node_algorithms::lower_bound_range(this->header_ptr(), key, key_node_comp)); + return std::pair( const_iterator(ret.first, this->real_value_traits_ptr()) + , const_iterator(ret.second, this->real_value_traits_ptr())); + } + + //bounded_range std::pair bounded_range (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) { return this->bounded_range(lower_value, upper_value, this->comp(), left_closed, right_closed); } @@ -374,6 +410,7 @@ struct bstbase2 , const_iterator(ret.second, this->real_value_traits_ptr())); } + //insert_unique_check template std::pair insert_unique_check (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data) diff --git a/include/boost/intrusive/bstree_algorithms.hpp b/include/boost/intrusive/bstree_algorithms.hpp index b94310b..d7f785f 100644 --- a/include/boost/intrusive/bstree_algorithms.hpp +++ b/include/boost/intrusive/bstree_algorithms.hpp @@ -487,18 +487,18 @@ class bstree_algorithms //! Throws: Nothing. static node_ptr next_node(const node_ptr & node) { - node_ptr p_right(NodeTraits::get_right(node)); - if(p_right){ - return minimum(p_right); + node_ptr const n_right(NodeTraits::get_right(node)); + if(n_right){ + return minimum(n_right); } else { - node_ptr p(node); - node_ptr x = NodeTraits::get_parent(p); - while(p == NodeTraits::get_right(x)){ - p = x; - x = NodeTraits::get_parent(x); + node_ptr n(node); + node_ptr p(NodeTraits::get_parent(n)); + while(n == NodeTraits::get_right(p)){ + n = p; + p = NodeTraits::get_parent(p); } - return NodeTraits::get_right(p) != x ? x : detail::uncast(p); + return NodeTraits::get_right(n) != p ? p : n; } } @@ -902,6 +902,31 @@ class bstree_algorithms return bounded_range(header, key, key, comp, true, true); } + //! Requires: "header" must be the header node of a tree. + //! KeyNodePtrCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs. + //! + //! Effects: Returns an a pair of node_ptr delimiting a range containing + //! the first element that is equivalent to "key" according to "comp" or an + //! empty range that indicates the position where that element would be + //! if there are no equivalent elements. + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + template + static std::pair lower_bound_range + (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + { + node_ptr const lb(lower_bound(header, key, comp)); + std::pair ret_ii(lb, lb); + if(lb != header && !comp(key, lb)){ + ret_ii.second = next_node(ret_ii.second); + } + return ret_ii; + } + //! Requires: "header" must be the header node of a tree. //! KeyNodePtrCompare is a function object that induces a strict weak //! ordering compatible with the strict weak ordering used to create the diff --git a/include/boost/intrusive/set.hpp b/include/boost/intrusive/set.hpp index 43673e3..b2e4290 100644 --- a/include/boost/intrusive/set.hpp +++ b/include/boost/intrusive/set.hpp @@ -304,21 +304,29 @@ class set_impl template const_iterator find(const KeyType& key, KeyValueCompare comp) const; + #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED + //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference) - std::pair equal_range(const_reference value); + std::pair equal_range(const_reference value) + { return this->tree_type::lower_bound_range(value); } //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare) template - std::pair equal_range(const KeyType& key, KeyValueCompare comp); + std::pair equal_range(const KeyType& key, KeyValueCompare comp) + { return this->tree_type::lower_bound_range(key, comp); } //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const std::pair - equal_range(const_reference value) const; + equal_range(const_reference value) const + { return this->tree_type::lower_bound_range(value); } //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const template std::pair - equal_range(const KeyType& key, KeyValueCompare comp) const; + equal_range(const KeyType& key, KeyValueCompare comp) const + { return this->tree_type::lower_bound_range(key, comp); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::rbtree::bounded_range(const_reference,const_reference,bool,bool) std::pair bounded_range diff --git a/include/boost/intrusive/sg_set.hpp b/include/boost/intrusive/sg_set.hpp index 11545ab..1997696 100644 --- a/include/boost/intrusive/sg_set.hpp +++ b/include/boost/intrusive/sg_set.hpp @@ -302,21 +302,29 @@ class sg_set_impl template const_iterator find(const KeyType& key, KeyValueCompare comp) const; - //! @copydoc ::boost::intrusive::sgtree::equal_range(const_reference) - std::pair equal_range(const_reference value); + #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::sgtree::equal_range(const KeyType&,KeyValueCompare) + //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference) + std::pair equal_range(const_reference value) + { return this->tree_type::lower_bound_range(value); } + + //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare) template - std::pair equal_range(const KeyType& key, KeyValueCompare comp); + std::pair equal_range(const KeyType& key, KeyValueCompare comp) + { return this->tree_type::lower_bound_range(key, comp); } - //! @copydoc ::boost::intrusive::sgtree::equal_range(const_reference)const + //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const std::pair - equal_range(const_reference value) const; + equal_range(const_reference value) const + { return this->tree_type::lower_bound_range(value); } - //! @copydoc ::boost::intrusive::sgtree::equal_range(const KeyType&,KeyValueCompare)const + //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const template std::pair - equal_range(const KeyType& key, KeyValueCompare comp) const; + equal_range(const KeyType& key, KeyValueCompare comp) const + { return this->tree_type::lower_bound_range(key, comp); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::sgtree::bounded_range(const_reference,const_reference,bool,bool) std::pair bounded_range diff --git a/include/boost/intrusive/splay_set.hpp b/include/boost/intrusive/splay_set.hpp index 97654fc..f47799c 100644 --- a/include/boost/intrusive/splay_set.hpp +++ b/include/boost/intrusive/splay_set.hpp @@ -309,21 +309,29 @@ class splay_set_impl template const_iterator find(const KeyType& key, KeyValueCompare comp) const; - //! @copydoc ::boost::intrusive::splaytree::equal_range(const_reference) - std::pair equal_range(const_reference value); + #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::splaytree::equal_range(const KeyType&,KeyValueCompare) + //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference) + std::pair equal_range(const_reference value) + { return this->tree_type::lower_bound_range(value); } + + //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare) template - std::pair equal_range(const KeyType& key, KeyValueCompare comp); + std::pair equal_range(const KeyType& key, KeyValueCompare comp) + { return this->tree_type::lower_bound_range(key, comp); } - //! @copydoc ::boost::intrusive::splaytree::equal_range(const_reference)const + //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const std::pair - equal_range(const_reference value) const; + equal_range(const_reference value) const + { return this->tree_type::lower_bound_range(value); } - //! @copydoc ::boost::intrusive::splaytree::equal_range(const KeyType&,KeyValueCompare)const + //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const template std::pair - equal_range(const KeyType& key, KeyValueCompare comp) const; + equal_range(const KeyType& key, KeyValueCompare comp) const + { return this->tree_type::lower_bound_range(key, comp); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::splaytree::bounded_range(const_reference,const_reference,bool,bool) std::pair bounded_range diff --git a/include/boost/intrusive/splaytree_algorithms.hpp b/include/boost/intrusive/splaytree_algorithms.hpp index 32130e6..313d6af 100644 --- a/include/boost/intrusive/splaytree_algorithms.hpp +++ b/include/boost/intrusive/splaytree_algorithms.hpp @@ -353,6 +353,25 @@ class splaytree_algorithms (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { return bstree_algo::equal_range(header, key, comp); } + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! Additional notes: the first node of the range is splayed. + template + static std::pair lower_bound_range + (const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + { + splay_down(detail::uncast(header), key, comp); + std::pair ret = bstree_algo::lower_bound_range(header, key, comp); + //splay_up(ret.first, detail::uncast(header)); + return ret; + } + + //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare) + //! Additional note: no splaying is performed + template + static std::pair lower_bound_range + (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) + { return bstree_algo::lower_bound_range(header, key, comp); } + //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool) //! Additional notes: the first node of the range is splayed. template diff --git a/include/boost/intrusive/treap_set.hpp b/include/boost/intrusive/treap_set.hpp index cb59a72..6812e1a 100644 --- a/include/boost/intrusive/treap_set.hpp +++ b/include/boost/intrusive/treap_set.hpp @@ -346,21 +346,29 @@ class treap_set_impl template const_iterator find(const KeyType& key, KeyValueCompare comp) const; - //! @copydoc ::boost::intrusive::treap::equal_range(const_reference) - std::pair equal_range(const_reference value); + #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::treap::equal_range(const KeyType&,KeyValueCompare) + //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference) + std::pair equal_range(const_reference value) + { return this->tree_type::lower_bound_range(value); } + + //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare) template - std::pair equal_range(const KeyType& key, KeyValueCompare comp); + std::pair equal_range(const KeyType& key, KeyValueCompare comp) + { return this->tree_type::lower_bound_range(key, comp); } - //! @copydoc ::boost::intrusive::treap::equal_range(const_reference)const + //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const std::pair - equal_range(const_reference value) const; + equal_range(const_reference value) const + { return this->tree_type::lower_bound_range(value); } - //! @copydoc ::boost::intrusive::treap::equal_range(const KeyType&,KeyValueCompare)const + //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const template std::pair - equal_range(const KeyType& key, KeyValueCompare comp) const; + equal_range(const KeyType& key, KeyValueCompare comp) const + { return this->tree_type::lower_bound_range(key, comp); } + + #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED //! @copydoc ::boost::intrusive::treap::bounded_range(const_reference,const_reference,bool,bool) std::pair bounded_range