Fixes Boost Trac #11992: "Add an overload of insert_check taking a key_type"

This commit is contained in:
Ion Gaztañaga
2016-03-01 21:22:28 +01:00
parent 2548ae30e1
commit 4cf38987a8
18 changed files with 277 additions and 58 deletions

View File

@@ -1096,7 +1096,7 @@ And they also can receive an additional option:
* [*`compare<class Compare>`]: Comparison function for the objects to be inserted
in containers. The comparison functor must induce a strict weak ordering.
Default: `compare< std::less<T> >`
Default: `compare< std::less<key_type> >`
* [*`key_of_value<class KeyOfValueFunctionObject>`]: 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<class Compare>`]: Comparison function for the objects to be inserted
in containers. The comparison functor must induce a strict weak ordering.
Default: `compare< std::less<T> >`
Default: `compare< std::less<key_type> >`
* [*`key_of_value<class KeyOfValueFunctionObject>`]: 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<class Compare>`]: Comparison function for the objects to be inserted
in containers. The comparison functor must induce a strict weak ordering.
Default: `compare< std::less<T> >`
Default: `compare< std::less<key_type> >`
* [*`key_of_value<class KeyOfValueFunctionObject>`]: 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<class Compare>`]: Comparison function for the objects to be inserted
in containers. The comparison functor must induce a strict weak ordering.
Default: `compare< std::less<T> >`
Default: `compare< std::less<key_type> >`
* [*`floating_point<bool Enable>`]:
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<class Compare>`]: Comparison function for the objects to be inserted
in containers. The comparison functor must induce a strict weak ordering.
Default: `compare< std::less<T> >`
Default: `compare< std::less<key_type> >`
* [*`priority<class PriorityCompare>`]: Priority Comparison function for the objects to be inserted
in containers. The comparison functor must induce a strict weak ordering.
Default: `priority< priority_compare<T> >`
Default: `priority< priority_compare<key_type> >`
* [*`key_of_value<class KeyOfValueFunctionObject>`]: 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]

View File

@@ -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<iterator, bool> 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<iterator, bool> 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<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> 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<iterator,iterator> 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<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> 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<const_iterator, const_iterator>
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<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
equal_range(const KeyType& key, KeyTypeKeyCompare comp) const

View File

@@ -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<iterator, bool> 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<iterator, bool> 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);

View File

@@ -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<iterator, bool> 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<iterator, bool> 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<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check

View File

@@ -476,8 +476,20 @@ struct bstbase2
}
//insert_unique_check
template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> 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<iterator, bool> 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<class KeyType, class KeyTypeKeyCompare>
BOOST_INTRUSIVE_DOC1ST(std::pair<iterator BOOST_INTRUSIVE_I bool>
, typename detail::disable_if_convertible
<KeyType BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I
std::pair<iterator BOOST_INTRUSIVE_I bool> >::type)
insert_unique_check
(const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
{
std::pair<node_ptr, bool> ret =
@@ -488,8 +500,7 @@ struct bstbase2
template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> 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<node_ptr, bool> ret =
(node_algorithms::insert_unique_check

View File

@@ -2057,8 +2057,7 @@ class hashtable_impl
std::pair<iterator, bool> insert_unique(reference value)
{
insert_commit_data commit_data;
std::pair<iterator, bool> ret = this->insert_unique_check
(key_of_value()(value), this->priv_hasher(), this->priv_equal(), commit_data);
std::pair<iterator, bool> 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());
}
//! <b>Effects</b>: Checks if a value can be inserted in the unordered_set, using
//! a user provided key instead of the value itself.
//!
//! <b>Returns</b>: 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.
//!
//! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
//!
//! <b>Throws</b>: If hasher or key_compare throw. Strong guarantee.
//!
//! <b>Notes</b>: 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<iterator, bool> 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); }
//! <b>Requires</b>: 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

View File

@@ -42,10 +42,10 @@ struct priority_compare
/// @cond
template<class Less, class T>
template<class PrioComp, class T>
struct get_prio
{
typedef Less type;
typedef PrioComp type;
};

View File

@@ -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<iterator, bool> 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<iterator, bool> 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);

View File

@@ -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<iterator, bool> 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<iterator, bool> 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<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check

View File

@@ -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<iterator, bool> 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<iterator, bool> 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<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> 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<iterator,iterator> 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<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> 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<const_iterator, const_iterator>
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<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
equal_range(const KeyType& key, KeyTypeKeyCompare comp) const

View File

@@ -490,7 +490,11 @@ class sgtree_impl
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
BOOST_INTRUSIVE_DOC1ST(std::pair<iterator BOOST_INTRUSIVE_I bool>
, typename detail::disable_if_convertible
<KeyType BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I
std::pair<iterator BOOST_INTRUSIVE_I bool> >::type)
insert_unique_check
(const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
{
std::pair<node_ptr, bool> ret =
@@ -511,6 +515,16 @@ class sgtree_impl
return std::pair<iterator, bool>(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<iterator, bool> 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<iterator, bool> 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)
{

View File

@@ -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<iterator, bool> 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<iterator, bool> 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<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check

View File

@@ -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<iterator, bool> 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<iterator, bool> 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<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check

View File

@@ -80,7 +80,7 @@ class treap_impl
< typename get_prio
< VoidOrPrioComp
, typename bstree_impl
<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>::value_type>::type
<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>::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
<typename get_prio_type::type> 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_traits::link_mode>::value;
typedef detail::key_nodeptr_comp<priority_compare, value_traits> value_node_prio_comp_t;
typedef detail::key_nodeptr_comp<priority_compare, value_traits, key_of_value> key_node_prio_comp_t;
template<class KeyPrioComp>
detail::key_nodeptr_comp<KeyPrioComp, value_traits> key_node_prio_comp(KeyPrioComp keypriocomp) const
{ return detail::key_nodeptr_comp<KeyPrioComp, value_traits>(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<KeyPrioComp, value_traits, key_of_value> key_node_prio_comp(KeyPrioComp keypriocomp) const
{ return detail::key_nodeptr_comp<KeyPrioComp, value_traits, key_of_value>(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<iterator, bool> insert_unique(reference value)
{
insert_commit_data commit_data;
std::pair<iterator, bool> ret = this->insert_unique_check
(value, this->comp(), this->priv_pcomp(), commit_data);
std::pair<iterator, bool> ret = this->insert_unique_check(key_of_value()(value), commit_data);
if(!ret.second)
return ret;
return std::pair<iterator, bool> (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<iterator, bool> ret = this->insert_unique_check
(hint, value, this->comp(), this->priv_pcomp(), commit_data);
std::pair<iterator, bool> 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
}
}
//! <b>Effects</b>: Checks if a value can be inserted in the container, using
//! a user provided key instead of the value itself.
//!
//! <b>Returns</b>: 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.
//!
//! <b>Complexity</b>: Average complexity is at most logarithmic.
//!
//! <b>Throws</b>: If the comparison or predicate functions throw. Strong guarantee.
//!
//! <b>Notes</b>: 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<iterator, bool> 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); }
//! <b>Effects</b>: 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.
//!
//! <b>Returns</b>: 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.
//!
//! <b>Complexity</b>: Logarithmic in general, but it's amortized
//! constant time if t is inserted immediately before hint.
//!
//! <b>Throws</b>: If the comparison or predicate functions throw. Strong guarantee.
//!
//! <b>Notes</b>: 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<iterator, bool> 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); }
//! <b>Requires</b>: 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<class KeyType, class KeyTypeKeyCompare, class KeyValuePrioCompare>
std::pair<iterator, bool> insert_unique_check
BOOST_INTRUSIVE_DOC1ST(std::pair<iterator BOOST_INTRUSIVE_I bool>
, typename detail::disable_if_convertible
<KeyType BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I
std::pair<iterator BOOST_INTRUSIVE_I bool> >::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 <class ExtraChecker>
void check(ExtraChecker extra_checker) const
{
typedef detail::key_nodeptr_comp<priority_compare, value_traits, key_of_value> nodeptr_prio_comp_t;
tree_type::check(detail::treap_node_extra_checker
<ValueTraits, value_node_prio_comp_t, ExtraChecker>(this->value_node_prio_comp(), extra_checker));
<ValueTraits, nodeptr_prio_comp_t, ExtraChecker>
(this->key_node_prio_comp(this->priv_pcomp()), extra_checker));
}
//! @copydoc ::boost::intrusive::bstree::check()const

View File

@@ -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<iterator, bool> 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<iterator, bool> 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<class KeyType, class KeyTypeKeyCompare, class KeyValuePrioCompare>
std::pair<iterator, bool> insert_check

View File

@@ -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<iterator, bool> 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<class KeyType, class KeyHasher, class KeyEqual>
std::pair<iterator, bool> insert_check

View File

@@ -191,14 +191,6 @@ struct prio_comp
{ return this->priority_compare<int>::operator()(k.int_value(), v.int_value()); }
};
template<class ValueType>
struct prio_comp<ValueType, ValueType>
: priority_compare<ValueType>
{
bool operator()(const ValueType &v1, const ValueType &v2) const
{ return this->priority_compare<ValueType>::operator()(v1, v2); }
};
template<class ValueTraits, class ContainerDefiner>
void test_generic_set<ValueTraits, ContainerDefiner>::test_insert_advanced
(value_cont_type& values, detail::true_type)
@@ -208,14 +200,16 @@ void test_generic_set<ValueTraits, ContainerDefiner>::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<value_type, key_type> prio_comp_t;
typedef priority_compare<key_type> 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<ValueTraits, ContainerDefiner>::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));
}
}

View File

@@ -78,14 +78,14 @@ void test_unordered<ValueTraits, ContainerDefiner>::
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<typename unordered_type::bucket_ptr>::
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<ValueTraits, ContainerDefiner>
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<ValueTraits, ContainerDefiner>
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)
{