diff --git a/doc/intrusive.qbk b/doc/intrusive.qbk index 8f22132..cec74b5 100644 --- a/doc/intrusive.qbk +++ b/doc/intrusive.qbk @@ -1096,7 +1096,7 @@ And they also can receive an additional option: * [*`compare`]: Comparison function for the objects to be inserted in containers. The comparison functor must induce a strict weak ordering. - Default: `compare< std::less >` + Default: `compare< std::less >` * [*`key_of_value`]: A function object that will define the `key_type` of the value type to be stored. This type will allow a map-like interface. See @@ -1512,7 +1512,7 @@ And they also can receive an additional option: * [*`compare`]: Comparison function for the objects to be inserted in containers. The comparison functor must induce a strict weak ordering. - Default: `compare< std::less >` + Default: `compare< std::less >` * [*`key_of_value`]: A function object that will define the `key_type` of the value type to be stored. This type will allow a map-like interface. See @@ -1614,7 +1614,7 @@ And they also can receive an additional option: * [*`compare`]: Comparison function for the objects to be inserted in containers. The comparison functor must induce a strict weak ordering. - Default: `compare< std::less >` + Default: `compare< std::less >` * [*`key_of_value`]: A function object that will define the `key_type` of the value type to be stored. This type will allow a map-like interface. See @@ -1725,7 +1725,7 @@ And they also can receive additional options: * [*`compare`]: Comparison function for the objects to be inserted in containers. The comparison functor must induce a strict weak ordering. - Default: `compare< std::less >` + Default: `compare< std::less >` * [*`floating_point`]: When this option is deactivated, the scapegoat tree loses the ability to change @@ -1828,11 +1828,11 @@ And they also can receive additional options: * [*`compare`]: Comparison function for the objects to be inserted in containers. The comparison functor must induce a strict weak ordering. - Default: `compare< std::less >` + Default: `compare< std::less >` * [*`priority`]: Priority Comparison function for the objects to be inserted in containers. The comparison functor must induce a strict weak ordering. - Default: `priority< priority_compare >` + Default: `priority< priority_compare >` * [*`key_of_value`]: A function object that will define the `key_type` of the value type to be stored. This type will allow a map-like interface. See @@ -3840,6 +3840,7 @@ to be inserted in intrusive containers are allocated using `std::vector` or `std * Fixed bugs: * [@https://svn.boost.org/trac/boost/ticket/11832 Boost Trac #11832: ['clang-cl + boost intrusive = miscompile]] * [@https://svn.boost.org/trac/boost/ticket/11865 Boost Trac #11865: ['Intrusive list explicit ctor error with Clang 3.6 (C++11/14)]] + * [@https://svn.boost.org/trac/boost/ticket/11992 Boost Trac #11992: ['Add an overload of insert_check taking a key_type]] * [@https://github.com/boostorg/intrusive/pull/19 GitHub Pull #19: ['ebo_functor_holder: compile fix for copy constructor]] [endsect] diff --git a/include/boost/intrusive/avl_set.hpp b/include/boost/intrusive/avl_set.hpp index 8f7139a..2c96204 100644 --- a/include/boost/intrusive/avl_set.hpp +++ b/include/boost/intrusive/avl_set.hpp @@ -200,6 +200,17 @@ class avl_set_impl iterator insert(const_iterator hint, reference value) { return tree_type::insert_unique(hint, value); } + //! @copydoc ::boost::intrusive::avltree::insert_unique_check(const key_type&,insert_commit_data&) + std::pair insert_check + (const key_type &key, insert_commit_data &commit_data) + { return tree_type::insert_unique_check(key, commit_data); } + + //! @copydoc ::boost::intrusive::avltree::insert_unique_check(const_iterator,const key_type&,insert_commit_data&) + std::pair insert_check + (const_iterator hint, const key_type &key + ,insert_commit_data &commit_data) + { return tree_type::insert_unique_check(hint, key, commit_data); } + //! @copydoc ::boost::intrusive::avltree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&) template std::pair insert_check @@ -325,21 +336,21 @@ class avl_set_impl #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &) + //! @copydoc ::boost::intrusive::avltree::equal_range(const key_type &) std::pair equal_range(const key_type &key) { return this->tree_type::lower_bound_range(key); } - //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare) + //! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyTypeKeyCompare) template std::pair equal_range(const KeyType& key, KeyTypeKeyCompare comp) { return this->tree_type::equal_range(key, comp); } - //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)const + //! @copydoc ::boost::intrusive::avltree::equal_range(const key_type &)const std::pair equal_range(const key_type &key) const { return this->tree_type::lower_bound_range(key); } - //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)const + //! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyTypeKeyCompare)const template std::pair equal_range(const KeyType& key, KeyTypeKeyCompare comp) const diff --git a/include/boost/intrusive/avltree.hpp b/include/boost/intrusive/avltree.hpp index 37e3859..741d482 100644 --- a/include/boost/intrusive/avltree.hpp +++ b/include/boost/intrusive/avltree.hpp @@ -260,6 +260,14 @@ class avltree_impl (const_iterator hint, const KeyType &key ,KeyTypeKeyCompare comp, insert_commit_data &commit_data); + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const key_type&,insert_commit_data&) + std::pair insert_unique_check + (const key_type &key, insert_commit_data &commit_data); + + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const key_type&,insert_commit_data&) + std::pair insert_unique_check + (const_iterator hint, const key_type &key, insert_commit_data &commit_data); + //! @copydoc ::boost::intrusive::bstree::insert_unique_commit iterator insert_unique_commit(reference value, const insert_commit_data &commit_data); diff --git a/include/boost/intrusive/bs_set.hpp b/include/boost/intrusive/bs_set.hpp index 798ffa6..60f18a1 100644 --- a/include/boost/intrusive/bs_set.hpp +++ b/include/boost/intrusive/bs_set.hpp @@ -197,6 +197,17 @@ class bs_set_impl iterator insert(const_iterator hint, reference value) { return tree_type::insert_unique(hint, value); } + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const key_type&,insert_commit_data&) + std::pair insert_check + (const key_type &key, insert_commit_data &commit_data) + { return tree_type::insert_unique_check(key, commit_data); } + + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const key_type&,insert_commit_data&) + std::pair insert_check + (const_iterator hint, const key_type &key + ,insert_commit_data &commit_data) + { return tree_type::insert_unique_check(hint, key, commit_data); } + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&) template std::pair insert_check diff --git a/include/boost/intrusive/bstree.hpp b/include/boost/intrusive/bstree.hpp index 147d7e6..0fb9218 100644 --- a/include/boost/intrusive/bstree.hpp +++ b/include/boost/intrusive/bstree.hpp @@ -476,8 +476,20 @@ struct bstbase2 } //insert_unique_check - template std::pair insert_unique_check + (const key_type &key, insert_commit_data &commit_data) + { return this->insert_unique_check(key, this->key_comp(), commit_data); } + + std::pair insert_unique_check + (const_iterator hint, const key_type &key, insert_commit_data &commit_data) + { return this->insert_unique_check(hint, key, this->key_comp(), commit_data); } + + template + BOOST_INTRUSIVE_DOC1ST(std::pair + , typename detail::disable_if_convertible + >::type) + insert_unique_check (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data) { std::pair ret = @@ -488,8 +500,7 @@ struct bstbase2 template std::pair insert_unique_check - (const_iterator hint, const KeyType &key - ,KeyTypeKeyCompare comp, insert_commit_data &commit_data) + (const_iterator hint, const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data) { std::pair ret = (node_algorithms::insert_unique_check diff --git a/include/boost/intrusive/hashtable.hpp b/include/boost/intrusive/hashtable.hpp index 125330f..f9074c0 100644 --- a/include/boost/intrusive/hashtable.hpp +++ b/include/boost/intrusive/hashtable.hpp @@ -2057,8 +2057,7 @@ class hashtable_impl std::pair insert_unique(reference value) { insert_commit_data commit_data; - std::pair ret = this->insert_unique_check - (key_of_value()(value), this->priv_hasher(), this->priv_equal(), commit_data); + std::pair ret = this->insert_unique_check(key_of_value()(value), commit_data); if(ret.second){ ret.first = this->insert_unique_commit(value, commit_data); } @@ -2134,6 +2133,37 @@ class hashtable_impl , pos == this->priv_invalid_local_it()); } + //! Effects: Checks if a value can be inserted in the unordered_set, using + //! a user provided key instead of the value itself. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Average case O(1), worst case O(this->size()). + //! + //! Throws: If hasher or key_compare throw. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the hash or the equality is much cheaper to + //! construct than the value_type and this function offers the possibility to + //! use that the part to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the unordered_set. + //! + //! After a successful rehashing insert_commit_data remains valid. + std::pair insert_unique_check + ( const key_type &key, insert_commit_data &commit_data) + { return this->insert_unique_check(key, this->priv_hasher(), this->priv_equal(), commit_data); } + //! Requires: value must be an lvalue of type value_type. commit_data //! must have been obtained from a previous call to "insert_check". //! No objects should have been inserted or erased from the unordered_set between diff --git a/include/boost/intrusive/priority_compare.hpp b/include/boost/intrusive/priority_compare.hpp index 0cadd45..ffade48 100644 --- a/include/boost/intrusive/priority_compare.hpp +++ b/include/boost/intrusive/priority_compare.hpp @@ -42,10 +42,10 @@ struct priority_compare /// @cond -template +template struct get_prio { - typedef Less type; + typedef PrioComp type; }; diff --git a/include/boost/intrusive/rbtree.hpp b/include/boost/intrusive/rbtree.hpp index 0bcb9cf..276362d 100644 --- a/include/boost/intrusive/rbtree.hpp +++ b/include/boost/intrusive/rbtree.hpp @@ -263,6 +263,14 @@ class rbtree_impl (const_iterator hint, const KeyType &key ,KeyTypeKeyCompare comp, insert_commit_data &commit_data); + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const key_type&,insert_commit_data&) + std::pair insert_unique_check + (const key_type &key, insert_commit_data &commit_data); + + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const key_type&,insert_commit_data&) + std::pair insert_unique_check + (const_iterator hint, const key_type &key, insert_commit_data &commit_data); + //! @copydoc ::boost::intrusive::bstree::insert_unique_commit iterator insert_unique_commit(reference value, const insert_commit_data &commit_data); diff --git a/include/boost/intrusive/set.hpp b/include/boost/intrusive/set.hpp index a7d2b70..36c46c7 100644 --- a/include/boost/intrusive/set.hpp +++ b/include/boost/intrusive/set.hpp @@ -200,6 +200,17 @@ class set_impl iterator insert(const_iterator hint, reference value) { return tree_type::insert_unique(hint, value); } + //! @copydoc ::boost::intrusive::rbtree::insert_unique_check(const key_type&,insert_commit_data&) + std::pair insert_check + (const key_type &key, insert_commit_data &commit_data) + { return tree_type::insert_unique_check(key, commit_data); } + + //! @copydoc ::boost::intrusive::rbtree::insert_unique_check(const_iterator,const key_type&,insert_commit_data&) + std::pair insert_check + (const_iterator hint, const key_type &key + ,insert_commit_data &commit_data) + { return tree_type::insert_unique_check(hint, key, commit_data); } + //! @copydoc ::boost::intrusive::rbtree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&) template std::pair insert_check diff --git a/include/boost/intrusive/sg_set.hpp b/include/boost/intrusive/sg_set.hpp index c5aca1e..171bd59 100644 --- a/include/boost/intrusive/sg_set.hpp +++ b/include/boost/intrusive/sg_set.hpp @@ -198,6 +198,17 @@ class sg_set_impl iterator insert(const_iterator hint, reference value) { return tree_type::insert_unique(hint, value); } + //! @copydoc ::boost::intrusive::sgtree::insert_unique_check(const key_type&,insert_commit_data&) + std::pair insert_check + (const key_type &key, insert_commit_data &commit_data) + { return tree_type::insert_unique_check(key, commit_data); } + + //! @copydoc ::boost::intrusive::sgtree::insert_unique_check(const_iterator,const key_type&,insert_commit_data&) + std::pair insert_check + (const_iterator hint, const key_type &key + ,insert_commit_data &commit_data) + { return tree_type::insert_unique_check(hint, key, commit_data); } + //! @copydoc ::boost::intrusive::sgtree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&) template std::pair insert_check @@ -323,21 +334,21 @@ class sg_set_impl #endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED - //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &) + //! @copydoc ::boost::intrusive::sgtree::equal_range(const key_type &) std::pair equal_range(const key_type &key) { return this->tree_type::lower_bound_range(key); } - //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare) + //! @copydoc ::boost::intrusive::sgtree::equal_range(const KeyType&,KeyTypeKeyCompare) template std::pair equal_range(const KeyType& key, KeyTypeKeyCompare comp) { return this->tree_type::equal_range(key, comp); } - //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)const + //! @copydoc ::boost::intrusive::sgtree::equal_range(const key_type &)const std::pair equal_range(const key_type &key) const { return this->tree_type::lower_bound_range(key); } - //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)const + //! @copydoc ::boost::intrusive::sgtree::equal_range(const KeyType&,KeyTypeKeyCompare)const template std::pair equal_range(const KeyType& key, KeyTypeKeyCompare comp) const diff --git a/include/boost/intrusive/sgtree.hpp b/include/boost/intrusive/sgtree.hpp index 678a421..6e7af7d 100644 --- a/include/boost/intrusive/sgtree.hpp +++ b/include/boost/intrusive/sgtree.hpp @@ -490,7 +490,11 @@ class sgtree_impl //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&) template - std::pair insert_unique_check + BOOST_INTRUSIVE_DOC1ST(std::pair + , typename detail::disable_if_convertible + >::type) + insert_unique_check (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data) { std::pair ret = @@ -511,6 +515,16 @@ class sgtree_impl return std::pair(iterator(ret.first, this->priv_value_traits_ptr()), ret.second); } + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const key_type&,insert_commit_data&) + std::pair insert_unique_check + (const key_type &key, insert_commit_data &commit_data) + { return this->insert_unique_check(key, this->key_comp(), commit_data); } + + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const key_type&,insert_commit_data&) + std::pair insert_unique_check + (const_iterator hint, const key_type &key, insert_commit_data &commit_data) + { return this->insert_unique_check(hint, key, this->key_comp(), commit_data); } + //! @copydoc ::boost::intrusive::bstree::insert_unique_commit iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) { diff --git a/include/boost/intrusive/splay_set.hpp b/include/boost/intrusive/splay_set.hpp index ee2467d..893b580 100644 --- a/include/boost/intrusive/splay_set.hpp +++ b/include/boost/intrusive/splay_set.hpp @@ -198,6 +198,17 @@ class splay_set_impl iterator insert(const_iterator hint, reference value) { return tree_type::insert_unique(hint, value); } + //! @copydoc ::boost::intrusive::rbtree::insert_unique_check(const key_type&,insert_commit_data&) + std::pair insert_check + (const key_type &key, insert_commit_data &commit_data) + { return tree_type::insert_unique_check(key, commit_data); } + + //! @copydoc ::boost::intrusive::rbtree::insert_unique_check(const_iterator,const key_type&,insert_commit_data&) + std::pair insert_check + (const_iterator hint, const key_type &key + ,insert_commit_data &commit_data) + { return tree_type::insert_unique_check(hint, key, commit_data); } + //! @copydoc ::boost::intrusive::splaytree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&) template std::pair insert_check diff --git a/include/boost/intrusive/splaytree.hpp b/include/boost/intrusive/splaytree.hpp index 33ef2b1..afc1081 100644 --- a/include/boost/intrusive/splaytree.hpp +++ b/include/boost/intrusive/splaytree.hpp @@ -244,6 +244,14 @@ class splaytree_impl //! @copydoc ::boost::intrusive::bstree::insert_unique(const_iterator,reference) iterator insert_unique(const_iterator hint, reference value); + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const key_type&,insert_commit_data&) + std::pair insert_unique_check + (const key_type &key, insert_commit_data &commit_data); + + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const key_type&,insert_commit_data&) + std::pair insert_unique_check + (const_iterator hint, const key_type &key, insert_commit_data &commit_data); + //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&) template std::pair insert_unique_check diff --git a/include/boost/intrusive/treap.hpp b/include/boost/intrusive/treap.hpp index f9d2e73..3852719 100644 --- a/include/boost/intrusive/treap.hpp +++ b/include/boost/intrusive/treap.hpp @@ -80,7 +80,7 @@ class treap_impl < typename get_prio < VoidOrPrioComp , typename bstree_impl - ::value_type>::type + ::key_type>::type > /// @endcond { @@ -93,7 +93,7 @@ class treap_impl typedef tree_type implementation_defined; typedef get_prio < VoidOrPrioComp - , typename tree_type::value_type> get_prio_type; + , typename tree_type::key_type> get_prio_type; typedef detail::ebo_functor_holder prio_base; @@ -126,14 +126,11 @@ class treap_impl static const bool stateful_value_traits = implementation_defined::stateful_value_traits; static const bool safemode_or_autounlink = is_safe_autounlink::value; - typedef detail::key_nodeptr_comp value_node_prio_comp_t; + typedef detail::key_nodeptr_comp key_node_prio_comp_t; template - detail::key_nodeptr_comp key_node_prio_comp(KeyPrioComp keypriocomp) const - { return detail::key_nodeptr_comp(keypriocomp, &this->get_value_traits()); } - - value_node_prio_comp_t value_node_prio_comp() const - { return this->key_node_prio_comp(this->priv_pcomp()); } + detail::key_nodeptr_comp key_node_prio_comp(KeyPrioComp keypriocomp) const + { return detail::key_nodeptr_comp(keypriocomp, &this->get_value_traits()); } /// @cond private: @@ -414,7 +411,7 @@ class treap_impl ( this->tree_type::header_ptr() , to_insert , this->key_node_comp(this->key_comp()) - , this->value_node_prio_comp()) + , this->key_node_prio_comp(this->priv_pcomp())) , this->priv_value_traits_ptr()); this->tree_type::sz_traits().increment(); return ret; @@ -444,7 +441,7 @@ class treap_impl , hint.pointed_node() , to_insert , this->key_node_comp(this->key_comp()) - , this->value_node_prio_comp()) + , this->key_node_prio_comp(this->priv_pcomp())) , this->priv_value_traits_ptr()); this->tree_type::sz_traits().increment(); return ret; @@ -489,8 +486,7 @@ class treap_impl std::pair insert_unique(reference value) { insert_commit_data commit_data; - std::pair ret = this->insert_unique_check - (value, this->comp(), this->priv_pcomp(), commit_data); + std::pair ret = this->insert_unique_check(key_of_value()(value), commit_data); if(!ret.second) return ret; return std::pair (this->insert_unique_commit(value, commit_data), true); @@ -514,8 +510,7 @@ class treap_impl iterator insert_unique(const_iterator hint, reference value) { insert_commit_data commit_data; - std::pair ret = this->insert_unique_check - (hint, value, this->comp(), this->priv_pcomp(), commit_data); + std::pair ret = this->insert_unique_check(hint, key_of_value()(value), commit_data); if(!ret.second) return ret.first; return this->insert_unique_commit(value, commit_data); @@ -549,6 +544,68 @@ class treap_impl } } + //! Effects: Checks if a value can be inserted in the container, using + //! a user provided key instead of the value itself. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Average complexity is at most logarithmic. + //! + //! Throws: If the comparison or predicate functions throw. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! node that is used to impose the order is much cheaper to construct + //! than the value_type and this function offers the possibility to use that + //! part to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. This gives a total + //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the container. + std::pair insert_unique_check + ( const key_type &key, insert_commit_data &commit_data) + { return this->insert_unique_check(key, this->key_comp(), this->priv_pcomp(), commit_data); } + + //! Effects: Checks if a value can be inserted in the container, using + //! a user provided key instead of the value itself, using "hint" + //! as a hint to where it will be inserted. + //! + //! Returns: If there is an equivalent value + //! returns a pair containing an iterator to the already present value + //! and false. If the value can be inserted returns true in the returned + //! pair boolean and fills "commit_data" that is meant to be used with + //! the "insert_commit" function. + //! + //! Complexity: Logarithmic in general, but it's amortized + //! constant time if t is inserted immediately before hint. + //! + //! Throws: If the comparison or predicate functions throw. Strong guarantee. + //! + //! Notes: This function is used to improve performance when constructing + //! a value_type is expensive: if there is an equivalent value + //! the constructed object must be discarded. Many times, the part of the + //! constructing that is used to impose the order is much cheaper to construct + //! than the value_type and this function offers the possibility to use that key + //! to check if the insertion will be successful. + //! + //! If the check is successful, the user can construct the value_type and use + //! "insert_commit" to insert the object in constant-time. This can give a total + //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)). + //! + //! "commit_data" remains valid for a subsequent "insert_commit" only if no more + //! objects are inserted or erased from the container. + std::pair insert_unique_check + ( const_iterator hint, const key_type &key, insert_commit_data &commit_data) + { return this->insert_unique_check(hint, key, this->key_comp(), this->priv_pcomp(), commit_data); } + //! Requires: comp must be a comparison function that induces //! the same strict weak ordering as key_compare. //! key_value_pcomp must be a comparison function that induces @@ -583,7 +640,11 @@ class treap_impl //! "commit_data" remains valid for a subsequent "insert_commit" only if no more //! objects are inserted or erased from the container. template - std::pair insert_unique_check + BOOST_INTRUSIVE_DOC1ST(std::pair + , typename detail::disable_if_convertible + >::type) + insert_unique_check ( const KeyType &key, KeyTypeKeyCompare comp , KeyValuePrioCompare key_value_pcomp, insert_commit_data &commit_data) { @@ -689,7 +750,11 @@ class treap_impl BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); iterator ret ( node_algorithms::insert_before - ( this->tree_type::header_ptr(), pos.pointed_node(), to_insert, this->value_node_prio_comp()) + ( this->tree_type::header_ptr() + , pos.pointed_node() + , to_insert + , this->key_node_prio_comp(this->priv_pcomp()) + ) , this->priv_value_traits_ptr()); this->tree_type::sz_traits().increment(); return ret; @@ -713,7 +778,8 @@ class treap_impl { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); - node_algorithms::push_back(this->tree_type::header_ptr(), to_insert, this->value_node_prio_comp()); + node_algorithms::push_back + (this->tree_type::header_ptr(), to_insert, this->key_node_prio_comp(this->priv_pcomp())); this->tree_type::sz_traits().increment(); } @@ -735,7 +801,8 @@ class treap_impl { node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); - node_algorithms::push_front(this->tree_type::header_ptr(), to_insert, this->value_node_prio_comp()); + node_algorithms::push_front + (this->tree_type::header_ptr(), to_insert, this->key_node_prio_comp(this->priv_pcomp())); this->tree_type::sz_traits().increment(); } @@ -753,7 +820,8 @@ class treap_impl ++ret; node_ptr to_erase(i.pointed_node()); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(to_erase)); - node_algorithms::erase(this->tree_type::header_ptr(), to_erase, this->value_node_prio_comp()); + node_algorithms::erase + (this->tree_type::header_ptr(), to_erase, this->key_node_prio_comp(this->priv_pcomp())); this->tree_type::sz_traits().decrement(); if(safemode_or_autounlink) node_algorithms::init(to_erase); @@ -933,8 +1001,10 @@ class treap_impl template void check(ExtraChecker extra_checker) const { + typedef detail::key_nodeptr_comp nodeptr_prio_comp_t; tree_type::check(detail::treap_node_extra_checker - (this->value_node_prio_comp(), extra_checker)); + + (this->key_node_prio_comp(this->priv_pcomp()), extra_checker)); } //! @copydoc ::boost::intrusive::bstree::check()const diff --git a/include/boost/intrusive/treap_set.hpp b/include/boost/intrusive/treap_set.hpp index 4d26831..f97b376 100644 --- a/include/boost/intrusive/treap_set.hpp +++ b/include/boost/intrusive/treap_set.hpp @@ -229,6 +229,15 @@ class treap_set_impl iterator insert(const_iterator hint, reference value) { return tree_type::insert_unique(hint, value); } + //! @copydoc ::boost::intrusive::treap::insert_unique_check(const key_type,insert_commit_data&) + std::pair insert_check( const key_type &key, insert_commit_data &commit_data) + { return tree_type::insert_unique_check(key, commit_data); } + + //! @copydoc ::boost::intrusive::treap::insert_unique_check(const_iterator,const key_type&,insert_commit_data&) + std::pair insert_check + ( const_iterator hint, const key_type &key, insert_commit_data &commit_data) + { return tree_type::insert_unique_check(hint, key, commit_data); } + //! @copydoc ::boost::intrusive::treap::insert_unique_check(const KeyType&,KeyTypeKeyCompare,KeyValuePrioCompare,insert_commit_data&) template std::pair insert_check diff --git a/include/boost/intrusive/unordered_set.hpp b/include/boost/intrusive/unordered_set.hpp index 5148f02..1174dff 100644 --- a/include/boost/intrusive/unordered_set.hpp +++ b/include/boost/intrusive/unordered_set.hpp @@ -208,6 +208,10 @@ class unordered_set_impl void insert(Iterator b, Iterator e) { table_type::insert_unique(b, e); } + //! @copydoc ::boost::intrusive::hashtable::insert_unique_check(const key_type&,insert_commit_data&) + std::pair insert_check(const key_type &key, insert_commit_data &commit_data) + { return table_type::insert_unique_check(key, commit_data); } + //! @copydoc ::boost::intrusive::hashtable::insert_unique_check(const KeyType&,KeyHasher,KeyEqual,insert_commit_data&) template std::pair insert_check diff --git a/test/generic_set_test.hpp b/test/generic_set_test.hpp index 074ac68..1369c27 100644 --- a/test/generic_set_test.hpp +++ b/test/generic_set_test.hpp @@ -191,14 +191,6 @@ struct prio_comp { return this->priority_compare::operator()(k.int_value(), v.int_value()); } }; -template -struct prio_comp - : priority_compare -{ - bool operator()(const ValueType &v1, const ValueType &v2) const - { return this->priority_compare::operator()(v1, v2); } -}; - template void test_generic_set::test_insert_advanced (value_cont_type& values, detail::true_type) @@ -208,14 +200,16 @@ void test_generic_set::test_insert_advanced typedef typename set_type::key_of_value key_of_value; typedef typename set_type::key_type key_type; typedef typename set_type::value_type value_type; - typedef prio_comp prio_comp_t; + typedef priority_compare prio_comp_t; { set_type testset; testset.insert(values.begin(), values.begin() + values.size()); value_type v(1); typename set_type::insert_commit_data data; - BOOST_TEST (!testset.insert_check(key_of_value()(v), testset.key_comp(), prio_comp_t(), data).second); - BOOST_TEST (!testset.insert_check(testset.begin(), key_of_value()(v), testset.key_comp(), prio_comp_t(), data).second); + BOOST_TEST ((!testset.insert_check(key_of_value()(v), testset.key_comp(), prio_comp_t(), data).second)); + BOOST_TEST ((!testset.insert_check(testset.begin(), key_of_value()(v), testset.key_comp(), prio_comp_t(), data).second)); + BOOST_TEST ((!testset.insert_check(key_of_value()(v), data).second)); + BOOST_TEST ((!testset.insert_check(testset.begin(), key_of_value()(v), data).second)); } } @@ -232,8 +226,10 @@ void test_generic_set::test_insert_advanced testset.insert(values.begin(), values.begin() + values.size()); value_type v(1); typename set_type::insert_commit_data data; - BOOST_TEST (!testset.insert_check(key_of_value()(v), testset.key_comp(), data).second); - BOOST_TEST (!testset.insert_check(testset.begin(), key_of_value()(v), testset.key_comp(), data).second); + BOOST_TEST ((!testset.insert_check(key_of_value()(v), testset.key_comp(), data).second)); + BOOST_TEST ((!testset.insert_check(testset.begin(), key_of_value()(v), testset.key_comp(), data).second)); + BOOST_TEST ((!testset.insert_check(key_of_value()(v), data).second)); + BOOST_TEST ((!testset.insert_check(testset.begin(), key_of_value()(v), data).second)); } } diff --git a/test/unordered_test.hpp b/test/unordered_test.hpp index 38d6ddc..246b716 100644 --- a/test/unordered_test.hpp +++ b/test/unordered_test.hpp @@ -78,14 +78,14 @@ void test_unordered:: test::test_maybe_unique_container(testset, values, select_t()); } { - value_cont_type values(BucketSize); + value_cont_type vals(BucketSize); for (int i = 0; i < (int)BucketSize; ++i) - (&values[i])->value_ = i; + (&vals[i])->value_ = i; typename unordered_type::bucket_type buckets [BucketSize]; unordered_type testset(bucket_traits( pointer_traits:: pointer_to(buckets[0]), BucketSize)); - testset.insert(values.begin(), values.end()); + testset.insert(vals.begin(), vals.end()); test::test_iterator_forward(testset); } test_sort(values); @@ -162,6 +162,7 @@ void test_unordered typedef typename ContainerDefiner::template container <>::type unordered_set_type; typedef typename unordered_set_type::bucket_traits bucket_traits; + typedef typename unordered_set_type::key_of_value key_of_value; typename unordered_set_type::bucket_type buckets [BucketSize]; unordered_set_type testset(bucket_traits( @@ -169,6 +170,10 @@ void test_unordered pointer_to(buckets[0]), BucketSize)); testset.insert(&values[0] + 2, &values[0] + 5); + typename unordered_set_type::insert_commit_data commit_data; + BOOST_TEST ((!testset.insert_check(key_of_value()(values[2]), commit_data).second)); + BOOST_TEST (( testset.insert_check(key_of_value()(values[0]), commit_data).second)); + const unordered_set_type& const_testset = testset; if(unordered_set_type::incremental) {