mirror of
https://github.com/boostorg/intrusive.git
synced 2025-08-02 22:14:35 +02:00
Implemented equal_range for unique associative containers using lower_bound_range. This might be a bit slower when comparison function is very lightweight, but shines when it's heavy as it just needs to perform a single additional comparison and a possible successor iteration.
This commit is contained in:
@@ -304,21 +304,29 @@ class avl_set_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::avltree::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> 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<iterator,iterator> equal_range(const_reference value)
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
||||
std::pair<iterator,iterator> 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<const_iterator, const_iterator>
|
||||
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<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator>
|
||||
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<iterator,iterator> bounded_range
|
||||
|
@@ -302,21 +302,29 @@ class bs_set_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> 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<iterator,iterator> equal_range(const_reference value)
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
||||
std::pair<iterator,iterator> 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<const_iterator, const_iterator>
|
||||
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<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator>
|
||||
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<iterator,iterator> bounded_range
|
||||
|
@@ -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<iterator,iterator> 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<iterator,iterator> lower_bound_range(const_reference value)
|
||||
{ return this->lower_bound_range(value, this->comp()); }
|
||||
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> lower_bound_range(const KeyType &key, KeyValueCompare comp)
|
||||
{
|
||||
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
|
||||
key_node_comp(comp, &this->get_real_value_traits());
|
||||
std::pair<node_ptr, node_ptr> ret
|
||||
(node_algorithms::lower_bound_range(this->header_ptr(), key, key_node_comp));
|
||||
return std::pair<iterator, iterator>( iterator(ret.first, this->real_value_traits_ptr())
|
||||
, iterator(ret.second, this->real_value_traits_ptr()));
|
||||
}
|
||||
|
||||
std::pair<const_iterator, const_iterator>
|
||||
lower_bound_range(const_reference value) const
|
||||
{ return this->lower_bound_range(value, this->comp()); }
|
||||
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator>
|
||||
lower_bound_range(const KeyType &key, KeyValueCompare comp) const
|
||||
{
|
||||
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
|
||||
key_node_comp(comp, &this->get_real_value_traits());
|
||||
std::pair<node_ptr, node_ptr> ret
|
||||
(node_algorithms::lower_bound_range(this->header_ptr(), key, key_node_comp));
|
||||
return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->real_value_traits_ptr())
|
||||
, const_iterator(ret.second, this->real_value_traits_ptr()));
|
||||
}
|
||||
|
||||
//bounded_range
|
||||
std::pair<iterator,iterator> 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<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator, bool> insert_unique_check
|
||||
(const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
|
||||
|
@@ -487,18 +487,18 @@ class bstree_algorithms
|
||||
//! <b>Throws</b>: 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);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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.
|
||||
//!
|
||||
//! <b>Effects</b>: 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.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, node_ptr> lower_bound_range
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{
|
||||
node_ptr const lb(lower_bound(header, key, comp));
|
||||
std::pair<node_ptr, node_ptr> ret_ii(lb, lb);
|
||||
if(lb != header && !comp(key, lb)){
|
||||
ret_ii.second = next_node(ret_ii.second);
|
||||
}
|
||||
return ret_ii;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
|
@@ -304,21 +304,29 @@ class set_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
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<iterator,iterator> equal_range(const_reference value);
|
||||
std::pair<iterator,iterator> equal_range(const_reference value)
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
||||
std::pair<iterator,iterator> 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<const_iterator, const_iterator>
|
||||
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<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator>
|
||||
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<iterator,iterator> bounded_range
|
||||
|
@@ -302,21 +302,29 @@ class sg_set_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::sgtree::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> 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<iterator,iterator> equal_range(const_reference value)
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
||||
std::pair<iterator,iterator> 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<const_iterator, const_iterator>
|
||||
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<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator>
|
||||
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<iterator,iterator> bounded_range
|
||||
|
@@ -309,21 +309,29 @@ class splay_set_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> 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<iterator,iterator> equal_range(const_reference value)
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
||||
std::pair<iterator,iterator> 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<const_iterator, const_iterator>
|
||||
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<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator>
|
||||
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<iterator,iterator> bounded_range
|
||||
|
@@ -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<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, node_ptr> lower_bound_range
|
||||
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{
|
||||
splay_down(detail::uncast(header), key, comp);
|
||||
std::pair<node_ptr, node_ptr> 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<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, node_ptr> 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<class KeyType, class KeyNodePtrCompare>
|
||||
|
@@ -346,21 +346,29 @@ class treap_set_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::treap::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> 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<iterator,iterator> equal_range(const_reference value)
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
||||
std::pair<iterator,iterator> 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<const_iterator, const_iterator>
|
||||
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<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator>
|
||||
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<iterator,iterator> bounded_range
|
||||
|
Reference in New Issue
Block a user