From 07b1322fa3ba74b7b12a1431bfef74a52b3119bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sat, 14 Jul 2012 13:29:28 +0000 Subject: [PATCH] Added `bounded_range` function to trees [SVN r79498] --- include/boost/intrusive/avl_set.hpp | 170 +++++++++++++++++ include/boost/intrusive/avltree.hpp | 98 ++++++++++ .../boost/intrusive/avltree_algorithms.hpp | 25 +++ .../intrusive/detail/tree_algorithms.hpp | 178 +++++++++++------- include/boost/intrusive/detail/utilities.hpp | 2 +- include/boost/intrusive/rbtree.hpp | 98 ++++++++++ include/boost/intrusive/rbtree_algorithms.hpp | 25 +++ include/boost/intrusive/set.hpp | 170 +++++++++++++++++ include/boost/intrusive/sg_set.hpp | 170 +++++++++++++++++ include/boost/intrusive/sgtree.hpp | 106 ++++++++++- include/boost/intrusive/sgtree_algorithms.hpp | 25 +++ include/boost/intrusive/splay_set.hpp | 172 +++++++++++++++++ include/boost/intrusive/splaytree.hpp | 98 ++++++++++ .../boost/intrusive/splaytree_algorithms.hpp | 45 ++++- include/boost/intrusive/treap.hpp | 98 ++++++++++ include/boost/intrusive/treap_algorithms.hpp | 25 +++ include/boost/intrusive/treap_set.hpp | 170 +++++++++++++++++ 17 files changed, 1601 insertions(+), 74 deletions(-) diff --git a/include/boost/intrusive/avl_set.hpp b/include/boost/intrusive/avl_set.hpp index 3bcde1c..91e2dbb 100644 --- a/include/boost/intrusive/avl_set.hpp +++ b/include/boost/intrusive/avl_set.hpp @@ -969,6 +969,91 @@ class avl_set_impl equal_range(const KeyType& key, KeyValueCompare comp) const { return tree_.equal_range(key, comp); } + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair + bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair + bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + //! Requires: value must be an lvalue and shall be in a avl_set of //! appropriate type. Otherwise the behavior is undefined. //! @@ -2086,6 +2171,91 @@ class avl_multiset_impl equal_range(const KeyType& key, KeyValueCompare comp) const { return tree_.equal_range(key, comp); } + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair + bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair + bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + //! Requires: value must be an lvalue and shall be in a avl_multiset of //! appropriate type. Otherwise the behavior is undefined. //! diff --git a/include/boost/intrusive/avltree.hpp b/include/boost/intrusive/avltree.hpp index 8fac811..84376a8 100644 --- a/include/boost/intrusive/avltree.hpp +++ b/include/boost/intrusive/avltree.hpp @@ -1228,6 +1228,104 @@ class avltree_impl return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); } + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + 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, priv_comp(), left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::bounded_range + (this->priv_header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed)); + return std::pair(iterator(ret.first, this), iterator(ret.second, this)); + } + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const + { return this->bounded_range(lower_value, upper_value, priv_comp(), left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::bounded_range + (this->priv_header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed)); + return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); + } + //! Requires: Disposer::operator()(pointer) shouldn't throw. //! Cloner should yield to nodes equivalent to the original nodes. //! diff --git a/include/boost/intrusive/avltree_algorithms.hpp b/include/boost/intrusive/avltree_algorithms.hpp index 29c5e81..11463c7 100644 --- a/include/boost/intrusive/avltree_algorithms.hpp +++ b/include/boost/intrusive/avltree_algorithms.hpp @@ -464,6 +464,31 @@ class avltree_algorithms (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { return tree_algorithms::equal_range(header, key, comp); } + //! 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. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + static std::pair bounded_range + (const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp + , bool left_closed, bool right_closed) + { return tree_algorithms::bounded_range(header, lower_key, upper_key, comp, left_closed, right_closed); } + //! Requires: "h" must be the header node of a tree. //! NodePtrCompare 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/detail/tree_algorithms.hpp b/include/boost/intrusive/detail/tree_algorithms.hpp index 710238b..c92d39b 100644 --- a/include/boost/intrusive/detail/tree_algorithms.hpp +++ b/include/boost/intrusive/detail/tree_algorithms.hpp @@ -761,6 +761,82 @@ class tree_algorithms return (y == end || comp(key, y)) ? end : y; } + //! 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. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template< class KeyType, class KeyNodePtrCompare> + static std::pair bounded_range + ( const const_node_ptr & header + , const KeyType &lower_key + , const KeyType &upper_key + , KeyNodePtrCompare comp + , bool left_closed + , bool right_closed) + { + node_ptr y = uncast(header); + node_ptr x = NodeTraits::get_parent(header); + + while(x){ + //If x is less than lower_key the target + //range is on the right part + if(comp(x, lower_key)){ + //Check for invalid input range + BOOST_INTRUSIVE_INVARIANT_ASSERT(comp(x, upper_key)); + x = NodeTraits::get_right(x); + } + //If the upper_key is less than x, the target + //range is on the left part + else if(comp(upper_key, x)){ + //y > upper_key + y = x; + x = NodeTraits::get_left(x); + } + else{ + //x is inside the bounded range( x >= lower_key && x <= upper_key), + //so we must split lower and upper searches + // + //Sanity check: if lower_key and upper_key are equal, then both left_closed and right_closed can't be false + BOOST_INTRUSIVE_INVARIANT_ASSERT(left_closed || right_closed || comp(lower_key, x) || comp(x, upper_key)); + return std::pair( + left_closed + //If left_closed, then comp(x, lower_key) is already the lower_bound + //condition so we save one comparison and go to the next level + //following traditional lower_bound algo + ? lower_bound_loop(NodeTraits::get_left(x), x, lower_key, comp) + //If left-open, comp(x, lower_key) is not the upper_bound algo + //condition so we must recheck current 'x' node with upper_bound algo + : upper_bound_loop(x, y, lower_key, comp) + , + right_closed + //If right_closed, then comp(upper_key, x) is already the upper_bound + //condition so we can save one comparison and go to the next level + //following lower_bound algo + ? upper_bound_loop(NodeTraits::get_right(x), y, upper_key, comp) + //If right-open, comp(upper_key, x) is not the lower_bound algo + //condition so we must recheck current 'x' node with lower_bound algo + : lower_bound_loop(x, y, upper_key, comp) + ); + } + } + return std::pair (y, y); + } + //! 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 @@ -769,7 +845,7 @@ class tree_algorithms //! Effects: Returns an a pair of node_ptr delimiting a range containing //! all elements that are equivalent to "key" according to "comp" or an //! empty range that indicates the position where those elements would be - //! if they there are no equivalent elements. + //! if there are no equivalent elements. //! //! Complexity: Logarithmic. //! @@ -778,45 +854,7 @@ class tree_algorithms static std::pair equal_range (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { - node_ptr y = uncast(header); - node_ptr x = NodeTraits::get_parent(header); - - while(x){ - if(comp(x, key)){ - x = NodeTraits::get_right(x); - } - else if(comp(key, x)){ - y = x; - x = NodeTraits::get_left(x); - } - else{ - node_ptr xu(x), yu(y); - y = x, x = NodeTraits::get_left(x); - xu = NodeTraits::get_right(xu); - - while(x){ - if(comp(x, key)){ - x = NodeTraits::get_right(x); - } - else { - y = x; - x = NodeTraits::get_left(x); - } - } - - while(xu){ - if(comp(key, xu)){ - yu = xu; - xu = NodeTraits::get_left(xu); - } - else { - xu = NodeTraits::get_right(xu); - } - } - return std::pair (y, yu); - } - } - return std::pair (y, y); + return bounded_range(header, key, key, comp, true, true); } //! Requires: "header" must be the header node of a tree. @@ -835,18 +873,7 @@ class tree_algorithms static node_ptr lower_bound (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { - node_ptr y = uncast(header); - node_ptr x = NodeTraits::get_parent(header); - while(x){ - if(comp(x, key)){ - x = NodeTraits::get_right(x); - } - else { - y = x; - x = NodeTraits::get_left(x); - } - } - return y; + return lower_bound_loop(NodeTraits::get_parent(header), uncast(header), key, comp); } //! Requires: "header" must be the header node of a tree. @@ -864,18 +891,7 @@ class tree_algorithms static node_ptr upper_bound (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { - node_ptr y = uncast(header); - node_ptr x = NodeTraits::get_parent(header); - while(x){ - if(comp(key, x)){ - y = x; - x = NodeTraits::get_left(x); - } - else { - x = NodeTraits::get_right(x); - } - } - return y; + return upper_bound_loop(NodeTraits::get_parent(header), uncast(header), key, comp); } //! Requires: "header" must be the header node of a tree. @@ -1596,6 +1612,40 @@ class tree_algorithms } private: + + template + static node_ptr lower_bound_loop + (node_ptr x, node_ptr y, const KeyType &key, KeyNodePtrCompare comp) + { + while(x){ + if(comp(x, key)){ + x = NodeTraits::get_right(x); + } + else{ + y = x; + x = NodeTraits::get_left(x); + } + } + return y; + } + + template + static node_ptr upper_bound_loop + (node_ptr x, node_ptr y, const KeyType &key, KeyNodePtrCompare comp) + { + while(x){ + if(comp(key, x)){ + y = x; + x = NodeTraits::get_left(x); + } + else{ + x = NodeTraits::get_right(x); + } + } + return y; + } + + template static void insert_equal_check_impl (bool upper, const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0) diff --git a/include/boost/intrusive/detail/utilities.hpp b/include/boost/intrusive/detail/utilities.hpp index 661ee61..c6bc798 100644 --- a/include/boost/intrusive/detail/utilities.hpp +++ b/include/boost/intrusive/detail/utilities.hpp @@ -529,7 +529,7 @@ inline float fast_log2 (float val) x += 127 << 23; caster.x = x; val = caster.val; - val = ((-1.0f/3) * val + 2) * val - 2.0f/3; + val = ((-1.0f/3.f) * val + 2.f) * val - (2.0f/3.f); return (val + log_2); } diff --git a/include/boost/intrusive/rbtree.hpp b/include/boost/intrusive/rbtree.hpp index f843231..1c0c30e 100644 --- a/include/boost/intrusive/rbtree.hpp +++ b/include/boost/intrusive/rbtree.hpp @@ -1232,6 +1232,104 @@ class rbtree_impl return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); } + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + 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, priv_comp(), left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::bounded_range + (this->priv_header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed)); + return std::pair(iterator(ret.first, this), iterator(ret.second, this)); + } + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const + { return this->bounded_range(lower_value, upper_value, priv_comp(), left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::bounded_range + (this->priv_header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed)); + return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); + } + //! Requires: Disposer::operator()(pointer) shouldn't throw. //! Cloner should yield to nodes equivalent to the original nodes. //! diff --git a/include/boost/intrusive/rbtree_algorithms.hpp b/include/boost/intrusive/rbtree_algorithms.hpp index d31e2bb..451a550 100644 --- a/include/boost/intrusive/rbtree_algorithms.hpp +++ b/include/boost/intrusive/rbtree_algorithms.hpp @@ -518,6 +518,31 @@ class rbtree_algorithms (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { return tree_algorithms::equal_range(header, key, comp); } + //! 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. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + static std::pair bounded_range + (const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp + , bool left_closed, bool right_closed) + { return tree_algorithms::bounded_range(header, lower_key, upper_key, comp, left_closed, right_closed); } + //! Requires: "h" must be the header node of a tree. //! NodePtrCompare 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 145b263..9a61560 100644 --- a/include/boost/intrusive/set.hpp +++ b/include/boost/intrusive/set.hpp @@ -976,6 +976,91 @@ class set_impl equal_range(const KeyType& key, KeyValueCompare comp) const { return tree_.equal_range(key, comp); } + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair + bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair + bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + //! Requires: value must be an lvalue and shall be in a set of //! appropriate type. Otherwise the behavior is undefined. //! @@ -2096,6 +2181,91 @@ class multiset_impl equal_range(const KeyType& key, KeyValueCompare comp) const { return tree_.equal_range(key, comp); } + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair + bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair + bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + //! Requires: value must be an lvalue and shall be in a set of //! appropriate type. Otherwise the behavior is undefined. //! diff --git a/include/boost/intrusive/sg_set.hpp b/include/boost/intrusive/sg_set.hpp index 81c1db2..9b020cc 100644 --- a/include/boost/intrusive/sg_set.hpp +++ b/include/boost/intrusive/sg_set.hpp @@ -967,6 +967,91 @@ class sg_set_impl equal_range(const KeyType& key, KeyValueCompare comp) const { return tree_.equal_range(key, comp); } + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair + bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair + bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + //! Requires: value must be an lvalue and shall be in a sg_set of //! appropriate type. Otherwise the behavior is undefined. //! @@ -2119,6 +2204,91 @@ class sg_multiset_impl equal_range(const KeyType& key, KeyValueCompare comp) const { return tree_.equal_range(key, comp); } + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair + bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair + bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + //! Requires: value must be an lvalue and shall be in a sg_multiset of //! appropriate type. Otherwise the behavior is undefined. //! diff --git a/include/boost/intrusive/sgtree.hpp b/include/boost/intrusive/sgtree.hpp index 7854af9..f181f54 100644 --- a/include/boost/intrusive/sgtree.hpp +++ b/include/boost/intrusive/sgtree.hpp @@ -48,7 +48,7 @@ namespace intrusive { namespace detail{ -//! Returns floor(log(n)/log(sqrt(2))) -> floor(2*log2(n)) +//! Returns floor(log2(n)/log2(sqrt(2))) -> floor(2*log2(n)) //! Undefined if N is 0. //! //! This function does not use float point operations. @@ -83,9 +83,9 @@ struct h_alpha_t std::size_t operator()(std::size_t n) const { - //Returns floor(log1/alpha(n)) -> - // floor(log(n)/log(1/alpha)) -> - // floor(log(n)/(-log(alpha))) + //Returns floor(log2(1/alpha(n))) -> + // floor(log2(n)/log(1/alpha)) -> + // floor(log2(n)/(-log2(alpha))) //return static_cast(std::log(float(n))*inv_minus_logalpha_); return static_cast(detail::fast_log2(float(n))*inv_minus_logalpha_); } @@ -1404,6 +1404,104 @@ class sgtree_impl return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); } + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + 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, priv_comp(), left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::bounded_range + (this->priv_header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed)); + return std::pair(iterator(ret.first, this), iterator(ret.second, this)); + } + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const + { return this->bounded_range(lower_value, upper_value, priv_comp(), left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::bounded_range + (this->priv_header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed)); + return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); + } + //! Requires: Disposer::operator()(pointer) shouldn't throw. //! Cloner should yield to nodes equivalent to the original nodes. //! diff --git a/include/boost/intrusive/sgtree_algorithms.hpp b/include/boost/intrusive/sgtree_algorithms.hpp index afb95ff..bad1c32 100644 --- a/include/boost/intrusive/sgtree_algorithms.hpp +++ b/include/boost/intrusive/sgtree_algorithms.hpp @@ -421,6 +421,31 @@ class sgtree_algorithms (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { return tree_algorithms::equal_range(header, key, comp); } + //! 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. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + static std::pair bounded_range + (const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp + , bool left_closed, bool right_closed) + { return tree_algorithms::bounded_range(header, lower_key, upper_key, comp, left_closed, right_closed); } + //! Requires: "h" must be the header node of a tree. //! NodePtrCompare 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/splay_set.hpp b/include/boost/intrusive/splay_set.hpp index ba6114d..e7f3b94 100644 --- a/include/boost/intrusive/splay_set.hpp +++ b/include/boost/intrusive/splay_set.hpp @@ -934,6 +934,92 @@ class splay_set_impl equal_range_dont_splay(const KeyType& key, KeyValueCompare comp) const { return tree_.equal_range_dont_splay(key, comp); } + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair + bounded_range_dont_splay_dont_splay + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const + { return tree_.bounded_range_dont_splay(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair + bounded_range_dont_splay + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const + { return tree_.bounded_range_dont_splay(lower_key, upper_key, comp, left_closed, right_closed); } + //! Requires: value must be an lvalue and shall be in a splay_set of //! appropriate type. Otherwise the behavior is undefined. //! @@ -2073,6 +2159,92 @@ class splay_multiset_impl equal_range_dont_splay(const KeyType& key, KeyValueCompare comp) const { return tree_.equal_range_dont_splay(key, comp); } + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair + bounded_range_dont_splay + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const + { return tree_.bounded_range_dont_splay(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair + bounded_range_dont_splay + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const + { return tree_.bounded_range_dont_splay(lower_key, upper_key, comp, left_closed, right_closed); } + //! Requires: value must be an lvalue and shall be in a set of //! appropriate type. Otherwise the behavior is undefined. //! diff --git a/include/boost/intrusive/splaytree.hpp b/include/boost/intrusive/splaytree.hpp index 3db32e1..a1c5209 100644 --- a/include/boost/intrusive/splaytree.hpp +++ b/include/boost/intrusive/splaytree.hpp @@ -1169,6 +1169,104 @@ class splaytree_impl return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); } + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + 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, priv_comp(), left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::bounded_range + (this->priv_header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed)); + return std::pair(iterator(ret.first, this), iterator(ret.second, this)); + } + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const + { return this->bounded_range_dont_splay(lower_value, upper_value, priv_comp(), left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::bounded_range + (this->priv_header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed, false)); + return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); + } + //! Requires: Disposer::operator()(pointer) shouldn't throw. //! Cloner should yield to nodes equivalent to the original nodes. //! diff --git a/include/boost/intrusive/splaytree_algorithms.hpp b/include/boost/intrusive/splaytree_algorithms.hpp index 79baa1f..8155648 100644 --- a/include/boost/intrusive/splaytree_algorithms.hpp +++ b/include/boost/intrusive/splaytree_algorithms.hpp @@ -15,7 +15,7 @@ // The code has been modified and (supposely) improved by Ion Gaztanaga. // Here is the header of the file used as base code: // -// splay_tree.h -- implementation of a STL complatible splay tree. +// splay_tree.h -- implementation of a STL compatible splay tree. // // Copyright (c) 2004 Ralf Mattethat // @@ -473,6 +473,38 @@ class splaytree_algorithms return ret; } + //! 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. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + static std::pair bounded_range + (const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp + , bool left_closed, bool right_closed, bool splay = true) + { + std::pair ret = + tree_algorithms::bounded_range(header, lower_key, upper_key, comp, left_closed, right_closed); + + if(splay) + splay_up(ret.first, uncast(header)); + return ret; + } + //! 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 @@ -772,10 +804,11 @@ class splaytree_algorithms node_ptr leftmost (NodeTraits::get_left(header)); node_ptr rightmost(NodeTraits::get_right(header)); { + //Anti-exception rollback, recovers the original header node if an exception is thrown. detail::splaydown_rollback rollback(&t, header, leftmost, rightmost); - node_ptr null = header; - node_ptr l = null; - node_ptr r = null; + node_ptr null_node = header; + node_ptr l = null_node; + node_ptr r = null_node; for( ;; ){ if(comp(key, t)){ @@ -827,10 +860,12 @@ class splaytree_algorithms } } - assemble(t, l, r, null); + assemble(t, l, r, null_node); rollback.release(); } + //Now recover the original header except for the + //splayed root node. //t is the current root NodeTraits::set_parent(header, t); NodeTraits::set_parent(t, header); diff --git a/include/boost/intrusive/treap.hpp b/include/boost/intrusive/treap.hpp index 722f938..b539acc 100644 --- a/include/boost/intrusive/treap.hpp +++ b/include/boost/intrusive/treap.hpp @@ -1339,6 +1339,104 @@ class treap_impl return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); } + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + 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, priv_comp(), left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::bounded_range + (this->priv_header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed)); + return std::pair(iterator(ret.first, this), iterator(ret.second, this)); + } + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const + { return this->bounded_range(lower_value, upper_value, priv_comp(), left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const + { + detail::key_nodeptr_comp + key_node_comp(comp, this); + std::pair ret + (node_algorithms::bounded_range + (this->priv_header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed)); + return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this)); + } + //! Requires: Disposer::operator()(pointer) shouldn't throw. //! Cloner should yield to nodes equivalent to the original nodes. //! diff --git a/include/boost/intrusive/treap_algorithms.hpp b/include/boost/intrusive/treap_algorithms.hpp index 92958e8..967e731 100644 --- a/include/boost/intrusive/treap_algorithms.hpp +++ b/include/boost/intrusive/treap_algorithms.hpp @@ -499,6 +499,31 @@ class treap_algorithms (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp) { return tree_algorithms::equal_range(header, key, comp); } + //! 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. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + static std::pair bounded_range + (const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp + , bool left_closed, bool right_closed) + { return tree_algorithms::bounded_range(header, lower_key, upper_key, comp, left_closed, right_closed); } + //! Requires: "h" must be the header node of a tree. //! NodePtrCompare 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/treap_set.hpp b/include/boost/intrusive/treap_set.hpp index 02a3353..66adfaf 100644 --- a/include/boost/intrusive/treap_set.hpp +++ b/include/boost/intrusive/treap_set.hpp @@ -1043,6 +1043,91 @@ class treap_set_impl equal_range(const KeyType& key, KeyValueCompare comp) const { return tree_.equal_range(key, comp); } + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair + bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair + bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + //! Requires: value must be an lvalue and shall be in a treap_set of //! appropriate type. Otherwise the behavior is undefined. //! @@ -2265,6 +2350,91 @@ class treap_multiset_impl equal_range(const KeyType& key, KeyValueCompare comp) const { return tree_.equal_range(key, comp); } + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair bounded_range + (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + + //! Requires: 'lower_value' must not be greater than 'upper_value'. If + //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise + //! + //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If the predicate throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_value and upper_value. + std::pair + bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const + { return tree_.bounded_range(lower_value, upper_value, left_closed, right_closed); } + + //! Requires: KeyValueCompare is a function object that induces a strict weak + //! ordering compatible with the strict weak ordering used to create the + //! the tree. + //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If + //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false. + //! + //! Effects: Returns an a pair with the following criteria: + //! + //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise + //! + //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise + //! + //! Complexity: Logarithmic. + //! + //! Throws: If "comp" throws. + //! + //! Note: This function can be more efficient than calling upper_bound + //! and lower_bound for lower_key and upper_key. + template + std::pair + bounded_range + (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const + { return tree_.bounded_range(lower_key, upper_key, comp, left_closed, right_closed); } + //! Requires: value must be an lvalue and shall be in a treap_multiset of //! appropriate type. Otherwise the behavior is undefined. //!