summaryrefslogtreecommitdiff
path: root/boost/intrusive
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:30:07 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:32:57 +0900
commit71d216b90256936a9638f325af9bc69d720e75de (patch)
tree9c5f682d341c7c88ad0c8e3d4b262e00b6fb691a /boost/intrusive
parent733b5d5ae2c5d625211e2985ac25728ac3f54883 (diff)
downloadboost-71d216b90256936a9638f325af9bc69d720e75de.tar.gz
boost-71d216b90256936a9638f325af9bc69d720e75de.tar.bz2
boost-71d216b90256936a9638f325af9bc69d720e75de.zip
Imported Upstream version 1.59.0
Change-Id: I2dde00f4eca71df3eea9d251dcaecde18a6c90a5 Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/intrusive')
-rw-r--r--boost/intrusive/avl_set.hpp390
-rw-r--r--boost/intrusive/avltree.hpp232
-rw-r--r--boost/intrusive/bs_set.hpp390
-rw-r--r--boost/intrusive/bstree.hpp648
-rw-r--r--boost/intrusive/bstree_algorithms.hpp4
-rw-r--r--boost/intrusive/detail/common_slist_algorithms.hpp2
-rw-r--r--boost/intrusive/detail/default_header_holder.hpp8
-rw-r--r--boost/intrusive/detail/ebo_functor_holder.hpp1
-rw-r--r--boost/intrusive/detail/get_value_traits.hpp6
-rw-r--r--boost/intrusive/detail/hashtable_node.hpp69
-rw-r--r--boost/intrusive/detail/is_stateful_value_traits.hpp2
-rw-r--r--boost/intrusive/detail/iterator.hpp8
-rw-r--r--boost/intrusive/detail/key_nodeptr_comp.hpp28
-rw-r--r--boost/intrusive/detail/list_iterator.hpp2
-rw-r--r--boost/intrusive/detail/math.hpp8
-rw-r--r--boost/intrusive/detail/mpl.hpp320
-rw-r--r--boost/intrusive/detail/node_cloner_disposer.hpp41
-rw-r--r--boost/intrusive/detail/reverse_iterator.hpp33
-rw-r--r--boost/intrusive/detail/slist_iterator.hpp2
-rw-r--r--boost/intrusive/detail/std_fwd.hpp6
-rw-r--r--boost/intrusive/detail/transform_iterator.hpp13
-rw-r--r--boost/intrusive/detail/tree_iterator.hpp6
-rw-r--r--boost/intrusive/detail/tree_value_compare.hpp78
-rw-r--r--boost/intrusive/hashtable.hpp2320
-rw-r--r--boost/intrusive/intrusive_fwd.hpp18
-rw-r--r--boost/intrusive/list.hpp167
-rw-r--r--boost/intrusive/options.hpp11
-rw-r--r--boost/intrusive/rbtree.hpp236
-rw-r--r--boost/intrusive/rbtree_algorithms.hpp4
-rw-r--r--boost/intrusive/set.hpp390
-rw-r--r--boost/intrusive/sg_set.hpp390
-rw-r--r--boost/intrusive/sgtree.hpp287
-rw-r--r--boost/intrusive/slist.hpp206
-rw-r--r--boost/intrusive/splay_set.hpp416
-rw-r--r--boost/intrusive/splaytree.hpp255
-rw-r--r--boost/intrusive/treap.hpp395
-rw-r--r--boost/intrusive/treap_set.hpp398
-rw-r--r--boost/intrusive/unordered_set.hpp1917
38 files changed, 4372 insertions, 5335 deletions
diff --git a/boost/intrusive/avl_set.hpp b/boost/intrusive/avl_set.hpp
index d06d441a19..c3d8d999ac 100644
--- a/boost/intrusive/avl_set.hpp
+++ b/boost/intrusive/avl_set.hpp
@@ -40,15 +40,15 @@ namespace intrusive {
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class avl_set_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder>
#endif
{
/// @cond
- typedef bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder> tree_type;
+ typedef bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_set_impl)
typedef tree_type implementation_defined;
@@ -56,6 +56,8 @@ class avl_set_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -80,16 +82,16 @@ class avl_set_impl
public:
- //! @copydoc ::boost::intrusive::avltree::avltree(const value_compare &,const value_traits &)
- explicit avl_set_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::avltree::avltree(const key_compare &,const value_traits &)
+ explicit avl_set_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::avltree::avltree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::avltree::avltree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
avl_set_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(true, b, e, cmp, v_traits)
{}
@@ -171,11 +173,20 @@ class avl_set_impl
//! @copydoc ::boost::intrusive::avltree::swap
void swap(avl_set_impl& other);
- //! @copydoc ::boost::intrusive::avltree::clone_from
+ //! @copydoc ::boost::intrusive::avltree::clone_from(const avltree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const avl_set_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::avltree::clone_from(avltree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(avl_set_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::avltree::insert_unique(reference)
std::pair<iterator, bool> insert(reference value)
@@ -185,18 +196,18 @@ 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 KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::avltree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(key, key_value_comp, commit_data); }
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(key, comp, commit_data); }
- //! @copydoc ::boost::intrusive::avltree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::avltree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(hint, key, key_value_comp, commit_data); }
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(hint, key, comp, commit_data); }
//! @copydoc ::boost::intrusive::avltree::insert_unique(Iterator,Iterator)
template<class Iterator>
@@ -223,12 +234,12 @@ class avl_set_impl
//! @copydoc ::boost::intrusive::avltree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::avltree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::erase(const key_type &key)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -238,13 +249,13 @@ class avl_set_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::avltree::clear
void clear();
@@ -255,100 +266,100 @@ class avl_set_impl
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::avltree::count(const_reference)const
- size_type count(const_reference value) const
- { return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
+ //! @copydoc ::boost::intrusive::avltree::count(const key_type &)const
+ size_type count(const key_type &key) const
+ { return static_cast<size_type>(this->tree_type::find(key) != this->tree_type::cend()); }
- //! @copydoc ::boost::intrusive::avltree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const
+ //! @copydoc ::boost::intrusive::avltree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::avltree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::avltree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::avltree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::avltree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::avltree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::avltree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::avltree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::avltree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::avltree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return this->tree_type::lower_bound_range(value); }
+ //! @copydoc ::boost::intrusive::rbtree::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&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
+ //! @copydoc ::boost::intrusive::rbtree::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::lower_bound_range(key, comp); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return this->tree_type::lower_bound_range(value); }
+ equal_range(const key_type &key) const
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const
{ return this->tree_type::lower_bound_range(key, comp); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::avltree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::avltree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::avltree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::avltree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::avltree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -402,7 +413,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_avl_set
{
@@ -410,7 +421,7 @@ struct make_avl_set
typedef typename pack_options
< avltree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -421,6 +432,7 @@ struct make_avl_set
typedef avl_set_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -432,14 +444,14 @@ struct make_avl_set
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class avl_set
: public make_avl_set<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -448,7 +460,7 @@ class avl_set
typedef typename make_avl_set
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -456,7 +468,7 @@ class avl_set
BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_set)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -464,14 +476,14 @@ class avl_set
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit avl_set( const value_compare &cmp = value_compare()
+ explicit avl_set( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
avl_set( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -483,6 +495,14 @@ class avl_set
avl_set& operator=(BOOST_RV_REF(avl_set) x)
{ return static_cast<avl_set &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const avl_set &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(avl_set) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static avl_set &container_from_end_iterator(iterator end_iterator)
{ return static_cast<avl_set &>(Base::container_from_end_iterator(end_iterator)); }
@@ -512,15 +532,15 @@ class avl_set
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class avl_multiset_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder>
#endif
{
/// @cond
- typedef bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder> tree_type;
+ typedef bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_multiset_impl)
typedef tree_type implementation_defined;
@@ -528,6 +548,8 @@ class avl_multiset_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -551,16 +573,16 @@ class avl_multiset_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::avltree::avltree(const value_compare &,const value_traits &)
- explicit avl_multiset_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::avltree::avltree(const key_compare &,const value_traits &)
+ explicit avl_multiset_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::avltree::avltree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::avltree::avltree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
avl_multiset_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(false, b, e, cmp, v_traits)
{}
@@ -641,11 +663,20 @@ class avl_multiset_impl
//! @copydoc ::boost::intrusive::avltree::swap
void swap(avl_multiset_impl& other);
- //! @copydoc ::boost::intrusive::avltree::clone_from
+ //! @copydoc ::boost::intrusive::avltree::clone_from(const avltree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const avl_multiset_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::avltree::clone_from(avltree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(avl_multiset_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::avltree::insert_equal(reference)
iterator insert(reference value)
@@ -676,12 +707,12 @@ class avl_multiset_impl
//! @copydoc ::boost::intrusive::avltree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::avltree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -691,13 +722,13 @@ class avl_multiset_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::avltree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::avltree::clear
void clear();
@@ -706,88 +737,88 @@ class avl_multiset_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::avltree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::avltree::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::avltree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::avltree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::avltree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::avltree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::avltree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::avltree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::avltree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::avltree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::avltree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::avltree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::avltree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::avltree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::avltree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::avltree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::avltree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::avltree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @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);
- //! @copydoc ::boost::intrusive::avltree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::avltree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @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, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::avltree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::avltree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::avltree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::avltree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &key upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::avltree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::avltree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -841,7 +872,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_avl_multiset
{
@@ -849,7 +880,7 @@ struct make_avl_multiset
typedef typename pack_options
< avltree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -860,6 +891,7 @@ struct make_avl_multiset
typedef avl_multiset_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -872,14 +904,14 @@ struct make_avl_multiset
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class avl_multiset
: public make_avl_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -887,7 +919,7 @@ class avl_multiset
{
typedef typename make_avl_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -896,7 +928,7 @@ class avl_multiset
BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_multiset)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -904,14 +936,14 @@ class avl_multiset
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit avl_multiset( const value_compare &cmp = value_compare()
+ explicit avl_multiset( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
avl_multiset( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -923,6 +955,14 @@ class avl_multiset
avl_multiset& operator=(BOOST_RV_REF(avl_multiset) x)
{ return static_cast<avl_multiset &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const avl_multiset &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(avl_multiset) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static avl_multiset &container_from_end_iterator(iterator end_iterator)
{ return static_cast<avl_multiset &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/avltree.hpp b/boost/intrusive/avltree.hpp
index 1996d69c68..8462293d6f 100644
--- a/boost/intrusive/avltree.hpp
+++ b/boost/intrusive/avltree.hpp
@@ -48,19 +48,16 @@ struct is_default_hook_tag<default_avltree_hook_applier>
{ static const bool value = true; };
struct avltree_defaults
+ : bstree_defaults
{
typedef default_avltree_hook_applier proto_value_traits;
- static const bool constant_time_size = true;
- typedef std::size_t size_type;
- typedef void compare;
- typedef void header_holder_type;
};
/// @endcond
//! The class template avltree is an intrusive AVL tree container, that
//! is used to construct intrusive avl_set and avl_multiset containers.
-//! The no-throw guarantee holds only, if the value_compare object
+//! The no-throw guarantee holds only, if the key_compare object
//! doesn't throw.
//!
//! The template parameter \c T is the type to be managed by the container.
@@ -74,17 +71,17 @@ struct avltree_defaults
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class avltree_impl
/// @cond
- : public bstree_impl<ValueTraits, VoidOrKeyComp, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, AvlTreeAlgorithms, HeaderHolder>
/// @endcond
{
public:
typedef ValueTraits value_traits;
/// @cond
- typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
+ typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
, ConstantTimeSize, AvlTreeAlgorithms
, HeaderHolder> tree_type;
typedef tree_type implementation_defined;
@@ -94,6 +91,7 @@ class avltree_impl
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::reference reference;
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
@@ -124,16 +122,16 @@ class avltree_impl
typedef typename implementation_defined::insert_commit_data insert_commit_data;
- //! @copydoc ::boost::intrusive::bstree::bstree(const value_compare &,const value_traits &)
- explicit avltree_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &)
+ explicit avltree_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
avltree_impl( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(unique, b, e, cmp, v_traits)
{}
@@ -215,10 +213,23 @@ class avltree_impl
//! @copydoc ::boost::intrusive::bstree::swap
void swap(avltree_impl& other);
- //! @copydoc ::boost::intrusive::bstree::clone_from
+ //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const avltree_impl &src, Cloner cloner, Disposer disposer);
+ #else //BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(avltree_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
+
+ #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
iterator insert_equal(reference value);
@@ -235,16 +246,16 @@ class avltree_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 KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @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
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data);
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data);
- //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data);
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_commit
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data);
@@ -268,12 +279,12 @@ class avltree_impl
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::bstree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -283,13 +294,13 @@ class avltree_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::clear
void clear();
@@ -298,88 +309,88 @@ class avltree_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const key_type &ke)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &key)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -404,33 +415,23 @@ class avltree_impl
//! @copydoc ::boost::intrusive::bstree::remove_node
void remove_node(reference value);
- #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
-};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ friend bool operator< (const avltree_impl &x, const avltree_impl &y);
-template<class T, class ...Options>
-bool operator< (const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
+ friend bool operator==(const avltree_impl &x, const avltree_impl &y);
-template<class T, class ...Options>
-bool operator==(const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
+ friend bool operator!= (const avltree_impl &x, const avltree_impl &y);
-template<class T, class ...Options>
-bool operator!= (const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator>(const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
+ friend bool operator>(const avltree_impl &x, const avltree_impl &y);
-template<class T, class ...Options>
-bool operator<=(const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
+ friend bool operator<=(const avltree_impl &x, const avltree_impl &y);
-template<class T, class ...Options>
-bool operator>=(const avltree_impl<T, Options...> &x, const avltree_impl<T, Options...> &y);
+ friend bool operator>=(const avltree_impl &x, const avltree_impl &y);
-template<class T, class ...Options>
-void swap(avltree_impl<T, Options...> &x, avltree_impl<T, Options...> &y);
+ friend void swap(avltree_impl &x, avltree_impl &y);
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+};
-#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! Helper metafunction to define a \c avltree that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
@@ -439,7 +440,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_avltree
{
@@ -447,7 +448,7 @@ struct make_avltree
typedef typename pack_options
< avltree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -458,6 +459,7 @@ struct make_avltree
typedef avltree_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -471,14 +473,14 @@ struct make_avltree
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class avltree
: public make_avltree<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -487,7 +489,7 @@ class avltree
typedef typename make_avltree
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -495,7 +497,7 @@ class avltree
BOOST_MOVABLE_BUT_NOT_COPYABLE(avltree)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -505,14 +507,14 @@ class avltree
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit avltree( const value_compare &cmp = value_compare()
+ explicit avltree( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
avltree( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(unique, b, e, cmp, v_traits)
{}
@@ -524,6 +526,14 @@ class avltree
avltree& operator=(BOOST_RV_REF(avltree) x)
{ return static_cast<avltree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const avltree &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(avltree) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static avltree &container_from_end_iterator(iterator end_iterator)
{ return static_cast<avltree &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/bs_set.hpp b/boost/intrusive/bs_set.hpp
index f246ce606d..a46ca38a01 100644
--- a/boost/intrusive/bs_set.hpp
+++ b/boost/intrusive/bs_set.hpp
@@ -40,15 +40,15 @@ namespace intrusive {
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class bs_set_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>
#endif
{
/// @cond
- typedef bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder> tree_type;
+ typedef bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_set_impl)
typedef tree_type implementation_defined;
@@ -56,6 +56,7 @@ class bs_set_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -79,16 +80,16 @@ class bs_set_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::bstree::bstree(const value_compare &,const value_traits &)
- explicit bs_set_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &)
+ explicit bs_set_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
bs_set_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(true, b, e, cmp, v_traits)
{}
@@ -169,11 +170,20 @@ class bs_set_impl
//! @copydoc ::boost::intrusive::bstree::swap
void swap(bs_set_impl& other);
- //! @copydoc ::boost::intrusive::bstree::clone_from
+ //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const bs_set_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(bs_set_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::bstree::insert_unique(reference)
std::pair<iterator, bool> insert(reference value)
@@ -183,18 +193,18 @@ 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 KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(key, key_value_comp, commit_data); }
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(key, comp, commit_data); }
- //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(hint, key, key_value_comp, commit_data); }
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(hint, key, comp, commit_data); }
//! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator)
template<class Iterator>
@@ -221,12 +231,12 @@ class bs_set_impl
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::bstree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -236,13 +246,13 @@ class bs_set_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::clear
void clear();
@@ -253,100 +263,100 @@ class bs_set_impl
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::bstree::count(const_reference)const
- size_type count(const_reference value) const
- { return static_cast<size_type>(this->tree_type::find(value) == this->tree_type::cend()); }
+ //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
+ size_type count(const key_type &key) const
+ { return static_cast<size_type>(this->tree_type::find(key) != this->tree_type::cend()); }
- //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const
- { return static_cast<size_type>(this->tree_type::find(key, comp) == this->tree_type::cend()); }
+ //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const
+ { return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return this->tree_type::lower_bound_range(value); }
+ //! @copydoc ::boost::intrusive::bstree::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&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
+ //! @copydoc ::boost::intrusive::bstree::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::lower_bound_range(key, comp); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return this->tree_type::lower_bound_range(value); }
+ equal_range(const key_type &key) const
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const
{ return this->tree_type::lower_bound_range(key, comp); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type&,const key_type&,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type& lower_key, const key_type& upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type&,const key_type&,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type& lower_key, const key_type& upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -400,7 +410,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_bs_set
{
@@ -408,7 +418,7 @@ struct make_bs_set
typedef typename pack_options
< bstree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -419,6 +429,7 @@ struct make_bs_set
typedef bs_set_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -430,14 +441,14 @@ struct make_bs_set
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class bs_set
: public make_bs_set<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -446,7 +457,7 @@ class bs_set
typedef typename make_bs_set
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -454,22 +465,22 @@ class bs_set
BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_set)
public:
- typedef typename Base::value_compare value_compare;
typedef typename Base::value_traits value_traits;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit bs_set( const value_compare &cmp = value_compare()
+ explicit bs_set( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
bs_set( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -481,6 +492,14 @@ class bs_set
bs_set& operator=(BOOST_RV_REF(bs_set) x)
{ return static_cast<bs_set &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const bs_set &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(bs_set) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static bs_set &container_from_end_iterator(iterator end_iterator)
{ return static_cast<bs_set &>(Base::container_from_end_iterator(end_iterator)); }
@@ -510,15 +529,15 @@ class bs_set
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class bs_multiset_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>
#endif
{
/// @cond
- typedef bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder> tree_type;
+ typedef bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_multiset_impl)
typedef tree_type implementation_defined;
@@ -526,6 +545,7 @@ class bs_multiset_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -549,16 +569,16 @@ class bs_multiset_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::bstree::bstree(const value_compare &,const value_traits &)
- explicit bs_multiset_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &)
+ explicit bs_multiset_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
bs_multiset_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(false, b, e, cmp, v_traits)
{}
@@ -639,11 +659,20 @@ class bs_multiset_impl
//! @copydoc ::boost::intrusive::bstree::swap
void swap(bs_multiset_impl& other);
- //! @copydoc ::boost::intrusive::bstree::clone_from
+ //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const bs_multiset_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(bs_multiset_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
iterator insert(reference value)
@@ -674,12 +703,12 @@ class bs_multiset_impl
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::bstree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -689,13 +718,13 @@ class bs_multiset_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::clear
void clear();
@@ -704,88 +733,88 @@ class bs_multiset_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type & lower_key, const key_type & upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type & lower_key, const key_type & upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -839,7 +868,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_bs_multiset
{
@@ -847,7 +876,7 @@ struct make_bs_multiset
typedef typename pack_options
< bstree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -858,6 +887,7 @@ struct make_bs_multiset
typedef bs_multiset_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -870,14 +900,14 @@ struct make_bs_multiset
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class bs_multiset
: public make_bs_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -885,7 +915,7 @@ class bs_multiset
{
typedef typename make_bs_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -894,7 +924,7 @@ class bs_multiset
BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_multiset)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -902,14 +932,14 @@ class bs_multiset
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit bs_multiset( const value_compare &cmp = value_compare()
+ explicit bs_multiset( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
bs_multiset( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -921,6 +951,14 @@ class bs_multiset
bs_multiset& operator=(BOOST_RV_REF(bs_multiset) x)
{ return static_cast<bs_multiset &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const bs_multiset &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(bs_multiset) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static bs_multiset &container_from_end_iterator(iterator end_iterator)
{ return static_cast<bs_multiset &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/bstree.hpp b/boost/intrusive/bstree.hpp
index 39c9d3ed2a..7a67de6e12 100644
--- a/boost/intrusive/bstree.hpp
+++ b/boost/intrusive/bstree.hpp
@@ -35,6 +35,7 @@
#include <boost/intrusive/detail/size_holder.hpp>
#include <boost/intrusive/detail/algo_type.hpp>
#include <boost/intrusive/detail/algorithm.hpp>
+#include <boost/intrusive/detail/tree_value_compare.hpp>
#include <boost/intrusive/detail/get_value_traits.hpp>
#include <boost/intrusive/bstree_algorithms.hpp>
@@ -69,6 +70,7 @@ struct bstree_defaults
static const bool constant_time_size = true;
typedef std::size_t size_type;
typedef void compare;
+ typedef void key_of_value;
static const bool floating_point = true; //For sgtree
typedef void priority; //For treap
typedef void header_holder_type;
@@ -90,7 +92,6 @@ struct bstbase3
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::element_type) value_type;
- typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference) reference;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::reference) const_reference;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::difference_type) difference_type;
@@ -239,28 +240,62 @@ struct get_compare<void, T>
typedef ::std::less<T> type;
};
-template<class ValueTraits, class VoidOrKeyComp, algo_types AlgoType, typename HeaderHolder>
+template<class KeyOfValue, class T>
+struct get_key_of_value
+{
+ typedef KeyOfValue type;
+};
+
+template<class T>
+struct get_key_of_value<void, T>
+{
+ typedef ::boost::intrusive::detail::identity<T> type;
+};
+
+template<class T, class VoidOrKeyOfValue, class VoidOrKeyComp>
+struct bst_key_types
+{
+ typedef typename get_key_of_value
+ < VoidOrKeyOfValue, T>::type key_of_value;
+ typedef typename key_of_value::type key_type;
+ typedef typename get_compare< VoidOrKeyComp
+ , key_type
+ >::type key_compare;
+ typedef tree_value_compare
+ <key_type, T, key_compare, key_of_value> value_compare;
+};
+
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, algo_types AlgoType, typename HeaderHolder>
struct bstbase2
//Put the (possibly empty) functor in the first position to get EBO in MSVC
//Use public inheritance to avoid MSVC bugs with closures
- : public detail::ebo_functor_holder<typename get_compare< VoidOrKeyComp
- , typename ValueTraits::value_type
- >::type>
+ : public detail::ebo_functor_holder
+ < typename bst_key_types
+ < typename ValueTraits::value_type
+ , VoidOrKeyOfValue
+ , VoidOrKeyComp
+ >::value_compare
+ >
, public bstbase3<ValueTraits, AlgoType, HeaderHolder>
{
typedef bstbase3<ValueTraits, AlgoType, HeaderHolder> treeheader_t;
+ typedef bst_key_types< typename ValueTraits::value_type
+ , VoidOrKeyOfValue
+ , VoidOrKeyComp> key_types;
typedef typename treeheader_t::value_traits value_traits;
typedef typename treeheader_t::node_algorithms node_algorithms;
- typedef typename get_compare
- < VoidOrKeyComp, typename value_traits::value_type>::type value_compare;
- typedef BOOST_INTRUSIVE_IMPDEF(value_compare) key_compare;
+ typedef typename ValueTraits::value_type value_type;
+ typedef typename key_types::key_type key_type;
+ typedef typename key_types::key_of_value key_of_value;
+ typedef typename key_types::key_compare key_compare;
+ typedef typename key_types::value_compare value_compare;
typedef typename treeheader_t::iterator iterator;
typedef typename treeheader_t::const_iterator const_iterator;
typedef typename treeheader_t::node_ptr node_ptr;
typedef typename treeheader_t::const_node_ptr const_node_ptr;
- bstbase2(const value_compare &comp, const ValueTraits &vtraits)
- : detail::ebo_functor_holder<value_compare>(comp), treeheader_t(vtraits)
+ bstbase2(const key_compare &comp, const ValueTraits &vtraits)
+ : detail::ebo_functor_holder<value_compare>(value_compare(comp)), treeheader_t(vtraits)
{}
const value_compare &comp() const
@@ -271,8 +306,6 @@ struct bstbase2
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer;
- typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::element_type) value_type;
- typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference) reference;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::reference) const_reference;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::difference_type) difference_type;
@@ -282,203 +315,181 @@ struct bstbase2
{ return this->comp(); }
key_compare key_comp() const
- { return this->comp(); }
+ { return this->comp().key_comp(); }
//lower_bound
- iterator lower_bound(const_reference value)
- { return this->lower_bound(value, this->comp()); }
+ iterator lower_bound(const key_type &key)
+ { return this->lower_bound(key, this->key_comp()); }
- const_iterator lower_bound(const_reference value) const
- { return this->lower_bound(value, this->comp()); }
+ const_iterator lower_bound(const key_type &key) const
+ { return this->lower_bound(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType &key, KeyValueCompare comp)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
return iterator(node_algorithms::lower_bound
- (this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
+ (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
}
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp) const
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
return const_iterator(node_algorithms::lower_bound
- (this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
+ (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
}
//upper_bound
- iterator upper_bound(const_reference value)
- { return this->upper_bound(value, this->comp()); }
+ iterator upper_bound(const key_type &key)
+ { return this->upper_bound(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType &key, KeyValueCompare comp)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
return iterator(node_algorithms::upper_bound
- (this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
+ (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
}
- const_iterator upper_bound(const_reference value) const
- { return this->upper_bound(value, this->comp()); }
+ const_iterator upper_bound(const key_type &key) const
+ { return this->upper_bound(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp) const
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
return const_iterator(node_algorithms::upper_bound
- (this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
+ (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
+ }
+
+ template<class KeyTypeKeyCompare>
+ detail::key_nodeptr_comp<KeyTypeKeyCompare, value_traits, key_of_value> key_node_comp(KeyTypeKeyCompare comp) const
+ {
+ return detail::key_nodeptr_comp<KeyTypeKeyCompare, value_traits, key_of_value>(comp, &this->get_value_traits());
}
//find
- iterator find(const_reference value)
- { return this->find(value, this->comp()); }
+ iterator find(const key_type &key)
+ { return this->find(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType &key, KeyValueCompare comp)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType &key, KeyTypeKeyCompare comp)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
return iterator
- (node_algorithms::find(this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
+ (node_algorithms::find(this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
}
- const_iterator find(const_reference value) const
- { return this->find(value, this->comp()); }
+ const_iterator find(const key_type &key) const
+ { return this->find(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType &key, KeyValueCompare comp) const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType &key, KeyTypeKeyCompare comp) const
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
return const_iterator
- (node_algorithms::find(this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
+ (node_algorithms::find(this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
}
//equal_range
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return this->equal_range(value, this->comp()); }
+ std::pair<iterator,iterator> equal_range(const key_type &key)
+ { return this->equal_range(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType &key, KeyValueCompare comp)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
- (node_algorithms::equal_range(this->header_ptr(), key, key_node_comp));
+ (node_algorithms::equal_range(this->header_ptr(), key, this->key_node_comp(comp)));
return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr())
, iterator(ret.second, this->priv_value_traits_ptr()));
}
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return this->equal_range(value, this->comp()); }
+ equal_range(const key_type &key) const
+ { return this->equal_range(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType &key, KeyValueCompare comp) const
+ equal_range(const KeyType &key, KeyTypeKeyCompare comp) const
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
- (node_algorithms::equal_range(this->header_ptr(), key, key_node_comp));
+ (node_algorithms::equal_range(this->header_ptr(), key, this->key_node_comp(comp)));
return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr())
, const_iterator(ret.second, this->priv_value_traits_ptr()));
}
//lower_bound_range
- std::pair<iterator,iterator> lower_bound_range(const_reference value)
- { return this->lower_bound_range(value, this->comp()); }
+ std::pair<iterator,iterator> lower_bound_range(const key_type &key)
+ { return this->lower_bound_range(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> lower_bound_range(const KeyType &key, KeyValueCompare comp)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> lower_bound_range(const KeyType &key, KeyTypeKeyCompare comp)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
- (node_algorithms::lower_bound_range(this->header_ptr(), key, key_node_comp));
+ (node_algorithms::lower_bound_range(this->header_ptr(), key, this->key_node_comp(comp)));
return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr())
, iterator(ret.second, this->priv_value_traits_ptr()));
}
std::pair<const_iterator, const_iterator>
- lower_bound_range(const_reference value) const
- { return this->lower_bound_range(value, this->comp()); }
+ lower_bound_range(const key_type &key) const
+ { return this->lower_bound_range(key, this->key_comp()); }
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- lower_bound_range(const KeyType &key, KeyValueCompare comp) const
+ lower_bound_range(const KeyType &key, KeyTypeKeyCompare comp) const
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
- (node_algorithms::lower_bound_range(this->header_ptr(), key, key_node_comp));
+ (node_algorithms::lower_bound_range(this->header_ptr(), key, this->key_node_comp(comp)));
return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr())
, const_iterator(ret.second, this->priv_value_traits_ptr()));
}
//bounded_range
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed)
- { return this->bounded_range(lower_value, upper_value, this->comp(), left_closed, right_closed); }
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed)
+ { return this->bounded_range(lower_key, upper_key, this->key_comp(), left_closed, right_closed); }
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed)
+ (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
(node_algorithms::bounded_range
- (this->header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed));
+ (this->header_ptr(), lower_key, upper_key, this->key_node_comp(comp), left_closed, right_closed));
return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr())
, iterator(ret.second, this->priv_value_traits_ptr()));
}
std::pair<const_iterator,const_iterator> 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, this->comp(), left_closed, right_closed); }
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const
+ { return this->bounded_range(lower_key, upper_key, this->key_comp(), left_closed, right_closed); }
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator,const_iterator> bounded_range
- (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const
+ (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
(node_algorithms::bounded_range
- (this->header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed));
+ (this->header_ptr(), lower_key, upper_key, this->key_node_comp(comp), left_closed, right_closed));
return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr())
, const_iterator(ret.second, this->priv_value_traits_ptr()));
}
//insert_unique_check
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- ocomp(key_value_comp, &this->get_value_traits());
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
- (this->header_ptr(), key, ocomp, commit_data));
+ (this->header_ptr(), key, this->key_node_comp(comp), commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
}
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- ocomp(key_value_comp, &this->get_value_traits());
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
- (this->header_ptr(), hint.pointed_node(), key, ocomp, commit_data));
+ (this->header_ptr(), hint.pointed_node(), key, this->key_node_comp(comp), commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
}
};
@@ -486,19 +497,20 @@ struct bstbase2
//Due to MSVC's EBO implementation, to save space and maintain the ABI, we must put the non-empty size member
//in the first position, but if size is not going to be stored then we'll use an specialization
//that doesn't inherit from size_holder
-template<class ValueTraits, class VoidOrKeyComp, bool ConstantTimeSize, class SizeType, algo_types AlgoType, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, bool ConstantTimeSize, class SizeType, algo_types AlgoType, typename HeaderHolder>
struct bstbase_hack
: public detail::size_holder<ConstantTimeSize, SizeType>
- , public bstbase2 < ValueTraits, VoidOrKeyComp, AlgoType, HeaderHolder>
+ , public bstbase2 < ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder>
{
- typedef bstbase2< ValueTraits, VoidOrKeyComp, AlgoType, HeaderHolder> base_type;
+ typedef bstbase2< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder> base_type;
+ typedef typename base_type::key_compare key_compare;
typedef typename base_type::value_compare value_compare;
typedef SizeType size_type;
typedef typename base_type::node_traits node_traits;
typedef typename get_algo
<AlgoType, node_traits>::type algo_type;
- bstbase_hack(const value_compare & comp, const ValueTraits &vtraits)
+ bstbase_hack(const key_compare & comp, const ValueTraits &vtraits)
: base_type(comp, vtraits)
{
this->sz_traits().set_size(size_type(0));
@@ -514,17 +526,18 @@ struct bstbase_hack
};
//Specialization for ConstantTimeSize == false
-template<class ValueTraits, class VoidOrKeyComp, class SizeType, algo_types AlgoType, typename HeaderHolder>
-struct bstbase_hack<ValueTraits, VoidOrKeyComp, false, SizeType, AlgoType, HeaderHolder>
- : public bstbase2 < ValueTraits, VoidOrKeyComp, AlgoType, HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, algo_types AlgoType, typename HeaderHolder>
+struct bstbase_hack<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, false, SizeType, AlgoType, HeaderHolder>
+ : public bstbase2 < ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder>
{
- typedef bstbase2< ValueTraits, VoidOrKeyComp, AlgoType, HeaderHolder> base_type;
+ typedef bstbase2< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder> base_type;
typedef typename base_type::value_compare value_compare;
- bstbase_hack(const value_compare & comp, const ValueTraits &vtraits)
+ typedef typename base_type::key_compare key_compare;
+ bstbase_hack(const key_compare & comp, const ValueTraits &vtraits)
: base_type(comp, vtraits)
{}
- typedef detail::size_holder<true, SizeType> size_traits;
+ typedef detail::size_holder<false, SizeType> size_traits;
size_traits &sz_traits()
{ return s_size_traits; }
@@ -535,18 +548,18 @@ struct bstbase_hack<ValueTraits, VoidOrKeyComp, false, SizeType, AlgoType, Heade
static size_traits s_size_traits;
};
-template<class ValueTraits, class VoidOrKeyComp, class SizeType, algo_types AlgoType, typename HeaderHolder>
-detail::size_holder<true, SizeType> bstbase_hack<ValueTraits, VoidOrKeyComp, false, SizeType, AlgoType, HeaderHolder>::s_size_traits;
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, algo_types AlgoType, typename HeaderHolder>
+detail::size_holder<false, SizeType> bstbase_hack<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, false, SizeType, AlgoType, HeaderHolder>::s_size_traits;
//This class will
-template<class ValueTraits, class VoidOrKeyComp, bool ConstantTimeSize, class SizeType, algo_types AlgoType, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, bool ConstantTimeSize, class SizeType, algo_types AlgoType, typename HeaderHolder>
struct bstbase
- : public bstbase_hack< ValueTraits, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder>
+ : public bstbase_hack< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder>
{
- typedef bstbase_hack< ValueTraits, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder> base_type;
+ typedef bstbase_hack< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder> base_type;
typedef ValueTraits value_traits;
typedef typename base_type::value_compare value_compare;
- typedef value_compare key_compare;
+ typedef typename base_type::key_compare key_compare;
typedef typename base_type::const_reference const_reference;
typedef typename base_type::reference reference;
typedef typename base_type::iterator iterator;
@@ -556,7 +569,7 @@ struct bstbase
<AlgoType, node_traits>::type node_algorithms;
typedef SizeType size_type;
- bstbase(const value_compare & comp, const ValueTraits &vtraits)
+ bstbase(const key_compare & comp, const ValueTraits &vtraits)
: base_type(comp, vtraits)
{}
@@ -578,7 +591,7 @@ struct bstbase
/// @endcond
//! The class template bstree is an unbalanced intrusive binary search tree
-//! container. The no-throw guarantee holds only, if the value_compare object
+//! container. The no-throw guarantee holds only, if the key_compare object
//! doesn't throw.
//!
//! The complexity guarantees only hold if the tree is balanced, logarithmic
@@ -595,14 +608,14 @@ struct bstbase
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
#endif
class bstree_impl
- : public bstbase<ValueTraits, VoidKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder>
+ : public bstbase<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder>
{
public:
/// @cond
- typedef bstbase<ValueTraits, VoidKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder> data_type;
+ typedef bstbase<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder> data_type;
typedef tree_iterator<ValueTraits, false> iterator_type;
typedef tree_iterator<ValueTraits, true> const_iterator_type;
/// @endcond
@@ -611,13 +624,14 @@ class bstree_impl
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::element_type) value_type;
- typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type;
+ typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::key_type) key_type;
+ typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::key_of_value) key_of_value;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference) reference;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::reference) const_reference;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::difference_type) difference_type;
typedef BOOST_INTRUSIVE_IMPDEF(SizeType) size_type;
typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::value_compare) value_compare;
- typedef BOOST_INTRUSIVE_IMPDEF(value_compare) key_compare;
+ typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::key_compare) key_compare;
typedef BOOST_INTRUSIVE_IMPDEF(iterator_type) iterator;
typedef BOOST_INTRUSIVE_IMPDEF(const_iterator_type) const_iterator;
typedef BOOST_INTRUSIVE_IMPDEF(boost::intrusive::reverse_iterator<iterator>) reverse_iterator;
@@ -660,8 +674,8 @@ class bstree_impl
//!
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor of the value_compare object throws. Basic guarantee.
- explicit bstree_impl( const value_compare &cmp = value_compare()
+ //! or the copy constructor of the key_compare object throws. Basic guarantee.
+ explicit bstree_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: data_type(cmp, v_traits)
{}
@@ -677,10 +691,10 @@ class bstree_impl
//!
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor/operator() of the value_compare object throws. Basic guarantee.
+ //! or the copy constructor/operator() of the key_compare object throws. Basic guarantee.
template<class Iterator>
bstree_impl( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: data_type(cmp, v_traits)
{
@@ -863,7 +877,7 @@ class bstree_impl
//!
//! <b>Complexity</b>: Constant.
//!
- //! <b>Throws</b>: If value_compare copy-constructor throws.
+ //! <b>Throws</b>: If key_compare copy-constructor throws.
key_compare key_comp() const;
//! <b>Effects</b>: Returns the value_compare object used by the container.
@@ -960,7 +974,7 @@ class bstree_impl
//!
//! <b>Effects</b>: Erases all the elements from *this
//! calling Disposer::operator()(pointer), clones all the
- //! elements from src calling Cloner::operator()(const_reference )
+ //! elements from src calling Cloner::operator()(reference)
//! and inserts them on *this. Copies the predicate from the source container.
//!
//! If cloner throws, all cloned elements are unlinked and disposed
@@ -973,7 +987,7 @@ class bstree_impl
//! <b>Note</b>: This version can modify the source container, useful to implement
//! move semantics.
template <class Cloner, class Disposer>
- void clone_from(bstree_impl &src, Cloner cloner, Disposer disposer)
+ void clone_from(BOOST_RV_REF(bstree_impl) src, Cloner cloner, Disposer disposer)
{
this->clear_and_dispose(disposer);
if(!src.empty()){
@@ -997,19 +1011,17 @@ class bstree_impl
//! <b>Complexity</b>: Average complexity for insert element is at
//! most logarithmic.
//!
- //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
+ //! <b>Throws</b>: If the internal key_compare ordering function throws. Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
iterator insert_equal(reference value)
{
- detail::key_nodeptr_comp<value_compare, value_traits>
- key_node_comp(this->comp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret(node_algorithms::insert_equal_upper_bound
- (this->header_ptr(), to_insert, key_node_comp), this->priv_value_traits_ptr());
+ (this->header_ptr(), to_insert, this->key_node_comp(this->key_comp())), this->priv_value_traits_ptr());
this->sz_traits().increment();
return ret;
}
@@ -1024,19 +1036,17 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic in general, but it is amortized
//! constant time if t is inserted immediately before hint.
//!
- //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
+ //! <b>Throws</b>: If the internal key_compare ordering function throws. Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
iterator insert_equal(const_iterator hint, reference value)
{
- detail::key_nodeptr_comp<value_compare, value_traits>
- key_node_comp(this->comp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret(node_algorithms::insert_equal
- (this->header_ptr(), hint.pointed_node(), to_insert, key_node_comp), this->priv_value_traits_ptr());
+ (this->header_ptr(), hint.pointed_node(), to_insert, this->key_node_comp(this->key_comp())), this->priv_value_traits_ptr());
this->sz_traits().increment();
return ret;
}
@@ -1078,10 +1088,13 @@ class bstree_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(), commit_data);
- if(!ret.second)
- return ret;
- return std::pair<iterator, bool> (this->insert_unique_commit(value, commit_data), true);
+ std::pair<node_ptr, bool> ret =
+ (node_algorithms::insert_unique_check
+ (this->header_ptr(), key_of_value()(value), this->key_node_comp(this->key_comp()), commit_data));
+ return std::pair<iterator, bool>
+ ( ret.second ? this->insert_unique_commit(value, commit_data)
+ : iterator(ret.first, this->priv_value_traits_ptr())
+ , ret.second);
}
//! <b>Requires</b>: value must be an lvalue, and "hint" must be
@@ -1101,10 +1114,11 @@ class bstree_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(), commit_data);
- if(!ret.second)
- return ret.first;
- return this->insert_unique_commit(value, commit_data);
+ std::pair<node_ptr, bool> ret =
+ (node_algorithms::insert_unique_check
+ (this->header_ptr(), hint.pointed_node(), key_of_value()(value), this->key_node_comp(this->key_comp()), commit_data));
+ return ret.second ? this->insert_unique_commit(value, commit_data)
+ : iterator(ret.first, this->priv_value_traits_ptr());
}
//! <b>Requires</b>: Dereferencing iterator must yield an lvalue
@@ -1136,9 +1150,9 @@ class bstree_impl
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! <b>Requires</b>: key_value_comp must be a comparison function that induces
- //! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an arbitrary key with the contained values.
+ //! <b>Requires</b>: comp must be a comparison function that induces
+ //! the same strict weak ordering as key_compare. The difference is that
+ //! comp compares an arbitrary key with the contained values.
//!
//! <b>Effects</b>: Checks if a value can be inserted in the container, using
//! a user provided key instead of the value itself.
@@ -1151,7 +1165,7 @@ class bstree_impl
//!
//! <b>Complexity</b>: Average complexity is at most logarithmic.
//!
- //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
+ //! <b>Throws</b>: If the comp ordering function throws. 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
@@ -1166,13 +1180,13 @@ class bstree_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 KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data);
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data);
- //! <b>Requires</b>: key_value_comp must be a comparison function that induces
- //! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an arbitrary key with the contained values.
+ //! <b>Requires</b>: comp must be a comparison function that induces
+ //! the same strict weak ordering as key_compare. The difference is that
+ //! comp compares an arbitrary key with the contained values.
//!
//! <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"
@@ -1187,7 +1201,7 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic in general, but it's amortized
//! constant time if t is inserted immediately before hint.
//!
- //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
+ //! <b>Throws</b>: If the comp ordering function throws. 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
@@ -1202,10 +1216,10 @@ class bstree_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 KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data);
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data);
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
@@ -1351,8 +1365,8 @@ class bstree_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
- size_type erase(const_reference value)
- { return this->erase(value, this->comp()); }
+ size_type erase(const key_type &key)
+ { return this->erase(key, this->key_comp()); }
//! <b>Effects</b>: Erases all the elements with the given key.
//! according to the comparison functor "comp".
@@ -1365,12 +1379,10 @@ class bstree_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
- /// @endcond
- )
+ template<class KeyType, class KeyTypeKeyCompare>
+ BOOST_INTRUSIVE_DOC1ST(size_type
+ , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
+ erase(const KeyType& key, KeyTypeKeyCompare comp)
{
std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n;
@@ -1398,12 +1410,6 @@ class bstree_impl
return ret;
}
- #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
- template<class Disposer>
- iterator erase_and_dispose(iterator i, Disposer disposer)
- { return this->erase_and_dispose(const_iterator(i), disposer); }
- #endif
-
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//!
//! <b>Effects</b>: Erases all the elements with the given value.
@@ -1418,9 +1424,9 @@ class bstree_impl
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer)
+ size_type erase_and_dispose(const key_type &key, Disposer disposer)
{
- std::pair<iterator,iterator> p = this->equal_range(value);
+ std::pair<iterator,iterator> p = this->equal_range(key);
size_type n;
this->private_erase(p.first, p.second, n, disposer);
return n;
@@ -1456,12 +1462,10 @@ class bstree_impl
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
- /// @endcond
- )
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ BOOST_INTRUSIVE_DOC1ST(size_type
+ , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
+ erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer)
{
std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n;
@@ -1512,9 +1516,9 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
//! to number of objects with the given value.
//!
- //! <b>Throws</b>: If `value_compare` throws.
- size_type count(const_reference value) const
- { return size_type(this->count(value, this->comp())); }
+ //! <b>Throws</b>: If `key_compare` throws.
+ size_type count(const key_type &key) const
+ { return size_type(this->count(key, this->key_comp())); }
//! <b>Effects</b>: Returns the number of contained elements with the given key
//!
@@ -1522,8 +1526,8 @@ class bstree_impl
//! to number of objects with the given key.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType &key, KeyValueCompare comp) const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType &key, KeyTypeKeyCompare comp) const
{
std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
size_type n = 0;
@@ -1535,11 +1539,11 @@ class bstree_impl
//Add non-const overloads to theoretically const members
//as some algorithms have different behavior when non-const versions are used (like splay trees).
- size_type count(const_reference value)
- { return size_type(this->count(value, this->comp())); }
+ size_type count(const key_type &key)
+ { return size_type(this->count(key, this->key_comp())); }
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType &key, KeyValueCompare comp)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType &key, KeyTypeKeyCompare comp)
{
std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
size_type n = 0;
@@ -1554,16 +1558,16 @@ class bstree_impl
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
- iterator lower_bound(const_reference value);
+ //! <b>Throws</b>: If `key_compare` throws.
+ iterator lower_bound(const key_type &key);
//! <b>Effects</b>: Returns an iterator to the first element whose
//! key is not less than k or end() if that element does not exist.
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
- const_iterator lower_bound(const_reference value) const;
+ //! <b>Throws</b>: If `key_compare` throws.
+ const_iterator lower_bound(const key_type &key) const;
//! <b>Effects</b>: Returns an iterator to the first element whose
//! key is not less than k or end() if that element does not exist.
@@ -1571,8 +1575,8 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp);
//! <b>Effects</b>: Returns a const iterator to the first element whose
//! key is not less than k or end() if that element does not exist.
@@ -1580,16 +1584,16 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const;
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp) const;
//! <b>Effects</b>: Returns an iterator to the first element whose
//! key is greater than k or end() if that element does not exist.
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
- iterator upper_bound(const_reference value);
+ //! <b>Throws</b>: If `key_compare` throws.
+ iterator upper_bound(const key_type &key);
//! <b>Effects</b>: Returns an iterator to the first element whose
//! key is greater than k according to comp or end() if that element
@@ -1598,16 +1602,16 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp);
//! <b>Effects</b>: Returns an iterator to the first element whose
//! key is greater than k or end() if that element does not exist.
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
- const_iterator upper_bound(const_reference value) const;
+ //! <b>Throws</b>: If `key_compare` throws.
+ const_iterator upper_bound(const key_type &key) const;
//! <b>Effects</b>: Returns an iterator to the first element whose
//! key is greater than k according to comp or end() if that element
@@ -1616,16 +1620,16 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const;
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp) const;
//! <b>Effects</b>: Finds an iterator to the first element whose key is
//! k or end() if that element does not exist.
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
- iterator find(const_reference value);
+ //! <b>Throws</b>: If `key_compare` throws.
+ iterator find(const key_type &key);
//! <b>Effects</b>: Finds an iterator to the first element whose key is
//! k or end() if that element does not exist.
@@ -1633,16 +1637,16 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType &key, KeyTypeKeyCompare comp);
//! <b>Effects</b>: Finds a const_iterator to the first element whose key is
//! k or end() if that element does not exist.
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
- const_iterator find(const_reference value) const;
+ //! <b>Throws</b>: If `key_compare` throws.
+ const_iterator find(const key_type &key) const;
//! <b>Effects</b>: Finds a const_iterator to the first element whose key is
//! k or end() if that element does not exist.
@@ -1650,8 +1654,8 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType &key, KeyValueCompare comp) const;
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType &key, KeyTypeKeyCompare comp) const;
//! <b>Effects</b>: Finds a range containing all elements whose key is k or
//! an empty range that indicates the position where those elements would be
@@ -1659,8 +1663,8 @@ class bstree_impl
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! <b>Throws</b>: If `key_compare` throws.
+ std::pair<iterator,iterator> equal_range(const key_type &key);
//! <b>Effects</b>: Finds a range containing all elements whose key is k or
//! an empty range that indicates the position where those elements would be
@@ -1669,8 +1673,8 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp);
//! <b>Effects</b>: Finds a range containing all elements whose key is k or
//! an empty range that indicates the position where those elements would be
@@ -1678,9 +1682,9 @@ class bstree_impl
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
+ //! <b>Throws</b>: If `key_compare` throws.
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
//! <b>Effects</b>: Finds a range containing all elements whose key is k or
//! an empty range that indicates the position where those elements would be
@@ -1689,12 +1693,12 @@ class bstree_impl
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: If `comp` throws.
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType &key, KeyValueCompare comp) const;
+ equal_range(const KeyType &key, KeyTypeKeyCompare comp) const;
- //! <b>Requires</b>: 'lower_value' must not be greater than 'upper_value'. If
- //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false.
+ //! <b>Requires</b>: 'lower_key' must not be greater than 'upper_key'. If
+ //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false.
//!
//! <b>Effects</b>: Returns an a pair with the following criteria:
//!
@@ -1704,16 +1708,16 @@ class bstree_impl
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
+ //! <b>Throws</b>: If `key_compare` throws.
//!
//! <b>Note</b>: This function can be more efficient than calling upper_bound
//! and lower_bound for lower_value and upper_value.
//!
//! <b>Note</b>: Experimental function, the interface might change in future releases.
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_value, bool left_closed, bool right_closed);
- //! <b>Requires</b>: KeyValueCompare is a function object that induces a strict weak
+ //! <b>Requires</b>: KeyTypeKeyCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the
//! the container.
//! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If
@@ -1733,12 +1737,12 @@ class bstree_impl
//! and lower_bound for lower_key and upper_key.
//!
//! <b>Note</b>: Experimental function, the interface might change in future releases.
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! <b>Requires</b>: 'lower_value' must not be greater than 'upper_value'. If
- //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false.
+ //! <b>Requires</b>: 'lower_key' must not be greater than 'upper_key'. If
+ //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false.
//!
//! <b>Effects</b>: Returns an a pair with the following criteria:
//!
@@ -1748,16 +1752,16 @@ class bstree_impl
//!
//! <b>Complexity</b>: Logarithmic.
//!
- //! <b>Throws</b>: If `value_compare` throws.
+ //! <b>Throws</b>: If `key_compare` throws.
//!
//! <b>Note</b>: This function can be more efficient than calling upper_bound
//! and lower_bound for lower_value and upper_value.
//!
//! <b>Note</b>: Experimental function, the interface might change in future releases.
std::pair<const_iterator,const_iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! <b>Requires</b>: KeyValueCompare is a function object that induces a strict weak
+ //! <b>Requires</b>: KeyTypeKeyCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the
//! the container.
//! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If
@@ -1777,9 +1781,9 @@ class bstree_impl
//! and lower_bound for lower_key and upper_key.
//!
//! <b>Note</b>: Experimental function, the interface might change in future releases.
- template<class KeyType, class KeyValueCompare>
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator,const_iterator> bounded_range
- (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! <b>Requires</b>: value must be an lvalue and shall be in a set of
//! appropriate type. Otherwise the behavior is undefined.
@@ -1936,8 +1940,8 @@ class bstree_impl
template <class ExtraChecker>
void check(ExtraChecker extra_checker) const
{
- typedef detail::key_nodeptr_comp<value_compare, value_traits> nodeptr_comp_t;
- nodeptr_comp_t nodeptr_comp(this->comp(), &this->get_value_traits());
+ typedef detail::key_nodeptr_comp<key_compare, value_traits, key_of_value> nodeptr_comp_t;
+ nodeptr_comp_t nodeptr_comp(this->key_comp(), &this->get_value_traits());
typedef typename get_node_checker<AlgoType, ValueTraits, nodeptr_comp_t, ExtraChecker>::type node_checker_t;
typename node_checker_t::return_type checker_return;
node_algorithms::check(this->header_ptr(), node_checker_t(nodeptr_comp, extra_checker), checker_return);
@@ -1956,6 +1960,32 @@ class bstree_impl
check(detail::empty_node_checker<ValueTraits>());
}
+ friend bool operator==(const bstree_impl &x, const bstree_impl &y)
+ {
+ if(constant_time_size && x.size() != y.size()){
+ return false;
+ }
+ return boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
+ }
+
+ friend bool operator!=(const bstree_impl &x, const bstree_impl &y)
+ { return !(x == y); }
+
+ friend bool operator<(const bstree_impl &x, const bstree_impl &y)
+ { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+
+ friend bool operator>(const bstree_impl &x, const bstree_impl &y)
+ { return y < x; }
+
+ friend bool operator<=(const bstree_impl &x, const bstree_impl &y)
+ { return !(x > y); }
+
+ friend bool operator>=(const bstree_impl &x, const bstree_impl &y)
+ { return !(x < y); }
+
+ friend void swap(bstree_impl &x, bstree_impl &y)
+ { x.swap(y); }
+
/// @cond
private:
template<class Disposer>
@@ -1975,111 +2005,6 @@ class bstree_impl
/// @endcond
};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
-#endif
-inline bool operator<
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
-#else
-( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
-, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
-#endif
-{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
-#endif
-bool operator==
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
-#else
-( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
-, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
-#endif
-{
- typedef bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> tree_type;
-
- if(tree_type::constant_time_size && x.size() != y.size()){
- return false;
- }
- return boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
-}
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
-#endif
-inline bool operator!=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
-#else
-( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
-, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
-#endif
-{ return !(x == y); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
-#endif
-inline bool operator>
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
-#else
-( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
-, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
-#endif
-{ return y < x; }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
-#endif
-inline bool operator<=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
-#else
-( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
-, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
-#endif
-{ return !(y < x); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
-#endif
-inline bool operator>=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
-#else
-( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
-, const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
-#endif
-{ return !(x < y); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
-#endif
-inline void swap
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(bstree_impl<T, Options...> &x, bstree_impl<T, Options...> &y)
-#else
-( bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
-, bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
-#endif
-{ x.swap(y); }
-
//! Helper metafunction to define a \c bstree that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
@@ -2087,7 +2012,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_bstree
{
@@ -2095,7 +2020,7 @@ struct make_bstree
typedef typename pack_options
< bstree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -2106,6 +2031,7 @@ struct make_bstree
typedef bstree_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -2120,14 +2046,14 @@ struct make_bstree
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class bstree
: public make_bstree<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -2136,7 +2062,7 @@ class bstree
typedef typename make_bstree
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -2144,7 +2070,7 @@ class bstree
BOOST_MOVABLE_BUT_NOT_COPYABLE(bstree)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -2152,14 +2078,14 @@ class bstree
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- bstree( const value_compare &cmp = value_compare()
+ bstree( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
bstree( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(unique, b, e, cmp, v_traits)
{}
@@ -2171,6 +2097,14 @@ class bstree
bstree& operator=(BOOST_RV_REF(bstree) x)
{ return static_cast<bstree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const bstree &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(bstree) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static bstree &container_from_end_iterator(iterator end_iterator)
{ return static_cast<bstree &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/bstree_algorithms.hpp b/boost/intrusive/bstree_algorithms.hpp
index f7e915e914..dcb7e5c4ff 100644
--- a/boost/intrusive/bstree_algorithms.hpp
+++ b/boost/intrusive/bstree_algorithms.hpp
@@ -37,10 +37,6 @@ namespace intrusive {
template <class NodePtr>
struct insert_commit_data_t
{
- insert_commit_data_t()
- : link_left(false)
- , node()
- {}
bool link_left;
NodePtr node;
};
diff --git a/boost/intrusive/detail/common_slist_algorithms.hpp b/boost/intrusive/detail/common_slist_algorithms.hpp
index deaea7c97b..c6fa289a23 100644
--- a/boost/intrusive/detail/common_slist_algorithms.hpp
+++ b/boost/intrusive/detail/common_slist_algorithms.hpp
@@ -46,7 +46,7 @@ class common_slist_algorithms
; this_node != (p_next = NodeTraits::get_next(p))
; p = p_next){
//Logic error: possible use of linear lists with
- //operations only permitted with lists
+ //operations only permitted with circular lists
BOOST_INTRUSIVE_INVARIANT_ASSERT(p);
}
return p;
diff --git a/boost/intrusive/detail/default_header_holder.hpp b/boost/intrusive/detail/default_header_holder.hpp
index d10109b8c9..5f9cd9a444 100644
--- a/boost/intrusive/detail/default_header_holder.hpp
+++ b/boost/intrusive/detail/default_header_holder.hpp
@@ -51,15 +51,15 @@ struct default_header_holder : public NodeTraits::node
};
// type function producing the header node holder
-template < typename Value_Traits, typename HeaderHolder >
+template < typename ValueTraits, typename HeaderHolder >
struct get_header_holder_type
{
typedef HeaderHolder type;
};
-template < typename Value_Traits >
-struct get_header_holder_type< Value_Traits, void >
+template < typename ValueTraits >
+struct get_header_holder_type< ValueTraits, void >
{
- typedef default_header_holder< typename Value_Traits::node_traits > type;
+ typedef default_header_holder< typename ValueTraits::node_traits > type;
};
} //namespace detail
diff --git a/boost/intrusive/detail/ebo_functor_holder.hpp b/boost/intrusive/detail/ebo_functor_holder.hpp
index e8e73ff62a..27dd093b60 100644
--- a/boost/intrusive/detail/ebo_functor_holder.hpp
+++ b/boost/intrusive/detail/ebo_functor_holder.hpp
@@ -203,6 +203,7 @@ class ebo_functor_holder
typedef ebo_functor_holder_impl<T, is_unary_or_binary_function<T>::value> super;
public:
+ typedef T functor_type;
ebo_functor_holder(){}
explicit ebo_functor_holder(const T& t)
: super(t)
diff --git a/boost/intrusive/detail/get_value_traits.hpp b/boost/intrusive/detail/get_value_traits.hpp
index 686e059583..222f8078a6 100644
--- a/boost/intrusive/detail/get_value_traits.hpp
+++ b/boost/intrusive/detail/get_value_traits.hpp
@@ -107,9 +107,9 @@ BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_base_hook, hooktags::is_ba
template <class T>
struct internal_member_value_traits
{
- template <class U> static one test(...);
- template <class U> static two test(typename U::member_value_traits* = 0);
- static const bool value = sizeof(test<T>(0)) == sizeof(two);
+ template <class U> static yes_type test(...);
+ template <class U> static no_type test(typename U::member_value_traits* = 0);
+ static const bool value = sizeof(test<T>(0)) == sizeof(no_type);
};
template<class SupposedValueTraits, class T, bool = is_default_hook_tag<SupposedValueTraits>::value>
diff --git a/boost/intrusive/detail/hashtable_node.hpp b/boost/intrusive/detail/hashtable_node.hpp
index 923a3e1d38..352be28cbe 100644
--- a/boost/intrusive/detail/hashtable_node.hpp
+++ b/boost/intrusive/detail/hashtable_node.hpp
@@ -113,9 +113,9 @@ struct bucket_traits_impl
template <class NodeTraits>
struct hash_reduced_slist_node_traits
{
- template <class U> static detail::one test(...);
- template <class U> static detail::two test(typename U::reduced_slist_node_traits* = 0);
- static const bool value = sizeof(test<NodeTraits>(0)) == sizeof(detail::two);
+ template <class U> static detail::no_type test(...);
+ template <class U> static detail::yes_type test(typename U::reduced_slist_node_traits*);
+ static const bool value = sizeof(test<NodeTraits>(0)) == sizeof(detail::yes_type);
};
template <class NodeTraits>
@@ -154,52 +154,48 @@ struct get_slist_impl
template<class BucketValueTraits, bool IsConst>
class hashtable_iterator
{
- typedef boost::intrusive::iterator
- < std::forward_iterator_tag
- , typename BucketValueTraits::value_traits::value_type
- , typename pointer_traits<typename BucketValueTraits::value_traits::value_type*>::difference_type
- , typename detail::add_const_if_c
- <typename BucketValueTraits::value_traits::value_type, IsConst>::type *
- , typename detail::add_const_if_c
- <typename BucketValueTraits::value_traits::value_type, IsConst>::type &
- > iterator_traits;
-
- typedef typename BucketValueTraits::value_traits value_traits;
- typedef typename BucketValueTraits::bucket_traits bucket_traits;
- typedef typename value_traits::node_traits node_traits;
+ typedef typename BucketValueTraits::value_traits value_traits;
+ typedef typename BucketValueTraits::bucket_traits bucket_traits;
+
+ typedef iiterator< value_traits, IsConst
+ , std::forward_iterator_tag> types_t;
+ public:
+ typedef typename types_t::iterator_traits::difference_type difference_type;
+ typedef typename types_t::iterator_traits::value_type value_type;
+ typedef typename types_t::iterator_traits::pointer pointer;
+ typedef typename types_t::iterator_traits::reference reference;
+ typedef typename types_t::iterator_traits::iterator_category iterator_category;
+
+ private:
+ typedef typename value_traits::node_traits node_traits;
+ typedef typename node_traits::node_ptr node_ptr;
typedef typename detail::get_slist_impl
- <typename detail::reduced_slist_node_traits
- <typename value_traits::node_traits>::type
- >::type slist_impl;
- typedef typename slist_impl::iterator siterator;
- typedef typename slist_impl::const_iterator const_siterator;
- typedef detail::bucket_impl<slist_impl> bucket_type;
+ < typename detail::reduced_slist_node_traits
+ <node_traits>::type >::type slist_impl;
+ typedef typename slist_impl::iterator siterator;
+ typedef typename slist_impl::const_iterator const_siterator;
+ typedef detail::bucket_impl<slist_impl> bucket_type;
typedef typename pointer_traits
- <typename value_traits::pointer>::template rebind_pointer
- < const BucketValueTraits >::type const_bucketvaltraits_ptr;
- typedef typename slist_impl::size_type size_type;
-
+ <pointer>::template rebind_pointer
+ < const BucketValueTraits >::type const_bucketvaltraits_ptr;
+ typedef typename slist_impl::size_type size_type;
- static typename node_traits::node_ptr downcast_bucket(typename bucket_type::node_ptr p)
+ static node_ptr downcast_bucket(typename bucket_type::node_ptr p)
{
- return pointer_traits<typename node_traits::node_ptr>::
+ return pointer_traits<node_ptr>::
pointer_to(static_cast<typename node_traits::node&>(*p));
}
public:
- typedef typename iterator_traits::difference_type difference_type;
- typedef typename iterator_traits::value_type value_type;
- typedef typename iterator_traits::pointer pointer;
- typedef typename iterator_traits::reference reference;
- typedef typename iterator_traits::iterator_category iterator_category;
hashtable_iterator ()
: slist_it_() //Value initialization to achieve "null iterators" (N3644)
{}
explicit hashtable_iterator(siterator ptr, const BucketValueTraits *cont)
- : slist_it_ (ptr), traitsptr_ (cont ? pointer_traits<const_bucketvaltraits_ptr>::pointer_to(*cont) : const_bucketvaltraits_ptr() )
+ : slist_it_ (ptr)
+ , traitsptr_ (cont ? pointer_traits<const_bucketvaltraits_ptr>::pointer_to(*cont) : const_bucketvaltraits_ptr() )
{}
hashtable_iterator(const hashtable_iterator<BucketValueTraits, false> &other)
@@ -212,7 +208,6 @@ class hashtable_iterator
hashtable_iterator<BucketValueTraits, false> unconst() const
{ return hashtable_iterator<BucketValueTraits, false>(this->slist_it(), this->get_bucket_value_traits()); }
- public:
hashtable_iterator& operator++()
{ this->increment(); return *this; }
@@ -234,8 +229,8 @@ class hashtable_iterator
pointer operator->() const
{
- return boost::intrusive::detail::to_raw_pointer(this->priv_value_traits().to_value_ptr
- (downcast_bucket(slist_it_.pointed_node())));
+ return this->priv_value_traits().to_value_ptr
+ (downcast_bucket(slist_it_.pointed_node()));
}
const const_bucketvaltraits_ptr &get_bucket_value_traits() const
diff --git a/boost/intrusive/detail/is_stateful_value_traits.hpp b/boost/intrusive/detail/is_stateful_value_traits.hpp
index 680b043aa8..e43f6d340a 100644
--- a/boost/intrusive/detail/is_stateful_value_traits.hpp
+++ b/boost/intrusive/detail/is_stateful_value_traits.hpp
@@ -32,7 +32,7 @@ namespace detail {
template<class ValueTraits>
struct is_stateful_value_traits
{
- static const bool value = !detail::is_empty_class<ValueTraits>::value;
+ static const bool value = !detail::is_empty<ValueTraits>::value;
};
}}}
diff --git a/boost/intrusive/detail/iterator.hpp b/boost/intrusive/detail/iterator.hpp
index fb6fb81976..9f0fe606f4 100644
--- a/boost/intrusive/detail/iterator.hpp
+++ b/boost/intrusive/detail/iterator.hpp
@@ -141,6 +141,14 @@ typename iterator_enable_if_tag_difference_type
return off;
}
+template<class I>
+typename iterator_traits<I>::pointer iterator_arrow_result(const I &i)
+{ return i.operator->(); }
+
+template<class T>
+T * iterator_arrow_result(T *p)
+{ return p; }
+
} //namespace intrusive
} //namespace boost
diff --git a/boost/intrusive/detail/key_nodeptr_comp.hpp b/boost/intrusive/detail/key_nodeptr_comp.hpp
index 8c456634e5..df2b895db9 100644
--- a/boost/intrusive/detail/key_nodeptr_comp.hpp
+++ b/boost/intrusive/detail/key_nodeptr_comp.hpp
@@ -28,18 +28,27 @@ namespace boost {
namespace intrusive {
namespace detail {
-template<class KeyValueCompare, class ValueTraits>
+template < class KeyTypeKeyCompare
+ , class ValueTraits
+ , class KeyOfValue = void
+ >
struct key_nodeptr_comp
//Use public inheritance to avoid MSVC bugs with closures
- : public ebo_functor_holder<KeyValueCompare>
+ : public ebo_functor_holder<KeyTypeKeyCompare>
{
typedef ValueTraits value_traits;
typedef typename value_traits::value_type value_type;
typedef typename value_traits::node_ptr node_ptr;
typedef typename value_traits::const_node_ptr const_node_ptr;
- typedef ebo_functor_holder<KeyValueCompare> base_t;
-
- key_nodeptr_comp(KeyValueCompare kcomp, const ValueTraits *traits)
+ typedef ebo_functor_holder<KeyTypeKeyCompare> base_t;
+ typedef typename detail::if_c
+ < detail::is_same<KeyOfValue, void>::value
+ , detail::identity<value_type>
+ , KeyOfValue
+ >::type key_of_value;
+ typedef typename key_of_value::type key_type;
+
+ key_nodeptr_comp(KeyTypeKeyCompare kcomp, const ValueTraits *traits)
: base_t(kcomp), traits_(traits)
{}
@@ -51,12 +60,13 @@ struct key_nodeptr_comp
//key_forward
template<class T>
- const value_type & key_forward
- (const T &node, typename enable_if_c<is_node_ptr<T>::value>::type * = 0) const
- { return *traits_->to_value_ptr(node); }
+ typename enable_if<is_node_ptr<T>, const key_type &>::type
+ key_forward(const T &node) const
+ { return key_of_value()(*traits_->to_value_ptr(node)); }
template<class T>
- const T & key_forward(const T &key, typename enable_if_c<!is_node_ptr<T>::value>::type* = 0) const
+ typename disable_if<is_node_ptr<T>, const T &>::type
+ const key_forward(const T &key) const
{ return key; }
//operator() 1 arg
diff --git a/boost/intrusive/detail/list_iterator.hpp b/boost/intrusive/detail/list_iterator.hpp
index 77c9fa6097..6af4841c3e 100644
--- a/boost/intrusive/detail/list_iterator.hpp
+++ b/boost/intrusive/detail/list_iterator.hpp
@@ -34,7 +34,7 @@ namespace intrusive {
template<class ValueTraits, bool IsConst>
class list_iterator
{
- protected:
+ private:
typedef iiterator
<ValueTraits, IsConst, std::bidirectional_iterator_tag> types_t;
diff --git a/boost/intrusive/detail/math.hpp b/boost/intrusive/detail/math.hpp
index 03000fceeb..dfebe2ab42 100644
--- a/boost/intrusive/detail/math.hpp
+++ b/boost/intrusive/detail/math.hpp
@@ -127,7 +127,7 @@ namespace detail {
{ return (n >> 1) + ((n & 1u) & (n != 1)); }
template<std::size_t N>
- inline std::size_t floor_log2 (std::size_t x, integer<std::size_t, N>)
+ inline std::size_t floor_log2 (std::size_t x, integral_constant<std::size_t, N>)
{
const std::size_t Bits = N;
const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
@@ -156,7 +156,7 @@ namespace detail {
//http://stackoverflow.com/questions/11376288/fast-computing-of-log2-for-64-bit-integers
//Thanks to Desmond Hume
- inline std::size_t floor_log2 (std::size_t v, integer<std::size_t, 32>)
+ inline std::size_t floor_log2 (std::size_t v, integral_constant<std::size_t, 32>)
{
static const int MultiplyDeBruijnBitPosition[32] =
{
@@ -173,7 +173,7 @@ namespace detail {
return MultiplyDeBruijnBitPosition[(std::size_t)(v * 0x07C4ACDDU) >> 27];
}
- inline std::size_t floor_log2 (std::size_t v, integer<std::size_t, 64>)
+ inline std::size_t floor_log2 (std::size_t v, integral_constant<std::size_t, 64>)
{
static const std::size_t MultiplyDeBruijnBitPosition[64] = {
63, 0, 58, 1, 59, 47, 53, 2,
@@ -198,7 +198,7 @@ namespace detail {
inline std::size_t floor_log2 (std::size_t x)
{
const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
- return floor_log2(x, integer<std::size_t, Bits>());
+ return floor_log2(x, integral_constant<std::size_t, Bits>());
}
#endif
diff --git a/boost/intrusive/detail/mpl.hpp b/boost/intrusive/detail/mpl.hpp
index 39d2c58bd3..8d227a16fd 100644
--- a/boost/intrusive/detail/mpl.hpp
+++ b/boost/intrusive/detail/mpl.hpp
@@ -23,260 +23,48 @@
#endif
#include <boost/intrusive/detail/config_begin.hpp>
+#include <boost/move/detail/type_traits.hpp>
#include <cstddef>
namespace boost {
namespace intrusive {
namespace detail {
-
-template <typename T, typename U>
-struct is_same
-{
- static const bool value = false;
-};
-
-template <typename T>
-struct is_same<T, T>
-{
- static const bool value = true;
-};
-
-template<typename T>
-struct add_const
-{ typedef const T type; };
-
-template<typename T>
-struct remove_const
-{ typedef T type; };
-
-template<typename T>
-struct remove_const<const T>
-{ typedef T type; };
-
-template<typename T>
-struct remove_cv
-{ typedef T type; };
-
-template<typename T>
-struct remove_cv<const T>
-{ typedef T type; };
-
-template<typename T>
-struct remove_cv<const volatile T>
-{ typedef T type; };
-
-template<typename T>
-struct remove_cv<volatile T>
-{ typedef T type; };
-
-template<class T>
-struct remove_reference
-{
- typedef T type;
-};
-
-template<class T>
-struct remove_reference<T&>
-{
- typedef T type;
-};
-
-template<class T>
-struct remove_pointer
-{
- typedef T type;
-};
-
-template<class T>
-struct remove_pointer<T*>
-{
- typedef T type;
-};
-
-template<class T>
-struct add_pointer
-{
- typedef T *type;
-};
-
-typedef char one;
-struct two {one _[2];};
-
-template< bool C_ >
-struct bool_
-{
- static const bool value = C_;
-};
-
-template< class Integer, Integer Value >
-struct integer
-{
- static const Integer value = Value;
-};
-
-typedef bool_<true> true_;
-typedef bool_<false> false_;
-
-typedef true_ true_type;
-typedef false_ false_type;
-
-typedef char yes_type;
-struct no_type
-{
- char padding[8];
-};
-
-template <bool B, class T = void>
-struct enable_if_c {
- typedef T type;
-};
-
-template <class T>
-struct enable_if_c<false, T> {};
-
-template <class Cond, class T = void>
-struct enable_if : public enable_if_c<Cond::value, T>{};
-
-template<class F, class Param>
-struct apply
-{
- typedef typename F::template apply<Param>::type type;
-};
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
-
-template <class T, class U>
-struct is_convertible
-{
- static const bool value = __is_convertible_to(T, U);
-};
-
-#else
-
-template <class T, class U>
-class is_convertible
-{
- typedef char true_t;
- class false_t { char dummy[2]; };
- //use any_conversion as first parameter since in MSVC
- //overaligned types can't go through ellipsis
- static false_t dispatch(...);
- static true_t dispatch(U);
- static typename remove_reference<T>::type &trigger();
- public:
- static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
-};
-
-#endif
-
-template<
- bool C
- , typename T1
- , typename T2
- >
-struct if_c
-{
- typedef T1 type;
-};
-
-template<
- typename T1
- , typename T2
- >
-struct if_c<false,T1,T2>
-{
- typedef T2 type;
-};
-
-template<
- typename C
- , typename T1
- , typename T2
- >
-struct if_
-{
- typedef typename if_c<0 != C::value, T1, T2>::type type;
-};
-
-template<
- bool C
- , typename F1
- , typename F2
- >
-struct eval_if_c
- : if_c<C,F1,F2>::type
-{};
-
-template<
- typename C
- , typename T1
- , typename T2
- >
-struct eval_if
- : if_<C,T1,T2>::type
-{};
-
-// identity is an extension: it is not part of the standard.
-template <class T>
-struct identity
-{
- typedef T type;
-};
-
-template<class T, bool Add>
-struct add_const_if_c
-{
- typedef typename if_c
- < Add
- , typename add_const<T>::type
- , T
- >::type type;
-};
-
-
-//boost::alignment_of yields to 10K lines of preprocessed code, so we
-//need an alternative
-template <typename T> struct alignment_of;
-
-template <typename T>
-struct alignment_of_hack
-{
- char c;
- T t;
- alignment_of_hack();
-};
-
-template <unsigned A, unsigned S>
-struct alignment_logic
-{
- static const std::size_t value = A < S ? A : S;
-};
-
-template< typename T >
-struct alignment_of
-{
- static const std::size_t value = alignment_logic
- < sizeof(alignment_of_hack<T>) - sizeof(T)
- , sizeof(T)
- >::value;
-};
-
-template<class Class>
-class is_empty_class
-{
- template <typename T>
- struct empty_helper_t1 : public T
- {
- empty_helper_t1();
- int i[256];
- };
-
- struct empty_helper_t2
- { int i[256]; };
-
- public:
- static const bool value = sizeof(empty_helper_t1<Class>) == sizeof(empty_helper_t2);
-};
+
+using boost::move_detail::is_same;
+using boost::move_detail::add_const;
+using boost::move_detail::remove_const;
+using boost::move_detail::remove_cv;
+using boost::move_detail::remove_reference;
+using boost::move_detail::add_reference;
+using boost::move_detail::remove_pointer;
+using boost::move_detail::add_pointer;
+using boost::move_detail::true_type;
+using boost::move_detail::false_type;
+using boost::move_detail::enable_if_c;
+using boost::move_detail::enable_if;
+using boost::move_detail::disable_if_c;
+using boost::move_detail::disable_if;
+using boost::move_detail::is_convertible;
+using boost::move_detail::if_c;
+using boost::move_detail::if_;
+using boost::move_detail::is_const;
+using boost::move_detail::identity;
+using boost::move_detail::alignment_of;
+using boost::move_detail::is_empty;
+using boost::move_detail::addressof;
+using boost::move_detail::integral_constant;
+using boost::move_detail::enable_if_convertible;
+using boost::move_detail::disable_if_convertible;
+using boost::move_detail::bool_;
+using boost::move_detail::true_;
+using boost::move_detail::false_;
+using boost::move_detail::yes_type;
+using boost::move_detail::no_type;
+using boost::move_detail::apply;
+using boost::move_detail::eval_if_c;
+using boost::move_detail::eval_if;
+using boost::move_detail::unvoid_ref;
+using boost::move_detail::add_const_if_c;
template<std::size_t S>
struct ls_zeros
@@ -296,10 +84,6 @@ struct ls_zeros<1>
static const std::size_t value = 0;
};
-template <typename T> struct unvoid_ref { typedef T &type; };
-template <> struct unvoid_ref<void> { struct type_impl { }; typedef type_impl & type; };
-template <> struct unvoid_ref<const void> { struct type_impl { }; typedef type_impl & type; };
-
// Infrastructure for providing a default type for T::TNAME if absent.
#define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \
template <typename T, typename DefaultType> \
@@ -360,8 +144,8 @@ template <class T>\
struct TRAITS_PREFIX##_bool\
{\
template<bool Add>\
- struct two_or_three {one _[2 + Add];};\
- template <class U> static one test(...);\
+ struct two_or_three {yes_type _[2 + Add];};\
+ template <class U> static yes_type test(...);\
template <class U> static two_or_three<U::TYPEDEF_TO_FIND> test (int);\
static const std::size_t value = sizeof(test<T>(0));\
};\
@@ -369,7 +153,7 @@ struct TRAITS_PREFIX##_bool\
template <class T>\
struct TRAITS_PREFIX##_bool_is_true\
{\
- static const bool value = TRAITS_PREFIX##_bool<T>::value > sizeof(one)*2;\
+ static const bool value = TRAITS_PREFIX##_bool<T>::value > sizeof(yes_type)*2;\
};\
//
@@ -380,10 +164,10 @@ struct TRAITS_PREFIX##_bool_is_true\
private: \
template<Signature> struct helper;\
template<typename T> \
- static ::boost::intrusive::detail::yes_type check(helper<&T::FUNC_NAME>*); \
- template<typename T> static ::boost::intrusive::detail::no_type check(...); \
+ static ::boost::intrusive::detail::yes_type test(helper<&T::FUNC_NAME>*); \
+ template<typename T> static ::boost::intrusive::detail::no_type test(...); \
public: \
- static const bool value = sizeof(check<U>(0)) == sizeof(::boost::intrusive::detail::yes_type); \
+ static const bool value = sizeof(test<U>(0)) == sizeof(::boost::intrusive::detail::yes_type); \
}; \
//
@@ -398,9 +182,9 @@ struct TRAITS_NAME \
struct Base : public Type, public BaseMixin { Base(); }; \
template <typename T, T t> class Helper{}; \
template <typename U> \
- static ::boost::intrusive::detail::no_type check(U*, Helper<void (BaseMixin::*)(), &U::FUNC_NAME>* = 0); \
- static ::boost::intrusive::detail::yes_type check(...); \
- static const bool value = sizeof(::boost::intrusive::detail::yes_type) == sizeof(check((Base*)(0))); \
+ static ::boost::intrusive::detail::no_type test(U*, Helper<void (BaseMixin::*)(), &U::FUNC_NAME>* = 0); \
+ static ::boost::intrusive::detail::yes_type test(...); \
+ static const bool value = sizeof(::boost::intrusive::detail::yes_type) == sizeof(test((Base*)(0))); \
};\
//
@@ -413,18 +197,6 @@ struct TRAITS_NAME \
{};\
//
-
-template <typename T>
-inline T* addressof(T& obj)
-{
- return static_cast<T*>
- (static_cast<void*>
- (const_cast<char*>
- (&reinterpret_cast<const char&>(obj))
- )
- );
-}
-
} //namespace detail
} //namespace intrusive
} //namespace boost
diff --git a/boost/intrusive/detail/node_cloner_disposer.hpp b/boost/intrusive/detail/node_cloner_disposer.hpp
index 65af3e37b8..3fe2954347 100644
--- a/boost/intrusive/detail/node_cloner_disposer.hpp
+++ b/boost/intrusive/detail/node_cloner_disposer.hpp
@@ -36,21 +36,22 @@ struct node_cloner
//Use public inheritance to avoid MSVC bugs with closures
: public ebo_functor_holder<F>
{
- typedef ValueTraits value_traits;
- typedef typename value_traits::node_traits node_traits;
- typedef typename node_traits::node_ptr node_ptr;
- typedef ebo_functor_holder<F> base_t;
+ typedef ValueTraits value_traits;
+ typedef typename value_traits::node_traits node_traits;
+ typedef typename node_traits::node_ptr node_ptr;
+ typedef ebo_functor_holder<F> base_t;
typedef typename get_algo< AlgoType
- , node_traits>::type node_algorithms;
+ , node_traits>::type node_algorithms;
static const bool safemode_or_autounlink =
is_safe_autounlink<value_traits::link_mode>::value;
- typedef typename value_traits::value_type value_type;
- typedef typename value_traits::pointer pointer;
- typedef typename node_traits::node node;
- typedef typename value_traits::const_node_ptr const_node_ptr;
- typedef typename value_traits::reference reference;
- typedef typename value_traits::const_reference const_reference;
-
+ typedef typename value_traits::value_type value_type;
+ typedef typename value_traits::pointer pointer;
+ typedef typename value_traits::const_pointer const_pointer;
+ typedef typename node_traits::node node;
+ typedef typename value_traits::const_node_ptr const_node_ptr;
+ typedef typename pointer_traits<pointer>::reference reference;
+ typedef typename pointer_traits
+ <const_pointer>::reference const_reference;
typedef typename if_c<IsConst, const_reference, reference>::type reference_type;
node_cloner(F f, const ValueTraits *traits)
@@ -63,21 +64,7 @@ struct node_cloner
reference_type v = *traits_->to_value_ptr(p);
node_ptr n = traits_->to_node_ptr(*base_t::get()(v));
//Cloned node must be in default mode if the linking mode requires it
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
- return n;
- }
-
- // hashtables use this method, which is proxy-reference unfriendly
- node_ptr operator()(const node &to_clone)
- {
- reference_type v =
- *traits_->to_value_ptr
- (pointer_traits<const_node_ptr>::pointer_to(to_clone));
- node_ptr n = traits_->to_node_ptr(*base_t::get()(v));
- //Cloned node must be in default mode if the linking mode requires it
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(n));
return n;
}
diff --git a/boost/intrusive/detail/reverse_iterator.hpp b/boost/intrusive/detail/reverse_iterator.hpp
index 6a6fee5ac2..552e8f4d71 100644
--- a/boost/intrusive/detail/reverse_iterator.hpp
+++ b/boost/intrusive/detail/reverse_iterator.hpp
@@ -23,6 +23,7 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/iterator.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
namespace boost {
namespace intrusive {
@@ -49,10 +50,17 @@ class reverse_iterator
{}
template<class OtherIt>
- reverse_iterator(const reverse_iterator<OtherIt>& r)
+ reverse_iterator( const reverse_iterator<OtherIt>& r
+ , typename boost::intrusive::detail::enable_if_convertible<OtherIt, It>::type* =0
+ )
: m_current(r.base())
{}
+ template<class OtherIt>
+ typename boost::intrusive::detail::enable_if_convertible<OtherIt, It, reverse_iterator &>::type
+ operator=( const reverse_iterator<OtherIt>& r)
+ { m_current = r.base(); return *this; }
+
It base() const
{ return m_current; }
@@ -60,10 +68,10 @@ class reverse_iterator
{ It temp(m_current); --temp; return *temp; }
pointer operator->() const
- { It temp(m_current); --temp; return temp.operator->(); }
+ { It temp(m_current); --temp; return iterator_arrow_result(temp); }
reference operator[](difference_type off) const
- { return this->m_current[-off-1]; }
+ { return this->m_current[-off - 1]; }
reverse_iterator& operator++()
{ --m_current; return *this; }
@@ -109,22 +117,17 @@ class reverse_iterator
reverse_iterator& operator+=(difference_type off)
{ m_current -= off; return *this; }
- friend reverse_iterator operator+(const reverse_iterator & l, difference_type off)
- {
- reverse_iterator tmp(l.m_current);
- tmp.m_current -= off;
- return tmp;
- }
+ friend reverse_iterator operator+(reverse_iterator l, difference_type off)
+ { l.m_current -= off; return l; }
+
+ friend reverse_iterator operator+(difference_type off, reverse_iterator r)
+ { return (r += off); }
reverse_iterator& operator-=(difference_type off)
{ m_current += off; return *this; }
- friend reverse_iterator operator-(const reverse_iterator & l, difference_type off)
- {
- reverse_iterator tmp(l.m_current);
- tmp.m_current += off;
- return tmp;
- }
+ friend reverse_iterator operator-(reverse_iterator l, difference_type off)
+ { l.m_current += off; return l; }
friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r)
{ return r.m_current - l.m_current; }
diff --git a/boost/intrusive/detail/slist_iterator.hpp b/boost/intrusive/detail/slist_iterator.hpp
index 80a6fef924..1699064ec1 100644
--- a/boost/intrusive/detail/slist_iterator.hpp
+++ b/boost/intrusive/detail/slist_iterator.hpp
@@ -36,7 +36,7 @@ namespace intrusive {
template<class ValueTraits, bool IsConst>
class slist_iterator
{
- protected:
+ private:
typedef iiterator
<ValueTraits, IsConst, std::forward_iterator_tag> types_t;
diff --git a/boost/intrusive/detail/std_fwd.hpp b/boost/intrusive/detail/std_fwd.hpp
index 0492c1dc3d..4b5cedbae3 100644
--- a/boost/intrusive/detail/std_fwd.hpp
+++ b/boost/intrusive/detail/std_fwd.hpp
@@ -23,10 +23,12 @@
// Standard predeclarations
//////////////////////////////////////////////////////////////////////////////
-#if defined(__clang__) && defined(_LIBCPP_VERSION)
+#if defined(_LIBCPP_VERSION)
#define BOOST_INTRUSIVE_CLANG_INLINE_STD_NS
#pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wc++11-extensions"
+ #if defined(__clang__)
+ #pragma GCC diagnostic ignored "-Wc++11-extensions"
+ #endif
#define BOOST_INTRUSIVE_STD_NS_BEG _LIBCPP_BEGIN_NAMESPACE_STD
#define BOOST_INTRUSIVE_STD_NS_END _LIBCPP_END_NAMESPACE_STD
#elif defined(BOOST_GNU_STDLIB) && defined(_GLIBCXX_BEGIN_NAMESPACE_VERSION) //GCC >= 4.6
diff --git a/boost/intrusive/detail/transform_iterator.hpp b/boost/intrusive/detail/transform_iterator.hpp
index 89ec973967..5e3b1a7652 100644
--- a/boost/intrusive/detail/transform_iterator.hpp
+++ b/boost/intrusive/detail/transform_iterator.hpp
@@ -23,6 +23,7 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/intrusive/detail/iterator.hpp>
namespace boost {
namespace intrusive {
@@ -58,14 +59,14 @@ struct operator_arrow_proxy<T&>
template <class Iterator, class UnaryFunction>
class transform_iterator
- : public boost::intrusive::iterator
- < typename Iterator::iterator_category
- , typename detail::remove_reference<typename UnaryFunction::result_type>::type
- , typename Iterator::difference_type
- , operator_arrow_proxy<typename UnaryFunction::result_type>
- , typename UnaryFunction::result_type>
{
public:
+ typedef typename Iterator::iterator_category iterator_category;
+ typedef typename detail::remove_reference<typename UnaryFunction::result_type>::type value_type;
+ typedef typename Iterator::difference_type difference_type;
+ typedef operator_arrow_proxy<typename UnaryFunction::result_type> pointer;
+ typedef typename UnaryFunction::result_type reference;
+
explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
: members_(it, f)
{}
diff --git a/boost/intrusive/detail/tree_iterator.hpp b/boost/intrusive/detail/tree_iterator.hpp
index 525761f3d6..c2e980d27a 100644
--- a/boost/intrusive/detail/tree_iterator.hpp
+++ b/boost/intrusive/detail/tree_iterator.hpp
@@ -40,13 +40,11 @@ namespace intrusive {
template<class ValueTraits, bool IsConst>
class tree_iterator
{
- protected:
+ private:
typedef iiterator< ValueTraits, IsConst
, std::bidirectional_iterator_tag> types_t;
-
- typedef ValueTraits value_traits;
+ typedef typename types_t::value_traits value_traits;
typedef typename types_t::node_traits node_traits;
-
typedef typename types_t::node node;
typedef typename types_t::node_ptr node_ptr;
typedef typename types_t::const_value_traits_ptr const_value_traits_ptr;
diff --git a/boost/intrusive/detail/tree_value_compare.hpp b/boost/intrusive/detail/tree_value_compare.hpp
new file mode 100644
index 0000000000..a05741edee
--- /dev/null
+++ b/boost/intrusive/detail/tree_value_compare.hpp
@@ -0,0 +1,78 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP
+#define BOOST_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/intrusive/detail/ebo_functor_holder.hpp>
+
+namespace boost{
+namespace intrusive{
+
+template<class Key, class T, class KeyCompare, class KeyOfValue>
+struct tree_value_compare
+ : public boost::intrusive::detail::ebo_functor_holder<KeyCompare>
+{
+ typedef boost::intrusive::detail::ebo_functor_holder<KeyCompare> base_t;
+ typedef T value_type;
+ typedef KeyCompare key_compare;
+ typedef KeyOfValue key_of_value;
+ typedef Key key_type;
+
+ explicit tree_value_compare(const key_compare &kcomp)
+ : base_t(kcomp)
+ {}
+
+ tree_value_compare()
+ : base_t()
+ {}
+
+ const key_compare &key_comp() const
+ { return static_cast<const key_compare &>(*this); }
+
+ key_compare &key_comp()
+ { return static_cast<key_compare &>(*this); }
+
+ template<class U>
+ struct is_key
+ : boost::intrusive::detail::is_same<const U, const key_type>
+ {};
+
+ template<class U>
+ typename boost::intrusive::detail::enable_if<is_key<U>, const key_type &>::type
+ key_forward(const U &key) const
+ { return key; }
+
+ template<class U>
+ typename boost::intrusive::detail::disable_if<is_key<U>, const key_type &>::type
+ key_forward(const U &key) const
+ { return KeyOfValue()(key); }
+
+ template<class KeyType, class KeyType2>
+ bool operator()(const KeyType &key1, const KeyType2 &key2) const
+ { return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
+
+ template<class KeyType, class KeyType2>
+ bool operator()(const KeyType &key1, const KeyType2 &key2)
+ { return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
+};
+
+} //namespace intrusive{
+} //namespace boost{
+
+#endif //#ifdef BOOST_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP
diff --git a/boost/intrusive/hashtable.hpp b/boost/intrusive/hashtable.hpp
index 1d4f3d3f0c..125330ff6e 100644
--- a/boost/intrusive/hashtable.hpp
+++ b/boost/intrusive/hashtable.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006-2013
+// (C) Copyright Ion Gaztanaga 2006-2015
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -26,6 +26,7 @@
#include <boost/intrusive/detail/node_cloner_disposer.hpp>
#include <boost/intrusive/detail/simple_disposers.hpp>
#include <boost/intrusive/detail/size_holder.hpp>
+#include <boost/intrusive/detail/iterator.hpp>
//Implementation utilities
#include <boost/intrusive/unordered_set_hook.hpp>
@@ -55,6 +56,62 @@ namespace intrusive {
/// @cond
+template<class InputIt, class T>
+InputIt priv_algo_find(InputIt first, InputIt last, const T& value)
+{
+ for (; first != last; ++first) {
+ if (*first == value) {
+ return first;
+ }
+ }
+ return last;
+}
+
+template<class InputIt, class T>
+typename boost::intrusive::iterator_traits<InputIt>::difference_type
+ priv_algo_count(InputIt first, InputIt last, const T& value)
+{
+ typename boost::intrusive::iterator_traits<InputIt>::difference_type ret = 0;
+ for (; first != last; ++first) {
+ if (*first == value) {
+ ret++;
+ }
+ }
+ return ret;
+}
+
+template <class ForwardIterator1, class ForwardIterator2>
+bool priv_algo_is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2)
+{
+ typedef typename
+ boost::intrusive::iterator_traits<ForwardIterator2>::difference_type
+ distance_type;
+ //Efficiently compare identical prefixes: O(N) if sequences
+ //have the same elements in the same order.
+ for ( ; first1 != last1; ++first1, ++first2){
+ if (! (*first1 == *first2))
+ break;
+ }
+ if (first1 == last1){
+ return true;
+ }
+
+ //Establish last2 assuming equal ranges by iterating over the
+ //rest of the list.
+ ForwardIterator2 last2 = first2;
+ boost::intrusive::iterator_advance(last2, boost::intrusive::iterator_distance(first1, last1));
+ for(ForwardIterator1 scan = first1; scan != last1; ++scan){
+ if (scan != (priv_algo_find)(first1, scan, *scan)){
+ continue; //We've seen this one before.
+ }
+ distance_type matches = (priv_algo_count)(first2, last2, *scan);
+ if (0 == matches || (priv_algo_count)(scan, last1, *scan != matches)){
+ return false;
+ }
+ }
+ return true;
+}
+
template<int Dummy = 0>
struct prime_list_holder
{
@@ -169,35 +226,23 @@ struct unordered_bucket_ptr_impl
};
template <class T>
-struct store_hash_bool
+struct store_hash_is_true
{
template<bool Add>
- struct two_or_three {one _[2 + Add];};
- template <class U> static one test(...);
+ struct two_or_three {yes_type _[2 + Add];};
+ template <class U> static yes_type test(...);
template <class U> static two_or_three<U::store_hash> test (int);
- static const std::size_t value = sizeof(test<T>(0));
+ static const bool value = sizeof(test<T>(0)) > sizeof(yes_type)*2;
};
template <class T>
-struct store_hash_is_true
-{
- static const bool value = store_hash_bool<T>::value > sizeof(one)*2;
-};
-
-template <class T>
-struct optimize_multikey_bool
+struct optimize_multikey_is_true
{
template<bool Add>
- struct two_or_three {one _[2 + Add];};
- template <class U> static one test(...);
+ struct two_or_three {yes_type _[2 + Add];};
+ template <class U> static yes_type test(...);
template <class U> static two_or_three<U::optimize_multikey> test (int);
- static const std::size_t value = sizeof(test<T>(0));
-};
-
-template <class T>
-struct optimize_multikey_is_true
-{
- static const bool value = optimize_multikey_bool<T>::value > sizeof(one)*2;
+ static const bool value = sizeof(test<T>(0)) > sizeof(yes_type)*2;
};
struct insert_commit_data_impl
@@ -216,6 +261,23 @@ inline typename pointer_traits<SlistNodePtr>::template rebind_pointer<Node>::typ
template<class NodeTraits>
struct group_functions
{
+ // A group is reverse-linked
+ //
+ // A is "first in group"
+ // C is "last in group"
+ // __________________
+ // | _____ _____ |
+ // | | | | | | <- Group links
+ // ^ V ^ V ^ V
+ // _ _ _ _
+ // A|_| B|_| C|_| D|_|
+ //
+ // ^ | ^ | ^ | ^ V <- Bucket links
+ // _ _____| |_____| |______| |____| |
+ // |B| |
+ // ^________________________________|
+ //
+
typedef NodeTraits node_traits;
typedef unordered_group_adapter<node_traits> group_traits;
typedef typename node_traits::node_ptr node_ptr;
@@ -225,6 +287,7 @@ struct group_functions
typedef typename reduced_node_traits::node_ptr slist_node_ptr;
typedef typename reduced_node_traits::node slist_node;
typedef circular_slist_algorithms<group_traits> group_algorithms;
+ typedef circular_slist_algorithms<node_traits> node_algorithms;
static slist_node_ptr get_bucket_before_begin
(const slist_node_ptr &bucket_beg, const slist_node_ptr &bucket_end, const node_ptr &p)
@@ -260,53 +323,20 @@ struct group_functions
static node_ptr get_prev_to_first_in_group(const slist_node_ptr &bucket_node, const node_ptr &first_in_group)
{
- //Just iterate using group links and obtain the node
- //before "first_in_group)"
- node_ptr prev_node = detail::dcast_bucket_ptr<node>(bucket_node);
- node_ptr nxt(node_traits::get_next(prev_node));
- while(nxt != first_in_group){
- prev_node = group_traits::get_next(nxt);
- nxt = node_traits::get_next(prev_node);
+ node_ptr nb = detail::dcast_bucket_ptr<node>(bucket_node);
+ node_ptr n;
+ while((n = node_traits::get_next(nb)) != first_in_group){
+ nb = group_traits::get_next(n); //go to last in group
}
- return prev_node;
- }
-
- static node_ptr get_first_in_group_of_last_in_group(const node_ptr &last_in_group)
- {
- //Just iterate using group links and obtain the node
- //before "last_in_group"
- node_ptr possible_first = group_traits::get_next(last_in_group);
- node_ptr possible_first_prev = group_traits::get_next(possible_first);
- // The deleted node is at the end of the group, so the
- // node in the group pointing to it is at the beginning
- // of the group. Find that to change its pointer.
- while(possible_first_prev != last_in_group){
- possible_first = possible_first_prev;
- possible_first_prev = group_traits::get_next(possible_first);
- }
- return possible_first;
+ return nb;
}
static void erase_from_group(const slist_node_ptr &end_ptr, const node_ptr &to_erase_ptr, detail::true_)
{
- node_ptr nxt_ptr(node_traits::get_next(to_erase_ptr));
- node_ptr prev_in_group_ptr(group_traits::get_next(to_erase_ptr));
- bool last_in_group = (end_ptr == nxt_ptr) ||
- (group_traits::get_next(nxt_ptr) != to_erase_ptr);
- bool is_first_in_group = node_traits::get_next(prev_in_group_ptr) != to_erase_ptr;
-
- if(is_first_in_group && last_in_group){
- group_algorithms::init(to_erase_ptr);
- }
- else if(is_first_in_group){
- group_algorithms::unlink_after(nxt_ptr);
- }
- else if(last_in_group){
- node_ptr first_in_group =
- get_first_in_group_of_last_in_group(to_erase_ptr);
- group_algorithms::unlink_after(first_in_group);
- }
- else{
+ node_ptr const nxt_ptr(node_traits::get_next(to_erase_ptr));
+ //Check if the next node is in the group (not end node) and reverse linked to
+ //'to_erase_ptr'. Erase if that's the case.
+ if(nxt_ptr != end_ptr && to_erase_ptr == group_traits::get_next(nxt_ptr)){
group_algorithms::unlink_after(nxt_ptr);
}
}
@@ -317,81 +347,42 @@ struct group_functions
static node_ptr get_last_in_group(const node_ptr &first_in_group, detail::true_)
{ return group_traits::get_next(first_in_group); }
- static node_ptr get_last_in_group(const node_ptr &n, detail::false_)
+ static node_ptr get_last_in_group(node_ptr n, detail::false_)
{ return n; }
- static void init_group(const node_ptr &n, true_)
- { group_algorithms::init(n); }
-
- static void init_group(const node_ptr &, false_)
- {}
-
- static void insert_in_group(const node_ptr &first_in_group, const node_ptr &n, true_)
+ static node_ptr get_first_in_group(node_ptr n, detail::true_)
{
- if(first_in_group){
- if(group_algorithms::unique(first_in_group))
- group_algorithms::link_after(first_in_group, n);
- else{
- group_algorithms::link_after(node_traits::get_next(first_in_group), n);
- }
- }
- else{
- group_algorithms::init_header(n);
+ node_ptr ng;
+ while(n == node_traits::get_next((ng = group_traits::get_next(n)))){
+ n = ng;
}
+ return n;
}
- static slist_node_ptr get_previous_and_next_in_group
- ( const slist_node_ptr &i, node_ptr &nxt_in_group
- //If first_end_ptr == last_end_ptr, then first_end_ptr is the bucket of i
- //Otherwise first_end_ptr is the first bucket and last_end_ptr the last one.
- , const slist_node_ptr &first_end_ptr, const slist_node_ptr &last_end_ptr)
- {
- slist_node_ptr prev;
- node_ptr elem(detail::dcast_bucket_ptr<node>(i));
-
- //It's the last in group if the next_node is a bucket
- slist_node_ptr nxt(node_traits::get_next(elem));
- bool last_in_group = (first_end_ptr <= nxt && nxt <= last_end_ptr) ||
- (group_traits::get_next(detail::dcast_bucket_ptr<node>(nxt)) != elem);
- //It's the first in group if group_previous's next_node is not
- //itself, as group list does not link bucket
- node_ptr prev_in_group(group_traits::get_next(elem));
- bool first_in_group = node_traits::get_next(prev_in_group) != elem;
-
- if(first_in_group){
- node_ptr start_pos;
- if(last_in_group){
- start_pos = elem;
- nxt_in_group = node_ptr();
- }
- else{
- start_pos = prev_in_group;
- nxt_in_group = node_traits::get_next(elem);
- }
- slist_node_ptr bucket_node;
- if(first_end_ptr != last_end_ptr){
- bucket_node = group_functions::get_bucket_before_begin
- (first_end_ptr, last_end_ptr, start_pos);
- }
- else{
- bucket_node = first_end_ptr;
- }
- prev = group_functions::get_prev_to_first_in_group(bucket_node, elem);
- }
- else{
- if(last_in_group){
- nxt_in_group = group_functions::get_first_in_group_of_last_in_group(elem);
- }
- else{
- nxt_in_group = node_traits::get_next(elem);
- }
- prev = group_traits::get_next(elem);
- }
- return prev;
+ static node_ptr next_group_if_first_in_group(node_ptr ptr)
+ {
+ return node_traits::get_next(group_traits::get_next(ptr));
}
+ static node_ptr get_first_in_group(const node_ptr &n, detail::false_)
+ { return n; }
+
+ static void insert_in_group(const node_ptr &first_in_group, const node_ptr &n, true_)
+ { group_algorithms::link_after(first_in_group, n); }
+
static void insert_in_group(const node_ptr&, const node_ptr&, false_)
{}
+
+ static node_ptr split_group(node_ptr const new_first_in_group)
+ {
+ node_ptr const first((get_first_in_group)(new_first_in_group, detail::true_()));
+ if(first != new_first_in_group){
+ node_ptr const last = group_traits::get_next(first);
+ group_traits::set_next(first, group_traits::get_next(new_first_in_group));
+ group_traits::set_next(new_first_in_group, last);
+ }
+ return first;
+ }
};
template<class BucketType, class SplitTraits>
@@ -453,8 +444,7 @@ inline std::size_t hash_to_bucket_split(std::size_t hash_value, std::size_t buck
{
std::size_t bucket_number = detail::hash_to_bucket(hash_value, bucket_cnt, detail::bool_<Power2Buckets>());
if(Incremental)
- if(bucket_number >= split)
- bucket_number -= bucket_cnt/2;
+ bucket_number -= static_cast<std::size_t>(bucket_number >= split)*(bucket_cnt/2);
return bucket_number;
}
@@ -513,6 +503,7 @@ struct hashtable_defaults
{
typedef default_hashtable_hook_applier proto_value_traits;
typedef std::size_t size_type;
+ typedef void key_of_value;
typedef void equal;
typedef void hash;
typedef default_bucket_traits bucket_traits;
@@ -576,17 +567,11 @@ struct node_cast_adaptor
}
};
-static const std::size_t hashtable_data_bool_flags_mask =
- ( hash_bool_flags::cache_begin_pos
- | hash_bool_flags::constant_time_size_pos
- | hash_bool_flags::incremental_pos
- );
-
//bucket_plus_vtraits stores ValueTraits + BucketTraits
//this data is needed by iterators to obtain the
//value from the iterator and detect the bucket
template<class ValueTraits, class BucketTraits>
-struct bucket_plus_vtraits : public ValueTraits
+struct bucket_plus_vtraits
{
typedef BucketTraits bucket_traits;
typedef ValueTraits value_traits;
@@ -607,6 +592,11 @@ struct bucket_plus_vtraits : public ValueTraits
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::node node;
typedef typename value_traits::value_type value_type;
+ typedef typename value_traits::pointer pointer;
+ typedef typename value_traits::const_pointer const_pointer;
+ typedef typename pointer_traits<pointer>::reference reference;
+ typedef typename pointer_traits
+ <const_pointer>::reference const_reference;
typedef circular_slist_algorithms<group_traits> group_algorithms;
typedef typename pointer_traits
<typename value_traits::pointer>::
@@ -618,16 +608,14 @@ struct bucket_plus_vtraits : public ValueTraits
<const bucket_plus_vtraits>::type const_bucket_value_traits_ptr;
typedef typename detail::unordered_bucket_ptr_impl
<value_traits>::type bucket_ptr;
- typedef detail::bool_<detail::optimize_multikey_is_true
- <node_traits>::value> optimize_multikey_t;
template<class BucketTraitsType>
bucket_plus_vtraits(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits)
- : ValueTraits(val_traits), bucket_traits_(::boost::forward<BucketTraitsType>(b_traits))
+ : data(val_traits, ::boost::forward<BucketTraitsType>(b_traits))
{}
bucket_plus_vtraits & operator =(const bucket_plus_vtraits &x)
- { bucket_traits_ = x.bucket_traits_; return *this; }
+ { data.bucket_traits_ = x.data.bucket_traits_; return *this; }
const_value_traits_ptr priv_value_traits_ptr() const
{ return pointer_traits<const_value_traits_ptr>::pointer_to(this->priv_value_traits()); }
@@ -646,18 +634,18 @@ struct bucket_plus_vtraits : public ValueTraits
//value traits
//
const value_traits &priv_value_traits() const
- { return *this; }
+ { return this->data; }
value_traits &priv_value_traits()
- { return *this; }
+ { return this->data; }
//bucket_traits
//
const bucket_traits &priv_bucket_traits() const
- { return this->bucket_traits_; }
+ { return this->data.bucket_traits_; }
bucket_traits &priv_bucket_traits()
- { return this->bucket_traits_; }
+ { return this->data.bucket_traits_; }
//bucket operations
bucket_ptr priv_bucket_pointer() const
@@ -674,6 +662,119 @@ struct bucket_plus_vtraits : public ValueTraits
siterator priv_invalid_local_it() const
{ return this->priv_bucket_traits().bucket_begin()->before_begin(); }
+ template<class NodeDisposer>
+ static size_type priv_erase_from_single_bucket(bucket_type &b, siterator sbefore_first, siterator slast, NodeDisposer node_disposer, detail::true_) //optimize multikey
+ {
+ size_type n = 0;
+ siterator const sfirst(++siterator(sbefore_first));
+ if(sfirst != slast){
+ node_ptr const nf = detail::dcast_bucket_ptr<node>(sfirst.pointed_node());
+ node_ptr const nl = detail::dcast_bucket_ptr<node>(slast.pointed_node());
+ node_ptr const ne = detail::dcast_bucket_ptr<node>(b.end().pointed_node());
+
+ if(group_functions_t::next_group_if_first_in_group(nf) != nf) {
+ // The node is at the beginning of a group.
+ if(nl != ne){
+ group_functions_t::split_group(nl);
+ }
+ }
+ else {
+ node_ptr const group1 = group_functions_t::split_group(nf);
+ if(nl != ne) {
+ node_ptr const group2 = group_functions_t::split_group(ne);
+ if(nf == group2) { //Both first and last in the same group
+ //so join group1 and group2
+ node_ptr const end1 = group_traits::get_next(group1);
+ node_ptr const end2 = group_traits::get_next(group2);
+ group_traits::set_next(group1, end2);
+ group_traits::set_next(group2, end1);
+ }
+ }
+ }
+
+ siterator it(++siterator(sbefore_first));
+ while(it != slast){
+ node_disposer((it++).pointed_node());
+ ++n;
+ }
+ b.erase_after(sbefore_first, slast);
+ }
+ return n;
+ }
+
+ template<class NodeDisposer>
+ static size_type priv_erase_from_single_bucket(bucket_type &b, siterator sbefore_first, siterator slast, NodeDisposer node_disposer, detail::false_) //optimize multikey
+ {
+ size_type n = 0;
+ siterator it(++siterator(sbefore_first));
+ while(it != slast){
+ node_disposer((it++).pointed_node());
+ ++n;
+ }
+ b.erase_after(sbefore_first, slast);
+ return n;
+ }
+
+ template<class NodeDisposer>
+ static void priv_erase_node(bucket_type &b, siterator i, NodeDisposer node_disposer, detail::true_) //optimize multikey
+ {
+ node_ptr const ne(detail::dcast_bucket_ptr<node>(b.end().pointed_node()));
+ node_ptr n(detail::dcast_bucket_ptr<node>(i.pointed_node()));
+ node_ptr pos = node_traits::get_next(group_traits::get_next(n));
+ node_ptr bn;
+ node_ptr nn(node_traits::get_next(n));
+
+ if(pos != n) {
+ //Node is the first of the group
+ bn = group_functions_t::get_prev_to_first_in_group(ne, n);
+
+ //Unlink the rest of the group if it's not the last node of its group
+ if(nn != ne && group_traits::get_next(nn) == n){
+ group_algorithms::unlink_after(nn);
+ }
+ }
+ else if(nn != ne && group_traits::get_next(nn) == n){
+ //Node is not the end of the group
+ bn = group_traits::get_next(n);
+ group_algorithms::unlink_after(nn);
+ }
+ else{
+ //Node is the end of the group
+ bn = group_traits::get_next(n);
+ node_ptr const x(group_algorithms::get_previous_node(n));
+ group_algorithms::unlink_after(x);
+ }
+ b.erase_after_and_dispose(bucket_type::s_iterator_to(*bn), node_disposer);
+ }
+
+ template<class NodeDisposer>
+ static void priv_erase_node(bucket_type &b, siterator i, NodeDisposer node_disposer, detail::false_) //optimize multikey
+ { b.erase_after_and_dispose(b.previous(i), node_disposer); }
+
+ template<class NodeDisposer, bool OptimizeMultikey>
+ size_type priv_erase_node_range( siterator const &before_first_it, size_type const first_bucket
+ , siterator const &last_it, size_type const last_bucket
+ , NodeDisposer node_disposer, detail::bool_<OptimizeMultikey> optimize_multikey_tag)
+ {
+ size_type num_erased(0);
+ siterator last_step_before_it;
+ if(first_bucket != last_bucket){
+ bucket_type *b = (&this->priv_bucket_pointer()[0]);
+ num_erased += this->priv_erase_from_single_bucket
+ (b[first_bucket], before_first_it, b[first_bucket].end(), node_disposer, optimize_multikey_tag);
+ for(size_type i = 0, n = (last_bucket - first_bucket - 1); i != n; ++i){
+ num_erased += this->priv_erase_whole_bucket(b[first_bucket+i+1], node_disposer);
+ }
+ last_step_before_it = b[last_bucket].before_begin();
+ }
+ else{
+ last_step_before_it = before_first_it;
+ }
+ num_erased += this->priv_erase_from_single_bucket
+ (this->priv_bucket_pointer()[last_bucket], last_step_before_it, last_it, node_disposer, optimize_multikey_tag);
+ return num_erased;
+ }
+
static siterator priv_get_last(bucket_type &b, detail::true_) //optimize multikey
{
//First find the last node of p's group.
@@ -690,14 +791,30 @@ struct bucket_plus_vtraits : public ValueTraits
return bucket_type::s_iterator_to(*last_node_group);
}
+ template<class NodeDisposer>
+ size_type priv_erase_whole_bucket(bucket_type &b, NodeDisposer node_disposer)
+ {
+ size_type num_erased = 0;
+ siterator b_begin(b.before_begin());
+ siterator nxt(b_begin);
+ ++nxt;
+ siterator const end_sit(b.end());
+ while(nxt != end_sit){
+ //No need to init group links as we'll delete all bucket nodes
+ nxt = bucket_type::s_erase_after_and_dispose(b_begin, node_disposer);
+ ++num_erased;
+ }
+ return num_erased;
+ }
+
static siterator priv_get_last(bucket_type &b, detail::false_) //NOT optimize multikey
{ return b.previous(b.end()); }
static siterator priv_get_previous(bucket_type &b, siterator i, detail::true_) //optimize multikey
{
- node_ptr elem(detail::dcast_bucket_ptr<node>(i.pointed_node()));
- node_ptr prev_in_group(group_traits::get_next(elem));
- bool first_in_group = node_traits::get_next(prev_in_group) != elem;
+ node_ptr const elem(detail::dcast_bucket_ptr<node>(i.pointed_node()));
+ node_ptr const prev_in_group(group_traits::get_next(elem));
+ bool const first_in_group = node_traits::get_next(prev_in_group) != elem;
typename bucket_type::node &n = first_in_group
? *group_functions_t::get_prev_to_first_in_group(b.end().pointed_node(), elem)
: *group_traits::get_next(elem)
@@ -708,19 +825,6 @@ struct bucket_plus_vtraits : public ValueTraits
static siterator priv_get_previous(bucket_type &b, siterator i, detail::false_) //NOT optimize multikey
{ return b.previous(i); }
- static void priv_clear_group_nodes(bucket_type &b, detail::true_) //optimize multikey
- {
- siterator it(b.begin()), itend(b.end());
- while(it != itend){
- node_ptr to_erase(detail::dcast_bucket_ptr<node>(it.pointed_node()));
- ++it;
- group_algorithms::init(to_erase);
- }
- }
-
- static void priv_clear_group_nodes(bucket_type &, detail::false_) //NOT optimize multikey
- {}
-
std::size_t priv_get_bucket_num_no_hash_store(siterator it, detail::true_) //optimize multikey
{
const bucket_ptr f(this->priv_bucket_pointer()), l(f + this->priv_bucket_count() - 1);
@@ -757,19 +861,19 @@ struct bucket_plus_vtraits : public ValueTraits
static std::size_t priv_stored_hash(slist_node_ptr n, detail::true_) //store_hash
{ return node_traits::get_hash(detail::dcast_bucket_ptr<node>(n)); }
- static std::size_t priv_stored_hash(slist_node_ptr, detail::false_) //NO store_hash (This should never be called)
- { BOOST_INTRUSIVE_INVARIANT_ASSERT(0); return 0; }
+ static std::size_t priv_stored_hash(slist_node_ptr, detail::false_) //NO store_hash
+ { return std::size_t(-1); }
- node &priv_value_to_node(value_type &v)
+ node &priv_value_to_node(reference v)
{ return *this->priv_value_traits().to_node_ptr(v); }
- const node &priv_value_to_node(const value_type &v) const
+ const node &priv_value_to_node(const_reference v) const
{ return *this->priv_value_traits().to_node_ptr(v); }
- value_type &priv_value_from_slist_node(slist_node_ptr n)
+ reference priv_value_from_slist_node(slist_node_ptr n)
{ return *this->priv_value_traits().to_value_ptr(detail::dcast_bucket_ptr<node>(n)); }
- const value_type &priv_value_from_slist_node(slist_node_ptr n) const
+ const_reference priv_value_from_slist_node(slist_node_ptr n) const
{ return *this->priv_value_traits().to_value_ptr(detail::dcast_bucket_ptr<node>(n)); }
void priv_clear_buckets(const bucket_ptr buckets_ptr, const size_type bucket_cnt)
@@ -777,7 +881,6 @@ struct bucket_plus_vtraits : public ValueTraits
bucket_ptr buckets_it = buckets_ptr;
for(size_type bucket_i = 0; bucket_i != bucket_cnt; ++buckets_it, ++bucket_i){
if(safemode_or_autounlink){
- bucket_plus_vtraits::priv_clear_group_nodes(*buckets_it, optimize_multikey_t());
buckets_it->clear_and_dispose(detail::init_disposer<node_algorithms>());
}
else{
@@ -786,10 +889,51 @@ struct bucket_plus_vtraits : public ValueTraits
}
}
- bucket_traits bucket_traits_;
+ std::size_t priv_stored_or_compute_hash(const value_type &v, detail::true_) const //For store_hash == true
+ { return node_traits::get_hash(this->priv_value_traits().to_node_ptr(v)); }
+
+ typedef hashtable_iterator<bucket_plus_vtraits, false> iterator;
+ typedef hashtable_iterator<bucket_plus_vtraits, true> const_iterator;
+
+ iterator end()
+ { return iterator(this->priv_invalid_local_it(), 0); }
+
+ const_iterator end() const
+ { return this->cend(); }
+
+ const_iterator cend() const
+ { return const_iterator(this->priv_invalid_local_it(), 0); }
+
+ static size_type suggested_upper_bucket_count(size_type n)
+ {
+ const std::size_t *primes = &prime_list_holder<0>::prime_list[0];
+ const std::size_t *primes_end = primes + prime_list_holder<0>::prime_list_size;
+ std::size_t const* bound = std::lower_bound(primes, primes_end, n);
+ bound -= (bound == primes_end);
+ return size_type(*bound);
+ }
+
+ static size_type suggested_lower_bucket_count(size_type n)
+ {
+ const std::size_t *primes = &prime_list_holder<0>::prime_list[0];
+ const std::size_t *primes_end = primes + prime_list_holder<0>::prime_list_size;
+ size_type const* bound = std::upper_bound(primes, primes_end, n);
+ bound -= (bound != primes);
+ return size_type(*bound);
+ }
+
+ //Public functions:
+ struct data_type : public ValueTraits
+ {
+ template<class BucketTraitsType>
+ data_type(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits)
+ : ValueTraits(val_traits), bucket_traits_(::boost::forward<BucketTraitsType>(b_traits))
+ {}
+ bucket_traits bucket_traits_;
+ } data;
};
-template<class Hash, class T>
+template<class Hash, class>
struct get_hash
{
typedef Hash type;
@@ -801,76 +945,124 @@ struct get_hash<void, T>
typedef ::boost::hash<T> type;
};
+template<class EqualTo, class>
+struct get_equal_to
+{
+ typedef EqualTo type;
+};
+
+template<class T>
+struct get_equal_to<void, T>
+{
+ typedef std::equal_to<T> type;
+};
+
+template<class KeyOfValue, class T>
+struct get_hash_key_of_value
+{
+ typedef KeyOfValue type;
+};
+
+template<class T>
+struct get_hash_key_of_value<void, T>
+{
+ typedef ::boost::intrusive::detail::identity<T> type;
+};
+
+template<class T, class VoidOrKeyOfValue>
+struct hash_key_types_base
+{
+ typedef typename get_hash_key_of_value
+ < VoidOrKeyOfValue, T>::type key_of_value;
+ typedef typename key_of_value::type key_type;
+};
+
+template<class T, class VoidOrKeyOfValue, class VoidOrKeyHash>
+struct hash_key_hash
+ : get_hash
+ < VoidOrKeyHash
+ , typename hash_key_types_base<T, VoidOrKeyOfValue>::key_type
+ >
+{};
+
+template<class T, class VoidOrKeyOfValue, class VoidOrKeyEqual>
+struct hash_key_equal
+ : get_equal_to
+ < VoidOrKeyEqual
+ , typename hash_key_types_base<T, VoidOrKeyOfValue>::key_type
+ >
+
+{};
+
//bucket_hash_t
//Stores bucket_plus_vtraits plust the hash function
-template<class VoidOrKeyHash, class ValueTraits, class BucketTraits>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class BucketTraits>
struct bucket_hash_t
//Use public inheritance to avoid MSVC bugs with closures
: public detail::ebo_functor_holder
- <typename get_hash< VoidOrKeyHash
- , typename bucket_plus_vtraits<ValueTraits,BucketTraits>::value_traits::value_type
- >::type
- >
+ <typename hash_key_hash < typename bucket_plus_vtraits<ValueTraits,BucketTraits>::value_traits::value_type
+ , VoidOrKeyOfValue
+ , VoidOrKeyHash
+ >::type
+ >
+ , bucket_plus_vtraits<ValueTraits, BucketTraits> //4
{
typedef typename bucket_plus_vtraits<ValueTraits,BucketTraits>::value_traits value_traits;
typedef typename value_traits::value_type value_type;
typedef typename value_traits::node_traits node_traits;
- typedef typename get_hash< VoidOrKeyHash, value_type>::type hasher;
+ typedef hash_key_hash
+ < value_type, VoidOrKeyOfValue, VoidOrKeyHash> hash_key_hash_t;
+ typedef typename hash_key_hash_t::type hasher;
+ typedef typename hash_key_types_base<value_type, VoidOrKeyOfValue>::key_of_value key_of_value;
+
typedef BucketTraits bucket_traits;
typedef bucket_plus_vtraits<ValueTraits, BucketTraits> bucket_plus_vtraits_t;
+ typedef detail::ebo_functor_holder<hasher> base_t;
template<class BucketTraitsType>
bucket_hash_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h)
- : detail::ebo_functor_holder<hasher>(h), internal(val_traits, ::boost::forward<BucketTraitsType>(b_traits))
+ : detail::ebo_functor_holder<hasher>(h), bucket_plus_vtraits_t(val_traits, ::boost::forward<BucketTraitsType>(b_traits))
{}
const hasher &priv_hasher() const
- { return this->detail::ebo_functor_holder<hasher>::get(); }
+ { return this->base_t::get(); }
hasher &priv_hasher()
- { return this->detail::ebo_functor_holder<hasher>::get(); }
+ { return this->base_t::get(); }
- std::size_t priv_stored_or_compute_hash(const value_type &v, detail::true_) const //For store_hash == true
- { return node_traits::get_hash(this->internal.priv_value_traits().to_node_ptr(v)); }
+ using bucket_plus_vtraits_t::priv_stored_or_compute_hash; //For store_hash == true
std::size_t priv_stored_or_compute_hash(const value_type &v, detail::false_) const //For store_hash == false
- { return this->priv_hasher()(v); }
-
- bucket_plus_vtraits_t internal; //4
+ { return this->priv_hasher()(key_of_value()(v)); }
};
-
-template<class EqualTo, class T>
-struct get_equal_to
+template<class ValueTraits, class BucketTraits, class VoidOrKeyOfValue, class VoidOrKeyEqual>
+struct hashtable_equal_holder
{
- typedef EqualTo type;
-};
-
-template<class T>
-struct get_equal_to<void, T>
-{
- typedef ::std::equal_to<T> type;
+ typedef detail::ebo_functor_holder
+ < typename hash_key_equal < typename bucket_plus_vtraits<ValueTraits, BucketTraits>::value_traits::value_type
+ , VoidOrKeyOfValue
+ , VoidOrKeyEqual
+ >::type
+ > type;
};
//bucket_hash_equal_t
//Stores bucket_hash_t and the equality function when the first
//non-empty bucket shall not be cached.
-template<class VoidOrKeyHash, class VoidOrKeyEqual, class ValueTraits, class BucketTraits, bool>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class BucketTraits, bool>
struct bucket_hash_equal_t
//Use public inheritance to avoid MSVC bugs with closures
- : public detail::ebo_functor_holder //equal
- <typename get_equal_to< VoidOrKeyEqual
- , typename bucket_plus_vtraits<ValueTraits,BucketTraits>::value_traits::value_type
- >::type
- >
+ : public bucket_hash_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, BucketTraits> //3
+ , public hashtable_equal_holder<ValueTraits, BucketTraits, VoidOrKeyOfValue, VoidOrKeyEqual>::type //equal
{
- typedef bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> bucket_hash_type;
+ typedef typename hashtable_equal_holder
+ <ValueTraits, BucketTraits, VoidOrKeyOfValue, VoidOrKeyEqual>::type equal_holder_t;
+ typedef bucket_hash_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, BucketTraits> bucket_hash_type;
typedef bucket_plus_vtraits<ValueTraits,BucketTraits> bucket_plus_vtraits_t;
- typedef typename bucket_plus_vtraits_t::value_traits value_traits;
- typedef typename get_equal_to< VoidOrKeyEqual
- , typename value_traits::value_type
- >::type value_equal;
+ typedef ValueTraits value_traits;
+ typedef typename equal_holder_t::functor_type key_equal;
typedef typename bucket_hash_type::hasher hasher;
typedef BucketTraits bucket_traits;
typedef typename bucket_plus_vtraits_t::slist_impl slist_impl;
@@ -880,13 +1072,13 @@ struct bucket_hash_equal_t
typedef typename detail::unordered_bucket_ptr_impl<value_traits>::type bucket_ptr;
template<class BucketTraitsType>
- bucket_hash_equal_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const value_equal &e)
- : detail::ebo_functor_holder<value_equal>(e)
- , internal(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h)
+ bucket_hash_equal_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const key_equal &e)
+ : bucket_hash_type(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h)
+ , equal_holder_t(e)
{}
bucket_ptr priv_get_cache()
- { return this->internal.internal.priv_bucket_pointer(); }
+ { return this->bucket_hash_type::priv_bucket_pointer(); }
void priv_set_cache(const bucket_ptr &)
{}
@@ -903,14 +1095,14 @@ struct bucket_hash_equal_t
siterator priv_begin() const
{
size_type n = 0;
- size_type bucket_cnt = this->internal.internal.priv_bucket_count();
+ size_type bucket_cnt = this->bucket_hash_type::priv_bucket_count();
for (n = 0; n < bucket_cnt; ++n){
- bucket_type &b = this->internal.internal.priv_bucket_pointer()[n];
+ bucket_type &b = this->bucket_hash_type::priv_bucket_pointer()[n];
if(!b.empty()){
return b.begin();
}
}
- return this->internal.internal.priv_invalid_local_it();
+ return this->bucket_hash_type::priv_invalid_local_it();
}
void priv_insertion_update_cache(size_type)
@@ -922,43 +1114,38 @@ struct bucket_hash_equal_t
void priv_erasure_update_cache()
{}
- const value_equal &priv_equal() const
- { return this->detail::ebo_functor_holder<value_equal>::get(); }
+ const key_equal &priv_equal() const
+ { return this->equal_holder_t::get(); }
- value_equal &priv_equal()
- { return this->detail::ebo_functor_holder<value_equal>::get(); }
-
- bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> internal; //3
+ key_equal &priv_equal()
+ { return this->equal_holder_t::get(); }
};
//bucket_hash_equal_t
//Stores bucket_hash_t and the equality function when the first
//non-empty bucket shall be cached.
-template<class VoidOrKeyHash, class VoidOrKeyEqual, class ValueTraits, class BucketTraits> //cache_begin == true version
-struct bucket_hash_equal_t<VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTraits, true>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class BucketTraits> //cache_begin == true version
+struct bucket_hash_equal_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, true>
//Use public inheritance to avoid MSVC bugs with closures
- : public detail::ebo_functor_holder //equal
- <typename get_equal_to< VoidOrKeyEqual
- , typename bucket_plus_vtraits<ValueTraits,BucketTraits>::value_traits::value_type
- >::type
- >
+ : bucket_hash_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, BucketTraits> //2
+ , hashtable_equal_holder<ValueTraits, BucketTraits, VoidOrKeyOfValue, VoidOrKeyEqual>::type
{
- typedef bucket_plus_vtraits<ValueTraits, BucketTraits> bucket_plus_vtraits_t;
- typedef bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> bucket_hash_type;
- typedef typename bucket_plus_vtraits
- <ValueTraits,BucketTraits>::value_traits value_traits;
- typedef typename get_equal_to
- < VoidOrKeyEqual
- , typename value_traits::value_type>::type value_equal;
+ typedef typename hashtable_equal_holder
+ <ValueTraits, BucketTraits, VoidOrKeyOfValue, VoidOrKeyEqual>::type equal_holder_t;
+
+ typedef bucket_plus_vtraits<ValueTraits,BucketTraits> bucket_plus_vtraits_t;
+ typedef ValueTraits value_traits;
+ typedef typename equal_holder_t::functor_type key_equal;
+ typedef bucket_hash_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, BucketTraits> bucket_hash_type;
typedef typename bucket_hash_type::hasher hasher;
typedef BucketTraits bucket_traits;
typedef typename bucket_plus_vtraits_t::slist_impl::size_type size_type;
typedef typename bucket_plus_vtraits_t::slist_impl::iterator siterator;
template<class BucketTraitsType>
- bucket_hash_equal_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const value_equal &e)
- : detail::ebo_functor_holder<value_equal>(e)
- , internal(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h)
+ bucket_hash_equal_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const key_equal &e)
+ : bucket_hash_type(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h)
+ , equal_holder_t(e)
{}
typedef typename detail::unordered_bucket_ptr_impl
@@ -974,10 +1161,10 @@ struct bucket_hash_equal_t<VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTra
{ cached_begin_ = p; }
std::size_t priv_get_cache_bucket_num()
- { return this->cached_begin_ - this->internal.internal.priv_bucket_pointer(); }
+ { return this->cached_begin_ - this->bucket_hash_type::priv_bucket_pointer(); }
void priv_initialize_cache()
- { this->cached_begin_ = this->internal.internal.priv_invalid_bucket(); }
+ { this->cached_begin_ = this->bucket_hash_type::priv_invalid_bucket(); }
void priv_swap_cache(bucket_hash_equal_t &other)
{
@@ -986,8 +1173,8 @@ struct bucket_hash_equal_t<VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTra
siterator priv_begin() const
{
- if(this->cached_begin_ == this->internal.internal.priv_invalid_bucket()){
- return this->internal.internal.priv_invalid_local_it();
+ if(this->cached_begin_ == this->bucket_hash_type::priv_invalid_bucket()){
+ return this->bucket_hash_type::priv_invalid_local_it();
}
else{
return this->cached_begin_->begin();
@@ -996,34 +1183,34 @@ struct bucket_hash_equal_t<VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTra
void priv_insertion_update_cache(size_type insertion_bucket)
{
- bucket_ptr p = this->internal.internal.priv_bucket_pointer() + insertion_bucket;
+ bucket_ptr p = this->bucket_hash_type::priv_bucket_pointer() + insertion_bucket;
if(p < this->cached_begin_){
this->cached_begin_ = p;
}
}
- const value_equal &priv_equal() const
- { return this->detail::ebo_functor_holder<value_equal>::get(); }
+ const key_equal &priv_equal() const
+ { return this->equal_holder_t::get(); }
- value_equal &priv_equal()
- { return this->detail::ebo_functor_holder<value_equal>::get(); }
+ key_equal &priv_equal()
+ { return this->equal_holder_t::get(); }
void priv_erasure_update_cache_range(size_type first_bucket_num, size_type last_bucket_num)
{
//If the last bucket is the end, the cache must be updated
//to the last position if all
if(this->priv_get_cache_bucket_num() == first_bucket_num &&
- this->internal.internal.priv_bucket_pointer()[first_bucket_num].empty() ){
- this->priv_set_cache(this->internal.internal.priv_bucket_pointer() + last_bucket_num);
+ this->bucket_hash_type::priv_bucket_pointer()[first_bucket_num].empty() ){
+ this->priv_set_cache(this->bucket_hash_type::priv_bucket_pointer() + last_bucket_num);
this->priv_erasure_update_cache();
}
}
void priv_erasure_update_cache()
{
- if(this->cached_begin_ != this->internal.internal.priv_invalid_bucket()){
- size_type current_n = this->priv_get_cache() - this->internal.internal.priv_bucket_pointer();
- for( const size_type num_buckets = this->internal.internal.priv_bucket_count()
+ if(this->cached_begin_ != this->bucket_hash_type::priv_invalid_bucket()){
+ size_type current_n = this->priv_get_cache() - this->bucket_hash_type::priv_bucket_pointer();
+ for( const size_type num_buckets = this->bucket_hash_type::priv_bucket_count()
; current_n < num_buckets
; ++current_n, ++this->priv_get_cache()){
if(!this->priv_get_cache()->empty()){
@@ -1035,103 +1222,291 @@ struct bucket_hash_equal_t<VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTra
}
bucket_ptr cached_begin_;
- bucket_hash_t<VoidOrKeyHash, ValueTraits, BucketTraits> internal; //2
};
+//This wrapper around size_traits is used
+//to maintain minimal container size with compilers like MSVC
+//that have problems with EBO and multiple empty base classes
+template<class DeriveFrom, class SizeType, bool>
+struct hashtable_size_traits_wrapper
+ : public DeriveFrom
+{
+ template<class Base, class Arg0, class Arg1, class Arg2>
+ hashtable_size_traits_wrapper( BOOST_FWD_REF(Base) base, BOOST_FWD_REF(Arg0) arg0
+ , BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2)
+ : DeriveFrom(::boost::forward<Base>(base)
+ , ::boost::forward<Arg0>(arg0)
+ , ::boost::forward<Arg1>(arg1)
+ , ::boost::forward<Arg2>(arg2))
+ {}
+ typedef detail::size_holder < true, SizeType> size_traits;//size_traits
+
+ size_traits size_traits_;
+
+ const size_traits &priv_size_traits() const
+ { return size_traits_; }
+
+ size_traits &priv_size_traits()
+ { return size_traits_; }
+};
+
+template<class DeriveFrom, class SizeType>
+struct hashtable_size_traits_wrapper<DeriveFrom, SizeType, false>
+ : public DeriveFrom
+{
+ template<class Base, class Arg0, class Arg1, class Arg2>
+ hashtable_size_traits_wrapper( BOOST_FWD_REF(Base) base, BOOST_FWD_REF(Arg0) arg0
+ , BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2)
+ : DeriveFrom(::boost::forward<Base>(base)
+ , ::boost::forward<Arg0>(arg0)
+ , ::boost::forward<Arg1>(arg1)
+ , ::boost::forward<Arg2>(arg2))
+ {}
+
+ typedef detail::size_holder< false, SizeType> size_traits;
+
+ const size_traits &priv_size_traits() const
+ { return size_traits_; }
+
+ size_traits &priv_size_traits()
+ { return size_traits_; }
+
+ static size_traits size_traits_;
+};
+
+template<class DeriveFrom, class SizeType>
+detail::size_holder< false, SizeType > hashtable_size_traits_wrapper<DeriveFrom, SizeType, false>::size_traits_;
+
//hashdata_internal
//Stores bucket_hash_equal_t and split_traits
-template<class SizeType, std::size_t BoolFlags, class VoidOrKeyHash, class VoidOrKeyEqual, class ValueTraits, class BucketTraits>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class BucketTraits, class SizeType, std::size_t BoolFlags>
struct hashdata_internal
- : public detail::size_holder< 0 != (BoolFlags & hash_bool_flags::incremental_pos), SizeType, int> //split_traits
+ : public hashtable_size_traits_wrapper
+ < bucket_hash_equal_t
+ < ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual
+ , BucketTraits
+ , 0 != (BoolFlags & hash_bool_flags::cache_begin_pos)
+ > //2
+ , SizeType
+ , (BoolFlags & hash_bool_flags::incremental_pos) != 0
+ >
{
- typedef bucket_hash_equal_t
- < VoidOrKeyHash, VoidOrKeyEqual
- , ValueTraits, BucketTraits
- , 0 != (BoolFlags & hash_bool_flags::cache_begin_pos)
+ typedef hashtable_size_traits_wrapper
+ < bucket_hash_equal_t
+ < ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual
+ , BucketTraits
+ , 0 != (BoolFlags & hash_bool_flags::cache_begin_pos)
+ > //2
+ , SizeType
+ , (BoolFlags & hash_bool_flags::incremental_pos) != 0
> internal_type;
- typedef typename internal_type::value_equal value_equal;
+ typedef typename internal_type::key_equal key_equal;
typedef typename internal_type::hasher hasher;
typedef bucket_plus_vtraits<ValueTraits,BucketTraits> bucket_plus_vtraits_t;
typedef typename bucket_plus_vtraits_t::size_type size_type;
+ typedef typename internal_type::size_traits split_traits;
typedef typename bucket_plus_vtraits_t::bucket_ptr bucket_ptr;
- typedef detail::size_holder
- <0 != (BoolFlags & hash_bool_flags::incremental_pos)
- , SizeType, int> split_traits;
- typedef typename bucket_plus_vtraits_t::
- value_traits::node_traits node_traits;
- typedef detail::bool_<detail::optimize_multikey_is_true
- <node_traits>::value> optimize_multikey_t;
+ typedef typename bucket_plus_vtraits_t::const_value_traits_ptr const_value_traits_ptr;
+ typedef typename bucket_plus_vtraits_t::siterator siterator;
+ typedef typename bucket_plus_vtraits_t::bucket_traits bucket_traits;
+ typedef typename bucket_plus_vtraits_t::value_traits value_traits;
+ typedef typename bucket_plus_vtraits_t::bucket_type bucket_type;
+ typedef typename value_traits::value_type value_type;
+ typedef typename value_traits::pointer pointer;
+ typedef typename value_traits::const_pointer const_pointer;
+ typedef typename pointer_traits<pointer>::reference reference;
+ typedef typename pointer_traits
+ <const_pointer>::reference const_reference;
+ typedef typename value_traits::node_traits node_traits;
+ typedef typename node_traits::node node;
+ typedef typename node_traits::node_ptr node_ptr;
+ typedef typename node_traits::const_node_ptr const_node_ptr;
+ typedef detail::node_functions<node_traits> node_functions_t;
+ typedef typename detail::get_slist_impl
+ <typename detail::reduced_slist_node_traits
+ <typename value_traits::node_traits>::type
+ >::type slist_impl;
+ typedef typename slist_impl::node_algorithms node_algorithms;
+ typedef typename slist_impl::node_ptr slist_node_ptr;
+
+ typedef hash_key_types_base
+ < typename ValueTraits::value_type
+ , VoidOrKeyOfValue
+ > hash_types_base;
+ typedef typename hash_types_base::key_of_value key_of_value;
+
+ static const bool store_hash = detail::store_hash_is_true<node_traits>::value;
+ static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
+ static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
+
+ typedef detail::bool_<store_hash> store_hash_t;
+
+ typedef detail::transform_iterator
+ < typename slist_impl::iterator
+ , downcast_node_to_value_t
+ < value_traits
+ , false> > local_iterator;
+
+ typedef detail::transform_iterator
+ < typename slist_impl::iterator
+ , downcast_node_to_value_t
+ < value_traits
+ , true> > const_local_iterator;
+ //
template<class BucketTraitsType>
hashdata_internal( const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits
- , const hasher & h, const value_equal &e)
- : internal(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h, e)
+ , const hasher & h, const key_equal &e)
+ : internal_type(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h, e)
{}
split_traits &priv_split_traits()
- { return *this; }
+ { return this->priv_size_traits(); }
const split_traits &priv_split_traits() const
- { return *this; }
+ { return this->priv_size_traits(); }
~hashdata_internal()
{ this->priv_clear_buckets(); }
void priv_clear_buckets()
{
- this->internal.internal.internal.priv_clear_buckets
- ( this->internal.priv_get_cache()
- , this->internal.internal.internal.priv_bucket_count()
- - (this->internal.priv_get_cache()
- - this->internal.internal.internal.priv_bucket_pointer()));
+ this->internal_type::priv_clear_buckets
+ ( this->priv_get_cache()
+ , this->internal_type::priv_bucket_count()
+ - (this->priv_get_cache()
+ - this->internal_type::priv_bucket_pointer()));
}
void priv_clear_buckets_and_cache()
{
this->priv_clear_buckets();
- this->internal.priv_initialize_cache();
+ this->priv_initialize_cache();
}
void priv_initialize_buckets_and_cache()
{
- this->internal.internal.internal.priv_clear_buckets
- ( this->internal.internal.internal.priv_bucket_pointer()
- , this->internal.internal.internal.priv_bucket_count());
- this->internal.priv_initialize_cache();
+ this->internal_type::priv_clear_buckets
+ ( this->internal_type::priv_bucket_pointer()
+ , this->internal_type::priv_bucket_count());
+ this->priv_initialize_cache();
}
- internal_type internal; //2
-};
+ typedef hashtable_iterator<bucket_plus_vtraits_t, false> iterator;
+ typedef hashtable_iterator<bucket_plus_vtraits_t, true> const_iterator;
-//hashtable_data_t
-//Stores hashdata_internal and size_traits
-template<class SizeType, std::size_t BoolFlags, class VoidOrKeyHash, class VoidOrKeyEqual, class ValueTraits, class BucketTraits>
-struct hashtable_data_t
- : public detail::size_holder
- < 0 != (BoolFlags & hash_bool_flags::constant_time_size_pos), SizeType> //size_traits
-{
- typedef detail::size_holder
- < 0 != (BoolFlags & hash_bool_flags::constant_time_size_pos)
- , SizeType> size_traits;
- typedef hashdata_internal
- < SizeType
- , BoolFlags & (hash_bool_flags::incremental_pos | hash_bool_flags::cache_begin_pos)
- , VoidOrKeyHash, VoidOrKeyEqual
- , ValueTraits, BucketTraits> internal_type;
- typedef ValueTraits value_traits;
- typedef typename internal_type::value_equal value_equal;
- typedef typename internal_type::hasher hasher;
- typedef BucketTraits bucket_traits;
- typedef bucket_plus_vtraits
- <ValueTraits,BucketTraits> bucket_plus_vtraits_t;
+ static std::size_t priv_stored_hash(slist_node_ptr n, detail::true_ true_value)
+ { return bucket_plus_vtraits<ValueTraits, BucketTraits>::priv_stored_hash(n, true_value); }
- template<class BucketTraitsType>
- hashtable_data_t( BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h
- , const value_equal &e, const value_traits &val_traits)
- : internal(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h, e)
- {}
+ static std::size_t priv_stored_hash(slist_node_ptr n, detail::false_ false_value)
+ { return bucket_plus_vtraits<ValueTraits, BucketTraits>::priv_stored_hash(n, false_value); }
+
+ //public functions
+ SizeType split_count() const
+ {
+ return this->priv_split_traits().get_size();
+ }
+
+ iterator iterator_to(reference value)
+ {
+ return iterator(bucket_type::s_iterator_to
+ (this->priv_value_to_node(value)), &this->get_bucket_value_traits());
+ }
+
+ const_iterator iterator_to(const_reference value) const
+ {
+ siterator const sit = bucket_type::s_iterator_to
+ ( *pointer_traits<node_ptr>::const_cast_from
+ (pointer_traits<const_node_ptr>::pointer_to(this->priv_value_to_node(value)))
+ );
+ return const_iterator(sit, &this->get_bucket_value_traits());
+ }
+
+ static local_iterator s_local_iterator_to(reference value)
+ {
+ BOOST_STATIC_ASSERT((!stateful_value_traits));
+ siterator sit = bucket_type::s_iterator_to(*value_traits::to_node_ptr(value));
+ return local_iterator(sit, const_value_traits_ptr());
+ }
+
+ static const_local_iterator s_local_iterator_to(const_reference value)
+ {
+ BOOST_STATIC_ASSERT((!stateful_value_traits));
+ siterator const sit = bucket_type::s_iterator_to
+ ( *pointer_traits<node_ptr>::const_cast_from
+ (value_traits::to_node_ptr(value))
+ );
+ return const_local_iterator(sit, const_value_traits_ptr());
+ }
+
+ local_iterator local_iterator_to(reference value)
+ {
+ siterator sit = bucket_type::s_iterator_to(this->priv_value_to_node(value));
+ return local_iterator(sit, this->priv_value_traits_ptr());
+ }
+
+ const_local_iterator local_iterator_to(const_reference value) const
+ {
+ siterator sit = bucket_type::s_iterator_to
+ ( *pointer_traits<node_ptr>::const_cast_from
+ (pointer_traits<const_node_ptr>::pointer_to(this->priv_value_to_node(value)))
+ );
+ return const_local_iterator(sit, this->priv_value_traits_ptr());
+ }
+
+ size_type bucket_count() const
+ { return this->priv_bucket_count(); }
- internal_type internal; //1
+ size_type bucket_size(size_type n) const
+ { return this->priv_bucket_pointer()[n].size(); }
+
+ bucket_ptr bucket_pointer() const
+ { return this->priv_bucket_pointer(); }
+
+ local_iterator begin(size_type n)
+ { return local_iterator(this->priv_bucket_pointer()[n].begin(), this->priv_value_traits_ptr()); }
+
+ const_local_iterator begin(size_type n) const
+ { return this->cbegin(n); }
+
+ const_local_iterator cbegin(size_type n) const
+ {
+ return const_local_iterator
+ ( pointer_traits<bucket_ptr>::const_cast_from(this->priv_bucket_pointer())[n].begin()
+ , this->priv_value_traits_ptr());
+ }
+
+ using internal_type::end;
+ using internal_type::cend;
+ local_iterator end(size_type n)
+ { return local_iterator(this->priv_bucket_pointer()[n].end(), this->priv_value_traits_ptr()); }
+
+ const_local_iterator end(size_type n) const
+ { return this->cend(n); }
+
+ const_local_iterator cend(size_type n) const
+ {
+ return const_local_iterator
+ ( pointer_traits<bucket_ptr>::const_cast_from(this->priv_bucket_pointer())[n].end()
+ , this->priv_value_traits_ptr());
+ }
+
+ //Public functions for hashtable_impl
+
+ iterator begin()
+ { return iterator(this->priv_begin(), &this->get_bucket_value_traits()); }
+
+ const_iterator begin() const
+ { return this->cbegin(); }
+
+ const_iterator cbegin() const
+ { return const_iterator(this->priv_begin(), &this->get_bucket_value_traits()); }
+
+ hasher hash_function() const
+ { return this->priv_hasher(); }
+
+ key_equal key_eq() const
+ { return this->priv_equal(); }
};
/// @endcond
@@ -1175,61 +1550,82 @@ struct hashtable_data_t
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidOrKeyHash, class VoidOrKeyEqual, class SizeType, class BucketTraits, std::size_t BoolFlags>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class BucketTraits, class SizeType, std::size_t BoolFlags>
#endif
class hashtable_impl
- : private hashtable_data_t
- < SizeType
- , BoolFlags & hashtable_data_bool_flags_mask
- , VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTraits>
+ : private hashtable_size_traits_wrapper
+ < hashdata_internal
+ < ValueTraits
+ , VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual
+ , BucketTraits, SizeType
+ , BoolFlags & (hash_bool_flags::incremental_pos | hash_bool_flags::cache_begin_pos) //1
+ >
+ , SizeType
+ , (BoolFlags & hash_bool_flags::constant_time_size_pos) != 0
+ >
{
- typedef hashtable_data_t
- < SizeType
- , BoolFlags & hashtable_data_bool_flags_mask
- , VoidOrKeyHash, VoidOrKeyEqual, ValueTraits, BucketTraits> data_type;
-
+ typedef hashtable_size_traits_wrapper
+ < hashdata_internal
+ < ValueTraits
+ , VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual
+ , BucketTraits, SizeType
+ , BoolFlags & (hash_bool_flags::incremental_pos | hash_bool_flags::cache_begin_pos) //1
+ >
+ , SizeType
+ , (BoolFlags & hash_bool_flags::constant_time_size_pos) != 0
+ > internal_type;
+ typedef typename internal_type::size_traits size_traits;
+ typedef hash_key_types_base
+ < typename ValueTraits::value_type
+ , VoidOrKeyOfValue
+ > hash_types_base;
public:
typedef ValueTraits value_traits;
/// @cond
typedef BucketTraits bucket_traits;
- typedef typename detail::get_slist_impl
- <typename detail::reduced_slist_node_traits
- <typename value_traits::node_traits>::type
- >::type slist_impl;
+ typedef typename internal_type::slist_impl slist_impl;
typedef bucket_plus_vtraits<ValueTraits, BucketTraits> bucket_plus_vtraits_t;
typedef typename bucket_plus_vtraits_t::const_value_traits_ptr const_value_traits_ptr;
+ using internal_type::begin;
+ using internal_type::cbegin;
+ using internal_type::end;
+ using internal_type::cend;
+ using internal_type::hash_function;
+ using internal_type::key_eq;
+ using internal_type::bucket_size;
+ using internal_type::bucket_count;
+ using internal_type::local_iterator_to;
+ using internal_type::s_local_iterator_to;
+ using internal_type::iterator_to;
+ using internal_type::bucket_pointer;
+ using internal_type::suggested_upper_bucket_count;
+ using internal_type::suggested_lower_bucket_count;
+ using internal_type::split_count;
/// @endcond
typedef typename value_traits::pointer pointer;
typedef typename value_traits::const_pointer const_pointer;
typedef typename value_traits::value_type value_type;
+ typedef typename hash_types_base::key_type key_type;
+ typedef typename hash_types_base::key_of_value key_of_value;
typedef typename pointer_traits<pointer>::reference reference;
typedef typename pointer_traits<const_pointer>::reference const_reference;
typedef typename pointer_traits<pointer>::difference_type difference_type;
typedef SizeType size_type;
- typedef value_type key_type;
- typedef typename data_type::value_equal key_equal;
- typedef typename data_type::value_equal value_equal;
- typedef typename data_type::hasher hasher;
+ typedef typename internal_type::key_equal key_equal;
+ typedef typename internal_type::hasher hasher;
typedef detail::bucket_impl<slist_impl> bucket_type;
- typedef typename pointer_traits
- <pointer>::template rebind_pointer
- < bucket_type >::type bucket_ptr;
- typedef typename pointer_traits
- <pointer>::template rebind_pointer
- < const bucket_type >::type const_bucket_ptr;
- typedef typename pointer_traits
- <bucket_ptr>::reference bucket_reference;
- typedef typename pointer_traits
- <bucket_ptr>::reference const_bucket_reference;
+ typedef typename internal_type::bucket_ptr bucket_ptr;
typedef typename slist_impl::iterator siterator;
typedef typename slist_impl::const_iterator const_siterator;
- typedef hashtable_iterator<bucket_plus_vtraits_t, false> iterator;
- typedef hashtable_iterator<bucket_plus_vtraits_t, true> const_iterator;
+ typedef typename internal_type::iterator iterator;
+ typedef typename internal_type::const_iterator const_iterator;
+ typedef typename internal_type::local_iterator local_iterator;
+ typedef typename internal_type::const_local_iterator const_local_iterator;
typedef typename value_traits::node_traits node_traits;
typedef typename node_traits::node node;
typedef typename pointer_traits
@@ -1244,8 +1640,8 @@ class hashtable_impl
<const_node_ptr>::reference const_node_reference;
typedef typename slist_impl::node_algorithms node_algorithms;
- static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
- static const bool store_hash = detail::store_hash_is_true<node_traits>::value;
+ static const bool stateful_value_traits = internal_type::stateful_value_traits;
+ static const bool store_hash = internal_type::store_hash;
static const bool unique_keys = 0 != (BoolFlags & hash_bool_flags::unique_keys_pos);
static const bool constant_time_size = 0 != (BoolFlags & hash_bool_flags::constant_time_size_pos);
@@ -1258,6 +1654,7 @@ class hashtable_impl
= detail::optimize_multikey_is_true<node_traits>::value && !unique_keys;
/// @cond
+ static const bool is_multikey = !unique_keys;
private:
//Configuration error: compare_hash<> can't be specified without store_hash<>
@@ -1272,12 +1669,11 @@ class hashtable_impl
//optimize_multikey is not true
typedef unordered_group_adapter<node_traits> group_traits;
typedef circular_slist_algorithms<group_traits> group_algorithms;
- typedef detail::bool_<store_hash> store_hash_t;
+ typedef typename internal_type::store_hash_t store_hash_t;
typedef detail::bool_<optimize_multikey> optimize_multikey_t;
typedef detail::bool_<cache_begin> cache_begin_t;
typedef detail::bool_<power_2_buckets> power_2_buckets_t;
- typedef detail::size_holder<constant_time_size, size_type> size_traits;
- typedef detail::size_holder<incremental, size_type, int> split_traits;
+ typedef typename internal_type::split_traits split_traits;
typedef detail::group_functions<node_traits> group_functions_t;
typedef detail::node_functions<node_traits> node_functions_t;
@@ -1285,7 +1681,7 @@ class hashtable_impl
//noncopyable, movable
BOOST_MOVABLE_BUT_NOT_COPYABLE(hashtable_impl)
- static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
+ static const bool safemode_or_autounlink = internal_type::safemode_or_autounlink;
//Constant-time size is incompatible with auto-unlink hooks!
BOOST_STATIC_ASSERT(!(constant_time_size && ((int)value_traits::link_mode == (int)auto_unlink)));
@@ -1293,14 +1689,19 @@ class hashtable_impl
BOOST_STATIC_ASSERT(!(cache_begin && ((int)value_traits::link_mode == (int)auto_unlink)));
template<class Disposer>
- node_cast_adaptor< detail::node_disposer<Disposer, value_traits, CircularSListAlgorithms>
- , slist_node_ptr, node_ptr >
+ struct typeof_node_disposer
+ {
+ typedef node_cast_adaptor
+ < detail::node_disposer< Disposer, value_traits, CircularSListAlgorithms>
+ , slist_node_ptr, node_ptr > type;
+ };
+
+ template<class Disposer>
+ typename typeof_node_disposer<Disposer>::type
make_node_disposer(const Disposer &disposer) const
{
- return node_cast_adaptor
- < detail::node_disposer<Disposer, value_traits, CircularSListAlgorithms>
- , slist_node_ptr, node_ptr >
- (disposer, &this->priv_value_traits());
+ typedef typename typeof_node_disposer<Disposer>::type return_t;
+ return return_t(disposer, &this->priv_value_traits());
}
/// @endcond
@@ -1308,17 +1709,6 @@ class hashtable_impl
public:
typedef detail::insert_commit_data_impl insert_commit_data;
- typedef detail::transform_iterator
- < typename slist_impl::iterator
- , downcast_node_to_value_t
- < value_traits
- , false> > local_iterator;
-
- typedef detail::transform_iterator
- < typename slist_impl::iterator
- , downcast_node_to_value_t
- < value_traits
- , true> > const_local_iterator;
public:
@@ -1339,9 +1729,42 @@ class hashtable_impl
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
, const value_traits &v_traits = value_traits())
- : data_type(b_traits, hash_func, equal_func, v_traits)
+ : internal_type(v_traits, b_traits, hash_func, equal_func)
{
- this->data_type::internal.priv_initialize_buckets_and_cache();
+ this->priv_initialize_buckets_and_cache();
+ this->priv_size_traits().set_size(size_type(0));
+ size_type bucket_sz = this->priv_bucket_count();
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(bucket_sz != 0);
+ //Check power of two bucket array if the option is activated
+ BOOST_INTRUSIVE_INVARIANT_ASSERT
+ (!power_2_buckets || (0 == (bucket_sz & (bucket_sz-1))));
+ this->priv_split_traits().set_size(bucket_sz>>1);
+ }
+
+ //! <b>Requires</b>: buckets must not be being used by any other resource
+ //! and dereferencing iterator must yield an lvalue of type value_type.
+ //!
+ //! <b>Effects</b>: Constructs an empty container and inserts elements from
+ //! [b, e).
+ //!
+ //! <b>Complexity</b>: If N is distance(b, e): Average case is O(N)
+ //! (with a good hash function and with buckets_len >= N),worst case O(N^2).
+ //!
+ //! <b>Throws</b>: If value_traits::node_traits::node
+ //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
+ //! or the copy constructor or invocation of hasher or key_equal throws.
+ //!
+ //! <b>Notes</b>: buckets array must be disposed only after
+ //! *this is disposed.
+ template<class Iterator>
+ hashtable_impl ( bool unique, Iterator b, Iterator e
+ , const bucket_traits &b_traits
+ , const hasher & hash_func = hasher()
+ , const key_equal &equal_func = key_equal()
+ , const value_traits &v_traits = value_traits())
+ : internal_type(v_traits, b_traits, hash_func, equal_func)
+ {
+ this->priv_initialize_buckets_and_cache();
this->priv_size_traits().set_size(size_type(0));
size_type bucket_sz = this->priv_bucket_count();
BOOST_INTRUSIVE_INVARIANT_ASSERT(bucket_sz != 0);
@@ -1349,16 +1772,21 @@ class hashtable_impl
BOOST_INTRUSIVE_INVARIANT_ASSERT
(!power_2_buckets || (0 == (bucket_sz & (bucket_sz-1))));
this->priv_split_traits().set_size(bucket_sz>>1);
+ //Now insert
+ if(unique)
+ this->insert_unique(b, e);
+ else
+ this->insert_equal(b, e);
}
//! <b>Effects</b>: to-do
//!
hashtable_impl(BOOST_RV_REF(hashtable_impl) x)
- : data_type( ::boost::move(x.priv_bucket_traits())
- , ::boost::move(x.priv_hasher())
- , ::boost::move(x.priv_equal())
- , ::boost::move(x.priv_value_traits())
- )
+ : internal_type( ::boost::move(x.priv_value_traits())
+ , ::boost::move(x.priv_bucket_traits())
+ , ::boost::move(x.priv_hasher())
+ , ::boost::move(x.priv_equal())
+ )
{
this->priv_swap_cache(x);
x.priv_initialize_cache();
@@ -1387,7 +1815,6 @@ class hashtable_impl
//!
//! <b>Throws</b>: Nothing.
~hashtable_impl();
- #endif
//! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_set.
//!
@@ -1395,8 +1822,7 @@ class hashtable_impl
//! Worst case (empty unordered_set): O(this->bucket_count())
//!
//! <b>Throws</b>: Nothing.
- iterator begin()
- { return iterator(this->priv_begin(), &this->get_bucket_value_traits()); }
+ iterator begin();
//! <b>Effects</b>: Returns a const_iterator pointing to the beginning
//! of the unordered_set.
@@ -1405,8 +1831,7 @@ class hashtable_impl
//! Worst case (empty unordered_set): O(this->bucket_count())
//!
//! <b>Throws</b>: Nothing.
- const_iterator begin() const
- { return this->cbegin(); }
+ const_iterator begin() const;
//! <b>Effects</b>: Returns a const_iterator pointing to the beginning
//! of the unordered_set.
@@ -1415,48 +1840,44 @@ class hashtable_impl
//! Worst case (empty unordered_set): O(this->bucket_count())
//!
//! <b>Throws</b>: Nothing.
- const_iterator cbegin() const
- { return const_iterator(this->priv_begin(), &this->get_bucket_value_traits()); }
+ const_iterator cbegin() const;
//! <b>Effects</b>: Returns an iterator pointing to the end of the unordered_set.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
- iterator end()
- { return iterator(this->priv_invalid_local_it(), 0); }
+ iterator end();
//! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_set.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
- const_iterator end() const
- { return this->cend(); }
+ const_iterator end() const;
//! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_set.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
- const_iterator cend() const
- { return const_iterator(this->priv_invalid_local_it(), 0); }
+ const_iterator cend() const;
//! <b>Effects</b>: Returns the hasher object used by the unordered_set.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: If hasher copy-constructor throws.
- hasher hash_function() const
- { return this->priv_hasher(); }
+ hasher hash_function() const;
//! <b>Effects</b>: Returns the key_equal object used by the unordered_set.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: If key_equal copy-constructor throws.
- key_equal key_eq() const
- { return this->priv_equal(); }
+ key_equal key_eq() const;
+
+ #endif
//! <b>Effects</b>: Returns true if the container is empty.
//!
@@ -1525,16 +1946,8 @@ class hashtable_impl
::boost::adl_move_swap(this->priv_bucket_traits(), other.priv_bucket_traits());
::boost::adl_move_swap(this->priv_value_traits(), other.priv_value_traits());
this->priv_swap_cache(other);
- if(constant_time_size){
- size_type backup = this->priv_size_traits().get_size();
- this->priv_size_traits().set_size(other.priv_size_traits().get_size());
- other.priv_size_traits().set_size(backup);
- }
- if(incremental){
- size_type backup = this->priv_split_traits().get_size();
- this->priv_split_traits().set_size(other.priv_split_traits().get_size());
- other.priv_split_traits().set_size(backup);
- }
+ ::boost::adl_move_swap(this->priv_size_traits(), other.priv_size_traits());
+ ::boost::adl_move_swap(this->priv_split_traits(), other.priv_split_traits());
}
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw
@@ -1558,87 +1971,30 @@ class hashtable_impl
//! throws. Basic guarantee.
template <class Cloner, class Disposer>
void clone_from(const hashtable_impl &src, Cloner cloner, Disposer disposer)
- {
- this->clear_and_dispose(disposer);
- if(!constant_time_size || !src.empty()){
- const size_type src_bucket_count = src.bucket_count();
- const size_type dst_bucket_count = this->bucket_count();
- //Check power of two bucket array if the option is activated
- BOOST_INTRUSIVE_INVARIANT_ASSERT
- (!power_2_buckets || (0 == (src_bucket_count & (src_bucket_count-1))));
- BOOST_INTRUSIVE_INVARIANT_ASSERT
- (!power_2_buckets || (0 == (dst_bucket_count & (dst_bucket_count-1))));
+ { this->priv_clone_from(src, cloner, disposer); }
- //If src bucket count is bigger or equal, structural copy is possible
- if(!incremental && (src_bucket_count >= dst_bucket_count)){
- //First clone the first ones
- const bucket_ptr src_buckets = src.priv_bucket_pointer();
- const bucket_ptr dst_buckets = this->priv_bucket_pointer();
- size_type constructed;
-
- typedef node_cast_adaptor< detail::node_disposer<Disposer, value_traits, CircularSListAlgorithms>
- , slist_node_ptr, node_ptr > NodeDisposer;
- typedef node_cast_adaptor< detail::node_cloner <Cloner, value_traits, CircularSListAlgorithms>
- , slist_node_ptr, node_ptr > NodeCloner;
- NodeDisposer node_disp(disposer, &this->priv_value_traits());
-
- detail::exception_array_disposer<bucket_type, NodeDisposer, size_type>
- rollback(dst_buckets[0], node_disp, constructed);
- for( constructed = 0
- ; constructed < dst_bucket_count
- ; ++constructed){
- dst_buckets[constructed].clone_from
- ( src_buckets[constructed]
- , NodeCloner(cloner, &this->priv_value_traits()), node_disp);
- }
- if(src_bucket_count != dst_bucket_count){
- //Now insert the remaining ones using the modulo trick
- for(//"constructed" comes from the previous loop
- ; constructed < src_bucket_count
- ; ++constructed){
- bucket_type &dst_b =
- dst_buckets[detail::hash_to_bucket_split<power_2_buckets, incremental>(constructed, dst_bucket_count, dst_bucket_count)];
- bucket_type &src_b = src_buckets[constructed];
- for( siterator b(src_b.begin()), e(src_b.end())
- ; b != e
- ; ++b){
- dst_b.push_front(*(NodeCloner(cloner, &this->priv_value_traits())(*b.pointed_node())));
- }
- }
- }
- this->priv_hasher() = src.priv_hasher();
- this->priv_equal() = src.priv_equal();
- rollback.release();
- this->priv_size_traits().set_size(src.priv_size_traits().get_size());
- this->priv_split_traits().set_size(dst_bucket_count);
- this->priv_insertion_update_cache(0u);
- this->priv_erasure_update_cache();
- }
- else if(store_hash){
- //Unlike previous cloning algorithm, this can throw
- //if cloner, hasher or comparison functor throw
- const_iterator b(src.cbegin()), e(src.cend());
- detail::exception_disposer<hashtable_impl, Disposer>
- rollback(*this, disposer);
- for(; b != e; ++b){
- std::size_t hash_value = this->priv_stored_or_compute_hash(*b, store_hash_t());;
- this->priv_insert_equal_with_hash(*cloner(*b), hash_value);
- }
- rollback.release();
- }
- else{
- //Unlike previous cloning algorithm, this can throw
- //if cloner, hasher or comparison functor throw
- const_iterator b(src.cbegin()), e(src.cend());
- detail::exception_disposer<hashtable_impl, Disposer>
- rollback(*this, disposer);
- for(; b != e; ++b){
- this->insert_equal(*cloner(*b));
- }
- rollback.release();
- }
- }
- }
+ //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw
+ //! Cloner should yield to nodes that compare equal and produce the same
+ //! hash than the original node.
+ //!
+ //! <b>Effects</b>: Erases all the elements from *this
+ //! calling Disposer::operator()(pointer), clones all the
+ //! elements from src calling Cloner::operator()(reference)
+ //! and inserts them on *this. The hash function and the equality
+ //! predicate are copied from the source.
+ //!
+ //! If store_hash option is true, this method does not use the hash function.
+ //!
+ //! If any operation throws, all cloned elements are unlinked and disposed
+ //! calling Disposer::operator()(pointer).
+ //!
+ //! <b>Complexity</b>: Linear to erased plus inserted elements.
+ //!
+ //! <b>Throws</b>: If cloner or hasher throw or hash or equality predicate copying
+ //! throws. Basic guarantee.
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(hashtable_impl) src, Cloner cloner, Disposer disposer)
+ { this->priv_clone_from(static_cast<hashtable_impl&>(src), cloner, disposer); }
//! <b>Requires</b>: value must be an lvalue
//!
@@ -1657,9 +2013,10 @@ class hashtable_impl
size_type bucket_num;
std::size_t hash_value;
siterator prev;
- siterator it = this->priv_find
- (value, this->priv_hasher(), this->priv_equal(), bucket_num, hash_value, prev);
- return this->priv_insert_equal_find(value, bucket_num, hash_value, it);
+ siterator const it = this->priv_find
+ (key_of_value()(value), this->priv_hasher(), this->priv_equal(), bucket_num, hash_value, prev);
+ bool const next_is_in_group = optimize_multikey && it != this->priv_invalid_local_it();
+ return this->priv_insert_equal_after_find(value, bucket_num, hash_value, prev, next_is_in_group);
}
//! <b>Requires</b>: Dereferencing iterator must yield an lvalue
@@ -1701,11 +2058,11 @@ class hashtable_impl
{
insert_commit_data commit_data;
std::pair<iterator, bool> ret = this->insert_unique_check
- (value, this->priv_hasher(), this->priv_equal(), commit_data);
- if(!ret.second)
- return ret;
- return std::pair<iterator, bool>
- (this->insert_unique_commit(value, commit_data), true);
+ (key_of_value()(value), this->priv_hasher(), this->priv_equal(), commit_data);
+ if(ret.second){
+ ret.first = this->insert_unique_commit(value, commit_data);
+ }
+ return ret;
}
//! <b>Requires</b>: Dereferencing iterator must yield an lvalue
@@ -1762,22 +2119,19 @@ class hashtable_impl
//! objects are inserted or erased from the unordered_set.
//!
//! After a successful rehashing insert_commit_data remains valid.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
+ template<class KeyType, class KeyHasher, class KeyEqual>
std::pair<iterator, bool> insert_unique_check
( const KeyType &key
, KeyHasher hash_func
- , KeyValueEqual equal_func
+ , KeyEqual equal_func
, insert_commit_data &commit_data)
{
size_type bucket_num;
siterator prev;
- siterator prev_pos =
- this->priv_find(key, hash_func, equal_func, bucket_num, commit_data.hash, prev);
- bool success = prev_pos == this->priv_invalid_local_it();
- if(success){
- prev_pos = prev;
- }
- return std::pair<iterator, bool>(iterator(prev_pos, &this->get_bucket_value_traits()),success);
+ siterator const pos = this->priv_find(key, hash_func, equal_func, bucket_num, commit_data.hash, prev);
+ return std::pair<iterator, bool>
+ ( iterator(pos, &this->get_bucket_value_traits())
+ , pos == this->priv_invalid_local_it());
}
//! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
@@ -1804,12 +2158,11 @@ class hashtable_impl
size_type bucket_num = this->priv_hash_to_bucket(commit_data.hash);
bucket_type &b = this->priv_bucket_pointer()[bucket_num];
this->priv_size_traits().increment();
- node_ptr n = pointer_traits<node_ptr>::pointer_to(this->priv_value_to_node(value));
+ node_ptr const n = pointer_traits<node_ptr>::pointer_to(this->priv_value_to_node(value));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(n));
node_functions_t::store_hash(n, commit_data.hash, store_hash_t());
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
this->priv_insertion_update_cache(bucket_num);
- group_functions_t::insert_in_group(node_ptr(), n, optimize_multikey_t());
+ group_functions_t::insert_in_group(n, n, optimize_multikey_t());
return iterator(b.insert_after(b.before_begin(), *n), &this->get_bucket_value_traits());
}
@@ -1848,8 +2201,8 @@ class hashtable_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
- size_type erase(const_reference value)
- { return this->erase(value, this->priv_hasher(), this->priv_equal()); }
+ size_type erase(const key_type &key)
+ { return this->erase(key, this->priv_hasher(), this->priv_equal()); }
//! <b>Requires</b>: "hash_func" must be a hash function that induces
//! the same hash values as the stored hasher. The difference is that
@@ -1871,8 +2224,8 @@ class hashtable_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- size_type erase(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ size_type erase(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func)
{ return this->erase_and_dispose(key, hash_func, equal_func, detail::null_disposer()); }
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1887,15 +2240,16 @@ class hashtable_impl
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class Disposer>
- void erase_and_dispose(const_iterator i, Disposer disposer
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0
- /// @endcond
- )
- {
- this->priv_erase(i, disposer, optimize_multikey_t());
+ BOOST_INTRUSIVE_DOC1ST(void
+ , typename detail::disable_if_convertible<Disposer BOOST_INTRUSIVE_I const_iterator>::type)
+ erase_and_dispose(const_iterator i, Disposer disposer)
+ {
+ //Get the bucket number and local iterator for both iterators
+ siterator const first_local_it(i.slist_it());
+ size_type const first_bucket_num = this->priv_get_bucket_num(first_local_it);
+ this->priv_erase_node(this->priv_bucket_pointer()[first_bucket_num], first_local_it, make_node_disposer(disposer), optimize_multikey_t());
this->priv_size_traits().decrement();
- this->priv_erasure_update_cache();
+ this->priv_erasure_update_cache_range(first_bucket_num, first_bucket_num);
}
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1934,7 +2288,10 @@ class hashtable_impl
last_local_it = e.slist_it();
last_bucket_num = this->priv_get_bucket_num(last_local_it);
}
- this->priv_erase_range(before_first_local_it, first_bucket_num, last_local_it, last_bucket_num, disposer);
+ size_type const num_erased = this->priv_erase_node_range
+ ( before_first_local_it, first_bucket_num, last_local_it, last_bucket_num
+ , make_node_disposer(disposer), optimize_multikey_t());
+ this->priv_size_traits().set_size(this->priv_size_traits().get_size()-num_erased);
this->priv_erasure_update_cache_range(first_bucket_num, last_bucket_num);
}
}
@@ -1955,8 +2312,8 @@ class hashtable_impl
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer)
- { return this->erase_and_dispose(value, this->priv_hasher(), this->priv_equal(), disposer); }
+ size_type erase_and_dispose(const key_type &key, Disposer disposer)
+ { return this->erase_and_dispose(key, this->priv_hasher(), this->priv_equal(), disposer); }
//! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//!
@@ -1973,45 +2330,37 @@ class hashtable_impl
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
- template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
+ template<class KeyType, class KeyHasher, class KeyEqual, class Disposer>
size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func
- ,KeyValueEqual equal_func, Disposer disposer)
+ ,KeyEqual equal_func, Disposer disposer)
{
size_type bucket_num;
std::size_t h;
siterator prev;
siterator it = this->priv_find(key, hash_func, equal_func, bucket_num, h, prev);
- bool success = it != this->priv_invalid_local_it();
+ bool const success = it != this->priv_invalid_local_it();
+
size_type cnt(0);
- if(!success){
- return 0;
- }
- else if(optimize_multikey){
- siterator last = bucket_type::s_iterator_to
- (*node_traits::get_next(group_functions_t::get_last_in_group
- (detail::dcast_bucket_ptr<node>(it.pointed_node()), optimize_multikey_t())));
- this->priv_erase_range_impl(bucket_num, prev, last, disposer, cnt);
- }
- else{
- //If found erase all equal values
- bucket_type &b = this->priv_bucket_pointer()[bucket_num];
- for(siterator end_sit = b.end(); it != end_sit; ++cnt, ++it){
- slist_node_ptr n(it.pointed_node());
- const value_type &v = this->priv_value_from_slist_node(n);
- if(compare_hash){
- std::size_t vh = this->priv_stored_or_compute_hash(v, store_hash_t());
- if(h != vh || !equal_func(key, v)){
- break;
- }
- }
- else if(!equal_func(key, v)){
- break;
- }
- this->priv_size_traits().decrement();
+ if(success){
+ if(optimize_multikey){
+ cnt = this->priv_erase_from_single_bucket
+ (this->priv_bucket_pointer()[bucket_num], prev, ++(priv_last_in_group)(it), make_node_disposer(disposer), optimize_multikey_t());
}
- b.erase_after_and_dispose(prev, it, make_node_disposer(disposer));
+ else{
+ bucket_type &b = this->priv_bucket_pointer()[bucket_num];
+ siterator const end_sit = b.end();
+ do{
+ ++cnt;
+ ++it;
+ }while(it != end_sit &&
+ this->priv_is_value_equal_to_key
+ (this->priv_value_from_slist_node(it.pointed_node()), h, key, equal_func));
+ bucket_type::s_erase_after_and_dispose(prev, it, make_node_disposer(disposer));
+ }
+ this->priv_size_traits().set_size(this->priv_size_traits().get_size()-cnt);
+ this->priv_erasure_update_cache();
}
- this->priv_erasure_update_cache();
+
return cnt;
}
@@ -2026,7 +2375,7 @@ class hashtable_impl
//! to the erased elements. No destructors are called.
void clear()
{
- this->data_type::internal.priv_clear_buckets_and_cache();
+ this->priv_clear_buckets_and_cache();
this->priv_size_traits().set_size(size_type(0));
}
@@ -2047,8 +2396,9 @@ class hashtable_impl
if(!constant_time_size || !this->empty()){
size_type num_buckets = this->bucket_count();
bucket_ptr b = this->priv_bucket_pointer();
+ typename typeof_node_disposer<Disposer>::type d(disposer, &this->priv_value_traits());
for(; num_buckets--; ++b){
- b->clear_and_dispose(make_node_disposer(disposer));
+ b->clear_and_dispose(d);
}
this->priv_size_traits().set_size(size_type(0));
}
@@ -2060,8 +2410,8 @@ class hashtable_impl
//! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
//!
//! <b>Throws</b>: If the internal hasher or the equality functor throws.
- size_type count(const_reference value) const
- { return this->count(value, this->priv_hasher(), this->priv_equal()); }
+ size_type count(const key_type &key) const
+ { return this->count(key, this->priv_hasher(), this->priv_equal()); }
//! <b>Requires</b>: "hash_func" must be a hash function that induces
//! the same hash values as the stored hasher. The difference is that
@@ -2076,11 +2426,12 @@ class hashtable_impl
//! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
//!
//! <b>Throws</b>: If hash_func or equal throw.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- size_type count(const KeyType &key, const KeyHasher &hash_func, const KeyValueEqual &equal_func) const
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ size_type count(const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) const
{
- size_type bucket_n1, bucket_n2, cnt;
- this->priv_equal_range(key, hash_func, equal_func, bucket_n1, bucket_n2, cnt);
+ size_type cnt;
+ size_type n_bucket;
+ this->priv_local_equal_range(key, hash_func, equal_func, n_bucket, cnt);
return cnt;
}
@@ -2090,8 +2441,8 @@ class hashtable_impl
//! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
//!
//! <b>Throws</b>: If the internal hasher or the equality functor throws.
- iterator find(const_reference value)
- { return this->find(value, this->priv_hasher(), this->priv_equal()); }
+ iterator find(const key_type &key)
+ { return this->find(key, this->priv_hasher(), this->priv_equal()); }
//! <b>Requires</b>: "hash_func" must be a hash function that induces
//! the same hash values as the stored hasher. The difference is that
@@ -2112,14 +2463,14 @@ class hashtable_impl
//! <b>Note</b>: This function is used when constructing a value_type
//! is expensive and the value_type can be compared with a cheaper
//! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- iterator find(const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func)
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ iterator find(const KeyType &key, KeyHasher hash_func, KeyEqual equal_func)
{
size_type bucket_n;
std::size_t hash;
siterator prev;
- siterator local_it = this->priv_find(key, hash_func, equal_func, bucket_n, hash, prev);
- return iterator(local_it, &this->get_bucket_value_traits());
+ return iterator( this->priv_find(key, hash_func, equal_func, bucket_n, hash, prev)
+ , &this->get_bucket_value_traits());
}
//! <b>Effects</b>: Finds a const_iterator to the first element whose key is
@@ -2128,8 +2479,8 @@ class hashtable_impl
//! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
//!
//! <b>Throws</b>: If the internal hasher or the equality functor throws.
- const_iterator find(const_reference value) const
- { return this->find(value, this->priv_hasher(), this->priv_equal()); }
+ const_iterator find(const key_type &key) const
+ { return this->find(key, this->priv_hasher(), this->priv_equal()); }
//! <b>Requires</b>: "hash_func" must be a hash function that induces
//! the same hash values as the stored hasher. The difference is that
@@ -2150,15 +2501,15 @@ class hashtable_impl
//! <b>Note</b>: This function is used when constructing a value_type
//! is expensive and the value_type can be compared with a cheaper
//! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
+ template<class KeyType, class KeyHasher, class KeyEqual>
const_iterator find
- (const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func) const
+ (const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) const
{
size_type bucket_n;
std::size_t hash_value;
siterator prev;
- siterator sit = this->priv_find(key, hash_func, equal_func, bucket_n, hash_value, prev);
- return const_iterator(sit, &this->get_bucket_value_traits());
+ return const_iterator( this->priv_find(key, hash_func, equal_func, bucket_n, hash_value, prev)
+ , &this->get_bucket_value_traits());
}
//! <b>Effects</b>: Returns a range containing all elements with values equivalent
@@ -2168,8 +2519,8 @@ class hashtable_impl
//! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
//!
//! <b>Throws</b>: If the internal hasher or the equality functor throws.
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return this->equal_range(value, this->priv_hasher(), this->priv_equal()); }
+ std::pair<iterator,iterator> equal_range(const key_type &key)
+ { return this->equal_range(key, this->priv_hasher(), this->priv_equal()); }
//! <b>Requires</b>: "hash_func" must be a hash function that induces
//! the same hash values as the stored hasher. The difference is that
@@ -2191,15 +2542,15 @@ class hashtable_impl
//! <b>Note</b>: This function is used when constructing a value_type
//! is expensive and the value_type can be compared with a cheaper
//! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
+ template<class KeyType, class KeyHasher, class KeyEqual>
std::pair<iterator,iterator> equal_range
- (const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func)
+ (const KeyType &key, KeyHasher hash_func, KeyEqual equal_func)
{
- size_type bucket_n1, bucket_n2, cnt;
- std::pair<siterator, siterator> ret = this->priv_equal_range
- (key, hash_func, equal_func, bucket_n1, bucket_n2, cnt);
+ std::pair<siterator, siterator> ret =
+ this->priv_equal_range(key, hash_func, equal_func);
return std::pair<iterator, iterator>
- (iterator(ret.first, &this->get_bucket_value_traits()), iterator(ret.second, &this->get_bucket_value_traits()));
+ ( iterator(ret.first, &this->get_bucket_value_traits())
+ , iterator(ret.second, &this->get_bucket_value_traits()));
}
//! <b>Effects</b>: Returns a range containing all elements with values equivalent
@@ -2210,8 +2561,8 @@ class hashtable_impl
//!
//! <b>Throws</b>: If the internal hasher or the equality functor throws.
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return this->equal_range(value, this->priv_hasher(), this->priv_equal()); }
+ equal_range(const key_type &key) const
+ { return this->equal_range(key, this->priv_hasher(), this->priv_equal()); }
//! <b>Requires</b>: "hash_func" must be a hash function that induces
//! the same hash values as the stored hasher. The difference is that
@@ -2233,18 +2584,19 @@ class hashtable_impl
//! <b>Note</b>: This function is used when constructing a value_type
//! is expensive and the value_type can be compared with a cheaper
//! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
+ template<class KeyType, class KeyHasher, class KeyEqual>
std::pair<const_iterator,const_iterator> equal_range
- (const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func) const
+ (const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) const
{
- size_type bucket_n1, bucket_n2, cnt;
std::pair<siterator, siterator> ret =
- this->priv_equal_range(key, hash_func, equal_func, bucket_n1, bucket_n2, cnt);
+ this->priv_equal_range(key, hash_func, equal_func);
return std::pair<const_iterator, const_iterator>
( const_iterator(ret.first, &this->get_bucket_value_traits())
, const_iterator(ret.second, &this->get_bucket_value_traits()));
}
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+
//! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
//! appropriate type. Otherwise the behavior is undefined.
//!
@@ -2254,11 +2606,7 @@ class hashtable_impl
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: If the internal hash function throws.
- iterator iterator_to(reference value)
- {
- return iterator(bucket_type::s_iterator_to
- (this->priv_value_to_node(value)), &this->get_bucket_value_traits());
- }
+ iterator iterator_to(reference value);
//! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
//! appropriate type. Otherwise the behavior is undefined.
@@ -2269,13 +2617,7 @@ class hashtable_impl
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: If the internal hash function throws.
- const_iterator iterator_to(const_reference value) const
- {
- node_reference r = *pointer_traits<node_ptr>::const_cast_from
- (pointer_traits<const_node_ptr>::pointer_to(this->priv_value_to_node(value)));
- siterator sit = bucket_type::s_iterator_to(r);
- return const_iterator(sit, &this->get_bucket_value_traits());
- }
+ const_iterator iterator_to(const_reference value) const;
//! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
//! appropriate type. Otherwise the behavior is undefined.
@@ -2289,12 +2631,7 @@ class hashtable_impl
//!
//! <b>Note</b>: This static function is available only if the <i>value traits</i>
//! is stateless.
- static local_iterator s_local_iterator_to(reference value)
- {
- BOOST_STATIC_ASSERT((!stateful_value_traits));
- siterator sit = bucket_type::s_iterator_to(*value_traits::to_node_ptr(value));
- return local_iterator(sit, const_value_traits_ptr());
- }
+ static local_iterator s_local_iterator_to(reference value);
//! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
//! appropriate type. Otherwise the behavior is undefined.
@@ -2308,14 +2645,7 @@ class hashtable_impl
//!
//! <b>Note</b>: This static function is available only if the <i>value traits</i>
//! is stateless.
- static const_local_iterator s_local_iterator_to(const_reference value)
- {
- BOOST_STATIC_ASSERT((!stateful_value_traits));
- node_reference r = *pointer_traits<node_ptr>::const_cast_from
- (value_traits::to_node_ptr(value));
- siterator sit = bucket_type::s_iterator_to(r);
- return const_local_iterator(sit, const_value_traits_ptr());
- }
+ static const_local_iterator s_local_iterator_to(const_reference value);
//! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
//! appropriate type. Otherwise the behavior is undefined.
@@ -2326,11 +2656,7 @@ class hashtable_impl
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
- local_iterator local_iterator_to(reference value)
- {
- siterator sit = bucket_type::s_iterator_to(this->priv_value_to_node(value));
- return local_iterator(sit, this->priv_value_traits_ptr());
- }
+ local_iterator local_iterator_to(reference value);
//! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
//! appropriate type. Otherwise the behavior is undefined.
@@ -2341,13 +2667,7 @@ class hashtable_impl
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
- const_local_iterator local_iterator_to(const_reference value) const
- {
- node_reference r = *pointer_traits<node_ptr>::const_cast_from
- (pointer_traits<const_node_ptr>::pointer_to(this->priv_value_to_node(value)));
- siterator sit = bucket_type::s_iterator_to(r);
- return const_local_iterator(sit, this->priv_value_traits_ptr());
- }
+ const_local_iterator local_iterator_to(const_reference value) const;
//! <b>Effects</b>: Returns the number of buckets passed in the constructor
//! or the last rehash function.
@@ -2355,8 +2675,7 @@ class hashtable_impl
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
- size_type bucket_count() const
- { return this->priv_bucket_count(); }
+ size_type bucket_count() const;
//! <b>Requires</b>: n is in the range [0, this->bucket_count()).
//!
@@ -2365,8 +2684,8 @@ class hashtable_impl
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
- size_type bucket_size(size_type n) const
- { return this->priv_bucket_pointer()[n].size(); }
+ size_type bucket_size(size_type n) const;
+ #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! <b>Effects</b>: Returns the index of the bucket in which elements
//! with keys equivalent to k would be found, if any such element existed.
@@ -2392,17 +2711,17 @@ class hashtable_impl
//!
//! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
template<class KeyType, class KeyHasher>
- size_type bucket(const KeyType& k, const KeyHasher &hash_func) const
+ size_type bucket(const KeyType& k, KeyHasher hash_func) const
{ return this->priv_hash_to_bucket(hash_func(k)); }
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! <b>Effects</b>: Returns the bucket array pointer passed in the constructor
//! or the last rehash function.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
- bucket_ptr bucket_pointer() const
- { return this->priv_bucket_pointer(); }
+ bucket_ptr bucket_pointer() const;
//! <b>Requires</b>: n is in the range [0, this->bucket_count()).
//!
@@ -2415,8 +2734,7 @@ class hashtable_impl
//!
//! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
//! containing all of the elements in the nth bucket.
- local_iterator begin(size_type n)
- { return local_iterator(this->priv_bucket_pointer()[n].begin(), this->priv_value_traits_ptr()); }
+ local_iterator begin(size_type n);
//! <b>Requires</b>: n is in the range [0, this->bucket_count()).
//!
@@ -2429,8 +2747,7 @@ class hashtable_impl
//!
//! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
//! containing all of the elements in the nth bucket.
- const_local_iterator begin(size_type n) const
- { return this->cbegin(n); }
+ const_local_iterator begin(size_type n) const;
//! <b>Requires</b>: n is in the range [0, this->bucket_count()).
//!
@@ -2443,11 +2760,7 @@ class hashtable_impl
//!
//! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
//! containing all of the elements in the nth bucket.
- const_local_iterator cbegin(size_type n) const
- {
- bucket_reference br = pointer_traits<bucket_ptr>::const_cast_from(this->priv_bucket_pointer())[n];
- return const_local_iterator(br.begin(), this->priv_value_traits_ptr());
- }
+ const_local_iterator cbegin(size_type n) const;
//! <b>Requires</b>: n is in the range [0, this->bucket_count()).
//!
@@ -2460,8 +2773,7 @@ class hashtable_impl
//!
//! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
//! containing all of the elements in the nth bucket.
- local_iterator end(size_type n)
- { return local_iterator(this->priv_bucket_pointer()[n].end(), this->priv_value_traits_ptr()); }
+ local_iterator end(size_type n);
//! <b>Requires</b>: n is in the range [0, this->bucket_count()).
//!
@@ -2474,8 +2786,7 @@ class hashtable_impl
//!
//! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
//! containing all of the elements in the nth bucket.
- const_local_iterator end(size_type n) const
- { return this->cend(n); }
+ const_local_iterator end(size_type n) const;
//! <b>Requires</b>: n is in the range [0, this->bucket_count()).
//!
@@ -2488,11 +2799,8 @@ class hashtable_impl
//!
//! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
//! containing all of the elements in the nth bucket.
- const_local_iterator cend(size_type n) const
- {
- bucket_reference br = pointer_traits<bucket_ptr>::const_cast_from(this->priv_bucket_pointer())[n];
- return const_local_iterator ( br.end(), this->priv_value_traits_ptr());
- }
+ const_local_iterator cend(size_type n) const;
+ #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! <b>Requires</b>: new_bucket_traits can hold a pointer to a new bucket array
//! or the same as the old bucket array with a different length. new_size is the length of the
@@ -2520,36 +2828,33 @@ class hashtable_impl
//Check power of two bucket array if the option is activated
BOOST_INTRUSIVE_INVARIANT_ASSERT
- (!power_2_buckets || (0 == (new_bucket_count & (new_bucket_count-1u))));
+ (!power_2_buckets || (0 == (new_bucket_count & (new_bucket_count-1u))));
size_type n = this->priv_get_cache_bucket_num();
const bool same_buffer = old_buckets == new_buckets;
//If the new bucket length is a common factor
//of the old one we can avoid hash calculations.
- const bool fast_shrink = (!incremental) && (old_bucket_count > new_bucket_count) &&
- (power_2_buckets ||(old_bucket_count % new_bucket_count) == 0);
+ const bool fast_shrink = (!incremental) && (old_bucket_count >= new_bucket_count) &&
+ (power_2_buckets || (old_bucket_count % new_bucket_count) == 0);
//If we are shrinking the same bucket array and it's
//is a fast shrink, just rehash the last nodes
size_type new_first_bucket_num = new_bucket_count;
if(same_buffer && fast_shrink && (n < new_bucket_count)){
+ new_first_bucket_num = n;
n = new_bucket_count;
- new_first_bucket_num = this->priv_get_cache_bucket_num();
}
//Anti-exception stuff: they destroy the elements if something goes wrong.
//If the source and destination buckets are the same, the second rollback function
//is harmless, because all elements have been already unlinked and destroyed
typedef detail::init_disposer<node_algorithms> NodeDisposer;
+ typedef detail::exception_array_disposer<bucket_type, NodeDisposer, size_type> ArrayDisposer;
NodeDisposer node_disp;
- bucket_type & newbuck = new_buckets[0];
- bucket_type & oldbuck = old_buckets[0];
- detail::exception_array_disposer<bucket_type, NodeDisposer, size_type>
- rollback1(newbuck, node_disp, new_bucket_count);
- detail::exception_array_disposer<bucket_type, NodeDisposer, size_type>
- rollback2(oldbuck, node_disp, old_bucket_count);
+ ArrayDisposer rollback1(new_buckets[0], node_disp, new_bucket_count);
+ ArrayDisposer rollback2(old_buckets[0], node_disp, old_bucket_count);
//Put size in a safe value for rollback exception
- size_type size_backup = this->priv_size_traits().get_size();
+ size_type const size_backup = this->priv_size_traits().get_size();
this->priv_size_traits().set_size(0);
//Put cache to safe position
this->priv_initialize_cache();
@@ -2558,20 +2863,17 @@ class hashtable_impl
//Iterate through nodes
for(; n < old_bucket_count; ++n){
bucket_type &old_bucket = old_buckets[n];
-
if(!fast_shrink){
- siterator before_i(old_bucket.before_begin());
- siterator end_sit(old_bucket.end());
- siterator i(old_bucket.begin());
- for(;i != end_sit; ++i){
+ for( siterator before_i(old_bucket.before_begin()), i(old_bucket.begin()), end_sit(old_bucket.end())
+ ; i != end_sit
+ ; i = before_i, ++i){
const value_type &v = this->priv_value_from_slist_node(i.pointed_node());
const std::size_t hash_value = this->priv_stored_or_compute_hash(v, store_hash_t());
- const size_type new_n = detail::hash_to_bucket_split<power_2_buckets, incremental>(hash_value, new_bucket_count, new_bucket_count);
+ const size_type new_n = detail::hash_to_bucket_split<power_2_buckets, incremental>
+ (hash_value, new_bucket_count, new_bucket_count);
if(cache_begin && new_n < new_first_bucket_num)
new_first_bucket_num = new_n;
- siterator last = bucket_type::s_iterator_to
- (*group_functions_t::get_last_in_group
- (detail::dcast_bucket_ptr<node>(i.pointed_node()), optimize_multikey_t()));
+ siterator const last = (priv_last_in_group)(i);
if(same_buffer && new_n == n){
before_i = last;
}
@@ -2579,7 +2881,6 @@ class hashtable_impl
bucket_type &new_b = new_buckets[new_n];
new_b.splice_after(new_b.before_begin(), old_bucket, before_i, last);
}
- i = before_i;
}
}
else{
@@ -2587,12 +2888,10 @@ class hashtable_impl
if(cache_begin && new_n < new_first_bucket_num)
new_first_bucket_num = new_n;
bucket_type &new_b = new_buckets[new_n];
- if(!old_bucket.empty()){
- new_b.splice_after( new_b.before_begin()
- , old_bucket
- , old_bucket.before_begin()
- , hashtable_impl::priv_get_last(old_bucket));
- }
+ new_b.splice_after( new_b.before_begin()
+ , old_bucket
+ , old_bucket.before_begin()
+ , bucket_plus_vtraits_t::priv_get_last(old_bucket, optimize_multikey_t()));
}
}
@@ -2621,56 +2920,47 @@ class hashtable_impl
const size_type split_idx = this->priv_split_traits().get_size();
const size_type bucket_cnt = this->priv_bucket_count();
const bucket_ptr buck_ptr = this->priv_bucket_pointer();
+ bool ret = false;
if(grow){
//Test if the split variable can be changed
- if(split_idx >= bucket_cnt)
- return false;
-
- const size_type bucket_to_rehash = split_idx - bucket_cnt/2;
- bucket_type &old_bucket = buck_ptr[bucket_to_rehash];
- siterator before_i(old_bucket.before_begin());
- const siterator end_sit(old_bucket.end());
- siterator i(old_bucket.begin());
- this->priv_split_traits().increment();
-
- //Anti-exception stuff: if an exception is thrown while
- //moving elements from old_bucket to the target bucket, all moved
- //elements are moved back to the original one.
- detail::incremental_rehash_rollback<bucket_type, split_traits> rollback
- ( buck_ptr[split_idx], old_bucket, this->priv_split_traits());
- for(;i != end_sit; ++i){
- const value_type &v = this->priv_value_from_slist_node(i.pointed_node());
- const std::size_t hash_value = this->priv_stored_or_compute_hash(v, store_hash_t());
- const size_type new_n = this->priv_hash_to_bucket(hash_value);
- siterator last = bucket_type::s_iterator_to
- (*group_functions_t::get_last_in_group
- (detail::dcast_bucket_ptr<node>(i.pointed_node()), optimize_multikey_t()));
- if(new_n == bucket_to_rehash){
- before_i = last;
- }
- else{
- bucket_type &new_b = buck_ptr[new_n];
- new_b.splice_after(new_b.before_begin(), old_bucket, before_i, last);
+ if((ret = split_idx < bucket_cnt)){
+ const size_type bucket_to_rehash = split_idx - bucket_cnt/2;
+ bucket_type &old_bucket = buck_ptr[bucket_to_rehash];
+ this->priv_split_traits().increment();
+
+ //Anti-exception stuff: if an exception is thrown while
+ //moving elements from old_bucket to the target bucket, all moved
+ //elements are moved back to the original one.
+ detail::incremental_rehash_rollback<bucket_type, split_traits> rollback
+ ( buck_ptr[split_idx], old_bucket, this->priv_split_traits());
+ for( siterator before_i(old_bucket.before_begin()), i(old_bucket.begin()), end_sit(old_bucket.end())
+ ; i != end_sit; i = before_i, ++i){
+ const value_type &v = this->priv_value_from_slist_node(i.pointed_node());
+ const std::size_t hash_value = this->priv_stored_or_compute_hash(v, store_hash_t());
+ const size_type new_n = this->priv_hash_to_bucket(hash_value);
+ siterator const last = (priv_last_in_group)(i);
+ if(new_n == bucket_to_rehash){
+ before_i = last;
+ }
+ else{
+ bucket_type &new_b = buck_ptr[new_n];
+ new_b.splice_after(new_b.before_begin(), old_bucket, before_i, last);
+ }
}
- i = before_i;
+ rollback.release();
+ this->priv_erasure_update_cache();
}
- rollback.release();
- this->priv_erasure_update_cache();
- return true;
}
- else{
- //Test if the split variable can be changed
- if(split_idx <= bucket_cnt/2)
- return false;
+ else if((ret = split_idx > bucket_cnt/2)){ //!grow
const size_type target_bucket_num = split_idx - 1 - bucket_cnt/2;
bucket_type &target_bucket = buck_ptr[target_bucket_num];
bucket_type &source_bucket = buck_ptr[split_idx-1];
target_bucket.splice_after(target_bucket.cbefore_begin(), source_bucket);
this->priv_split_traits().decrement();
this->priv_insertion_update_cache(target_bucket_num);
- return true;
}
+ return ret;
}
//! <b>Effects</b>: If new_bucket_traits.bucket_count() is not
@@ -2690,24 +2980,22 @@ class hashtable_impl
{
//This function is only available for containers with incremental hashing
BOOST_STATIC_ASSERT(( incremental && power_2_buckets ));
- size_type new_bucket_traits_size = new_bucket_traits.bucket_count();
- size_type cur_bucket_traits = this->priv_bucket_count();
- if(new_bucket_traits_size/2 != cur_bucket_traits && new_bucket_traits_size != cur_bucket_traits/2){
- return false;
- }
-
+ size_type const new_bucket_traits_size = new_bucket_traits.bucket_count();
+ size_type const cur_bucket_traits = this->priv_bucket_count();
const size_type split_idx = this->split_count();
+ //Test new bucket size is consistent with internal bucket size and split count
if(new_bucket_traits_size/2 == cur_bucket_traits){
- //Test if the split variable can be changed
if(!(split_idx >= cur_bucket_traits))
return false;
}
- else{
- //Test if the split variable can be changed
- if(!(split_idx <= cur_bucket_traits/2))
+ else if(new_bucket_traits_size == cur_bucket_traits/2){
+ if(!(split_idx <= new_bucket_traits_size))
return false;
}
+ else{
+ return false;
+ }
const size_type ini_n = this->priv_get_cache_bucket_num();
const bucket_ptr old_buckets = this->priv_bucket_pointer();
@@ -2725,19 +3013,16 @@ class hashtable_impl
return true;
}
- //! <b>Requires</b>:
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+
+ //! <b>Requires</b>: incremental<> option must be set
//!
- //! <b>Effects</b>:
+ //! <b>Effects</b>: returns the current split count
//!
- //! <b>Complexity</b>:
+ //! <b>Complexity</b>: Constant
//!
- //! <b>Throws</b>:
- size_type split_count() const
- {
- //This function is only available if incremental hashing is activated
- BOOST_STATIC_ASSERT(( incremental && power_2_buckets ));
- return this->priv_split_traits().get_size();
- }
+ //! <b>Throws</b>: Nothing
+ size_type split_count() const;
//! <b>Effects</b>: Returns the nearest new bucket count optimized for
//! the container that is bigger or equal than n. This suggestion can be
@@ -2748,14 +3033,7 @@ class hashtable_impl
//! <b>Complexity</b>: Amortized constant time.
//!
//! <b>Throws</b>: Nothing.
- static size_type suggested_upper_bucket_count(size_type n)
- {
- const std::size_t *primes = &prime_list_holder<0>::prime_list[0];
- const std::size_t *primes_end = primes + prime_list_holder<0>::prime_list_size;
- std::size_t const* bound = std::lower_bound(primes, primes_end, n);
- bound -= (bound == primes_end);
- return size_type(*bound);
- }
+ static size_type suggested_upper_bucket_count(size_type n);
//! <b>Effects</b>: Returns the nearest new bucket count optimized for
//! the container that is smaller or equal than n. This suggestion can be
@@ -2766,403 +3044,306 @@ class hashtable_impl
//! <b>Complexity</b>: Amortized constant time.
//!
//! <b>Throws</b>: Nothing.
- static size_type suggested_lower_bucket_count(size_type n)
- {
- const std::size_t *primes = &prime_list_holder<0>::prime_list[0];
- const std::size_t *primes_end = primes + prime_list_holder<0>::prime_list_size;
- size_type const* bound = std::upper_bound(primes, primes_end, n);
- bound -= (bound != primes);
- return size_type(*bound);
- }
- /// @cond
- void check() const {}
- private:
- size_traits &priv_size_traits()
- { return static_cast<size_traits&>(static_cast<data_type&>(*this)); }
-
- const size_traits &priv_size_traits() const
- { return static_cast<const size_traits&>(static_cast<const data_type&>(*this)); }
-
- bucket_ptr priv_bucket_pointer() const
- { return this->data_type::internal.internal.internal.internal.priv_bucket_pointer(); }
-
- SizeType priv_bucket_count() const
- { return this->data_type::internal.internal.internal.internal.priv_bucket_count(); }
-
- const bucket_plus_vtraits<ValueTraits, BucketTraits> &get_bucket_value_traits() const
- { return this->data_type::internal.internal.internal.internal.get_bucket_value_traits(); }
-
- bucket_plus_vtraits<ValueTraits, BucketTraits> &get_bucket_value_traits()
- { return this->data_type::internal.internal.internal.internal.get_bucket_value_traits(); }
-
- bucket_traits &priv_bucket_traits()
- { return this->data_type::internal.internal.internal.internal.priv_bucket_traits(); }
+ static size_type suggested_lower_bucket_count(size_type n);
+ #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
- const bucket_traits &priv_bucket_traits() const
- { return this->data_type::internal.internal.internal.internal.priv_bucket_traits(); }
-
- value_traits &priv_value_traits()
- { return this->data_type::internal.internal.internal.internal.priv_value_traits(); }
-
- const value_traits &priv_value_traits() const
- { return this->data_type::internal.internal.internal.internal.priv_value_traits(); }
-
- const_value_traits_ptr priv_value_traits_ptr() const
- { return this->data_type::internal.internal.internal.internal.priv_value_traits_ptr(); }
-
- siterator priv_invalid_local_it() const
- { return this->data_type::internal.internal.internal.internal.priv_invalid_local_it(); }
-
- split_traits &priv_split_traits()
- { return this->data_type::internal.priv_split_traits(); }
-
- const split_traits &priv_split_traits() const
- { return this->data_type::internal.priv_split_traits(); }
- bucket_ptr priv_get_cache()
- { return this->data_type::internal.internal.priv_get_cache(); }
-
- void priv_initialize_cache()
- { return this->data_type::internal.internal.priv_initialize_cache(); }
-
- siterator priv_begin() const
- { return this->data_type::internal.internal.priv_begin(); }
-
- const value_equal &priv_equal() const
- { return this->data_type::internal.internal.priv_equal(); }
-
- value_equal &priv_equal()
- { return this->data_type::internal.internal.priv_equal(); }
-
- const hasher &priv_hasher() const
- { return this->data_type::internal.internal.internal.priv_hasher(); }
-
- hasher &priv_hasher()
- { return this->data_type::internal.internal.internal.priv_hasher(); }
-
- void priv_swap_cache(hashtable_impl &h)
- { this->data_type::internal.internal.priv_swap_cache(h.data_type::internal.internal); }
-
- node &priv_value_to_node(value_type &v)
- { return this->data_type::internal.internal.internal.internal.priv_value_to_node(v); }
-
- const node &priv_value_to_node(const value_type &v) const
- { return this->data_type::internal.internal.internal.internal.priv_value_to_node(v); }
-
- SizeType priv_get_cache_bucket_num()
- { return this->data_type::internal.internal.priv_get_cache_bucket_num(); }
-
- void priv_insertion_update_cache(SizeType n)
- { return this->data_type::internal.internal.priv_insertion_update_cache(n); }
-
- template<bool Boolean>
- std::size_t priv_stored_or_compute_hash(const value_type &v, detail::bool_<Boolean> b) const
- { return this->data_type::internal.internal.internal.priv_stored_or_compute_hash(v, b); }
-
- value_type &priv_value_from_slist_node(slist_node_ptr n)
- { return this->data_type::internal.internal.internal.internal.priv_value_from_slist_node(n); }
+ friend bool operator==(const hashtable_impl &x, const hashtable_impl &y)
+ {
+ //Taken from N3068
+ if(constant_time_size && x.size() != y.size()){
+ return false;
+ }
+ for (const_iterator ix = x.cbegin(), ex = x.cend(); ix != ex; ++ix){
+ std::pair<const_iterator, const_iterator> eqx(x.equal_range(key_of_value()(*ix))),
+ eqy(y.equal_range(key_of_value()(*ix)));
+ if (boost::intrusive::iterator_distance(eqx.first, eqx.second) !=
+ boost::intrusive::iterator_distance(eqy.first, eqy.second) ||
+ !(priv_algo_is_permutation)(eqx.first, eqx.second, eqy.first) ){
+ return false;
+ }
+ ix = eqx.second;
+ }
+ return true;
+ }
- const value_type &priv_value_from_slist_node(slist_node_ptr n) const
- { return this->data_type::internal.internal.internal.internal.priv_value_from_slist_node(n); }
+ friend bool operator!=(const hashtable_impl &x, const hashtable_impl &y)
+ { return !(x == y); }
- void priv_erasure_update_cache_range(SizeType first_bucket_num, SizeType last_bucket_num)
- { return this->data_type::internal.internal.priv_erasure_update_cache_range(first_bucket_num, last_bucket_num); }
+ friend bool operator<(const hashtable_impl &x, const hashtable_impl &y)
+ { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
- void priv_erasure_update_cache()
- { return this->data_type::internal.internal.priv_erasure_update_cache(); }
+ friend bool operator>(const hashtable_impl &x, const hashtable_impl &y)
+ { return y < x; }
- static std::size_t priv_stored_hash(slist_node_ptr n, detail::true_ true_value)
- { return bucket_plus_vtraits<ValueTraits, BucketTraits>::priv_stored_hash(n, true_value); }
+ friend bool operator<=(const hashtable_impl &x, const hashtable_impl &y)
+ { return !(y < x); }
- static std::size_t priv_stored_hash(slist_node_ptr n, detail::false_ false_value)
- { return bucket_plus_vtraits<ValueTraits, BucketTraits>::priv_stored_hash(n, false_value); }
+ friend bool operator>=(const hashtable_impl &x, const hashtable_impl &y)
+ { return !(x < y); }
- std::size_t priv_hash_to_bucket(std::size_t hash_value) const
- {
- return detail::hash_to_bucket_split<power_2_buckets, incremental>
- (hash_value, this->priv_bucket_traits().bucket_count(), this->priv_split_traits().get_size());
- }
+ /// @cond
+ void check() const {}
+ private:
- template<class Disposer>
- void priv_erase_range_impl
- (size_type bucket_num, siterator before_first_it, siterator end_sit, Disposer disposer, size_type &num_erased)
+ template <class MaybeConstHashtableImpl, class Cloner, class Disposer>
+ void priv_clone_from(MaybeConstHashtableImpl &src, Cloner cloner, Disposer disposer)
{
- const bucket_ptr buckets = this->priv_bucket_pointer();
- bucket_type &b = buckets[bucket_num];
-
- if(before_first_it == b.before_begin() && end_sit == b.end()){
- this->priv_erase_range_impl(bucket_num, 1, disposer, num_erased);
- }
- else{
- num_erased = 0;
- siterator to_erase(before_first_it);
- ++to_erase;
- slist_node_ptr end_ptr = end_sit.pointed_node();
- while(to_erase != end_sit){
- group_functions_t::erase_from_group(end_ptr, detail::dcast_bucket_ptr<node>(to_erase.pointed_node()), optimize_multikey_t());
- to_erase = b.erase_after_and_dispose(before_first_it, make_node_disposer(disposer));
- ++num_erased;
+ this->clear_and_dispose(disposer);
+ if(!constant_time_size || !src.empty()){
+ const size_type src_bucket_count = src.bucket_count();
+ const size_type dst_bucket_count = this->bucket_count();
+ //Check power of two bucket array if the option is activated
+ BOOST_INTRUSIVE_INVARIANT_ASSERT
+ (!power_2_buckets || (0 == (src_bucket_count & (src_bucket_count-1))));
+ BOOST_INTRUSIVE_INVARIANT_ASSERT
+ (!power_2_buckets || (0 == (dst_bucket_count & (dst_bucket_count-1))));
+ //If src bucket count is bigger or equal, structural copy is possible
+ const bool structural_copy = (!incremental) && (src_bucket_count >= dst_bucket_count) &&
+ (power_2_buckets || (src_bucket_count % dst_bucket_count) == 0);
+ if(structural_copy){
+ this->priv_structural_clone_from(src, cloner, disposer);
+ }
+ else{
+ //Unlike previous cloning algorithm, this can throw
+ //if cloner, hasher or comparison functor throw
+ typedef typename detail::if_c< detail::is_const<MaybeConstHashtableImpl>::value
+ , typename MaybeConstHashtableImpl::const_iterator
+ , typename MaybeConstHashtableImpl::iterator
+ >::type clone_iterator;
+ clone_iterator b(src.begin()), e(src.end());
+ detail::exception_disposer<hashtable_impl, Disposer> rollback(*this, disposer);
+ for(; b != e; ++b){
+ //No need to check for duplicates and insert it in the first position
+ //as this is an unordered container. So use minimal insertion code
+ std::size_t const hash_to_store = this->priv_stored_or_compute_hash(*b, store_hash_t());;
+ size_type const bucket_number = this->priv_hash_to_bucket(hash_to_store);
+ typedef typename detail::if_c
+ <detail::is_const<MaybeConstHashtableImpl>::value, const_reference, reference>::type reference_type;
+ reference_type r = *b;
+ this->priv_clone_front_in_bucket<reference_type>(bucket_number, r, hash_to_store, cloner);
+ }
+ rollback.release();
}
- this->priv_size_traits().set_size(this->priv_size_traits().get_size()-num_erased);
}
}
- template<class Disposer>
- void priv_erase_range_impl
- (size_type first_bucket_num, size_type num_buckets, Disposer disposer, size_type &num_erased)
- {
- //Now fully clear the intermediate buckets
- const bucket_ptr buckets = this->priv_bucket_pointer();
- num_erased = 0;
- for(size_type i = first_bucket_num; i < (num_buckets + first_bucket_num); ++i){
- bucket_type &b = buckets[i];
- siterator b_begin(b.before_begin());
- siterator nxt(b_begin);
- ++nxt;
- siterator end_sit(b.end());
- while(nxt != end_sit){
- group_functions_t::init_group(detail::dcast_bucket_ptr<node>(nxt.pointed_node()), optimize_multikey_t());
- nxt = b.erase_after_and_dispose
- (b_begin, make_node_disposer(disposer));
- this->priv_size_traits().decrement();
- ++num_erased;
+ template<class ValueReference, class Cloner>
+ void priv_clone_front_in_bucket( size_type const bucket_number
+ , typename detail::identity<ValueReference>::type src_ref
+ , std::size_t const hash_to_store, Cloner cloner)
+ {
+ //No need to check for duplicates and insert it in the first position
+ //as this is an unordered container. So use minimal insertion code
+ //std::size_t const hash_value = this->priv_stored_or_compute_hash(src_ref, store_hash_t());;
+ //size_type const bucket_number = this->priv_hash_to_bucket(hash_value);
+ bucket_type &cur_bucket = this->priv_bucket_pointer()[bucket_number];
+ siterator const prev(cur_bucket.before_begin());
+ //Just check if the cloned node is equal to the first inserted value in the new bucket
+ //as equal src values were contiguous and they should be already inserted in the
+ //destination bucket.
+ bool const next_is_in_group = optimize_multikey && !cur_bucket.empty() &&
+ this->priv_equal()( key_of_value()(src_ref)
+ , key_of_value()(this->priv_value_from_slist_node((++siterator(prev)).pointed_node())));
+ this->priv_insert_equal_after_find(*cloner(src_ref), bucket_number, hash_to_store, prev, next_is_in_group);
+ }
+
+ template <class MaybeConstHashtableImpl, class Cloner, class Disposer>
+ void priv_structural_clone_from(MaybeConstHashtableImpl &src, Cloner cloner, Disposer disposer)
+ {
+ //First clone the first ones
+ const size_type src_bucket_count = src.bucket_count();
+ const size_type dst_bucket_count = this->bucket_count();
+ const bucket_ptr src_buckets = src.priv_bucket_pointer();
+ const bucket_ptr dst_buckets = this->priv_bucket_pointer();
+ size_type constructed = 0;
+ typedef node_cast_adaptor< detail::node_disposer<Disposer, value_traits, CircularSListAlgorithms>
+ , slist_node_ptr, node_ptr > NodeDisposer;
+ NodeDisposer node_disp(disposer, &this->priv_value_traits());
+
+ detail::exception_array_disposer<bucket_type, NodeDisposer, size_type>
+ rollback(dst_buckets[0], node_disp, constructed);
+ //Now insert the remaining ones using the modulo trick
+ for( //"constructed" already initialized
+ ; constructed < src_bucket_count
+ ; ++constructed){
+ //Since incremental hashing can't be structurally copied, avoid hash_to_bucket_split
+ const std::size_t new_n = detail::hash_to_bucket(constructed, dst_bucket_count, detail::bool_<power_2_buckets>());
+ bucket_type &src_b = src_buckets[constructed];
+ for( siterator b(src_b.begin()), e(src_b.end()); b != e; ++b){
+ slist_node_ptr const n(b.pointed_node());
+ typedef typename detail::if_c
+ <detail::is_const<MaybeConstHashtableImpl>::value, const_reference, reference>::type reference_type;
+ reference_type r = this->priv_value_from_slist_node(n);
+ this->priv_clone_front_in_bucket<reference_type>
+ (new_n, r, this->priv_stored_hash(n, store_hash_t()), cloner);
}
}
+ this->priv_hasher() = src.priv_hasher();
+ this->priv_equal() = src.priv_equal();
+ rollback.release();
+ this->priv_size_traits().set_size(src.priv_size_traits().get_size());
+ this->priv_split_traits().set_size(dst_bucket_count);
+ this->priv_insertion_update_cache(0u);
+ this->priv_erasure_update_cache();
}
- template<class Disposer>
- void priv_erase_range( siterator before_first_it, size_type first_bucket
- , siterator last_it, size_type last_bucket
- , Disposer disposer)
+ std::size_t priv_hash_to_bucket(std::size_t hash_value) const
{
- size_type num_erased;
- if (first_bucket == last_bucket){
- this->priv_erase_range_impl(first_bucket, before_first_it, last_it, disposer, num_erased);
- }
- else {
- bucket_type *b = (&this->priv_bucket_pointer()[0]);
- this->priv_erase_range_impl(first_bucket, before_first_it, b[first_bucket].end(), disposer, num_erased);
- if(size_type n = (last_bucket - first_bucket - 1))
- this->priv_erase_range_impl(first_bucket + 1, n, disposer, num_erased);
- this->priv_erase_range_impl(last_bucket, b[last_bucket].before_begin(), last_it, disposer, num_erased);
- }
+ return detail::hash_to_bucket_split<power_2_buckets, incremental>
+ (hash_value, this->priv_bucket_traits().bucket_count(), this->priv_split_traits().get_size());
}
- std::size_t priv_get_bucket_num(siterator it)
- { return this->priv_get_bucket_num_hash_dispatch(it, store_hash_t()); }
-
- std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::true_) //store_hash
+ iterator priv_insert_equal_after_find(reference value, size_type bucket_num, std::size_t hash_value, siterator prev, bool const next_is_in_group)
{
- return this->priv_hash_to_bucket
- (this->priv_stored_hash(it.pointed_node(), store_hash_t()));
+ //Now store hash if needed
+ node_ptr n = pointer_traits<node_ptr>::pointer_to(this->priv_value_to_node(value));
+ node_functions_t::store_hash(n, hash_value, store_hash_t());
+ //Checks for some modes
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(n));
+ //Shortcut to optimize_multikey cases
+ group_functions_t::insert_in_group
+ ( next_is_in_group ? detail::dcast_bucket_ptr<node>((++siterator(prev)).pointed_node()) : n
+ , n, optimize_multikey_t());
+ //Update cache and increment size if needed
+ this->priv_insertion_update_cache(bucket_num);
+ this->priv_size_traits().increment();
+ //Insert the element in the bucket after it
+ return iterator(bucket_type::s_insert_after(prev, *n), &this->get_bucket_value_traits());
}
- std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::false_) //NO store_hash
- { return this->data_type::internal.internal.internal.internal.priv_get_bucket_num_no_hash_store(it, optimize_multikey_t()); }
-
- static siterator priv_get_previous(bucket_type &b, siterator i)
- { return bucket_plus_vtraits_t::priv_get_previous(b, i, optimize_multikey_t()); }
-
- static siterator priv_get_last(bucket_type &b)
- { return bucket_plus_vtraits_t::priv_get_last(b, optimize_multikey_t()); }
-
- template<class Disposer>
- void priv_erase(const_iterator i, Disposer disposer, detail::true_)
- {
- slist_node_ptr elem(i.slist_it().pointed_node());
- slist_node_ptr f_bucket_end, l_bucket_end;
- if(store_hash){
- f_bucket_end = l_bucket_end =
- (this->priv_bucket_pointer()
- [this->priv_hash_to_bucket
- (this->priv_stored_hash(elem, store_hash_t()))
- ]).before_begin().pointed_node();
- }
- else{
- f_bucket_end = this->priv_bucket_pointer()->cend().pointed_node();
- l_bucket_end = f_bucket_end + this->priv_bucket_count() - 1;
- }
- node_ptr nxt_in_group;
- siterator prev = bucket_type::s_iterator_to
- (*group_functions_t::get_previous_and_next_in_group
- ( elem, nxt_in_group, f_bucket_end, l_bucket_end)
- );
- bucket_type::s_erase_after_and_dispose(prev, make_node_disposer(disposer));
- if(nxt_in_group)
- group_algorithms::unlink_after(nxt_in_group);
- if(safemode_or_autounlink)
- group_algorithms::init(detail::dcast_bucket_ptr<node>(elem));
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ siterator priv_find //In case it is not found previt is bucket.before_begin()
+ ( const KeyType &key, KeyHasher hash_func
+ , KeyEqual equal_func, size_type &bucket_number, std::size_t &h, siterator &previt) const
+ {
+ h = hash_func(key);
+ return this->priv_find_with_hash(key, equal_func, bucket_number, h, previt);
}
- template <class Disposer>
- void priv_erase(const_iterator i, Disposer disposer, detail::false_)
+ template<class KeyType, class KeyEqual>
+ bool priv_is_value_equal_to_key(const value_type &v, const std::size_t h, const KeyType &key, KeyEqual equal_func) const
{
- siterator to_erase(i.slist_it());
- bucket_type &b = this->priv_bucket_pointer()[this->priv_get_bucket_num(to_erase)];
- siterator prev(this->priv_get_previous(b, to_erase));
- b.erase_after_and_dispose(prev, make_node_disposer(disposer));
+ (void)h;
+ return (!compare_hash || this->priv_stored_or_compute_hash(v, store_hash_t()) == h) && equal_func(key, key_of_value()(v));
}
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- siterator priv_find
- ( const KeyType &key, KeyHasher hash_func
- , KeyValueEqual equal_func, size_type &bucket_number, std::size_t &h, siterator &previt) const
+ //return previous iterator to the next equal range group in case
+ static siterator priv_last_in_group(const siterator &it_first_in_group)
{
- h = hash_func(key);
- return this->priv_find_with_hash(key, equal_func, bucket_number, h, previt);
+ return bucket_type::s_iterator_to
+ (*group_functions_t::get_last_in_group
+ (detail::dcast_bucket_ptr<node>(it_first_in_group.pointed_node()), optimize_multikey_t()));
}
- template<class KeyType, class KeyValueEqual>
- siterator priv_find_with_hash
- ( const KeyType &key, KeyValueEqual equal_func, size_type &bucket_number, const std::size_t h, siterator &previt) const
+ template<class KeyType, class KeyEqual>
+ siterator priv_find_with_hash //In case it is not found previt is bucket.before_begin()
+ ( const KeyType &key, KeyEqual equal_func, size_type &bucket_number, const std::size_t h, siterator &previt) const
{
bucket_number = this->priv_hash_to_bucket(h);
bucket_type &b = this->priv_bucket_pointer()[bucket_number];
previt = b.before_begin();
- if(constant_time_size && this->empty()){
- return this->priv_invalid_local_it();
- }
-
siterator it = previt;
- ++it;
-
- while(it != b.end()){
- const value_type &v = this->priv_value_from_slist_node(it.pointed_node());
- if(compare_hash){
- std::size_t vh = this->priv_stored_or_compute_hash(v, store_hash_t());
- if(h == vh && equal_func(key, v)){
- return it;
- }
- }
- else if(equal_func(key, v)){
+ siterator const endit = b.end();
+
+ while(++it != endit){
+ if(this->priv_is_value_equal_to_key(this->priv_value_from_slist_node(it.pointed_node()), h, key, equal_func)){
return it;
}
- if(optimize_multikey){
- previt = bucket_type::s_iterator_to
- (*group_functions_t::get_last_in_group
- (detail::dcast_bucket_ptr<node>(it.pointed_node()), optimize_multikey_t()));
- it = previt;
- }
- else{
- previt = it;
- }
- ++it;
+ previt = it = (priv_last_in_group)(it);
}
previt = b.before_begin();
return this->priv_invalid_local_it();
}
- iterator priv_insert_equal_with_hash(reference value, std::size_t hash_value)
- {
- size_type bucket_num;
- siterator prev;
- siterator it = this->priv_find_with_hash
- (value, this->priv_equal(), bucket_num, hash_value, prev);
- return this->priv_insert_equal_find(value, bucket_num, hash_value, it);
- }
-
- iterator priv_insert_equal_find(reference value, size_type bucket_num, std::size_t hash_value, siterator it)
- {
- bucket_type &b = this->priv_bucket_pointer()[bucket_num];
- bool found_equal = it != this->priv_invalid_local_it();
- if(!found_equal){
- it = b.before_begin();
- }
- //Now store hash if needed
- node_ptr n = pointer_traits<node_ptr>::pointer_to(this->priv_value_to_node(value));
- node_functions_t::store_hash(n, hash_value, store_hash_t());
- //Checks for some modes
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
- //Shortcut for optimize_multikey cases
- if(optimize_multikey){
- node_ptr first_in_group = found_equal ?
- detail::dcast_bucket_ptr<node>(it.pointed_node()) : node_ptr();
- group_functions_t::insert_in_group(first_in_group, n, optimize_multikey_t());
- }
- //Update cache and increment size if needed
- this->priv_insertion_update_cache(bucket_num);
- this->priv_size_traits().increment();
- //Insert the element in the bucket after it
- return iterator(b.insert_after(it, *n), &this->get_bucket_value_traits());
- }
-
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- std::pair<siterator, siterator> priv_equal_range
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ std::pair<siterator, siterator> priv_local_equal_range
( const KeyType &key
, KeyHasher hash_func
- , KeyValueEqual equal_func
- , size_type &bucket_number_first
- , size_type &bucket_number_second
+ , KeyEqual equal_func
+ , size_type &found_bucket
, size_type &cnt) const
{
- std::size_t h;
cnt = 0;
- siterator prev;
//Let's see if the element is present
+
+ siterator prev;
+ size_type n_bucket;
+ std::size_t h;
std::pair<siterator, siterator> to_return
- ( this->priv_find(key, hash_func, equal_func, bucket_number_first, h, prev)
+ ( this->priv_find(key, hash_func, equal_func, n_bucket, h, prev)
, this->priv_invalid_local_it());
- if(to_return.first == to_return.second){
- bucket_number_second = bucket_number_first;
- return to_return;
- }
- {
+
+ if(to_return.first != to_return.second){
+ found_bucket = n_bucket;
//If it's present, find the first that it's not equal in
//the same bucket
- bucket_type &b = this->priv_bucket_pointer()[bucket_number_first];
+ bucket_type &b = this->priv_bucket_pointer()[n_bucket];
siterator it = to_return.first;
+ ++cnt; //At least one is found
if(optimize_multikey){
- to_return.second = bucket_type::s_iterator_to
- (*node_traits::get_next(group_functions_t::get_last_in_group
- (detail::dcast_bucket_ptr<node>(it.pointed_node()), optimize_multikey_t())));
-
- cnt = 0;
- for(; it != to_return.second; ++it){ ++cnt; }
- if(to_return.second != b.end()){
- bucket_number_second = bucket_number_first;
- return to_return;
- }
+ to_return.second = ++(priv_last_in_group)(it);
+ cnt += boost::intrusive::iterator_distance(++it, to_return.second);
}
else{
- ++cnt;
- ++it;
- while(it != b.end()){
- const value_type &v = this->priv_value_from_slist_node(it.pointed_node());
- if(compare_hash){
- std::size_t hv = this->priv_stored_or_compute_hash(v, store_hash_t());
- if(hv != h || !equal_func(key, v)){
- to_return.second = it;
- bucket_number_second = bucket_number_first;
- return to_return;
- }
- }
- else if(!equal_func(key, v)){
- to_return.second = it;
- bucket_number_second = bucket_number_first;
- return to_return;
- }
- ++it;
+ siterator const bend = b.end();
+ while(++it != bend &&
+ this->priv_is_value_equal_to_key(this->priv_value_from_slist_node(it.pointed_node()), h, key, equal_func)){
++cnt;
}
+ to_return.second = it;
}
}
+ return to_return;
+ }
- //If we reached the end, find the first, non-empty bucket
- for(bucket_number_second = bucket_number_first+1
- ; bucket_number_second != this->priv_bucket_count()
- ; ++bucket_number_second){
- bucket_type &b = this->priv_bucket_pointer()[bucket_number_second];
- if(!b.empty()){
- to_return.second = b.begin();
- return to_return;
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ std::pair<siterator, siterator> priv_equal_range
+ ( const KeyType &key
+ , KeyHasher hash_func
+ , KeyEqual equal_func) const
+ {
+ size_type n_bucket;
+ size_type cnt;
+
+ //Let's see if the element is present
+ std::pair<siterator, siterator> to_return
+ (this->priv_local_equal_range(key, hash_func, equal_func, n_bucket, cnt));
+ //If not, find the next element as ".second" if ".second" local iterator
+ //is not pointing to an element.
+ bucket_ptr const bp = this->priv_bucket_pointer();
+ if(to_return.first != to_return.second &&
+ to_return.second == bp[n_bucket].end()){
+ to_return.second = this->priv_invalid_local_it();
+ ++n_bucket;
+ for( const size_type max_bucket = this->priv_bucket_count()
+ ; n_bucket != max_bucket
+ ; ++n_bucket){
+ bucket_type &b = bp[n_bucket];
+ if(!b.empty()){
+ to_return.second = b.begin();
+ break;
+ }
}
}
-
- //Otherwise, return the end node
- to_return.second = this->priv_invalid_local_it();
return to_return;
}
+
+ std::size_t priv_get_bucket_num(siterator it)
+ { return this->priv_get_bucket_num_hash_dispatch(it, store_hash_t()); }
+
+ std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::true_) //store_hash
+ {
+ return this->priv_hash_to_bucket
+ (this->priv_stored_hash(it.pointed_node(), store_hash_t()));
+ }
+
+ std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::false_) //NO store_hash
+ { return this->priv_get_bucket_num_no_hash_store(it, optimize_multikey_t()); }
+
+ static siterator priv_get_previous(bucket_type &b, siterator i)
+ { return bucket_plus_vtraits_t::priv_get_previous(b, i, optimize_multikey_t()); }
+
/// @endcond
};
@@ -3232,16 +3413,17 @@ struct make_hashtable
typedef hashtable_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::hash
, typename packed_options::equal
- , typename packed_options::size_type
, bucket_traits
+ , typename packed_options::size_type
, (std::size_t(false)*hash_bool_flags::unique_keys_pos)
- | (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
- | (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
- | (std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos)
- | (std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos)
- | (std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos)
+ |(std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
+ |(std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
+ |(std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos)
+ |(std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos)
+ |(std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos)
> implementation_defined;
/// @endcond
@@ -3299,6 +3481,14 @@ class hashtable
hashtable& operator=(BOOST_RV_REF(hashtable) x)
{ return static_cast<hashtable&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(const hashtable &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(hashtable) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
};
#endif
diff --git a/boost/intrusive/intrusive_fwd.hpp b/boost/intrusive/intrusive_fwd.hpp
index 88cb537c6b..b6b14c0698 100644
--- a/boost/intrusive/intrusive_fwd.hpp
+++ b/boost/intrusive/intrusive_fwd.hpp
@@ -184,6 +184,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -198,6 +199,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -212,6 +214,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -251,6 +254,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -265,6 +269,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -279,6 +284,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -294,6 +300,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -308,6 +315,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -322,6 +330,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -362,6 +371,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -376,6 +386,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -390,6 +401,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -405,6 +417,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -419,6 +432,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -433,6 +447,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -447,6 +462,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -461,6 +477,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
@@ -475,6 +492,7 @@ template
, class O3 = void
, class O4 = void
, class O5 = void
+ , class O6 = void
>
#else
template<class T, class ...Options>
diff --git a/boost/intrusive/list.hpp b/boost/intrusive/list.hpp
index 906b002907..cc6d73bb43 100644
--- a/boost/intrusive/list.hpp
+++ b/boost/intrusive/list.hpp
@@ -248,8 +248,7 @@ class list_impl
void push_back(reference value)
{
node_ptr to_insert = priv_value_traits().to_node_ptr(value);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert));
node_algorithms::link_before(this->get_root_node(), to_insert);
this->priv_size_traits().increment();
}
@@ -267,8 +266,7 @@ class list_impl
void push_front(reference value)
{
node_ptr to_insert = priv_value_traits().to_node_ptr(value);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert));
node_algorithms::link_before(node_traits::get_next(this->get_root_node()), to_insert);
this->priv_size_traits().increment();
}
@@ -770,6 +768,33 @@ class list_impl
rollback.release();
}
+ //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
+ //!
+ //! <b>Effects</b>: Erases all the elements from *this
+ //! calling Disposer::operator()(pointer), clones all the
+ //! elements from src calling Cloner::operator()(reference)
+ //! and inserts them on *this.
+ //!
+ //! If cloner throws, all cloned elements are unlinked and disposed
+ //! calling Disposer::operator()(pointer).
+ //!
+ //! <b>Complexity</b>: Linear to erased plus inserted elements.
+ //!
+ //! <b>Throws</b>: If cloner throws. Basic guarantee.
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(list_impl) src, Cloner cloner, Disposer disposer)
+ {
+ this->clear_and_dispose(disposer);
+ detail::exception_disposer<list_impl, Disposer>
+ rollback(*this, disposer);
+ iterator b(src.begin()), e(src.end());
+ for(; b != e; ++b){
+ this->push_back(*cloner(*b));
+ }
+ rollback.release();
+ }
+
//! <b>Requires</b>: value must be an lvalue and p must be a valid iterator of *this.
//!
//! <b>Effects</b>: Inserts the value before the position pointed by p.
@@ -784,8 +809,7 @@ class list_impl
iterator insert(const_iterator p, reference value)
{
node_ptr to_insert = this->priv_value_traits().to_node_ptr(value);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert));
node_algorithms::link_before(p.pointed_node(), to_insert);
this->priv_size_traits().increment();
return iterator(to_insert, this->priv_value_traits_ptr());
@@ -1320,6 +1344,32 @@ class list_impl
BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count);
}
+ friend bool operator==(const list_impl &x, const list_impl &y)
+ {
+ if(constant_time_size && x.size() != y.size()){
+ return false;
+ }
+ return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
+ }
+
+ friend bool operator!=(const list_impl &x, const list_impl &y)
+ { return !(x == y); }
+
+ friend bool operator<(const list_impl &x, const list_impl &y)
+ { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+
+ friend bool operator>(const list_impl &x, const list_impl &y)
+ { return y < x; }
+
+ friend bool operator<=(const list_impl &x, const list_impl &y)
+ { return !(y < x); }
+
+ friend bool operator>=(const list_impl &x, const list_impl &y)
+ { return !(x < y); }
+
+ friend void swap(list_impl &x, list_impl &y)
+ { x.swap(y); }
+
/// @cond
private:
@@ -1338,103 +1388,6 @@ class list_impl
/// @endcond
};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
-#endif
-inline bool operator<
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
-#else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
-#endif
-{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
-#endif
-bool operator==
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
-#else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
-#endif
-{
- typedef list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> list_type;
- const bool C = list_type::constant_time_size;
- if(C && x.size() != y.size()){
- return false;
- }
- return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
-}
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
-#endif
-inline bool operator!=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
-#else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
-#endif
-{ return !(x == y); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
-#endif
-inline bool operator>
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
-#else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
-#endif
-{ return y < x; }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
-#endif
-inline bool operator<=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
-#else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
-#endif
-{ return !(y < x); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
-#endif
-inline bool operator>=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
-#else
-(const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
-#endif
-{ return !(x < y); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template <class ValueTraits, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
-#endif
-inline void swap
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(list_impl<T, Options...> &x, list_impl<T, Options...> &y)
-#else
-(list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &x, list_impl<ValueTraits, SizeType, ConstantTimeSize, HeaderHolder> &y)
-#endif
-{ x.swap(y); }
//! Helper metafunction to define a \c list that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
@@ -1518,6 +1471,14 @@ class list
list& operator=(BOOST_RV_REF(list) x)
{ return static_cast<list &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const list &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(list) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static list &container_from_end_iterator(iterator end_iterator)
{ return static_cast<list &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/options.hpp b/boost/intrusive/options.hpp
index ec6e9674d9..fdcb5cb3c5 100644
--- a/boost/intrusive/options.hpp
+++ b/boost/intrusive/options.hpp
@@ -61,6 +61,15 @@ BOOST_INTRUSIVE_OPTION_TYPE(size_type, SizeType, SizeType, size_type)
//!comparison functor for the value type
BOOST_INTRUSIVE_OPTION_TYPE(compare, Compare, Compare, compare)
+//!This option setter specifies the a function object
+//!that specifies the type of the key of an associative
+//!container and an operator to obtain it from a value type.
+//!
+//!This function object must the define a `key_type` and
+//!a member with signature `const key_type & operator()(const value_type &) const`
+//!that will return the key from a value_type of an associative container
+BOOST_INTRUSIVE_OPTION_TYPE(key_of_value, KeyOfValue, KeyOfValue, key_of_value)
+
//!This option setter for scapegoat containers specifies if
//!the intrusive scapegoat container should use a non-variable
//!alpha value that does not need floating-point operations.
@@ -199,7 +208,7 @@ BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_multikey, bool, Enabled, optimize_multi
//!This allows using masks instead of the default modulo operation to determine
//!the bucket number from the hash value, leading to better performance.
//!In debug mode, if power of two buckets mode is activated, the bucket length
-//!will be checked to through assertions to assure the bucket length is power of two.
+//!will be checked with assertions.
BOOST_INTRUSIVE_OPTION_CONSTANT(power_2_buckets, bool, Enabled, power_2_buckets)
//!This option setter specifies if the container will cache a pointer to the first
diff --git a/boost/intrusive/rbtree.hpp b/boost/intrusive/rbtree.hpp
index 4ef50b4c4f..f3afd017c8 100644
--- a/boost/intrusive/rbtree.hpp
+++ b/boost/intrusive/rbtree.hpp
@@ -48,19 +48,16 @@ struct is_default_hook_tag<default_rbtree_hook_applier>
{ static const bool value = true; };
struct rbtree_defaults
+ : bstree_defaults
{
typedef default_rbtree_hook_applier proto_value_traits;
- static const bool constant_time_size = true;
- typedef std::size_t size_type;
- typedef void compare;
- typedef void header_holder_type;
};
/// @endcond
//! The class template rbtree is an intrusive red-black tree container, that
//! is used to construct intrusive set and multiset containers. The no-throw
-//! guarantee holds only, if the value_compare object
+//! guarantee holds only, if the key_compare object
//! doesn't throw.
//!
//! The template parameter \c T is the type to be managed by the container.
@@ -74,17 +71,17 @@ struct rbtree_defaults
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class rbtree_impl
/// @cond
- : public bstree_impl<ValueTraits, VoidOrKeyComp, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
/// @endcond
{
public:
typedef ValueTraits value_traits;
/// @cond
- typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
+ typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
, ConstantTimeSize, RbTreeAlgorithms
, HeaderHolder> tree_type;
typedef tree_type implementation_defined;
@@ -94,6 +91,7 @@ class rbtree_impl
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::reference reference;
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
@@ -123,16 +121,16 @@ class rbtree_impl
typedef typename implementation_defined::insert_commit_data insert_commit_data;
- //! @copydoc ::boost::intrusive::bstree::bstree(const value_compare &,const value_traits &)
- explicit rbtree_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &)
+ explicit rbtree_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
rbtree_impl( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(unique, b, e, cmp, v_traits)
{}
@@ -213,13 +211,26 @@ class rbtree_impl
//! @copydoc ::boost::intrusive::bstree::swap
void swap(rbtree_impl& other);
- //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree &src, cloner, Disposer)
+ //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const rbtree_impl &src, Cloner cloner, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::clone_from(bstree &src, cloner, Disposer)
+ #else //BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
template <class Cloner, class Disposer>
- void clone_from(rbtree_impl &src, Cloner cloner, Disposer disposer);
+ void clone_from(BOOST_RV_REF(rbtree_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
+
+ #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(rbtree_impl &&src, Cloner cloner, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
iterator insert_equal(reference value);
@@ -237,16 +248,16 @@ class rbtree_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 KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @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
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data);
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data);
- //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data);
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_commit
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data);
@@ -270,12 +281,12 @@ class rbtree_impl
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::bstree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::erase(const key_type &key)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -285,13 +296,13 @@ class rbtree_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::clear
void clear();
@@ -300,88 +311,88 @@ class rbtree_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -406,33 +417,23 @@ class rbtree_impl
//! @copydoc ::boost::intrusive::bstree::remove_node
void remove_node(reference value);
- #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
-};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ friend bool operator< (const rbtree_impl &x, const rbtree_impl &y);
-template<class T, class ...Options>
-bool operator< (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
+ friend bool operator==(const rbtree_impl &x, const rbtree_impl &y);
-template<class T, class ...Options>
-bool operator==(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
+ friend bool operator!= (const rbtree_impl &x, const rbtree_impl &y);
-template<class T, class ...Options>
-bool operator!= (const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator>(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
+ friend bool operator>(const rbtree_impl &x, const rbtree_impl &y);
-template<class T, class ...Options>
-bool operator<=(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
+ friend bool operator<=(const rbtree_impl &x, const rbtree_impl &y);
-template<class T, class ...Options>
-bool operator>=(const rbtree_impl<T, Options...> &x, const rbtree_impl<T, Options...> &y);
+ friend bool operator>=(const rbtree_impl &x, const rbtree_impl &y);
-template<class T, class ...Options>
-void swap(rbtree_impl<T, Options...> &x, rbtree_impl<T, Options...> &y);
+ friend void swap(rbtree_impl &x, rbtree_impl &y);
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+};
-#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! Helper metafunction to define a \c rbtree that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
@@ -441,7 +442,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_rbtree
{
@@ -449,7 +450,7 @@ struct make_rbtree
typedef typename pack_options
< rbtree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -460,6 +461,7 @@ struct make_rbtree
typedef rbtree_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -473,14 +475,14 @@ struct make_rbtree
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class rbtree
: public make_rbtree<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -489,7 +491,7 @@ class rbtree
typedef typename make_rbtree
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -497,7 +499,7 @@ class rbtree
BOOST_MOVABLE_BUT_NOT_COPYABLE(rbtree)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -507,14 +509,14 @@ class rbtree
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit rbtree( const value_compare &cmp = value_compare()
+ explicit rbtree( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
rbtree( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(unique, b, e, cmp, v_traits)
{}
@@ -526,6 +528,14 @@ class rbtree
rbtree& operator=(BOOST_RV_REF(rbtree) x)
{ return static_cast<rbtree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const rbtree &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(rbtree) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static rbtree &container_from_end_iterator(iterator end_iterator)
{ return static_cast<rbtree &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/rbtree_algorithms.hpp b/boost/intrusive/rbtree_algorithms.hpp
index ad9c7658e3..00d9fe3b18 100644
--- a/boost/intrusive/rbtree_algorithms.hpp
+++ b/boost/intrusive/rbtree_algorithms.hpp
@@ -92,8 +92,8 @@ struct rbtree_node_checker
if (node_traits::get_color(p) == node_traits::red()){
//Red nodes have black children
- const node_ptr p_left(node_traits::get_left(p));
- const node_ptr p_right(node_traits::get_right(p));
+ const node_ptr p_left(node_traits::get_left(p)); (void)p_left;
+ const node_ptr p_right(node_traits::get_right(p)); (void)p_right;
BOOST_INTRUSIVE_INVARIANT_ASSERT(!p_left || node_traits::get_color(p_left) == node_traits::black());
BOOST_INTRUSIVE_INVARIANT_ASSERT(!p_right || node_traits::get_color(p_right) == node_traits::black());
//Red node can't be root
diff --git a/boost/intrusive/set.hpp b/boost/intrusive/set.hpp
index 1048429005..ae6a7a0812 100644
--- a/boost/intrusive/set.hpp
+++ b/boost/intrusive/set.hpp
@@ -42,15 +42,15 @@ namespace intrusive {
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class set_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
#endif
{
/// @cond
- typedef bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder> tree_type;
+ typedef bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(set_impl)
typedef tree_type implementation_defined;
@@ -58,6 +58,8 @@ class set_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -81,16 +83,16 @@ class set_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::rbtree::rbtree(const value_compare &,const value_traits &)
- explicit set_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::rbtree::rbtree(const key_compare &,const value_traits &)
+ explicit set_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::rbtree::rbtree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::rbtree::rbtree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
set_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(true, b, e, cmp, v_traits)
{}
@@ -171,11 +173,20 @@ class set_impl
//! @copydoc ::boost::intrusive::rbtree::swap
void swap(set_impl& other);
- //! @copydoc ::boost::intrusive::rbtree::clone_from
+ //! @copydoc ::boost::intrusive::rbtree::clone_from(const rbtree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const set_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::rbtree::clone_from(rbtree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(set_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::rbtree::insert_unique(reference)
std::pair<iterator, bool> insert(reference value)
@@ -185,18 +196,18 @@ 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 KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(key, key_value_comp, commit_data); }
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(key, comp, commit_data); }
- //! @copydoc ::boost::intrusive::rbtree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(hint, key, key_value_comp, commit_data); }
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(hint, key, comp, commit_data); }
//! @copydoc ::boost::intrusive::rbtree::insert_unique(Iterator,Iterator)
template<class Iterator>
@@ -223,12 +234,12 @@ class set_impl
//! @copydoc ::boost::intrusive::rbtree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::rbtree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -238,13 +249,13 @@ class set_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::rbtree::clear
void clear();
@@ -255,100 +266,100 @@ class set_impl
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::count(const_reference)const
- size_type count(const_reference value) const
- { return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
+ //! @copydoc ::boost::intrusive::rbtree::count(const key_type &)const
+ size_type count(const key_type &key) const
+ { return static_cast<size_type>(this->tree_type::find(key) != this->tree_type::cend()); }
- //! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const
+ //! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::rbtree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::rbtree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::rbtree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::rbtree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::rbtree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::rbtree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::rbtree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return this->tree_type::lower_bound_range(value); }
+ //! @copydoc ::boost::intrusive::rbtree::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&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
+ //! @copydoc ::boost::intrusive::rbtree::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::lower_bound_range(key, comp); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return this->tree_type::lower_bound_range(value); }
+ equal_range(const key_type &key) const
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const
{ return this->tree_type::lower_bound_range(key, comp); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::rbtree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::rbtree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::rbtree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::rbtree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -402,7 +413,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_set
{
@@ -410,7 +421,7 @@ struct make_set
typedef typename pack_options
< rbtree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -421,6 +432,7 @@ struct make_set
typedef set_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -432,14 +444,14 @@ struct make_set
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class set
: public make_set<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -448,7 +460,7 @@ class set
typedef typename make_set
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -456,7 +468,7 @@ class set
BOOST_MOVABLE_BUT_NOT_COPYABLE(set)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -464,14 +476,14 @@ class set
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit set( const value_compare &cmp = value_compare()
+ explicit set( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
set( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -483,6 +495,14 @@ class set
set& operator=(BOOST_RV_REF(set) x)
{ return static_cast<set &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const set &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(set) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static set &container_from_end_iterator(iterator end_iterator)
{ return static_cast<set &>(Base::container_from_end_iterator(end_iterator)); }
@@ -512,15 +532,15 @@ class set
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class multiset_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder>
#endif
{
/// @cond
- typedef bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder> tree_type;
+ typedef bstree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(multiset_impl)
typedef tree_type implementation_defined;
@@ -528,6 +548,8 @@ class multiset_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -551,16 +573,16 @@ class multiset_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::rbtree::rbtree(const value_compare &,const value_traits &)
- explicit multiset_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::rbtree::rbtree(const key_compare &,const value_traits &)
+ explicit multiset_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::rbtree::rbtree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::rbtree::rbtree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
multiset_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(false, b, e, cmp, v_traits)
{}
@@ -641,11 +663,20 @@ class multiset_impl
//! @copydoc ::boost::intrusive::rbtree::swap
void swap(multiset_impl& other);
- //! @copydoc ::boost::intrusive::rbtree::clone_from
+ //! @copydoc ::boost::intrusive::rbtree::clone_from(const rbtree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const multiset_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::rbtree::clone_from(rbtree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(multiset_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::rbtree::insert_equal(reference)
iterator insert(reference value)
@@ -676,12 +707,12 @@ class multiset_impl
//! @copydoc ::boost::intrusive::rbtree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::rbtree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -691,13 +722,13 @@ class multiset_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::rbtree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::rbtree::clear
void clear();
@@ -706,88 +737,88 @@ class multiset_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::rbtree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::rbtree::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::rbtree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::rbtree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::rbtree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::rbtree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::rbtree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::rbtree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::rbtree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::rbtree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::rbtree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::rbtree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::rbtree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::rbtree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::rbtree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::rbtree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::rbtree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -841,7 +872,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_multiset
{
@@ -849,7 +880,7 @@ struct make_multiset
typedef typename pack_options
< rbtree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -860,6 +891,7 @@ struct make_multiset
typedef multiset_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -872,14 +904,14 @@ struct make_multiset
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class multiset
: public make_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -887,7 +919,7 @@ class multiset
{
typedef typename make_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -896,7 +928,7 @@ class multiset
BOOST_MOVABLE_BUT_NOT_COPYABLE(multiset)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -904,14 +936,14 @@ class multiset
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- multiset( const value_compare &cmp = value_compare()
+ multiset( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
multiset( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -923,6 +955,14 @@ class multiset
multiset& operator=(BOOST_RV_REF(multiset) x)
{ return static_cast<multiset &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const multiset &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(multiset) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static multiset &container_from_end_iterator(iterator end_iterator)
{ return static_cast<multiset &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/sg_set.hpp b/boost/intrusive/sg_set.hpp
index 7e250cb6a0..560845e7a2 100644
--- a/boost/intrusive/sg_set.hpp
+++ b/boost/intrusive/sg_set.hpp
@@ -40,15 +40,15 @@ namespace intrusive {
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool FloatingPoint, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool FloatingPoint, typename HeaderHolder>
#endif
class sg_set_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public sgtree_impl<ValueTraits, Compare, SizeType, FloatingPoint, HeaderHolder>
+ : public sgtree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, FloatingPoint, HeaderHolder>
#endif
{
/// @cond
- typedef sgtree_impl<ValueTraits, Compare, SizeType, FloatingPoint, HeaderHolder> tree_type;
+ typedef sgtree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, FloatingPoint, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(sg_set_impl)
typedef tree_type implementation_defined;
@@ -56,6 +56,8 @@ class sg_set_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -79,16 +81,16 @@ class sg_set_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::sgtree::sgtree(const value_compare &,const value_traits &)
- explicit sg_set_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::sgtree::sgtree(const key_compare &,const value_traits &)
+ explicit sg_set_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::sgtree::sgtree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::sgtree::sgtree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
sg_set_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(true, b, e, cmp, v_traits)
{}
@@ -169,11 +171,20 @@ class sg_set_impl
//! @copydoc ::boost::intrusive::sgtree::swap
void swap(sg_set_impl& other);
- //! @copydoc ::boost::intrusive::sgtree::clone_from
+ //! @copydoc ::boost::intrusive::sgtree::clone_from(const sgtree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const sg_set_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::sgtree::clone_from(sgtree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(sg_set_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::sgtree::insert_unique(reference)
std::pair<iterator, bool> insert(reference value)
@@ -183,18 +194,18 @@ 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 KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::sgtree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(key, key_value_comp, commit_data); }
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(key, comp, commit_data); }
- //! @copydoc ::boost::intrusive::sgtree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::sgtree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(hint, key, key_value_comp, commit_data); }
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(hint, key, comp, commit_data); }
//! @copydoc ::boost::intrusive::sgtree::insert_unique(Iterator,Iterator)
template<class Iterator>
@@ -221,12 +232,12 @@ class sg_set_impl
//! @copydoc ::boost::intrusive::sgtree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::sgtree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -236,13 +247,13 @@ class sg_set_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::sgtree::clear
void clear();
@@ -253,100 +264,100 @@ class sg_set_impl
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::sgtree::count(const_reference)const
- size_type count(const_reference value) const
- { return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
+ //! @copydoc ::boost::intrusive::sgtree::count(const key_type &)const
+ size_type count(const key_type &key) const
+ { return static_cast<size_type>(this->tree_type::find(key) != this->tree_type::cend()); }
- //! @copydoc ::boost::intrusive::sgtree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const
+ //! @copydoc ::boost::intrusive::sgtree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::sgtree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::sgtree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::sgtree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::sgtree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::sgtree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::sgtree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::sgtree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::sgtree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::sgtree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::sgtree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::sgtree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::sgtree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::sgtree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::sgtree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::sgtree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return this->tree_type::lower_bound_range(value); }
+ //! @copydoc ::boost::intrusive::rbtree::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&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
+ //! @copydoc ::boost::intrusive::rbtree::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::lower_bound_range(key, comp); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return this->tree_type::lower_bound_range(value); }
+ equal_range(const key_type &key) const
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const
{ return this->tree_type::lower_bound_range(key, comp); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::sgtree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::sgtree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::sgtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::sgtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::sgtree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::sgtree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::sgtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::sgtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::sgtree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -413,7 +424,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_sg_set
{
@@ -421,7 +432,7 @@ struct make_sg_set
typedef typename pack_options
< sgtree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -432,6 +443,7 @@ struct make_sg_set
typedef sg_set_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::floating_point
@@ -443,14 +455,14 @@ struct make_sg_set
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class sg_set
: public make_sg_set<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -459,7 +471,7 @@ class sg_set
typedef typename make_sg_set
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -467,7 +479,7 @@ class sg_set
BOOST_MOVABLE_BUT_NOT_COPYABLE(sg_set)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -475,14 +487,14 @@ class sg_set
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit sg_set( const value_compare &cmp = value_compare()
+ explicit sg_set( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
sg_set( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -494,6 +506,14 @@ class sg_set
sg_set& operator=(BOOST_RV_REF(sg_set) x)
{ return static_cast<sg_set &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const sg_set &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(sg_set) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static sg_set &container_from_end_iterator(iterator end_iterator)
{ return static_cast<sg_set &>(Base::container_from_end_iterator(end_iterator)); }
@@ -523,15 +543,15 @@ class sg_set
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool FloatingPoint, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool FloatingPoint, typename HeaderHolder>
#endif
class sg_multiset_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public sgtree_impl<ValueTraits, Compare, SizeType, FloatingPoint, HeaderHolder>
+ : public sgtree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, FloatingPoint, HeaderHolder>
#endif
{
/// @cond
- typedef sgtree_impl<ValueTraits, Compare, SizeType, FloatingPoint, HeaderHolder> tree_type;
+ typedef sgtree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, FloatingPoint, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(sg_multiset_impl)
typedef tree_type implementation_defined;
@@ -539,6 +559,8 @@ class sg_multiset_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -562,16 +584,16 @@ class sg_multiset_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::sgtree::sgtree(const value_compare &,const value_traits &)
- explicit sg_multiset_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::sgtree::sgtree(const key_compare &,const value_traits &)
+ explicit sg_multiset_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::sgtree::sgtree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::sgtree::sgtree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
sg_multiset_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(false, b, e, cmp, v_traits)
{}
@@ -652,11 +674,20 @@ class sg_multiset_impl
//! @copydoc ::boost::intrusive::sgtree::swap
void swap(sg_multiset_impl& other);
- //! @copydoc ::boost::intrusive::sgtree::clone_from
+ //! @copydoc ::boost::intrusive::sgtree::clone_from(const sgtree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const sg_multiset_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::sgtree::clone_from(sgtree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(sg_multiset_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::sgtree::insert_equal(reference)
iterator insert(reference value)
@@ -687,12 +718,12 @@ class sg_multiset_impl
//! @copydoc ::boost::intrusive::sgtree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::sgtree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -702,13 +733,13 @@ class sg_multiset_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::sgtree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::sgtree::clear
void clear();
@@ -717,88 +748,88 @@ class sg_multiset_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::sgtree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::sgtree::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::sgtree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::sgtree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::sgtree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::sgtree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::sgtree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::sgtree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::sgtree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::sgtree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::sgtree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::sgtree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::sgtree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::sgtree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::sgtree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::sgtree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::sgtree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::sgtree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::sgtree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::sgtree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::sgtree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::sgtree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::sgtree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @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);
- //! @copydoc ::boost::intrusive::sgtree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::sgtree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::sgtree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @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, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::sgtree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::sgtree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::sgtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::sgtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::sgtree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::sgtree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::sgtree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::sgtree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::sgtree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -865,7 +896,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_sg_multiset
{
@@ -873,7 +904,7 @@ struct make_sg_multiset
typedef typename pack_options
< sgtree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -884,6 +915,7 @@ struct make_sg_multiset
typedef sg_multiset_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::floating_point
@@ -896,14 +928,14 @@ struct make_sg_multiset
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class sg_multiset
: public make_sg_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -911,7 +943,7 @@ class sg_multiset
{
typedef typename make_sg_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -920,7 +952,7 @@ class sg_multiset
BOOST_MOVABLE_BUT_NOT_COPYABLE(sg_multiset)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -928,14 +960,14 @@ class sg_multiset
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- sg_multiset( const value_compare &cmp = value_compare()
+ sg_multiset( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
sg_multiset( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -947,6 +979,14 @@ class sg_multiset
sg_multiset& operator=(BOOST_RV_REF(sg_multiset) x)
{ return static_cast<sg_multiset &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const sg_multiset &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(sg_multiset) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static sg_multiset &container_from_end_iterator(iterator end_iterator)
{ return static_cast<sg_multiset &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/sgtree.hpp b/boost/intrusive/sgtree.hpp
index feeaf3bcbf..dc84c80462 100644
--- a/boost/intrusive/sgtree.hpp
+++ b/boost/intrusive/sgtree.hpp
@@ -195,13 +195,9 @@ struct alpha_holder<false, SizeType>
} //namespace detail{
struct sgtree_defaults
+ : bstree_defaults
{
- typedef default_bstree_hook_applier proto_value_traits;
- static const bool constant_time_size = true;
- typedef std::size_t size_type;
- typedef void compare;
static const bool floating_point = true;
- typedef void header_holder_type;
};
/// @endcond
@@ -222,18 +218,18 @@ struct sgtree_defaults
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidOrKeyComp, class SizeType, bool FloatingPoint, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, bool FloatingPoint, typename HeaderHolder>
#endif
class sgtree_impl
/// @cond
- : public bstree_impl<ValueTraits, VoidOrKeyComp, SizeType, true, SgTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, true, SgTreeAlgorithms, HeaderHolder>
, public detail::alpha_holder<FloatingPoint, SizeType>
/// @endcond
{
public:
typedef ValueTraits value_traits;
/// @cond
- typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
+ typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
, true, SgTreeAlgorithms, HeaderHolder> tree_type;
typedef tree_type implementation_defined;
@@ -243,6 +239,7 @@ class sgtree_impl
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::reference reference;
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
@@ -284,16 +281,16 @@ class sgtree_impl
typedef BOOST_INTRUSIVE_IMPDEF(typename node_algorithms::insert_commit_data) insert_commit_data;
- //! @copydoc ::boost::intrusive::bstree::bstree(const value_compare &,const value_traits &)
- explicit sgtree_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &)
+ explicit sgtree_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
sgtree_impl( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{
@@ -408,26 +405,33 @@ class sgtree_impl
::boost::adl_move_swap(this->get_alpha_traits(), other.get_alpha_traits());
}
- //! @copydoc ::boost::intrusive::bstree::clone_from
+ //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer)
//! Additional notes: it also copies the alpha factor from the source container.
template <class Cloner, class Disposer>
void clone_from(const sgtree_impl &src, Cloner cloner, Disposer disposer)
{
- this->tree_type::clone_from(src, cloner, disposer);
+ tree_type::clone_from(src, cloner, disposer);
this->get_alpha_traits() = src.get_alpha_traits();
}
+ //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
+ //! Additional notes: it also copies the alpha factor from the source container.
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(sgtree_impl) src, Cloner cloner, Disposer disposer)
+ {
+ tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer);
+ this->get_alpha_traits() = ::boost::move(src.get_alpha_traits());
+ }
+
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
iterator insert_equal(reference value)
{
- detail::key_nodeptr_comp<value_compare, value_traits>
- key_node_comp(this->value_comp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
node_ptr p = node_algorithms::insert_equal_upper_bound
- (this->tree_type::header_ptr(), to_insert, key_node_comp
+ (this->tree_type::header_ptr(), to_insert, this->key_node_comp(this->key_comp())
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
this->tree_type::sz_traits().increment();
this->max_tree_size_ = (size_type)max_tree_size;
@@ -437,14 +441,12 @@ class sgtree_impl
//! @copydoc ::boost::intrusive::bstree::insert_equal(const_iterator,reference)
iterator insert_equal(const_iterator hint, reference value)
{
- detail::key_nodeptr_comp<value_compare, value_traits>
- key_node_comp(this->value_comp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
node_ptr p = node_algorithms::insert_equal
- (this->tree_type::header_ptr(), hint.pointed_node(), to_insert, key_node_comp
+ ( this->tree_type::header_ptr(), hint.pointed_node(), to_insert, this->key_node_comp(this->key_comp())
, (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size);
this->tree_type::sz_traits().increment();
this->max_tree_size_ = (size_type)max_tree_size;
@@ -464,46 +466,44 @@ class sgtree_impl
std::pair<iterator, bool> insert_unique(reference value)
{
insert_commit_data commit_data;
- std::pair<iterator, bool> ret = insert_unique_check(value, this->value_comp(), commit_data);
+ std::pair<iterator, bool> ret = this->insert_unique_check
+ (key_of_value()(value), this->key_comp(), commit_data);
if(!ret.second)
return ret;
- return std::pair<iterator, bool> (insert_unique_commit(value, commit_data), true);
+ return std::pair<iterator, bool> (this->insert_unique_commit(value, commit_data), true);
}
//! @copydoc ::boost::intrusive::bstree::insert_unique(const_iterator,reference)
iterator insert_unique(const_iterator hint, reference value)
{
insert_commit_data commit_data;
- std::pair<iterator, bool> ret = insert_unique_check(hint, value, this->value_comp(), commit_data);
+ std::pair<iterator, bool> ret = this->insert_unique_check
+ (hint, key_of_value()(value), this->key_comp(), commit_data);
if(!ret.second)
return ret.first;
- return insert_unique_commit(value, commit_data);
+ return this->insert_unique_commit(value, commit_data);
}
- //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @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
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- comp(key_value_comp, &this->get_value_traits());
std::pair<node_ptr, bool> ret =
- (node_algorithms::insert_unique_check
- (this->tree_type::header_ptr(), key, comp, commit_data));
+ node_algorithms::insert_unique_check
+ (this->tree_type::header_ptr(), key, this->key_node_comp(comp), commit_data);
return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
}
- //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- comp(key_value_comp, &this->get_value_traits());
std::pair<node_ptr, bool> ret =
- (node_algorithms::insert_unique_check
- (this->tree_type::header_ptr(), hint.pointed_node(), key, comp, commit_data));
+ node_algorithms::insert_unique_check
+ (this->tree_type::header_ptr(), hint.pointed_node(), key, this->key_node_comp(comp), commit_data);
return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
}
@@ -604,17 +604,15 @@ class sgtree_impl
iterator erase(const_iterator b, const_iterator e)
{ size_type n; return private_erase(b, e, n); }
- //! @copydoc ::boost::intrusive::bstree::erase(const_reference)
- size_type erase(const_reference value)
- { return this->erase(value, this->value_comp()); }
-
- //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
- /// @endcond
- )
+ //! @copydoc ::boost::intrusive::bstree::erase(const key_type &)
+ size_type erase(const key_type &key)
+ { return this->erase(key, this->key_comp()); }
+
+ //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ BOOST_INTRUSIVE_DOC1ST(size_type
+ , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
+ erase(const KeyType& key, KeyTypeKeyCompare comp)
{
std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n;
@@ -643,23 +641,21 @@ class sgtree_impl
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
{ size_type n; return private_erase(b, e, n, disposer); }
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer)
+ size_type erase_and_dispose(const key_type &key, Disposer disposer)
{
- std::pair<iterator,iterator> p = this->equal_range(value);
+ std::pair<iterator,iterator> p = this->equal_range(key);
size_type n;
private_erase(p.first, p.second, n, disposer);
return n;
}
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
- /// @endcond
- )
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ BOOST_INTRUSIVE_DOC1ST(size_type
+ , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
+ erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer)
{
std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n;
@@ -683,88 +679,88 @@ class sgtree_impl
}
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::bstree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -796,6 +792,20 @@ class sgtree_impl
//! @copydoc ::boost::intrusive::bstree::rebalance_subtree
iterator rebalance_subtree(iterator root);
+ friend bool operator< (const sgtree_impl &x, const sgtree_impl &y);
+
+ friend bool operator==(const sgtree_impl &x, const sgtree_impl &y);
+
+ friend bool operator!= (const sgtree_impl &x, const sgtree_impl &y);
+
+ friend bool operator>(const sgtree_impl &x, const sgtree_impl &y);
+
+ friend bool operator<=(const sgtree_impl &x, const sgtree_impl &y);
+
+ friend bool operator>=(const sgtree_impl &x, const sgtree_impl &y);
+
+ friend void swap(sgtree_impl &x, sgtree_impl &y);
+
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! <b>Returns</b>: The balance factor (alpha) used in this tree
@@ -850,30 +860,6 @@ class sgtree_impl
/// @endcond
};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-
-template<class T, class ...Options>
-bool operator< (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator==(const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator!= (const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator>(const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator<=(const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator>=(const sgtree_impl<T, Options...> &x, const sgtree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-void swap(sgtree_impl<T, Options...> &x, sgtree_impl<T, Options...> &y);
-
-#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! Helper metafunction to define a \c sgtree that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
@@ -882,7 +868,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_sgtree
{
@@ -890,7 +876,7 @@ struct make_sgtree
typedef typename pack_options
< sgtree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -901,6 +887,7 @@ struct make_sgtree
typedef sgtree_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::floating_point
@@ -914,14 +901,14 @@ struct make_sgtree
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class sgtree
: public make_sgtree<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -930,7 +917,7 @@ class sgtree
typedef typename make_sgtree
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -938,7 +925,7 @@ class sgtree
BOOST_MOVABLE_BUT_NOT_COPYABLE(sgtree)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -948,14 +935,14 @@ class sgtree
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit sgtree( const value_compare &cmp = value_compare()
+ explicit sgtree( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
sgtree( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(unique, b, e, cmp, v_traits)
{}
@@ -967,6 +954,14 @@ class sgtree
sgtree& operator=(BOOST_RV_REF(sgtree) x)
{ return static_cast<sgtree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const sgtree &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(sgtree) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static sgtree &container_from_end_iterator(iterator end_iterator)
{ return static_cast<sgtree &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/slist.hpp b/boost/intrusive/slist.hpp
index 757508149b..dd3a05f2f8 100644
--- a/boost/intrusive/slist.hpp
+++ b/boost/intrusive/slist.hpp
@@ -416,8 +416,7 @@ class slist_impl
void push_front(reference value)
{
node_ptr to_insert = priv_value_traits().to_node_ptr(value);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(to_insert));
if(cache_last){
if(this->empty()){
this->set_last_node(to_insert);
@@ -442,8 +441,7 @@ class slist_impl
{
BOOST_STATIC_ASSERT((cache_last));
node_ptr n = priv_value_traits().to_node_ptr(value);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(n));
node_algorithms::link_after(this->get_last_node(), n);
if(cache_last){
this->set_last_node(n);
@@ -768,6 +766,34 @@ class slist_impl
rollback.release();
}
+ //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
+ //!
+ //! <b>Effects</b>: Erases all the elements from *this
+ //! calling Disposer::operator()(pointer), clones all the
+ //! elements from src calling Cloner::operator()(reference)
+ //! and inserts them on *this.
+ //!
+ //! If cloner throws, all cloned elements are unlinked and disposed
+ //! calling Disposer::operator()(pointer).
+ //!
+ //! <b>Complexity</b>: Linear to erased plus inserted elements.
+ //!
+ //! <b>Throws</b>: If cloner throws.
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(slist_impl) src, Cloner cloner, Disposer disposer)
+ {
+ this->clear_and_dispose(disposer);
+ detail::exception_disposer<slist_impl, Disposer>
+ rollback(*this, disposer);
+ iterator prev(this->cbefore_begin());
+ iterator b(src.begin()), e(src.end());
+ for(; b != e; ++b){
+ prev = this->insert_after(prev, *cloner(*b));
+ }
+ rollback.release();
+ }
+
//! <b>Requires</b>: value must be an lvalue and prev_p must point to an element
//! contained by the list or to end().
//!
@@ -784,8 +810,7 @@ class slist_impl
iterator insert_after(const_iterator prev_p, reference value)
{
node_ptr n = priv_value_traits().to_node_ptr(value);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(n));
node_ptr prev_n(prev_p.pointed_node());
node_algorithms::link_after(prev_n, n);
if(cache_last && (this->get_last_node() == prev_n)){
@@ -815,8 +840,7 @@ class slist_impl
node_ptr prev_n(prev_p.pointed_node());
for (; f != l; ++f, ++count){
const node_ptr n = priv_value_traits().to_node_ptr(*f);
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(n));
node_algorithms::link_after(prev_n, n);
prev_n = n;
}
@@ -1028,6 +1052,15 @@ class slist_impl
/// @cond
+ static iterator s_insert_after(const_iterator const prev_p, reference value)
+ {
+ BOOST_STATIC_ASSERT(((!cache_last)&&(!constant_time_size)&&(!stateful_value_traits)));
+ node_ptr const n = value_traits::to_node_ptr(value);
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::inited(n));
+ node_algorithms::link_after(prev_p.pointed_node(), n);
+ return iterator (n, const_value_traits_ptr());
+ }
+
template<class Disposer>
static iterator s_erase_after_and_dispose(const_iterator prev, Disposer disposer)
{
@@ -1044,6 +1077,23 @@ class slist_impl
return it.unconst();
}
+ template<class Disposer>
+ static iterator s_erase_after_and_dispose(const_iterator before_f, const_iterator l, Disposer disposer)
+ {
+ BOOST_STATIC_ASSERT(((!cache_last)&&(!constant_time_size)&&(!stateful_value_traits)));
+ node_ptr bfp(before_f.pointed_node()), lp(l.pointed_node());
+ node_ptr fp(node_traits::get_next(bfp));
+ node_algorithms::unlink_after(bfp, lp);
+ while(fp != lp){
+ node_ptr to_erase(fp);
+ fp = node_traits::get_next(fp);
+ if(safemode_or_autounlink)
+ node_algorithms::init(to_erase);
+ disposer(value_traits::to_value_ptr(to_erase));
+ }
+ return l.unconst();
+ }
+
static iterator s_erase_after(const_iterator prev)
{ return s_erase_after_and_dispose(prev, detail::null_disposer()); }
@@ -1905,6 +1955,33 @@ class slist_impl
BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_size_traits().get_size() == node_count);
}
+
+ friend bool operator==(const slist_impl &x, const slist_impl &y)
+ {
+ if(constant_time_size && x.size() != y.size()){
+ return false;
+ }
+ return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
+ }
+
+ friend bool operator!=(const slist_impl &x, const slist_impl &y)
+ { return !(x == y); }
+
+ friend bool operator<(const slist_impl &x, const slist_impl &y)
+ { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+
+ friend bool operator>(const slist_impl &x, const slist_impl &y)
+ { return y < x; }
+
+ friend bool operator<=(const slist_impl &x, const slist_impl &y)
+ { return !(y < x); }
+
+ friend bool operator>=(const slist_impl &x, const slist_impl &y)
+ { return !(x < y); }
+
+ friend void swap(slist_impl &x, slist_impl &y)
+ { x.swap(y); }
+
private:
void priv_splice_after(const node_ptr & prev_pos_n, slist_impl &x, const node_ptr & before_f_n, const node_ptr & before_l_n)
{
@@ -2044,111 +2121,6 @@ class slist_impl
}
};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline bool operator<
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-bool operator==
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{
- typedef slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> slist_type;
- const bool C = slist_type::constant_time_size;
- if(C && x.size() != y.size()){
- return false;
- }
- return ::boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
-}
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline bool operator!=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ return !(x == y); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline bool operator>
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ return y < x; }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline bool operator<=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ return !(y < x); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline bool operator>=
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
-#else
-( const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, const slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ return !(x < y); }
-
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-template<class T, class ...Options>
-#else
-template<class ValueTraits, class SizeType, std::size_t BoolFlags, typename HeaderHolder>
-#endif
-inline void swap
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-(slist_impl<T, Options...> &x, slist_impl<T, Options...> &y)
-#else
-( slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &x
-, slist_impl<ValueTraits, SizeType, BoolFlags, HeaderHolder> &y)
-#endif
-{ x.swap(y); }
-
//! Helper metafunction to define a \c slist that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
@@ -2241,6 +2213,14 @@ class slist
slist& operator=(BOOST_RV_REF(slist) x)
{ return static_cast<slist &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const slist &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(slist) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static slist &container_from_end_iterator(iterator end_iterator)
{ return static_cast<slist &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/splay_set.hpp b/boost/intrusive/splay_set.hpp
index 80887dffdc..eea19d7999 100644
--- a/boost/intrusive/splay_set.hpp
+++ b/boost/intrusive/splay_set.hpp
@@ -40,15 +40,15 @@ namespace intrusive {
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class splay_set_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public splaytree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, HeaderHolder>
+ : public splaytree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, HeaderHolder>
#endif
{
/// @cond
- typedef splaytree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, HeaderHolder> tree_type;
+ typedef splaytree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(splay_set_impl)
typedef tree_type implementation_defined;
@@ -56,6 +56,8 @@ class splay_set_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -79,16 +81,16 @@ class splay_set_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::splaytree::splaytree(const value_compare &,const value_traits &)
- explicit splay_set_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::splaytree::splaytree(const key_compare &,const value_traits &)
+ explicit splay_set_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::splaytree::splaytree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::splaytree::splaytree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
splay_set_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(true, b, e, cmp, v_traits)
{}
@@ -169,11 +171,20 @@ class splay_set_impl
//! @copydoc ::boost::intrusive::splaytree::swap
void swap(splay_set_impl& other);
- //! @copydoc ::boost::intrusive::splaytree::clone_from
+ //! @copydoc ::boost::intrusive::splaytree::clone_from(const splaytree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const splay_set_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::splaytree::clone_from(splaytree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(splay_set_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::splaytree::insert_unique(reference)
std::pair<iterator, bool> insert(reference value)
@@ -183,18 +194,18 @@ class splay_set_impl
iterator insert(const_iterator hint, reference value)
{ return tree_type::insert_unique(hint, value); }
- //! @copydoc ::boost::intrusive::splaytree::insert_unique_check(const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::splaytree::insert_unique_check(const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(key, key_value_comp, commit_data); }
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(key, comp, commit_data); }
- //! @copydoc ::boost::intrusive::splaytree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::splaytree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(hint, key, key_value_comp, commit_data); }
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data)
+ { return tree_type::insert_unique_check(hint, key, comp, commit_data); }
//! @copydoc ::boost::intrusive::splaytree::insert_unique(Iterator,Iterator)
template<class Iterator>
@@ -221,12 +232,12 @@ class splay_set_impl
//! @copydoc ::boost::intrusive::splaytree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::splaytree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -236,13 +247,13 @@ class splay_set_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::splaytree::clear
void clear();
@@ -253,107 +264,107 @@ class splay_set_impl
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::splaytree::count(const_reference)const
- size_type count(const_reference value) const
- { return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
+ //! @copydoc ::boost::intrusive::splaytree::count(const key_type &)const
+ size_type count(const key_type &key) const
+ { return static_cast<size_type>(this->tree_type::find(key) != this->tree_type::cend()); }
- //! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const
+ //! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::splaytree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::splaytree::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::splaytree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::splaytree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::splaytree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::splaytree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::splaytree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::splaytree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::splaytree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::splaytree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::splaytree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::splaytree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::splaytree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::splaytree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return this->tree_type::lower_bound_range(value); }
+ //! @copydoc ::boost::intrusive::rbtree::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&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
+ //! @copydoc ::boost::intrusive::rbtree::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::lower_bound_range(key, comp); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return this->tree_type::lower_bound_range(value); }
+ equal_range(const key_type &key) const
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const
{ return this->tree_type::lower_bound_range(key, comp); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::splaytree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::splaytree::bounded_range(const key_type&,const key_type&,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::splaytree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::splaytree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::splaytree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::splaytree::bounded_range(const key_type&,const key_type&,bool,bool)const
std::pair<const_iterator, const_iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::splaytree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::splaytree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::splaytree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -382,12 +393,12 @@ class splay_set_impl
//! @copydoc ::boost::intrusive::splaytree::splay_up(iterator)
void splay_up(iterator i);
- //! @copydoc ::boost::intrusive::splaytree::splay_down(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator splay_down(const KeyType &key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::splay_down(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator splay_down(const KeyType &key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::splay_down(const_reference)
- iterator splay_down(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::splay_down(const key_type &key)
+ iterator splay_down(const key_type &key);
//! @copydoc ::boost::intrusive::splaytree::rebalance
void rebalance();
@@ -423,7 +434,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_splay_set
{
@@ -431,7 +442,7 @@ struct make_splay_set
typedef typename pack_options
< splaytree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -442,6 +453,7 @@ struct make_splay_set
typedef splay_set_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -453,14 +465,14 @@ struct make_splay_set
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class splay_set
: public make_splay_set<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -469,7 +481,7 @@ class splay_set
typedef typename make_splay_set
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -477,7 +489,7 @@ class splay_set
BOOST_MOVABLE_BUT_NOT_COPYABLE(splay_set)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -485,14 +497,14 @@ class splay_set
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit splay_set( const value_compare &cmp = value_compare()
+ explicit splay_set( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
splay_set( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -504,6 +516,14 @@ class splay_set
splay_set& operator=(BOOST_RV_REF(splay_set) x)
{ return static_cast<splay_set &>(this->Base::operator=(::boost::move(static_cast<Base&>(x)))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const splay_set &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(splay_set) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static splay_set &container_from_end_iterator(iterator end_iterator)
{ return static_cast<splay_set &>(Base::container_from_end_iterator(end_iterator)); }
@@ -533,15 +553,15 @@ class splay_set
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class Compare, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class splay_multiset_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public splaytree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, HeaderHolder>
+ : public splaytree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, HeaderHolder>
#endif
{
/// @cond
- typedef splaytree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, HeaderHolder> tree_type;
+ typedef splaytree_impl<ValueTraits, VoidOrKeyOfValue, Compare, SizeType, ConstantTimeSize, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(splay_multiset_impl)
typedef tree_type implementation_defined;
@@ -549,6 +569,8 @@ class splay_multiset_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
@@ -572,16 +594,16 @@ class splay_multiset_impl
static const bool constant_time_size = tree_type::constant_time_size;
public:
- //! @copydoc ::boost::intrusive::splaytree::splaytree(const value_compare &,const value_traits &)
- explicit splay_multiset_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::splaytree::splaytree(const key_compare &,const value_traits &)
+ explicit splay_multiset_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::splaytree::splaytree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::splaytree::splaytree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
splay_multiset_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(false, b, e, cmp, v_traits)
{}
@@ -662,11 +684,20 @@ class splay_multiset_impl
//! @copydoc ::boost::intrusive::splaytree::swap
void swap(splay_multiset_impl& other);
- //! @copydoc ::boost::intrusive::splaytree::clone_from
+ //! @copydoc ::boost::intrusive::splaytree::clone_from(const splaytree&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const splay_multiset_impl &src, Cloner cloner, Disposer disposer);
- #endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
+ #else
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::splaytree::clone_from(splaytree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(splay_multiset_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
//! @copydoc ::boost::intrusive::splaytree::insert_equal(reference)
iterator insert(reference value)
@@ -697,12 +728,12 @@ class splay_multiset_impl
//! @copydoc ::boost::intrusive::splaytree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::splaytree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::erase(const key_type&)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -712,13 +743,13 @@ class splay_multiset_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const key_type&, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::splaytree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::splaytree::clear
void clear();
@@ -727,88 +758,88 @@ class splay_multiset_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::splaytree::count(const_reference)
- size_type count(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::count(const key_type&)
+ size_type count(const key_type&);
- //! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::lower_bound(const key_type&)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::splaytree::lower_bound(const key_type&)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::splaytree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::splaytree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::splaytree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::upper_bound(const key_type&)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::splaytree::upper_bound(const key_type&)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::splaytree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::splaytree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::splaytree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::find(const key_type&)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::splaytree::find(const key_type&)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::splaytree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::splaytree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::splaytree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::equal_range(const key_type&)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::splaytree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::splaytree::equal_range(const key_type&)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::splaytree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::splaytree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::splaytree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::splaytree::bounded_range(const key_type&, const key_type&,bool,bool)
std::pair<iterator,iterator> bounded_range
(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::splaytree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::splaytree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::splaytree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::splaytree::bounded_range(const key_type&, const key_type&,bool,bool)const
std::pair<const_iterator, const_iterator> bounded_range
(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::splaytree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::splaytree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::splaytree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -837,12 +868,12 @@ class splay_multiset_impl
//! @copydoc ::boost::intrusive::splaytree::splay_up(iterator)
void splay_up(iterator i);
- //! @copydoc ::boost::intrusive::splaytree::splay_down(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator splay_down(const KeyType &key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::splaytree::splay_down(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator splay_down(const KeyType &key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::splaytree::splay_down(const_reference)
- iterator splay_down(const_reference value);
+ //! @copydoc ::boost::intrusive::splaytree::splay_down(const key_type &key)
+ iterator splay_down(const key_type &key);
//! @copydoc ::boost::intrusive::splaytree::rebalance
void rebalance();
@@ -878,7 +909,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_splay_multiset
{
@@ -886,7 +917,7 @@ struct make_splay_multiset
typedef typename pack_options
< splaytree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -897,6 +928,7 @@ struct make_splay_multiset
typedef splay_multiset_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -909,14 +941,14 @@ struct make_splay_multiset
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class splay_multiset
: public make_splay_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -924,7 +956,7 @@ class splay_multiset
{
typedef typename make_splay_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -933,7 +965,7 @@ class splay_multiset
BOOST_MOVABLE_BUT_NOT_COPYABLE(splay_multiset)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -941,14 +973,14 @@ class splay_multiset
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit splay_multiset( const value_compare &cmp = value_compare()
+ explicit splay_multiset( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
splay_multiset( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, v_traits)
{}
@@ -960,6 +992,14 @@ class splay_multiset
splay_multiset& operator=(BOOST_RV_REF(splay_multiset) x)
{ return static_cast<splay_multiset &>(this->Base::operator=(::boost::move(static_cast<Base&>(x)))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const splay_multiset &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(splay_multiset) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static splay_multiset &container_from_end_iterator(iterator end_iterator)
{ return static_cast<splay_multiset &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/splaytree.hpp b/boost/intrusive/splaytree.hpp
index e3866aa912..27d75df70f 100644
--- a/boost/intrusive/splaytree.hpp
+++ b/boost/intrusive/splaytree.hpp
@@ -40,19 +40,14 @@ namespace intrusive {
/// @cond
struct splaytree_defaults
-{
- typedef default_bstree_hook_applier proto_value_traits;
- static const bool constant_time_size = true;
- typedef std::size_t size_type;
- typedef void compare;
- typedef void header_holder_type;
-};
+ : bstree_defaults
+{};
/// @endcond
//! The class template splaytree is an intrusive splay tree container that
//! is used to construct intrusive splay_set and splay_multiset containers. The no-throw
-//! guarantee holds only, if the value_compare object
+//! guarantee holds only, if the key_compare object
//! doesn't throw.
//!
//! The template parameter \c T is the type to be managed by the container.
@@ -66,17 +61,17 @@ struct splaytree_defaults
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class splaytree_impl
/// @cond
- : public bstree_impl<ValueTraits, VoidOrKeyComp, SizeType, ConstantTimeSize, SplayTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, SplayTreeAlgorithms, HeaderHolder>
/// @endcond
{
public:
typedef ValueTraits value_traits;
/// @cond
- typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
+ typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
, ConstantTimeSize, SplayTreeAlgorithms
, HeaderHolder> tree_type;
typedef tree_type implementation_defined;
@@ -86,6 +81,7 @@ class splaytree_impl
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::reference reference;
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
@@ -115,16 +111,16 @@ class splaytree_impl
typedef typename implementation_defined::insert_commit_data insert_commit_data;
- //! @copydoc ::boost::intrusive::bstree::bstree(const value_compare &,const value_traits &)
- explicit splaytree_impl( const value_compare &cmp = value_compare()
+ //! @copydoc ::boost::intrusive::bstree::bstree(const key_compare &,const value_traits &)
+ explicit splaytree_impl( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{}
- //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
+ //! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const key_compare &,const value_traits &)
template<class Iterator>
splaytree_impl( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits)
{
@@ -210,10 +206,24 @@ class splaytree_impl
//! @copydoc ::boost::intrusive::bstree::swap
void swap(splaytree_impl& other);
- //! @copydoc ::boost::intrusive::bstree::clone_from
+ //! @copydoc ::boost::intrusive::bstree::clone_from(const bstree&,Cloner,Disposer)
+ //! Additional notes: it also copies the alpha factor from the source container.
template <class Cloner, class Disposer>
void clone_from(const splaytree_impl &src, Cloner cloner, Disposer disposer);
+ #else //BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ using tree_type::clone_from;
+
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ //! @copydoc ::boost::intrusive::bstree::clone_from(bstree&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(splaytree_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
+
+ #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
iterator insert_equal(reference value);
@@ -230,16 +240,16 @@ 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 KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @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
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data);
+ (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data);
- //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator, bool> insert_unique_check
(const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data);
+ ,KeyTypeKeyCompare comp, insert_commit_data &commit_data);
//! @copydoc ::boost::intrusive::bstree::insert_unique_commit
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data);
@@ -263,12 +273,12 @@ class splaytree_impl
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::bstree::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -278,13 +288,13 @@ class splaytree_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::bstree::clear
void clear();
@@ -293,120 +303,120 @@ class splaytree_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::bstree::count(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
//! Additional note: non-const function, splaying is performed.
- size_type count(const_reference value);
+ size_type count(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
+ //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: non-const function, splaying is performed.
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType &key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::count(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
//! Additional note: const function, no splaying is performed
- size_type count(const_reference value) const;
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
+ //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: const function, no splaying is performed
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType &key, KeyValueCompare comp) const;
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType &key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
//! Additional note: non-const function, splaying is performed.
- iterator lower_bound(const_reference value);
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
//! Additional note: const function, no splaying is performed
- const_iterator lower_bound(const_reference value) const;
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "key"
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: const function, no splaying is performed
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const;
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "value"
- iterator upper_bound(const_reference value);
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
//! Additional note: const function, no splaying is performed
- const_iterator upper_bound(const_reference value) const;
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "key"
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: const function, no splaying is performed
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const;
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "value"
- iterator find(const_reference value);
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
//! Additional note: const function, no splaying is performed
- const_iterator find(const_reference value) const;
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "key"
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType &key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: const function, no splaying is performed
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType &key, KeyValueCompare comp) const;
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType &key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "value"
- std::pair<iterator, iterator> equal_range(const_reference value);
+ std::pair<iterator, iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
//! Additional note: const function, no splaying is performed
- std::pair<const_iterator, const_iterator> equal_range(const_reference value) const;
+ std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
//! Additional note: non-const function, splaying is performed for the first
//! element of the equal range of "key"
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator, iterator> equal_range(const KeyType &key, KeyValueCompare comp);
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator, iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
//! Additional note: const function, no splaying is performed
- template<class KeyType, class KeyValueCompare>
- std::pair<const_iterator, const_iterator> equal_range(const KeyType &key, KeyValueCompare comp) const;
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<const_iterator, const_iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -455,8 +465,8 @@ class splaytree_impl
//! <b>Returns</b>: An iterator to the new root of the tree, end() if the tree is empty.
//!
//! <b>Throws</b>: If the comparison functor throws.
- template<class KeyType, class KeyValueCompare>
- iterator splay_down(const KeyType &key, KeyValueCompare comp)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator splay_down(const KeyType &key, KeyTypeKeyCompare comp)
{
detail::key_nodeptr_comp<value_compare, value_traits>
key_node_comp(comp, &this->get_value_traits());
@@ -473,8 +483,8 @@ class splaytree_impl
//! <b>Returns</b>: An iterator to the new root of the tree, end() if the tree is empty.
//!
//! <b>Throws</b>: If the predicate throws.
- iterator splay_down(const_reference value)
- { return this->splay_down(value, this->value_comp()); }
+ iterator splay_down(const key_type &key)
+ { return this->splay_down(key, this->key_comp()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree::rebalance
@@ -482,33 +492,23 @@ class splaytree_impl
//! @copydoc ::boost::intrusive::bstree::rebalance_subtree
iterator rebalance_subtree(iterator root);
- #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
-};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ friend bool operator< (const splaytree_impl &x, const splaytree_impl &y);
-template<class T, class ...Options>
-bool operator< (const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
+ friend bool operator==(const splaytree_impl &x, const splaytree_impl &y);
-template<class T, class ...Options>
-bool operator==(const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
+ friend bool operator!= (const splaytree_impl &x, const splaytree_impl &y);
-template<class T, class ...Options>
-bool operator!= (const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
+ friend bool operator>(const splaytree_impl &x, const splaytree_impl &y);
-template<class T, class ...Options>
-bool operator>(const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
+ friend bool operator<=(const splaytree_impl &x, const splaytree_impl &y);
-template<class T, class ...Options>
-bool operator<=(const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
+ friend bool operator>=(const splaytree_impl &x, const splaytree_impl &y);
-template<class T, class ...Options>
-bool operator>=(const splaytree_impl<T, Options...> &x, const splaytree_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-void swap(splaytree_impl<T, Options...> &x, splaytree_impl<T, Options...> &y);
+ friend void swap(splaytree_impl &x, splaytree_impl &y);
-#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+};
//! Helper metafunction to define a \c splaytree that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
@@ -517,7 +517,7 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_splaytree
{
@@ -525,7 +525,7 @@ struct make_splaytree
typedef typename pack_options
< splaytree_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -536,6 +536,7 @@ struct make_splaytree
typedef splaytree_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::size_type
, packed_options::constant_time_size
@@ -549,14 +550,14 @@ struct make_splaytree
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class splaytree
: public make_splaytree<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -565,7 +566,7 @@ class splaytree
typedef typename make_splaytree
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -573,7 +574,7 @@ class splaytree
BOOST_MOVABLE_BUT_NOT_COPYABLE(splaytree)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
@@ -583,14 +584,14 @@ class splaytree
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit splaytree( const value_compare &cmp = value_compare()
+ explicit splaytree( const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, v_traits)
{}
template<class Iterator>
splaytree( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const value_traits &v_traits = value_traits())
: Base(unique, b, e, cmp, v_traits)
{}
@@ -602,6 +603,14 @@ class splaytree
splaytree& operator=(BOOST_RV_REF(splaytree) x)
{ return static_cast<splaytree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const splaytree &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(splaytree) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static splaytree &container_from_end_iterator(iterator end_iterator)
{ return static_cast<splaytree &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/treap.hpp b/boost/intrusive/treap.hpp
index bf374696fb..52785dafb0 100644
--- a/boost/intrusive/treap.hpp
+++ b/boost/intrusive/treap.hpp
@@ -47,20 +47,16 @@ namespace intrusive {
/// @cond
struct treap_defaults
+ : bstree_defaults
{
- typedef default_bstree_hook_applier proto_value_traits;
- static const bool constant_time_size = true;
- typedef std::size_t size_type;
- typedef void compare;
typedef void priority;
- typedef void header_holder_type;
};
/// @endcond
//! The class template treap is an intrusive treap container that
//! is used to construct intrusive set and multiset containers. The no-throw
-//! guarantee holds only, if the value_compare object and priority_compare object
+//! guarantee holds only, if the key_compare object and priority_compare object
//! don't throw.
//!
//! The template parameter \c T is the type to be managed by the container.
@@ -74,24 +70,24 @@ struct treap_defaults
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidOrKeyComp, class VoidOrPrioComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class VoidOrPrioComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class treap_impl
/// @cond
- : public bstree_impl<ValueTraits, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>
+ : public bstree_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>
//Use public inheritance to avoid MSVC bugs with closures
, public detail::ebo_functor_holder
< typename get_prio
< VoidOrPrioComp
, typename bstree_impl
- <ValueTraits, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>::value_type>::type
+ <ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms, HeaderHolder>::value_type>::type
>
/// @endcond
{
public:
typedef ValueTraits value_traits;
/// @cond
- typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
+ typedef bstree_impl< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, SizeType
, ConstantTimeSize, BsTreeAlgorithms
, HeaderHolder> tree_type;
typedef tree_type implementation_defined;
@@ -108,6 +104,7 @@ class treap_impl
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::reference reference;
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
@@ -129,6 +126,15 @@ 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;
+
+ 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()); }
+
/// @cond
private:
@@ -153,7 +159,7 @@ class treap_impl
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
//! or the copy constructor of the value_compare/priority_compare objects throw. Basic guarantee.
- explicit treap_impl( const value_compare &cmp = value_compare()
+ explicit treap_impl( const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits), prio_base(pcmp)
@@ -170,11 +176,11 @@ class treap_impl
//!
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor/operator() of the value_compare/priority_compare objects
+ //! or the copy constructor/operator() of the key_compare/priority_compare objects
//! throw. Basic guarantee.
template<class Iterator>
treap_impl( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, v_traits), prio_base(pcmp)
@@ -356,6 +362,27 @@ class treap_impl
this->priv_pcomp() = src.priv_pcomp();
}
+ //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
+ //! Cloner should yield to nodes equivalent to the original nodes.
+ //!
+ //! <b>Effects</b>: Erases all the elements from *this
+ //! calling Disposer::operator()(pointer), clones all the
+ //! elements from src calling Cloner::operator()(reference)
+ //! and inserts them on *this. Copies the predicate from the source container.
+ //!
+ //! If cloner throws, all cloned elements are unlinked and disposed
+ //! calling Disposer::operator()(pointer).
+ //!
+ //! <b>Complexity</b>: Linear to erased plus inserted elements.
+ //!
+ //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(treap_impl) src, Cloner cloner, Disposer disposer)
+ {
+ tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer);
+ this->priv_pcomp() = ::boost::move(src.priv_pcomp());
+ }
+
//! <b>Requires</b>: value must be an lvalue
//!
//! <b>Effects</b>: Inserts value into the container before the upper bound.
@@ -363,21 +390,21 @@ class treap_impl
//! <b>Complexity</b>: Average complexity for insert element is at
//! most logarithmic.
//!
- //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw. Strong guarantee.
+ //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw. Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
iterator insert_equal(reference value)
{
- detail::key_nodeptr_comp<value_compare, value_traits>
- key_node_comp(this->value_comp(), &this->get_value_traits());
- detail::key_nodeptr_comp<priority_compare, value_traits>
- key_node_pcomp(this->priv_pcomp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
- iterator ret(node_algorithms::insert_equal_upper_bound
- (this->tree_type::header_ptr(), to_insert, key_node_comp, key_node_pcomp), this->priv_value_traits_ptr());
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
+ iterator ret
+ ( node_algorithms::insert_equal_upper_bound
+ ( this->tree_type::header_ptr()
+ , to_insert
+ , this->key_node_comp(this->key_comp())
+ , this->value_node_prio_comp())
+ , this->priv_value_traits_ptr());
this->tree_type::sz_traits().increment();
return ret;
}
@@ -392,21 +419,22 @@ class treap_impl
//! <b>Complexity</b>: Logarithmic in general, but it is amortized
//! constant time if t is inserted immediately before hint.
//!
- //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw. Strong guarantee.
+ //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw. Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
iterator insert_equal(const_iterator hint, reference value)
{
- detail::key_nodeptr_comp<value_compare, value_traits>
- key_node_comp(this->value_comp(), &this->get_value_traits());
- detail::key_nodeptr_comp<priority_compare, value_traits>
- key_node_pcomp(this->priv_pcomp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
- iterator ret (node_algorithms::insert_equal
- (this->tree_type::header_ptr(), hint.pointed_node(), to_insert, key_node_comp, key_node_pcomp), this->priv_value_traits_ptr());
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
+ iterator ret
+ (node_algorithms::insert_equal
+ ( this->tree_type::header_ptr()
+ , hint.pointed_node()
+ , to_insert
+ , this->key_node_comp(this->key_comp())
+ , this->value_node_prio_comp())
+ , this->priv_value_traits_ptr());
this->tree_type::sz_traits().increment();
return ret;
}
@@ -419,9 +447,9 @@ class treap_impl
//!
//! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
//! size of the range. However, it is linear in N if the range is already sorted
- //! by value_comp().
+ //! by key_comp().
//!
- //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw.
+ //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw.
//! Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
@@ -442,7 +470,7 @@ class treap_impl
//! <b>Complexity</b>: Average complexity for insert element is at
//! most logarithmic.
//!
- //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw.
+ //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw.
//! Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
@@ -450,10 +478,11 @@ class treap_impl
std::pair<iterator, bool> insert_unique(reference value)
{
insert_commit_data commit_data;
- std::pair<iterator, bool> ret = insert_unique_check(value, this->value_comp(), this->priv_pcomp(), commit_data);
+ std::pair<iterator, bool> ret = this->insert_unique_check
+ (value, this->comp(), this->priv_pcomp(), commit_data);
if(!ret.second)
return ret;
- return std::pair<iterator, bool> (insert_unique_commit(value, commit_data), true);
+ return std::pair<iterator, bool> (this->insert_unique_commit(value, commit_data), true);
}
//! <b>Requires</b>: value must be an lvalue, and "hint" must be
@@ -466,7 +495,7 @@ class treap_impl
//! constant time (two comparisons in the worst case)
//! if t is inserted immediately before hint.
//!
- //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw.
+ //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw.
//! Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
@@ -474,10 +503,11 @@ class treap_impl
iterator insert_unique(const_iterator hint, reference value)
{
insert_commit_data commit_data;
- std::pair<iterator, bool> ret = insert_unique_check(hint, value, this->value_comp(), this->priv_pcomp(), commit_data);
+ std::pair<iterator, bool> ret = this->insert_unique_check
+ (hint, value, this->comp(), this->priv_pcomp(), commit_data);
if(!ret.second)
return ret.first;
- return insert_unique_commit(value, commit_data);
+ return this->insert_unique_commit(value, commit_data);
}
//! <b>Requires</b>: Dereferencing iterator must yield an lvalue
@@ -487,9 +517,9 @@ class treap_impl
//!
//! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
//! size of the range. However, it is linear in N if the range is already sorted
- //! by value_comp().
+ //! by key_comp().
//!
- //! <b>Throws</b>: If the internal value_compare or priority_compare functions throw.
+ //! <b>Throws</b>: If the internal key_compare or priority_compare functions throw.
//! Strong guarantee.
//!
//! <b>Note</b>: Does not affect the validity of iterators and references.
@@ -508,11 +538,11 @@ class treap_impl
}
}
- //! <b>Requires</b>: key_value_comp must be a comparison function that induces
- //! the same strict weak ordering as value_compare.
+ //! <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
//! the same strict weak ordering as priority_compare. The difference is that
- //! key_value_pcomp and key_value_comp compare an arbitrary key with the contained values.
+ //! key_value_pcomp and comp compare an arbitrary key with the contained values.
//!
//! <b>Effects</b>: Checks if a value can be inserted in the container, using
//! a user provided key instead of the value itself.
@@ -525,7 +555,7 @@ class treap_impl
//!
//! <b>Complexity</b>: Average complexity is at most logarithmic.
//!
- //! <b>Throws</b>: If the key_value_comp or key_value_pcomp
+ //! <b>Throws</b>: If the comp or key_value_pcomp
//! ordering functions throw. Strong guarantee.
//!
//! <b>Notes</b>: This function is used to improve performance when constructing
@@ -541,26 +571,23 @@ 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 KeyValueCompare, class KeyValuePrioCompare>
+ template<class KeyType, class KeyTypeKeyCompare, class KeyValuePrioCompare>
std::pair<iterator, bool> insert_unique_check
- ( const KeyType &key, KeyValueCompare key_value_comp
+ ( const KeyType &key, KeyTypeKeyCompare comp
, KeyValuePrioCompare key_value_pcomp, insert_commit_data &commit_data)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- ocomp(key_value_comp, &this->get_value_traits());
- detail::key_nodeptr_comp<KeyValuePrioCompare, value_traits>
- pcomp(key_value_pcomp, &this->get_value_traits());
- std::pair<node_ptr, bool> ret =
+ std::pair<node_ptr, bool> const ret =
(node_algorithms::insert_unique_check
- (this->tree_type::header_ptr(), key, ocomp, pcomp, commit_data));
+ ( this->tree_type::header_ptr(), key
+ , this->key_node_comp(comp), this->key_node_prio_comp(key_value_pcomp), commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
}
- //! <b>Requires</b>: key_value_comp must be a comparison function that induces
- //! the same strict weak ordering as value_compare.
+ //! <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
//! the same strict weak ordering as priority_compare. The difference is that
- //! key_value_pcomp and key_value_comp compare an arbitrary key with the contained values.
+ //! key_value_pcomp and comp compare an arbitrary key with the contained values.
//!
//! <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"
@@ -575,7 +602,7 @@ class treap_impl
//! <b>Complexity</b>: Logarithmic in general, but it's amortized
//! constant time if t is inserted immediately before hint.
//!
- //! <b>Throws</b>: If the key_value_comp or key_value_pcomp
+ //! <b>Throws</b>: If the comp or key_value_pcomp
//! ordering functions throw. Strong guarantee.
//!
//! <b>Notes</b>: This function is used to improve performance when constructing
@@ -591,20 +618,17 @@ 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 KeyValueCompare, class KeyValuePrioCompare>
+ template<class KeyType, class KeyTypeKeyCompare, class KeyValuePrioCompare>
std::pair<iterator, bool> insert_unique_check
( const_iterator hint, const KeyType &key
- , KeyValueCompare key_value_comp
+ , KeyTypeKeyCompare comp
, KeyValuePrioCompare key_value_pcomp
, insert_commit_data &commit_data)
{
- detail::key_nodeptr_comp<KeyValueCompare, value_traits>
- ocomp(key_value_comp, &this->get_value_traits());
- detail::key_nodeptr_comp<KeyValuePrioCompare, value_traits>
- pcomp(key_value_pcomp, &this->get_value_traits());
- std::pair<node_ptr, bool> ret =
+ std::pair<node_ptr, bool> const ret =
(node_algorithms::insert_unique_check
- (this->tree_type::header_ptr(), hint.pointed_node(), key, ocomp, pcomp, commit_data));
+ ( this->tree_type::header_ptr(), hint.pointed_node(), key
+ , this->key_node_comp(comp), this->key_node_prio_comp(key_value_pcomp), commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
}
@@ -628,8 +652,7 @@ class treap_impl
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
{
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
node_algorithms::insert_unique_commit(this->tree_type::header_ptr(), to_insert, commit_data);
this->tree_type::sz_traits().increment();
return iterator(to_insert, this->priv_value_traits_ptr());
@@ -652,12 +675,11 @@ class treap_impl
iterator insert_before(const_iterator pos, reference value)
{
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
- detail::key_nodeptr_comp<priority_compare, value_traits>
- pcomp(this->priv_pcomp(), &this->get_value_traits());
- iterator ret (node_algorithms::insert_before
- (this->tree_type::header_ptr(), pos.pointed_node(), to_insert, pcomp), this->priv_value_traits_ptr());
+ 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->priv_value_traits_ptr());
this->tree_type::sz_traits().increment();
return ret;
}
@@ -679,11 +701,8 @@ class treap_impl
void push_back(reference value)
{
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
- detail::key_nodeptr_comp<priority_compare, value_traits>
- pcomp(this->priv_pcomp(), &this->get_value_traits());
- node_algorithms::push_back(this->tree_type::header_ptr(), to_insert, pcomp);
+ 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());
this->tree_type::sz_traits().increment();
}
@@ -704,11 +723,8 @@ class treap_impl
void push_front(reference value)
{
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
- detail::key_nodeptr_comp<priority_compare, value_traits>
- pcomp(this->priv_pcomp(), &this->get_value_traits());
- node_algorithms::push_front(this->tree_type::header_ptr(), to_insert, pcomp);
+ 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());
this->tree_type::sz_traits().increment();
}
@@ -725,11 +741,8 @@ class treap_impl
const_iterator ret(i);
++ret;
node_ptr to_erase(i.pointed_node());
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
- detail::key_nodeptr_comp<priority_compare, value_traits>
- key_node_pcomp(this->priv_pcomp(), &this->get_value_traits());
- node_algorithms::erase(this->tree_type::header_ptr(), to_erase, key_node_pcomp);
+ 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());
this->tree_type::sz_traits().decrement();
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
@@ -758,8 +771,8 @@ class treap_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
- size_type erase(const_reference value)
- { return this->erase(value, this->value_comp()); }
+ size_type erase(const key_type &key)
+ { return this->erase(key, this->key_comp()); }
//! <b>Effects</b>: Erases all the elements with the given key.
//! according to the comparison functor "comp".
@@ -773,12 +786,10 @@ class treap_impl
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
- /// @endcond
- )
+ template<class KeyType, class KeyTypeKeyCompare>
+ BOOST_INTRUSIVE_DOC1ST(size_type
+ , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
+ erase(const KeyType& key, KeyTypeKeyCompare comp)
{
std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n;
@@ -843,9 +854,9 @@ class treap_impl
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer)
+ size_type erase_and_dispose(const key_type &key, Disposer disposer)
{
- std::pair<iterator,iterator> p = this->equal_range(value);
+ std::pair<iterator,iterator> p = this->equal_range(key);
size_type n;
private_erase(p.first, p.second, n, disposer);
return n;
@@ -866,12 +877,10 @@ class treap_impl
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
- /// @endcond
- )
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ BOOST_INTRUSIVE_DOC1ST(size_type
+ , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
+ erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer)
{
std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n;
@@ -913,9 +922,8 @@ class treap_impl
template <class ExtraChecker>
void check(ExtraChecker extra_checker) const
{
- typedef detail::key_nodeptr_comp<priority_compare, value_traits> nodeptr_prio_comp_t;
- nodeptr_prio_comp_t nodeptr_prio_comp(priv_pcomp(), &this->get_value_traits());
- tree_type::check(detail::treap_node_extra_checker<ValueTraits, nodeptr_prio_comp_t, ExtraChecker>(nodeptr_prio_comp, extra_checker));
+ tree_type::check(detail::treap_node_extra_checker
+ <ValueTraits, value_node_prio_comp_t, ExtraChecker>(this->value_node_prio_comp(), extra_checker));
}
//! @copydoc ::boost::intrusive::bstree::check()const
@@ -923,88 +931,88 @@ class treap_impl
{ check(detail::empty_node_checker<ValueTraits>()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::bstree::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -1030,6 +1038,20 @@ class treap_impl
//! @copydoc ::boost::intrusive::bstree::remove_node
void remove_node(reference value);
+ friend bool operator< (const treap_impl &x, const treap_impl &y);
+
+ friend bool operator==(const treap_impl &x, const treap_impl &y);
+
+ friend bool operator!= (const treap_impl &x, const treap_impl &y);
+
+ friend bool operator>(const treap_impl &x, const treap_impl &y);
+
+ friend bool operator<=(const treap_impl &x, const treap_impl &y);
+
+ friend bool operator>=(const treap_impl &x, const treap_impl &y);
+
+ friend void swap(treap_impl &x, treap_impl &y);
+
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
/// @cond
@@ -1051,30 +1073,6 @@ class treap_impl
/// @endcond
};
-#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
-
-template<class T, class ...Options>
-bool operator< (const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator==(const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator!= (const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator>(const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator<=(const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-bool operator>=(const treap_impl<T, Options...> &x, const treap_impl<T, Options...> &y);
-
-template<class T, class ...Options>
-void swap(treap_impl<T, Options...> &x, treap_impl<T, Options...> &y);
-
-#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! Helper metafunction to define a \c treap that yields to the same type when the
//! same options (either explicitly or implicitly) are used.
@@ -1083,14 +1081,14 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_treap
{
typedef typename pack_options
< treap_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -1101,6 +1099,7 @@ struct make_treap
typedef treap_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::priority
, typename packed_options::size_type
@@ -1114,14 +1113,14 @@ struct make_treap
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class treap
: public make_treap<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -1130,7 +1129,7 @@ class treap
typedef typename make_treap
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -1138,7 +1137,7 @@ class treap
BOOST_MOVABLE_BUT_NOT_COPYABLE(treap)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::priority_compare priority_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
@@ -1149,7 +1148,7 @@ class treap
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit treap( const value_compare &cmp = value_compare()
+ explicit treap( const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, pcmp, v_traits)
@@ -1157,7 +1156,7 @@ class treap
template<class Iterator>
treap( bool unique, Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: Base(unique, b, e, cmp, pcmp, v_traits)
@@ -1170,6 +1169,14 @@ class treap
treap& operator=(BOOST_RV_REF(treap) x)
{ return static_cast<treap&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const treap &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(treap) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static treap &container_from_end_iterator(iterator end_iterator)
{ return static_cast<treap &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/treap_set.hpp b/boost/intrusive/treap_set.hpp
index a88df58e44..188c80fdce 100644
--- a/boost/intrusive/treap_set.hpp
+++ b/boost/intrusive/treap_set.hpp
@@ -40,16 +40,16 @@ namespace intrusive {
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidOrKeyComp, class VoidOrPrioComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class VoidOrPrioComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class treap_set_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public treap_impl<ValueTraits, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder>
+ : public treap_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder>
#endif
{
/// @cond
public:
- typedef treap_impl<ValueTraits, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder> tree_type;
+ typedef treap_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_set_impl)
typedef tree_type implementation_defined;
@@ -58,6 +58,8 @@ class treap_set_impl
public:
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::value_traits value_traits;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::reference reference;
@@ -65,8 +67,8 @@ class treap_set_impl
typedef typename implementation_defined::difference_type difference_type;
typedef typename implementation_defined::size_type size_type;
typedef typename implementation_defined::value_compare value_compare;
- typedef typename implementation_defined::priority_compare priority_compare;
typedef typename implementation_defined::key_compare key_compare;
+ typedef typename implementation_defined::priority_compare priority_compare;
typedef typename implementation_defined::iterator iterator;
typedef typename implementation_defined::const_iterator const_iterator;
typedef typename implementation_defined::reverse_iterator reverse_iterator;
@@ -87,8 +89,8 @@ class treap_set_impl
//!
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor of the value_compare object throws.
- explicit treap_set_impl( const value_compare &cmp = value_compare()
+ //! or the copy constructor of the key_compare object throws.
+ explicit treap_set_impl( const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, pcmp, v_traits)
@@ -105,10 +107,10 @@ class treap_set_impl
//!
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor/operator() of the value_compare object throws.
+ //! or the copy constructor/operator() of the key_compare object throws.
template<class Iterator>
treap_set_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: tree_type(true, b, e, cmp, pcmp, v_traits)
@@ -192,10 +194,23 @@ class treap_set_impl
//! @copydoc ::boost::intrusive::treap::swap
void swap(treap_set_impl& other);
- //! @copydoc ::boost::intrusive::treap::clone_from
+ //! @copydoc ::boost::intrusive::treap::clone_from(const treap&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const treap_set_impl &src, Cloner cloner, Disposer disposer);
+ #else
+
+ using tree_type::clone_from;
+
+ #endif
+
+ //! @copydoc ::boost::intrusive::treap::clone_from(treap&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(treap_set_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
+
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+
//! @copydoc ::boost::intrusive::treap::top()
iterator top();
@@ -226,20 +241,20 @@ 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 KeyType&,KeyValueCompare,KeyValuePrioCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare, class KeyValuePrioCompare>
+ //! @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
- ( const KeyType &key, KeyValueCompare key_value_comp, KeyValuePrioCompare key_value_pcomp
+ ( const KeyType &key, KeyTypeKeyCompare comp, KeyValuePrioCompare key_value_pcomp
, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(key, key_value_comp, key_value_pcomp, commit_data); }
+ { return tree_type::insert_unique_check(key, comp, key_value_pcomp, commit_data); }
- //! @copydoc ::boost::intrusive::treap::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,KeyValuePrioCompare,insert_commit_data&)
- template<class KeyType, class KeyValueCompare, class KeyValuePrioCompare>
+ //! @copydoc ::boost::intrusive::treap::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,KeyValuePrioCompare,insert_commit_data&)
+ template<class KeyType, class KeyTypeKeyCompare, class KeyValuePrioCompare>
std::pair<iterator, bool> insert_check
( const_iterator hint, const KeyType &key
- , KeyValueCompare key_value_comp, KeyValuePrioCompare key_value_pcomp
+ , KeyTypeKeyCompare comp, KeyValuePrioCompare key_value_pcomp
, insert_commit_data &commit_data)
- { return tree_type::insert_unique_check(hint, key, key_value_comp, key_value_pcomp, commit_data); }
+ { return tree_type::insert_unique_check(hint, key, comp, key_value_pcomp, commit_data); }
//! @copydoc ::boost::intrusive::treap::insert_unique(Iterator,Iterator)
template<class Iterator>
@@ -266,12 +281,12 @@ class treap_set_impl
//! @copydoc ::boost::intrusive::treap::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::treap::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::treap::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -281,13 +296,13 @@ class treap_set_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::treap::clear
void clear();
@@ -298,100 +313,100 @@ class treap_set_impl
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::treap::count(const_reference)const
- size_type count(const_reference value) const
- { return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
+ //! @copydoc ::boost::intrusive::treap::count(const key_type &)const
+ size_type count(const key_type &key) const
+ { return static_cast<size_type>(this->tree_type::find(key) != this->tree_type::cend()); }
- //! @copydoc ::boost::intrusive::treap::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const
+ //! @copydoc ::boost::intrusive::treap::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::treap::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::treap::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::treap::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::treap::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::treap::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::treap::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::treap::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::treap::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::treap::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::treap::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::treap::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::treap::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::treap::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::treap::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::treap::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return this->tree_type::lower_bound_range(value); }
+ //! @copydoc ::boost::intrusive::rbtree::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&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
+ //! @copydoc ::boost::intrusive::rbtree::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::lower_bound_range(key, comp); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return this->tree_type::lower_bound_range(value); }
+ equal_range(const key_type &key) const
+ { return this->tree_type::lower_bound_range(key); }
- //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const
{ return this->tree_type::lower_bound_range(key, comp); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! @copydoc ::boost::intrusive::treap::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::treap::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::treap::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::treap::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::treap::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::treap::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::treap::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::treap::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::treap::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -428,14 +443,14 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_treap_set
{
typedef typename pack_options
< treap_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -446,6 +461,7 @@ struct make_treap_set
typedef treap_set_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::priority
, typename packed_options::size_type
@@ -459,14 +475,14 @@ struct make_treap_set
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class treap_set
: public make_treap_set<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -475,7 +491,7 @@ class treap_set
typedef typename make_treap_set
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -483,7 +499,7 @@ class treap_set
BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_set)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::priority_compare priority_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
@@ -492,7 +508,7 @@ class treap_set
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit treap_set( const value_compare &cmp = value_compare()
+ explicit treap_set( const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, pcmp, v_traits)
@@ -500,7 +516,7 @@ class treap_set
template<class Iterator>
treap_set( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, pcmp, v_traits)
@@ -513,6 +529,14 @@ class treap_set
treap_set& operator=(BOOST_RV_REF(treap_set) x)
{ return static_cast<treap_set &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const treap_set &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(treap_set) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static treap_set &container_from_end_iterator(iterator end_iterator)
{ return static_cast<treap_set &>(Base::container_from_end_iterator(end_iterator)); }
@@ -542,15 +566,15 @@ class treap_set
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class VoidOrKeyComp, class VoidOrPrioComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class VoidOrPrioComp, class SizeType, bool ConstantTimeSize, typename HeaderHolder>
#endif
class treap_multiset_impl
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- : public treap_impl<ValueTraits, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder>
+ : public treap_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder>
#endif
{
/// @cond
- typedef treap_impl<ValueTraits, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder> tree_type;
+ typedef treap_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize, HeaderHolder> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_multiset_impl)
typedef tree_type implementation_defined;
@@ -559,6 +583,8 @@ class treap_multiset_impl
public:
typedef typename implementation_defined::value_type value_type;
typedef typename implementation_defined::value_traits value_traits;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::reference reference;
@@ -566,8 +592,8 @@ class treap_multiset_impl
typedef typename implementation_defined::difference_type difference_type;
typedef typename implementation_defined::size_type size_type;
typedef typename implementation_defined::value_compare value_compare;
- typedef typename implementation_defined::priority_compare priority_compare;
typedef typename implementation_defined::key_compare key_compare;
+ typedef typename implementation_defined::priority_compare priority_compare;
typedef typename implementation_defined::iterator iterator;
typedef typename implementation_defined::const_iterator const_iterator;
typedef typename implementation_defined::reverse_iterator reverse_iterator;
@@ -588,8 +614,8 @@ class treap_multiset_impl
//!
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor of the value_compare object throws.
- explicit treap_multiset_impl( const value_compare &cmp = value_compare()
+ //! or the copy constructor of the key_compare object throws.
+ explicit treap_multiset_impl( const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: tree_type(cmp, pcmp, v_traits)
@@ -606,10 +632,10 @@ class treap_multiset_impl
//!
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor/operator() of the value_compare object throws.
+ //! or the copy constructor/operator() of the key_compare object throws.
template<class Iterator>
treap_multiset_impl( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: tree_type(false, b, e, cmp, pcmp, v_traits)
@@ -693,10 +719,23 @@ class treap_multiset_impl
//! @copydoc ::boost::intrusive::treap::swap
void swap(treap_multiset_impl& other);
- //! @copydoc ::boost::intrusive::treap::clone_from
+ //! @copydoc ::boost::intrusive::treap::clone_from(const treap&,Cloner,Disposer)
template <class Cloner, class Disposer>
void clone_from(const treap_multiset_impl &src, Cloner cloner, Disposer disposer);
+ #else
+
+ using tree_type::clone_from;
+
+ #endif
+
+ //! @copydoc ::boost::intrusive::treap::clone_from(treap&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(treap_multiset_impl) src, Cloner cloner, Disposer disposer)
+ { tree_type::clone_from(BOOST_MOVE_BASE(tree_type, src), cloner, disposer); }
+
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+
//! @copydoc ::boost::intrusive::treap::top()
iterator top();
@@ -748,12 +787,12 @@ class treap_multiset_impl
//! @copydoc ::boost::intrusive::treap::erase(const_iterator,const_iterator)
iterator erase(const_iterator b, const_iterator e);
- //! @copydoc ::boost::intrusive::treap::erase(const_reference)
- size_type erase(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::erase(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- size_type erase(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::erase(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type erase(const KeyType& key, KeyTypeKeyCompare comp);
//! @copydoc ::boost::intrusive::treap::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
@@ -763,13 +802,13 @@ class treap_multiset_impl
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const_reference, Disposer)
+ //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const key_type &, Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer);
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
- template<class KeyType, class KeyValueCompare, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
+ //! @copydoc ::boost::intrusive::treap::erase_and_dispose(const KeyType&,KeyTypeKeyCompare,Disposer)
+ template<class KeyType, class KeyTypeKeyCompare, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer);
//! @copydoc ::boost::intrusive::treap::clear
void clear();
@@ -778,88 +817,88 @@ class treap_multiset_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer);
- //! @copydoc ::boost::intrusive::treap::count(const_reference)const
- size_type count(const_reference value) const;
+ //! @copydoc ::boost::intrusive::treap::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! @copydoc ::boost::intrusive::treap::count(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- size_type count(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::treap::count(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ size_type count(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::treap::lower_bound(const_reference)
- iterator lower_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::lower_bound(const key_type &)
+ iterator lower_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::lower_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator lower_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::lower_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::treap::lower_bound(const_reference)const
- const_iterator lower_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::treap::lower_bound(const key_type &)const
+ const_iterator lower_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::treap::lower_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::treap::lower_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator lower_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::treap::upper_bound(const_reference)
- iterator upper_bound(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::upper_bound(const key_type &)
+ iterator upper_bound(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::upper_bound(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator upper_bound(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::upper_bound(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::treap::upper_bound(const_reference)const
- const_iterator upper_bound(const_reference value) const;
+ //! @copydoc ::boost::intrusive::treap::upper_bound(const key_type &)const
+ const_iterator upper_bound(const key_type &key) const;
- //! @copydoc ::boost::intrusive::treap::upper_bound(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::treap::upper_bound(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator upper_bound(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::treap::find(const_reference)
- iterator find(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::find(const key_type &)
+ iterator find(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::find(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- iterator find(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::find(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ iterator find(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::treap::find(const_reference)const
- const_iterator find(const_reference value) const;
+ //! @copydoc ::boost::intrusive::treap::find(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! @copydoc ::boost::intrusive::treap::find(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
- const_iterator find(const KeyType& key, KeyValueCompare comp) const;
+ //! @copydoc ::boost::intrusive::treap::find(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
+ const_iterator find(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::treap::equal_range(const_reference)
- std::pair<iterator,iterator> equal_range(const_reference value);
+ //! @copydoc ::boost::intrusive::treap::equal_range(const key_type &)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
- //! @copydoc ::boost::intrusive::treap::equal_range(const KeyType&,KeyValueCompare)
- template<class KeyType, class KeyValueCompare>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
+ //! @copydoc ::boost::intrusive::treap::equal_range(const KeyType&,KeyTypeKeyCompare)
+ template<class KeyType, class KeyTypeKeyCompare>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyTypeKeyCompare comp);
- //! @copydoc ::boost::intrusive::treap::equal_range(const_reference)const
+ //! @copydoc ::boost::intrusive::treap::equal_range(const key_type &)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const;
+ equal_range(const key_type &key) const;
- //! @copydoc ::boost::intrusive::treap::equal_range(const KeyType&,KeyValueCompare)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::treap::equal_range(const KeyType&,KeyTypeKeyCompare)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyValueCompare comp) const;
+ equal_range(const KeyType& key, KeyTypeKeyCompare comp) const;
- //! @copydoc ::boost::intrusive::treap::bounded_range(const_reference,const_reference,bool,bool)
+ //! @copydoc ::boost::intrusive::treap::bounded_range(const key_type &,const key_type &,bool,bool)
std::pair<iterator,iterator> bounded_range
- (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
+ (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::treap::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::treap::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<iterator,iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
- //! @copydoc ::boost::intrusive::treap::bounded_range(const_reference,const_reference,bool,bool)const
+ //! @copydoc ::boost::intrusive::treap::bounded_range(const key_type &,const key_type &,bool,bool)const
std::pair<const_iterator, const_iterator>
- bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
+ bounded_range(const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
- //! @copydoc ::boost::intrusive::treap::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
- template<class KeyType, class KeyValueCompare>
+ //! @copydoc ::boost::intrusive::treap::bounded_range(const KeyType&,const KeyType&,KeyTypeKeyCompare,bool,bool)const
+ template<class KeyType, class KeyTypeKeyCompare>
std::pair<const_iterator, const_iterator> bounded_range
- (const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
+ (const KeyType& lower_key, const KeyType& upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
//! @copydoc ::boost::intrusive::treap::s_iterator_to(reference)
static iterator s_iterator_to(reference value);
@@ -896,14 +935,14 @@ template<class T, class ...Options>
#else
template<class T, class O1 = void, class O2 = void
, class O3 = void, class O4 = void
- , class O5 = void>
+ , class O5 = void, class O6 = void>
#endif
struct make_treap_multiset
{
typedef typename pack_options
< treap_defaults,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -914,6 +953,7 @@ struct make_treap_multiset
typedef treap_multiset_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::compare
, typename packed_options::priority
, typename packed_options::size_type
@@ -927,14 +967,14 @@ struct make_treap_multiset
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
-template<class T, class O1, class O2, class O3, class O4, class O5>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
#else
template<class T, class ...Options>
#endif
class treap_multiset
: public make_treap_multiset<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -943,7 +983,7 @@ class treap_multiset
typedef typename make_treap_multiset
<T,
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
- O1, O2, O3, O4, O5
+ O1, O2, O3, O4, O5, O6
#else
Options...
#endif
@@ -951,7 +991,7 @@ class treap_multiset
BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_multiset)
public:
- typedef typename Base::value_compare value_compare;
+ typedef typename Base::key_compare key_compare;
typedef typename Base::priority_compare priority_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::iterator iterator;
@@ -960,7 +1000,7 @@ class treap_multiset
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
- explicit treap_multiset( const value_compare &cmp = value_compare()
+ explicit treap_multiset( const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: Base(cmp, pcmp, v_traits)
@@ -968,7 +1008,7 @@ class treap_multiset
template<class Iterator>
treap_multiset( Iterator b, Iterator e
- , const value_compare &cmp = value_compare()
+ , const key_compare &cmp = key_compare()
, const priority_compare &pcmp = priority_compare()
, const value_traits &v_traits = value_traits())
: Base(b, e, cmp, pcmp, v_traits)
@@ -981,6 +1021,14 @@ class treap_multiset
treap_multiset& operator=(BOOST_RV_REF(treap_multiset) x)
{ return static_cast<treap_multiset &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+ template <class Cloner, class Disposer>
+ void clone_from(const treap_multiset &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(treap_multiset) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
+
static treap_multiset &container_from_end_iterator(iterator end_iterator)
{ return static_cast<treap_multiset &>(Base::container_from_end_iterator(end_iterator)); }
diff --git a/boost/intrusive/unordered_set.hpp b/boost/intrusive/unordered_set.hpp
index 4b0c91e741..5148f02f8c 100644
--- a/boost/intrusive/unordered_set.hpp
+++ b/boost/intrusive/unordered_set.hpp
@@ -64,14 +64,24 @@ namespace intrusive {
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Hash, class Equal, class SizeType, class BucketTraits, std::size_t BoolFlags>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class SizeType, class BucketTraits, std::size_t BoolFlags>
#endif
class unordered_set_impl
- : public hashtable_impl<ValueTraits, Hash, Equal, SizeType, BucketTraits, BoolFlags>
+ : public hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags|hash_bool_flags::unique_keys_pos>
{
/// @cond
private:
- typedef hashtable_impl<ValueTraits, Hash, Equal, SizeType, BucketTraits, BoolFlags> table_type;
+ typedef hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags|hash_bool_flags::unique_keys_pos> table_type;
+
+ template<class Iterator, class MaybeConstThis, class KeyType, class KeyHasher, class KeyEqual>
+ static std::pair<Iterator,Iterator> priv_equal_range(MaybeConstThis &c, const KeyType& key, KeyHasher hash_func, KeyEqual equal_func)
+ {
+ Iterator const it = c.find(key, hash_func, equal_func);
+ std::pair<Iterator,Iterator> ret(it, it);
+ if(it != c.end())
+ ++ret.second;
+ return ret;
+ }
//! This class is
//! movable
@@ -82,6 +92,8 @@ class unordered_set_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
+ typedef typename implementation_defined::key_of_value key_of_value;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::bucket_traits bucket_traits;
typedef typename implementation_defined::pointer pointer;
@@ -90,7 +102,6 @@ class unordered_set_impl
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
typedef typename implementation_defined::size_type size_type;
- typedef typename implementation_defined::key_type key_type;
typedef typename implementation_defined::key_equal key_equal;
typedef typename implementation_defined::hasher hasher;
typedef typename implementation_defined::bucket_type bucket_type;
@@ -108,19 +119,7 @@ class unordered_set_impl
public:
- //! <b>Requires</b>: buckets must not be being used by any other resource.
- //!
- //! <b>Effects</b>: Constructs an empty unordered_set_impl, storing a reference
- //! to the bucket array and copies of the hasher and equal functors.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If value_traits::node_traits::node
- //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor or invocation of Hash or Equal throws.
- //!
- //! <b>Notes</b>: buckets array must be disposed only after
- //! *this is disposed.
+ //! @copydoc ::boost::intrusive::hashtable::hashtable(const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
explicit unordered_set_impl( const bucket_traits &b_traits
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
@@ -128,21 +127,7 @@ class unordered_set_impl
: table_type(b_traits, hash_func, equal_func, v_traits)
{}
- //! <b>Requires</b>: buckets must not be being used by any other resource
- //! and Dereferencing iterator must yield an lvalue of type value_type.
- //!
- //! <b>Effects</b>: Constructs an empty unordered_set and inserts elements from
- //! [b, e).
- //!
- //! <b>Complexity</b>: If N is distance(b, e): Average case is O(N)
- //! (with a good hash function and with buckets_len >= N),worst case O(N2).
- //!
- //! <b>Throws</b>: If value_traits::node_traits::node
- //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor or invocation of hasher or key_equal throws.
- //!
- //! <b>Notes</b>: buckets array must be disposed only after
- //! *this is disposed.
+ //! @copydoc ::boost::intrusive::hashtable::hashtable(bool,Iterator,Iterator,const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
template<class Iterator>
unordered_set_impl( Iterator b
, Iterator e
@@ -150,859 +135,272 @@ class unordered_set_impl
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
, const value_traits &v_traits = value_traits())
- : table_type(b_traits, hash_func, equal_func, v_traits)
- { table_type::insert_unique(b, e); }
+ : table_type(true, b, e, b_traits, hash_func, equal_func, v_traits)
+ {}
- //! <b>Effects</b>: to-do
- //!
+ //! @copydoc ::boost::intrusive::hashtable::hashtable(hashtable&&)
unordered_set_impl(BOOST_RV_REF(unordered_set_impl) x)
: table_type(BOOST_MOVE_BASE(table_type, x))
{}
- //! <b>Effects</b>: to-do
- //!
+ //! @copydoc ::boost::intrusive::hashtable::operator=(hashtable&&)
unordered_set_impl& operator=(BOOST_RV_REF(unordered_set_impl) x)
{ return static_cast<unordered_set_impl&>(table_type::operator=(BOOST_MOVE_BASE(table_type, x))); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! <b>Effects</b>: Detaches all elements from this. The objects in the unordered_set
- //! are not deleted (i.e. no destructors are called).
- //!
- //! <b>Complexity</b>: Linear to the number of elements in the unordered_set, if
- //! it's a safe-mode or auto-unlink value. Otherwise constant.
- //!
- //! <b>Throws</b>: Nothing.
- ~unordered_set_impl()
- {}
+ //! @copydoc ::boost::intrusive::hashtable::~hashtable()
+ ~unordered_set_impl();
- //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_set.
- //!
- //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
- //! constant time with worst case (empty unordered_set) O(this->bucket_count())
- //!
- //! <b>Throws</b>: Nothing.
- iterator begin()
- { return table_type::begin(); }
+ //! @copydoc ::boost::intrusive::hashtable::begin()
+ iterator begin();
- //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
- //! of the unordered_set.
- //!
- //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
- //! constant time with worst case (empty unordered_set) O(this->bucket_count())
- //!
- //! <b>Throws</b>: Nothing.
- const_iterator begin() const
- { return table_type::begin(); }
+ //! @copydoc ::boost::intrusive::hashtable::begin()const
+ const_iterator begin() const;
- //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
- //! of the unordered_set.
- //!
- //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
- //! constant time with worst case (empty unordered_set) O(this->bucket_count())
- //!
- //! <b>Throws</b>: Nothing.
- const_iterator cbegin() const
- { return table_type::cbegin(); }
+ //! @copydoc ::boost::intrusive::hashtable::cbegin()const
+ const_iterator cbegin() const;
- //! <b>Effects</b>: Returns an iterator pointing to the end of the unordered_set.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- iterator end()
- { return table_type::end(); }
+ //! @copydoc ::boost::intrusive::hashtable::end()
+ iterator end();
- //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_set.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- const_iterator end() const
- { return table_type::end(); }
+ //! @copydoc ::boost::intrusive::hashtable::end()const
+ const_iterator end() const;
- //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_set.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- const_iterator cend() const
- { return table_type::cend(); }
+ //! @copydoc ::boost::intrusive::hashtable::cend()const
+ const_iterator cend() const;
- //! <b>Effects</b>: Returns the hasher object used by the unordered_set.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If hasher copy-constructor throws.
- hasher hash_function() const
- { return table_type::hash_function(); }
+ //! @copydoc ::boost::intrusive::hashtable::hash_function()const
+ hasher hash_function() const;
- //! <b>Effects</b>: Returns the key_equal object used by the unordered_set.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If key_equal copy-constructor throws.
- key_equal key_eq() const
- { return table_type::key_eq(); }
+ //! @copydoc ::boost::intrusive::hashtable::key_eq()const
+ key_equal key_eq() const;
- //! <b>Effects</b>: Returns true if the container is empty.
- //!
- //! <b>Complexity</b>: if constant-time size and cache_last options are disabled,
- //! average constant time (worst case, with empty() == true: O(this->bucket_count()).
- //! Otherwise constant.
- //!
- //! <b>Throws</b>: Nothing.
- bool empty() const
- { return table_type::empty(); }
+ //! @copydoc ::boost::intrusive::hashtable::empty()const
+ bool empty() const;
- //! <b>Effects</b>: Returns the number of elements stored in the unordered_set.
- //!
- //! <b>Complexity</b>: Linear to elements contained in *this if
- //! constant-time size option is disabled. Constant-time otherwise.
- //!
- //! <b>Throws</b>: Nothing.
- size_type size() const
- { return table_type::size(); }
+ //! @copydoc ::boost::intrusive::hashtable::size()const
+ size_type size() const;
- //! <b>Requires</b>: the hasher and the equality function unqualified swap
- //! call should not throw.
- //!
- //! <b>Effects</b>: Swaps the contents of two unordered_sets.
- //! Swaps also the contained bucket array and equality and hasher functors.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the swap() call for the comparison or hash functors
- //! found using ADL throw. Basic guarantee.
- void swap(unordered_set_impl& other)
- { table_type::swap(other.table_); }
-
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //! Cloner should yield to nodes that compare equal and produce the same
- //! hash than the original node.
- //!
- //! <b>Effects</b>: Erases all the elements from *this
- //! calling Disposer::operator()(pointer), clones all the
- //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this. The hash function and the equality
- //! predicate are copied from the source.
- //!
- //! If store_hash option is true, this method does not use the hash function.
- //!
- //! If any operation throws, all cloned elements are unlinked and disposed
- //! calling Disposer::operator()(pointer).
- //!
- //! <b>Complexity</b>: Linear to erased plus inserted elements.
- //!
- //! <b>Throws</b>: If cloner or hasher throw or hash or equality predicate copying
- //! throws. Basic guarantee.
+ //! @copydoc ::boost::intrusive::hashtable::hashtable
+ void swap(unordered_set_impl& other);
+
+ //! @copydoc ::boost::intrusive::hashtable::clone_from(const hashtable&,Cloner,Disposer)
template <class Cloner, class Disposer>
- void clone_from(const unordered_set_impl &src, Cloner cloner, Disposer disposer)
- { table_type::clone_from(src.table_, cloner, disposer); }
+ void clone_from(const unordered_set_impl &src, Cloner cloner, Disposer disposer);
+
+ #else
+
+ using table_type::clone_from;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! <b>Requires</b>: value must be an lvalue
- //!
- //! <b>Effects</b>: Tries to inserts value into the unordered_set.
- //!
- //! <b>Returns</b>: If the value
- //! is not already present inserts it and returns a pair containing the
- //! iterator to the new value and true. If there is an equivalent value
- //! returns a pair containing an iterator to the already present value
- //! and false.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws. Strong guarantee.
- //!
- //! <b>Note</b>: Does not affect the validity of iterators and references.
- //! No copy-constructors are called.
+ //! @copydoc ::boost::intrusive::hashtable::clone_from(hashtable&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(unordered_set_impl) src, Cloner cloner, Disposer disposer)
+ { table_type::clone_from(BOOST_MOVE_BASE(table_type, src), cloner, disposer); }
+
+ //! @copydoc ::boost::intrusive::hashtable::insert_unique(reference)
std::pair<iterator, bool> insert(reference value)
{ return table_type::insert_unique(value); }
- //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
- //! of type value_type.
- //!
- //! <b>Effects</b>: Equivalent to this->insert(t) for each element in [b, e).
- //!
- //! <b>Complexity</b>: Average case O(N), where N is distance(b, e).
- //! Worst case O(N*this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
- //!
- //! <b>Note</b>: Does not affect the validity of iterators and references.
- //! No copy-constructors are called.
+ //! @copydoc ::boost::intrusive::hashtable::insert_unique(Iterator,Iterator)
template<class Iterator>
void insert(Iterator b, Iterator e)
{ table_type::insert_unique(b, e); }
- //! <b>Requires</b>: "hasher" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hasher" hashes the given key instead of the value_type.
- //!
- //! "key_value_equal" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "key_value_equal" compares an arbitrary key with the contained values.
- //!
- //! <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_value_equal 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.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
+ //! @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
- (const KeyType &key, KeyHasher hasher, KeyValueEqual key_value_equal, insert_commit_data &commit_data)
+ (const KeyType &key, KeyHasher hasher, KeyEqual key_value_equal, insert_commit_data &commit_data)
{ return table_type::insert_unique_check(key, hasher, key_value_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
- //! the "insert_check" that filled "commit_data" and the call to "insert_commit".
- //!
- //! <b>Effects</b>: Inserts the value in the unordered_set using the information obtained
- //! from the "commit_data" that a previous "insert_check" filled.
- //!
- //! <b>Returns</b>: An iterator to the newly inserted object.
- //!
- //! <b>Complexity</b>: Constant time.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Notes</b>: This function has only sense if a "insert_check" has been
- //! previously executed to fill "commit_data". No value should be inserted or
- //! erased between the "insert_check" and "insert_commit" calls.
- //!
- //! After a successful rehashing insert_commit_data remains valid.
+ //! @copydoc ::boost::intrusive::hashtable::insert_unique_commit
iterator insert_commit(reference value, const insert_commit_data &commit_data)
{ return table_type::insert_unique_commit(value, commit_data); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! <b>Effects</b>: Erases the element pointed to by i.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased element. No destructors are called.
- void erase(const_iterator i)
- { table_type::erase(i); }
+ //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator)
+ void erase(const_iterator i);
- //! <b>Effects</b>: Erases the range pointed to by b end e.
- //!
- //! <b>Complexity</b>: Average case O(distance(b, e)),
- //! worst case O(this->size()).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
- void erase(const_iterator b, const_iterator e)
- { table_type::erase(b, e); }
+ //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator,const_iterator)
+ void erase(const_iterator b, const_iterator e);
- //! <b>Effects</b>: Erases all the elements with the given value.
- //!
- //! <b>Returns</b>: The number of erased elements.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
- size_type erase(const_reference value)
- { return table_type::erase(value); }
-
- //! <b>Requires</b>: "hasher" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hasher" hashes the given key instead of the value_type.
- //!
- //! "key_value_equal" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "key_value_equal" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Erases all the elements that have the same hash and
- //! compare equal with the given key.
- //!
- //! <b>Returns</b>: The number of erased elements.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- size_type erase(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
- { return table_type::erase(key, hash_func, equal_func); }
+ //! @copydoc ::boost::intrusive::hashtable::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases the element pointed to by i.
- //! Disposer::operator()(pointer) is called for the removed element.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators
- //! to the erased elements.
+ //! @copydoc ::boost::intrusive::hashtable::erase(const KeyType&,KeyHasher,KeyEqual)
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ size_type erase(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
+
+ //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
- void erase_and_dispose(const_iterator i, Disposer disposer
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0
- /// @endcond
- )
- { table_type::erase_and_dispose(i, disposer); }
-
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases the range pointed to by b end e.
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Complexity</b>: Average case O(distance(b, e)),
- //! worst case O(this->size()).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators
- //! to the erased elements.
+ BOOST_INTRUSIVE_DOC1ST(void
+ , typename detail::disable_if_convertible<Disposer BOOST_INTRUSIVE_I const_iterator>::type)
+ erase_and_dispose(const_iterator i, Disposer disposer);
+
+ //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,const_iterator,Disposer)
template<class Disposer>
- void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
- { table_type::erase_and_dispose(b, e, disposer); }
+ void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases all the elements with the given value.
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Returns</b>: The number of erased elements.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
+ //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const key_type &,Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer)
- { return table_type::erase_and_dispose(value, disposer); }
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases all the elements with the given key.
- //! according to the comparison functor "equal_func".
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Returns</b>: The number of erased elements.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
- //!
- //! <b>Note</b>: Invalidates the iterators
- //! to the erased elements.
- template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func, Disposer disposer)
- { return table_type::erase_and_dispose(key, hash_func, equal_func, disposer); }
+ //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const KeyType&,KeyHasher,KeyEqual,Disposer)
+ template<class KeyType, class KeyHasher, class KeyEqual, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func, Disposer disposer);
- //! <b>Effects</b>: Erases all of the elements.
- //!
- //! <b>Complexity</b>: Linear to the number of elements on the container.
- //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
- void clear()
- { return table_type::clear(); }
+ //! @copydoc ::boost::intrusive::hashtable::clear
+ void clear();
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases all of the elements.
- //!
- //! <b>Complexity</b>: Linear to the number of elements on the container.
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
+ //! @copydoc ::boost::intrusive::hashtable::clear_and_dispose
template<class Disposer>
- void clear_and_dispose(Disposer disposer)
- { return table_type::clear_and_dispose(disposer); }
+ void clear_and_dispose(Disposer disposer);
- //! <b>Effects</b>: Returns the number of contained elements with the given value
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- size_type count(const_reference value) const
- { return table_type::find(value) != end(); }
+ //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "equal_func" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "equal_func" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Returns the number of contained elements with the given key
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If hash_func or equal_func throw.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- size_type count(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
- { return table_type::find(key, hash_func, equal_func) != end(); }
+ //! @copydoc ::boost::intrusive::hashtable::count(const KeyType&,KeyHasher,KeyEqual)const
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ size_type count(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
- //! <b>Effects</b>: Finds an iterator to the first element is equal to
- //! "value" or end() if that element does not exist.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- iterator find(const_reference value)
- { return table_type::find(value); }
+ //! @copydoc ::boost::intrusive::hashtable::find(const key_type &)
+ iterator find(const key_type &key);
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "equal_func" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "equal_func" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Finds an iterator to the first element whose key is
- //! "key" according to the given hasher and equality functor or end() if
- //! that element does not exist.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If hash_func or equal_func throw.
- //!
- //! <b>Note</b>: This function is used when constructing a value_type
- //! is expensive and the value_type can be compared with a cheaper
- //! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
- { return table_type::find(key, hash_func, equal_func); }
-
- //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
- //! "key" or end() if that element does not exist.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- const_iterator find(const_reference value) const
- { return table_type::find(value); }
+ //! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "equal_func" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "equal_func" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Finds an iterator to the first element whose key is
- //! "key" according to the given hasher and equality functor or end() if
- //! that element does not exist.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If hash_func or equal_func throw.
- //!
- //! <b>Note</b>: This function is used when constructing a value_type
- //! is expensive and the value_type can be compared with a cheaper
- //! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- const_iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
- { return table_type::find(key, hash_func, equal_func); }
-
- //! <b>Effects</b>: Returns a range containing all elements with values equivalent
- //! to value. Returns std::make_pair(this->end(), this->end()) if no such
- //! elements exist.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return table_type::equal_range(value); }
+ //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "equal_func" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "equal_func" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Returns a range containing all elements with equivalent
- //! keys. Returns std::make_pair(this->end(), this->end()) if no such
- //! elements exist.
- //!
- //! <b>Complexity</b>: Average case O(this->count(key, hash_func, hash_func)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If hash_func or the equal_func throw.
- //!
- //! <b>Note</b>: This function is used when constructing a value_type
- //! is expensive and the value_type can be compared with a cheaper
- //! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- std::pair<iterator,iterator> equal_range(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
- { return table_type::equal_range(key, hash_func, equal_func); }
-
- //! <b>Effects</b>: Returns a range containing all elements with values equivalent
- //! to value. Returns std::make_pair(this->end(), this->end()) if no such
- //! elements exist.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
+ //! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)const
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ const_iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
+ #endif
+
+ //! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)
+ std::pair<iterator,iterator> equal_range(const key_type &key)
+ { return this->equal_range(key, this->hash_function(), this->key_eq()); }
+
+ //! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func)
+ { return this->priv_equal_range<iterator>(*this, key, hash_func, equal_func); }
+
+ //! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return table_type::equal_range(value); }
+ equal_range(const key_type &key) const
+ { return this->equal_range(key, this->hash_function(), this->key_eq()); }
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "equal_func" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "equal_func" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Returns a range containing all elements with equivalent
- //! keys. Returns std::make_pair(this->end(), this->end()) if no such
- //! elements exist.
- //!
- //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the hash_func or equal_func throw.
- //!
- //! <b>Note</b>: This function is used when constructing a value_type
- //! is expensive and the value_type can be compared with a cheaper
- //! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
+ //! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)const
+ template<class KeyType, class KeyHasher, class KeyEqual>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
- { return table_type::equal_range(key, hash_func, equal_func); }
+ equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const
+ { return this->priv_equal_range<const_iterator>(*this, key, hash_func, equal_func); }
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid iterator belonging to the unordered_set
- //! that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the internal hash function throws.
- iterator iterator_to(reference value)
- { return table_type::iterator_to(value); }
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ //! @copydoc ::boost::intrusive::hashtable::iterator_to(reference)
+ iterator iterator_to(reference value);
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid const_iterator belonging to the
- //! unordered_set that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the internal hash function throws.
- const_iterator iterator_to(const_reference value) const
- { return table_type::iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::iterator_to(const_reference)const
+ const_iterator iterator_to(const_reference value) const;
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
- //! that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: This static function is available only if the <i>value traits</i>
- //! is stateless.
- static local_iterator s_local_iterator_to(reference value)
- { return table_type::s_local_iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(reference)
+ static local_iterator s_local_iterator_to(reference value);
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
- //! the unordered_set that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: This static function is available only if the <i>value traits</i>
- //! is stateless.
- static const_local_iterator s_local_iterator_to(const_reference value)
- { return table_type::s_local_iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(const_reference)
+ static const_local_iterator s_local_iterator_to(const_reference value);
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
- //! that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- local_iterator local_iterator_to(reference value)
- { return table_type::local_iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(reference)
+ local_iterator local_iterator_to(reference value);
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
- //! the unordered_set that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- const_local_iterator local_iterator_to(const_reference value) const
- { return table_type::local_iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(const_reference)
+ const_local_iterator local_iterator_to(const_reference value) const;
- //! <b>Effects</b>: Returns the number of buckets passed in the constructor
- //! or the last rehash function.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- size_type bucket_count() const
- { return table_type::bucket_count(); }
+ //! @copydoc ::boost::intrusive::hashtable::bucket_count
+ size_type bucket_count() const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns the number of elements in the nth bucket.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- size_type bucket_size(size_type n) const
- { return table_type::bucket_size(n); }
+ //! @copydoc ::boost::intrusive::hashtable::bucket_size
+ size_type bucket_size(size_type n) const;
- //! <b>Effects</b>: Returns the index of the bucket in which elements
- //! with keys equivalent to k would be found, if any such element existed.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the hash functor throws.
- //!
- //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
- size_type bucket(const value_type& k) const
- { return table_type::bucket(k); }
+ //! @copydoc ::boost::intrusive::hashtable::bucket(const key_type&)const
+ size_type bucket(const key_type& k) const;
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! <b>Effects</b>: Returns the index of the bucket in which elements
- //! with keys equivalent to k would be found, if any such element existed.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If hash_func throws.
- //!
- //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
+ //! @copydoc ::boost::intrusive::hashtable::bucket(const KeyType&,KeyHasher)const
template<class KeyType, class KeyHasher>
- size_type bucket(const KeyType& k, KeyHasher hash_func) const
- { return table_type::bucket(k, hash_func); }
+ size_type bucket(const KeyType& k, KeyHasher hash_func) const;
- //! <b>Effects</b>: Returns the bucket array pointer passed in the constructor
- //! or the last rehash function.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- bucket_ptr bucket_pointer() const
- { return table_type::bucket_pointer(); }
+ //! @copydoc ::boost::intrusive::hashtable::bucket_pointer
+ bucket_ptr bucket_pointer() const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a local_iterator pointing to the beginning
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- local_iterator begin(size_type n)
- { return table_type::begin(n); }
+ //! @copydoc ::boost::intrusive::hashtable::begin(size_type)
+ local_iterator begin(size_type n);
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- const_local_iterator begin(size_type n) const
- { return table_type::begin(n); }
+ //! @copydoc ::boost::intrusive::hashtable::begin(size_type)const
+ const_local_iterator begin(size_type n) const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- const_local_iterator cbegin(size_type n) const
- { return table_type::cbegin(n); }
+ //! @copydoc ::boost::intrusive::hashtable::cbegin(size_type)const
+ const_local_iterator cbegin(size_type n) const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a local_iterator pointing to the end
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- local_iterator end(size_type n)
- { return table_type::end(n); }
+ //! @copydoc ::boost::intrusive::hashtable::end(size_type)
+ local_iterator end(size_type n);
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a const_local_iterator pointing to the end
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- const_local_iterator end(size_type n) const
- { return table_type::end(n); }
+ //! @copydoc ::boost::intrusive::hashtable::end(size_type)const
+ const_local_iterator end(size_type n) const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a const_local_iterator pointing to the end
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- const_local_iterator cend(size_type n) const
- { return table_type::cend(n); }
-
- //! <b>Requires</b>: new_buckets must be a pointer to a new bucket array
- //! or the same as the old bucket array. new_size is the length of the
- //! the array pointed by new_buckets. If new_buckets == this->bucket_pointer()
- //! n can be bigger or smaller than this->bucket_count().
- //!
- //! <b>Effects</b>: Updates the internal reference with the new bucket erases
- //! the values from the old bucket and inserts then in the new one.
- //!
- //! If store_hash option is true, this method does not use the hash function.
- //!
- //! <b>Complexity</b>: Average case linear in this->size(), worst case quadratic.
- //!
- //! <b>Throws</b>: If the hasher functor throws. Basic guarantee.
- void rehash(const bucket_traits &new_bucket_traits)
- { table_type::rehash(new_bucket_traits); }
+ //! @copydoc ::boost::intrusive::hashtable::cend(size_type)const
+ const_local_iterator cend(size_type n) const;
- //! <b>Requires</b>:
- //!
- //! <b>Effects</b>:
- //!
- //! <b>Complexity</b>:
- //!
- //! <b>Throws</b>:
- //!
- //! <b>Note</b>: this method is only available if incremental<true> option is activated.
- bool incremental_rehash(bool grow = true)
- { return table_type::incremental_rehash(grow); }
+ //! @copydoc ::boost::intrusive::hashtable::rehash(const bucket_traits &)
+ void rehash(const bucket_traits &new_bucket_traits);
- //! <b>Note</b>: this method is only available if incremental<true> option is activated.
- bool incremental_rehash(const bucket_traits &new_bucket_traits)
- { return table_type::incremental_rehash(new_bucket_traits); }
+ //! @copydoc ::boost::intrusive::hashtable::incremental_rehash(bool)
+ bool incremental_rehash(bool grow = true);
- //! <b>Requires</b>:
- //!
- //! <b>Effects</b>:
- //!
- //! <b>Complexity</b>:
- //!
- //! <b>Throws</b>:
- size_type split_count() const
- { return table_type::split_count(); }
-
- //! <b>Effects</b>: Returns the nearest new bucket count optimized for
- //! the container that is bigger than n. This suggestion can be used
- //! to create bucket arrays with a size that will usually improve
- //! container's performance. If such value does not exist, the
- //! higher possible value is returned.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- //!
- //! <b>Throws</b>: Nothing.
- static size_type suggested_upper_bucket_count(size_type n)
- { return table_type::suggested_upper_bucket_count(n); }
-
- //! <b>Effects</b>: Returns the nearest new bucket count optimized for
- //! the container that is smaller than n. This suggestion can be used
- //! to create bucket arrays with a size that will usually improve
- //! container's performance. If such value does not exist, the
- //! lower possible value is returned.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- //!
- //! <b>Throws</b>: Nothing.
- static size_type suggested_lower_bucket_count(size_type n)
- { return table_type::suggested_lower_bucket_count(n); }
+ //! @copydoc ::boost::intrusive::hashtable::incremental_rehash(const bucket_traits &)
+ bool incremental_rehash(const bucket_traits &new_bucket_traits);
+
+ //! @copydoc ::boost::intrusive::hashtable::split_count
+ size_type split_count() const;
+
+ //! @copydoc ::boost::intrusive::hashtable::suggested_upper_bucket_count
+ static size_type suggested_upper_bucket_count(size_type n);
+
+ //! @copydoc ::boost::intrusive::hashtable::suggested_lower_bucket_count
+ static size_type suggested_lower_bucket_count(size_type n);
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+ friend bool operator==(const unordered_set_impl &x, const unordered_set_impl &y)
+ {
+ if(table_type::constant_time_size && x.size() != y.size()){
+ return false;
+ }
+ //Find each element of x in y
+ for (const_iterator ix = x.cbegin(), ex = x.cend(), ey = y.cend(); ix != ex; ++ix){
+ const_iterator iy = y.find(key_of_value()(*ix));
+ if (iy == ey || !(*ix == *iy))
+ return false;
+ }
+ return true;
+ }
+
+ friend bool operator!=(const unordered_set_impl &x, const unordered_set_impl &y)
+ { return !(x == y); }
+
+ friend bool operator<(const unordered_set_impl &x, const unordered_set_impl &y)
+ { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+
+ friend bool operator>(const unordered_set_impl &x, const unordered_set_impl &y)
+ { return y < x; }
+
+ friend bool operator<=(const unordered_set_impl &x, const unordered_set_impl &y)
+ { return !(y < x); }
+
+ friend bool operator>=(const unordered_set_impl &x, const unordered_set_impl &y)
+ { return !(x < y); }
};
//! Helper metafunction to define an \c unordered_set that yields to the same type when the
@@ -1037,6 +435,7 @@ struct make_unordered_set
typedef unordered_set_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::hash
, typename packed_options::equal
, typename packed_options::size_type
@@ -1115,6 +514,14 @@ class unordered_set
unordered_set& operator=(BOOST_RV_REF(unordered_set) x)
{ return static_cast<unordered_set&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(const unordered_set &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(unordered_set) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
};
#endif
@@ -1158,14 +565,14 @@ class unordered_set
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template<class T, class ...Options>
#else
-template<class ValueTraits, class Hash, class Equal, class SizeType, class BucketTraits, std::size_t BoolFlags>
+template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class SizeType, class BucketTraits, std::size_t BoolFlags>
#endif
class unordered_multiset_impl
- : public hashtable_impl<ValueTraits, Hash, Equal, SizeType, BucketTraits, BoolFlags>
+ : public hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags>
{
/// @cond
private:
- typedef hashtable_impl<ValueTraits, Hash, Equal, SizeType, BucketTraits, BoolFlags> table_type;
+ typedef hashtable_impl<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags> table_type;
/// @endcond
//Movable
@@ -1175,6 +582,7 @@ class unordered_multiset_impl
public:
typedef typename implementation_defined::value_type value_type;
+ typedef typename implementation_defined::key_type key_type;
typedef typename implementation_defined::value_traits value_traits;
typedef typename implementation_defined::bucket_traits bucket_traits;
typedef typename implementation_defined::pointer pointer;
@@ -1183,7 +591,6 @@ class unordered_multiset_impl
typedef typename implementation_defined::const_reference const_reference;
typedef typename implementation_defined::difference_type difference_type;
typedef typename implementation_defined::size_type size_type;
- typedef typename implementation_defined::key_type key_type;
typedef typename implementation_defined::key_equal key_equal;
typedef typename implementation_defined::hasher hasher;
typedef typename implementation_defined::bucket_type bucket_type;
@@ -1201,19 +608,7 @@ class unordered_multiset_impl
public:
- //! <b>Requires</b>: buckets must not be being used by any other resource.
- //!
- //! <b>Effects</b>: Constructs an empty unordered_multiset, storing a reference
- //! to the bucket array and copies of the hasher and equal functors.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If value_traits::node_traits::node
- //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor or invocation of Hash or Equal throws.
- //!
- //! <b>Notes</b>: buckets array must be disposed only after
- //! *this is disposed.
+ //! @copydoc ::boost::intrusive::hashtable::hashtable(const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
explicit unordered_multiset_impl ( const bucket_traits &b_traits
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
@@ -1221,21 +616,7 @@ class unordered_multiset_impl
: table_type(b_traits, hash_func, equal_func, v_traits)
{}
- //! <b>Requires</b>: buckets must not be being used by any other resource
- //! and Dereferencing iterator must yield an lvalue of type value_type.
- //!
- //! <b>Effects</b>: Constructs an empty unordered_multiset and inserts elements from
- //! [b, e).
- //!
- //! <b>Complexity</b>: If N is distance(b, e): Average case is O(N)
- //! (with a good hash function and with buckets_len >= N),worst case O(N2).
- //!
- //! <b>Throws</b>: If value_traits::node_traits::node
- //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
- //! or the copy constructor or invocation of hasher or key_equal throws.
- //!
- //! <b>Notes</b>: buckets array must be disposed only after
- //! *this is disposed.
+ //! @copydoc ::boost::intrusive::hashtable::hashtable(bool,Iterator,Iterator,const bucket_traits &,const hasher &,const key_equal &,const value_traits &)
template<class Iterator>
unordered_multiset_impl ( Iterator b
, Iterator e
@@ -1243,8 +624,8 @@ class unordered_multiset_impl
, const hasher & hash_func = hasher()
, const key_equal &equal_func = key_equal()
, const value_traits &v_traits = value_traits())
- : table_type(b_traits, hash_func, equal_func, v_traits)
- { table_type::insert_equal(b, e); }
+ : table_type(false, b, e, b_traits, hash_func, equal_func, v_traits)
+ {}
//! <b>Effects</b>: to-do
//!
@@ -1259,785 +640,212 @@ class unordered_multiset_impl
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! <b>Effects</b>: Detaches all elements from this. The objects in the unordered_multiset
- //! are not deleted (i.e. no destructors are called).
- //!
- //! <b>Complexity</b>: Linear to the number of elements in the unordered_multiset, if
- //! it's a safe-mode or auto-unlink value. Otherwise constant.
- //!
- //! <b>Throws</b>: Nothing.
- ~unordered_multiset_impl()
- {}
+ //! @copydoc ::boost::intrusive::hashtable::~hashtable()
+ ~unordered_multiset_impl();
- //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_multiset.
- //!
- //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
- //! constant time with worst case (empty unordered_set) O(this->bucket_count())
- //!
- //! <b>Throws</b>: Nothing.
- iterator begin()
- { return table_type::begin(); }
+ //! @copydoc ::boost::intrusive::hashtable::begin()
+ iterator begin();
- //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
- //! of the unordered_multiset.
- //!
- //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
- //! constant time with worst case (empty unordered_set) O(this->bucket_count())
- //!
- //! <b>Throws</b>: Nothing.
- const_iterator begin() const
- { return table_type::begin(); }
+ //! @copydoc ::boost::intrusive::hashtable::begin()const
+ const_iterator begin() const;
- //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
- //! of the unordered_multiset.
- //!
- //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
- //! constant time with worst case (empty unordered_set) O(this->bucket_count())
- //!
- //! <b>Throws</b>: Nothing.
- const_iterator cbegin() const
- { return table_type::cbegin(); }
+ //! @copydoc ::boost::intrusive::hashtable::cbegin()const
+ const_iterator cbegin() const;
- //! <b>Effects</b>: Returns an iterator pointing to the end of the unordered_multiset.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- iterator end()
- { return table_type::end(); }
+ //! @copydoc ::boost::intrusive::hashtable::end()
+ iterator end();
- //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_multiset.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- const_iterator end() const
- { return table_type::end(); }
+ //! @copydoc ::boost::intrusive::hashtable::end()const
+ const_iterator end() const;
- //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_multiset.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- const_iterator cend() const
- { return table_type::cend(); }
+ //! @copydoc ::boost::intrusive::hashtable::cend()const
+ const_iterator cend() const;
- //! <b>Effects</b>: Returns the hasher object used by the unordered_set.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If hasher copy-constructor throws.
- hasher hash_function() const
- { return table_type::hash_function(); }
+ //! @copydoc ::boost::intrusive::hashtable::hash_function()const
+ hasher hash_function() const;
- //! <b>Effects</b>: Returns the key_equal object used by the unordered_multiset.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If key_equal copy-constructor throws.
- key_equal key_eq() const
- { return table_type::key_eq(); }
+ //! @copydoc ::boost::intrusive::hashtable::key_eq()const
+ key_equal key_eq() const;
- //! <b>Effects</b>: Returns true if the container is empty.
- //!
- //! <b>Complexity</b>: if constant-time size and cache_last options are disabled,
- //! average constant time (worst case, with empty() == true: O(this->bucket_count()).
- //! Otherwise constant.
- //!
- //! <b>Throws</b>: Nothing.
- bool empty() const
- { return table_type::empty(); }
+ //! @copydoc ::boost::intrusive::hashtable::empty()const
+ bool empty() const;
- //! <b>Effects</b>: Returns the number of elements stored in the unordered_multiset.
- //!
- //! <b>Complexity</b>: Linear to elements contained in *this if
- //! constant-time size option is disabled. Constant-time otherwise.
- //!
- //! <b>Throws</b>: Nothing.
- size_type size() const
- { return table_type::size(); }
+ //! @copydoc ::boost::intrusive::hashtable::size()const
+ size_type size() const;
- //! <b>Requires</b>: the hasher and the equality function unqualified swap
- //! call should not throw.
- //!
- //! <b>Effects</b>: Swaps the contents of two unordered_multisets.
- //! Swaps also the contained bucket array and equality and hasher functors.
- //!
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the swap() call for the comparison or hash functors
- //! found using ADL throw. Basic guarantee.
- void swap(unordered_multiset_impl& other)
- { table_type::swap(other.table_); }
-
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //! Cloner should yield to nodes that compare equal and produce the same
- //! hash than the original node.
- //!
- //! <b>Effects</b>: Erases all the elements from *this
- //! calling Disposer::operator()(pointer), clones all the
- //! elements from src calling Cloner::operator()(const_reference )
- //! and inserts them on *this. The hash function and the equality
- //! predicate are copied from the source.
- //!
- //! If store_hash option is true, this method does not use the hash function.
- //!
- //! If any operation throws, all cloned elements are unlinked and disposed
- //! calling Disposer::operator()(pointer).
- //!
- //! <b>Complexity</b>: Linear to erased plus inserted elements.
- //!
- //! <b>Throws</b>: If cloner or hasher throw or hash or equality predicate copying
- //! throws. Basic guarantee.
+ //! @copydoc ::boost::intrusive::hashtable::hashtable
+ void swap(unordered_multiset_impl& other);
+
+ //! @copydoc ::boost::intrusive::hashtable::clone_from(const hashtable&,Cloner,Disposer)
template <class Cloner, class Disposer>
- void clone_from(const unordered_multiset_impl &src, Cloner cloner, Disposer disposer)
- { table_type::clone_from(src.table_, cloner, disposer); }
+ void clone_from(const unordered_multiset_impl &src, Cloner cloner, Disposer disposer);
+
+ #else
+
+ using table_type::clone_from;
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! <b>Requires</b>: value must be an lvalue
- //!
- //! <b>Effects</b>: Inserts value into the unordered_multiset.
- //!
- //! <b>Returns</b>: An iterator to the new inserted value.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws. Strong guarantee.
- //!
- //! <b>Note</b>: Does not affect the validity of iterators and references.
- //! No copy-constructors are called.
+ //! @copydoc ::boost::intrusive::hashtable::clone_from(hashtable&&,Cloner,Disposer)
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(unordered_multiset_impl) src, Cloner cloner, Disposer disposer)
+ { table_type::clone_from(BOOST_MOVE_BASE(table_type, src), cloner, disposer); }
+
+ //! @copydoc ::boost::intrusive::hashtable::insert_equal(reference)
iterator insert(reference value)
{ return table_type::insert_equal(value); }
- //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
- //! of type value_type.
- //!
- //! <b>Effects</b>: Equivalent to this->insert(t) for each element in [b, e).
- //!
- //! <b>Complexity</b>: Average case is O(N), where N is the
- //! size of the range.
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
- //!
- //! <b>Note</b>: Does not affect the validity of iterators and references.
- //! No copy-constructors are called.
+ //! @copydoc ::boost::intrusive::hashtable::insert_equal(Iterator,Iterator)
template<class Iterator>
void insert(Iterator b, Iterator e)
{ table_type::insert_equal(b, e); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
- //! <b>Effects</b>: Erases the element pointed to by i.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased element. No destructors are called.
- void erase(const_iterator i)
- { table_type::erase(i); }
+ //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator)
+ void erase(const_iterator i);
- //! <b>Effects</b>: Erases the range pointed to by b end e.
- //!
- //! <b>Complexity</b>: Average case O(distance(b, e)),
- //! worst case O(this->size()).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
- void erase(const_iterator b, const_iterator e)
- { table_type::erase(b, e); }
+ //! @copydoc ::boost::intrusive::hashtable::erase(const_iterator,const_iterator)
+ void erase(const_iterator b, const_iterator e);
- //! <b>Effects</b>: Erases all the elements with the given value.
- //!
- //! <b>Returns</b>: The number of erased elements.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
- size_type erase(const_reference value)
- { return table_type::erase(value); }
-
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "key_value_equal" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "key_value_equal" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Erases all the elements that have the same hash and
- //! compare equal with the given key.
- //!
- //! <b>Returns</b>: The number of erased elements.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the hash_func or the equal_func functors throws.
- //! Basic guarantee.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- size_type erase(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
- { return table_type::erase(key, hash_func, equal_func); }
+ //! @copydoc ::boost::intrusive::hashtable::erase(const key_type &)
+ size_type erase(const key_type &key);
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases the element pointed to by i.
- //! Disposer::operator()(pointer) is called for the removed element.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators
- //! to the erased elements.
- template<class Disposer>
- void erase_and_dispose(const_iterator i, Disposer disposer
- /// @cond
- , typename detail::enable_if_c<!detail::is_convertible<Disposer, const_iterator>::value >::type * = 0
- /// @endcond
- )
- { table_type::erase_and_dispose(i, disposer); }
-
- #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ //! @copydoc ::boost::intrusive::hashtable::erase(const KeyType&,KeyHasher,KeyEqual)
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ size_type erase(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
+
+ //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,Disposer)
template<class Disposer>
- void erase_and_dispose(const_iterator i, Disposer disposer)
- { this->erase_and_dispose(const_iterator(i), disposer); }
- #endif
+ BOOST_INTRUSIVE_DOC1ST(void
+ , typename detail::disable_if_convertible<Disposer BOOST_INTRUSIVE_I const_iterator>::type)
+ erase_and_dispose(const_iterator i, Disposer disposer);
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases the range pointed to by b end e.
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Complexity</b>: Average case O(distance(b, e)),
- //! worst case O(this->size()).
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators
- //! to the erased elements.
+ //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const_iterator,const_iterator,Disposer)
template<class Disposer>
- void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
- { table_type::erase_and_dispose(b, e, disposer); }
+ void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases all the elements with the given value.
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Returns</b>: The number of erased elements.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws. Basic guarantee.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
+ //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const key_type &,Disposer)
template<class Disposer>
- size_type erase_and_dispose(const_reference value, Disposer disposer)
- { return table_type::erase_and_dispose(value, disposer); }
+ size_type erase_and_dispose(const key_type &key, Disposer disposer);
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases all the elements with the given key.
- //! according to the comparison functor "equal_func".
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Returns</b>: The number of erased elements.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If hash_func or equal_func throw. Basic guarantee.
- //!
- //! <b>Note</b>: Invalidates the iterators
- //! to the erased elements.
- template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
- size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func, Disposer disposer)
- { return table_type::erase_and_dispose(key, hash_func, equal_func, disposer); }
+ //! @copydoc ::boost::intrusive::hashtable::erase_and_dispose(const KeyType&,KeyHasher,KeyEqual,Disposer)
+ template<class KeyType, class KeyHasher, class KeyEqual, class Disposer>
+ size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func, Disposer disposer);
- //! <b>Effects</b>: Erases all the elements of the container.
- //!
- //! <b>Complexity</b>: Linear to the number of elements on the container.
- //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
- void clear()
- { return table_type::clear(); }
+ //! @copydoc ::boost::intrusive::hashtable::clear
+ void clear();
- //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
- //!
- //! <b>Effects</b>: Erases all the elements of the container.
- //!
- //! <b>Complexity</b>: Linear to the number of elements on the container.
- //! Disposer::operator()(pointer) is called for the removed elements.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: Invalidates the iterators (but not the references)
- //! to the erased elements. No destructors are called.
+ //! @copydoc ::boost::intrusive::hashtable::clear_and_dispose
template<class Disposer>
- void clear_and_dispose(Disposer disposer)
- { return table_type::clear_and_dispose(disposer); }
+ void clear_and_dispose(Disposer disposer);
- //! <b>Effects</b>: Returns the number of contained elements with the given key
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- size_type count(const_reference value) const
- { return table_type::count(value); }
+ //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
+ size_type count(const key_type &key) const;
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "key_value_equal" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "key_value_equal" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Returns the number of contained elements with the given key
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- size_type count(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
- { return table_type::count(key, hash_func, equal_func); }
+ //! @copydoc ::boost::intrusive::hashtable::count(const KeyType&,KeyHasher,KeyEqual)const
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ size_type count(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
- //! <b>Effects</b>: Finds an iterator to the first element whose value is
- //! "value" or end() if that element does not exist.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- iterator find(const_reference value)
- { return table_type::find(value); }
+ //! @copydoc ::boost::intrusive::hashtable::find(const key_type &)
+ iterator find(const key_type &key);
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "key_value_equal" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "key_value_equal" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Finds an iterator to the first element whose key is
- //! "key" according to the given hasher and equality functor or end() if
- //! that element does not exist.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- //!
- //! <b>Note</b>: This function is used when constructing a value_type
- //! is expensive and the value_type can be compared with a cheaper
- //! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
- { return table_type::find(key, hash_func, equal_func); }
-
- //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
- //! "key" or end() if that element does not exist.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- const_iterator find(const_reference value) const
- { return table_type::find(value); }
+ //! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "key_value_equal" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "key_value_equal" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Finds an iterator to the first element whose key is
- //! "key" according to the given hasher and equality functor or end() if
- //! that element does not exist.
- //!
- //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- //!
- //! <b>Note</b>: This function is used when constructing a value_type
- //! is expensive and the value_type can be compared with a cheaper
- //! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- const_iterator find(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
- { return table_type::find(key, hash_func, equal_func); }
-
- //! <b>Effects</b>: Returns a range containing all elements with values equivalent
- //! to value. Returns std::make_pair(this->end(), this->end()) if no such
- //! elements exist.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- std::pair<iterator,iterator> equal_range(const_reference value)
- { return table_type::equal_range(value); }
+ //! @copydoc ::boost::intrusive::hashtable::count(const key_type &)const
+ const_iterator find(const key_type &key) const;
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "key_value_equal" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "key_value_equal" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Returns a range containing all elements with equivalent
- //! keys. Returns std::make_pair(this->end(), this->end()) if no such
- //! elements exist.
- //!
- //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- //!
- //! <b>Note</b>: This function is used when constructing a value_type
- //! is expensive and the value_type can be compared with a cheaper
- //! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
- std::pair<iterator,iterator> equal_range
- (const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func)
- { return table_type::equal_range(key, hash_func, equal_func); }
-
- //! <b>Effects</b>: Returns a range containing all elements with values equivalent
- //! to value. Returns std::make_pair(this->end(), this->end()) if no such
- //! elements exist.
- //!
- //! <b>Complexity</b>: Average case O(this->count(value)). Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
+ //! @copydoc ::boost::intrusive::hashtable::find(const KeyType &,KeyHasher,KeyEqual)const
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ const_iterator find(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
+
+ //! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)
+ std::pair<iterator,iterator> equal_range(const key_type &key);
+
+ //! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)
+ template<class KeyType, class KeyHasher, class KeyEqual>
+ std::pair<iterator,iterator> equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func);
+
+ //! @copydoc ::boost::intrusive::hashtable::equal_range(const key_type&)const
std::pair<const_iterator, const_iterator>
- equal_range(const_reference value) const
- { return table_type::equal_range(value); }
+ equal_range(const key_type &key) const;
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! "key_value_equal" must be a equality function that induces
- //! the same equality as key_equal. The difference is that
- //! "key_value_equal" compares an arbitrary key with the contained values.
- //!
- //! <b>Effects</b>: Returns a range containing all elements with equivalent
- //! keys. Returns std::make_pair(this->end(), this->end()) if no such
- //! elements exist.
- //!
- //! <b>Complexity</b>: Average case O(this->count(key, hash_func, equal_func)).
- //! Worst case O(this->size()).
- //!
- //! <b>Throws</b>: If the internal hasher or the equality functor throws.
- //!
- //! <b>Note</b>: This function is used when constructing a value_type
- //! is expensive and the value_type can be compared with a cheaper
- //! key type. Usually this key is part of the value_type.
- template<class KeyType, class KeyHasher, class KeyValueEqual>
+ //! @copydoc ::boost::intrusive::hashtable::equal_range(const KeyType &,KeyHasher,KeyEqual)const
+ template<class KeyType, class KeyHasher, class KeyEqual>
std::pair<const_iterator, const_iterator>
- equal_range(const KeyType& key, KeyHasher hash_func, KeyValueEqual equal_func) const
- { return table_type::equal_range(key, hash_func, equal_func); }
+ equal_range(const KeyType& key, KeyHasher hash_func, KeyEqual equal_func) const;
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_multiset of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid iterator belonging to the unordered_multiset
- //! that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the hash function throws.
- iterator iterator_to(reference value)
- { return table_type::iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::iterator_to(reference)
+ iterator iterator_to(reference value);
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_multiset of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid const_iterator belonging to the
- //! unordered_multiset that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the hash function throws.
- const_iterator iterator_to(const_reference value) const
- { return table_type::iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::iterator_to(const_reference)const
+ const_iterator iterator_to(const_reference value) const;
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
- //! that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: This static function is available only if the <i>value traits</i>
- //! is stateless.
- static local_iterator s_local_iterator_to(reference value)
- { return table_type::s_local_iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(reference)
+ static local_iterator s_local_iterator_to(reference value);
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
- //! the unordered_set that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: This static function is available only if the <i>value traits</i>
- //! is stateless.
- static const_local_iterator s_local_iterator_to(const_reference value)
- { return table_type::s_local_iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::s_local_iterator_to(const_reference)
+ static const_local_iterator s_local_iterator_to(const_reference value);
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid local_iterator belonging to the unordered_set
- //! that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- local_iterator local_iterator_to(reference value)
- { return table_type::local_iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(reference)
+ local_iterator local_iterator_to(reference value);
- //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
- //! appropriate type. Otherwise the behavior is undefined.
- //!
- //! <b>Effects</b>: Returns: a valid const_local_iterator belonging to
- //! the unordered_set that points to the value
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- const_local_iterator local_iterator_to(const_reference value) const
- { return table_type::local_iterator_to(value); }
+ //! @copydoc ::boost::intrusive::hashtable::local_iterator_to(const_reference)
+ const_local_iterator local_iterator_to(const_reference value) const;
- //! <b>Effects</b>: Returns the number of buckets passed in the constructor
- //! or the last rehash function.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- size_type bucket_count() const
- { return table_type::bucket_count(); }
+ //! @copydoc ::boost::intrusive::hashtable::bucket_count
+ size_type bucket_count() const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns the number of elements in the nth bucket.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- size_type bucket_size(size_type n) const
- { return table_type::bucket_size(n); }
+ //! @copydoc ::boost::intrusive::hashtable::bucket_size
+ size_type bucket_size(size_type n) const;
- //! <b>Effects</b>: Returns the index of the bucket in which elements
- //! with keys equivalent to k would be found, if any such element existed.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the hash functor throws.
- //!
- //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
- size_type bucket(const value_type& k) const
- { return table_type::bucket(k); }
+ //! @copydoc ::boost::intrusive::hashtable::bucket(const key_type&)const
+ size_type bucket(const key_type& k) const;
- //! <b>Requires</b>: "hash_func" must be a hash function that induces
- //! the same hash values as the stored hasher. The difference is that
- //! "hash_func" hashes the given key instead of the value_type.
- //!
- //! <b>Effects</b>: Returns the index of the bucket in which elements
- //! with keys equivalent to k would be found, if any such element existed.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: If the hash functor throws.
- //!
- //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
+ //! @copydoc ::boost::intrusive::hashtable::bucket(const KeyType&,KeyHasher)const
template<class KeyType, class KeyHasher>
- size_type bucket(const KeyType& k, const KeyHasher &hash_func) const
- { return table_type::bucket(k, hash_func); }
+ size_type bucket(const KeyType& k, KeyHasher hash_func) const;
- //! <b>Effects</b>: Returns the bucket array pointer passed in the constructor
- //! or the last rehash function.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- bucket_ptr bucket_pointer() const
- { return table_type::bucket_pointer(); }
+ //! @copydoc ::boost::intrusive::hashtable::bucket_pointer
+ bucket_ptr bucket_pointer() const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a local_iterator pointing to the beginning
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- local_iterator begin(size_type n)
- { return table_type::begin(n); }
+ //! @copydoc ::boost::intrusive::hashtable::begin(size_type)
+ local_iterator begin(size_type n);
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- const_local_iterator begin(size_type n) const
- { return table_type::begin(n); }
+ //! @copydoc ::boost::intrusive::hashtable::begin(size_type)const
+ const_local_iterator begin(size_type n) const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a const_local_iterator pointing to the beginning
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- const_local_iterator cbegin(size_type n) const
- { return table_type::cbegin(n); }
+ //! @copydoc ::boost::intrusive::hashtable::cbegin(size_type)const
+ const_local_iterator cbegin(size_type n) const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a local_iterator pointing to the end
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- local_iterator end(size_type n)
- { return table_type::end(n); }
+ //! @copydoc ::boost::intrusive::hashtable::end(size_type)
+ local_iterator end(size_type n);
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a const_local_iterator pointing to the end
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- const_local_iterator end(size_type n) const
- { return table_type::end(n); }
+ //! @copydoc ::boost::intrusive::hashtable::end(size_type)const
+ const_local_iterator end(size_type n) const;
- //! <b>Requires</b>: n is in the range [0, this->bucket_count()).
- //!
- //! <b>Effects</b>: Returns a const_local_iterator pointing to the end
- //! of the sequence stored in the bucket n.
- //!
- //! <b>Complexity</b>: Constant.
- //!
- //! <b>Throws</b>: Nothing.
- //!
- //! <b>Note</b>: [this->begin(n), this->end(n)) is a valid range
- //! containing all of the elements in the nth bucket.
- const_local_iterator cend(size_type n) const
- { return table_type::cend(n); }
-
- //! <b>Requires</b>: new_buckets must be a pointer to a new bucket array
- //! or the same as the old bucket array. new_size is the length of the
- //! the array pointed by new_buckets. If new_buckets == this->bucket_pointer()
- //! n can be bigger or smaller than this->bucket_count().
- //!
- //! <b>Effects</b>: Updates the internal reference with the new bucket erases
- //! the values from the old bucket and inserts then in the new one.
- //!
- //! If store_hash option is true, this method does not use the hash function.
- //!
- //! <b>Complexity</b>: Average case linear in this->size(), worst case quadratic.
- //!
- //! <b>Throws</b>: If the hasher functor throws.
- void rehash(const bucket_traits &new_bucket_traits)
- { table_type::rehash(new_bucket_traits); }
+ //! @copydoc ::boost::intrusive::hashtable::cend(size_type)const
+ const_local_iterator cend(size_type n) const;
- //! <b>Requires</b>:
- //!
- //! <b>Effects</b>:
- //!
- //! <b>Complexity</b>:
- //!
- //! <b>Throws</b>:
- //!
- //! <b>Note</b>: this method is only available if incremental<true> option is activated.
- bool incremental_rehash(bool grow = true)
- { return table_type::incremental_rehash(grow); }
+ //! @copydoc ::boost::intrusive::hashtable::rehash(const bucket_traits &)
+ void rehash(const bucket_traits &new_bucket_traits);
- //! <b>Note</b>: this method is only available if incremental<true> option is activated.
- bool incremental_rehash(const bucket_traits &new_bucket_traits)
- { return table_type::incremental_rehash(new_bucket_traits); }
+ //! @copydoc ::boost::intrusive::hashtable::incremental_rehash(bool)
+ bool incremental_rehash(bool grow = true);
- //! <b>Requires</b>:
- //!
- //! <b>Effects</b>:
- //!
- //! <b>Complexity</b>:
- //!
- //! <b>Throws</b>:
- size_type split_count() const
- { return table_type::split_count(); }
-
- //! <b>Effects</b>: Returns the nearest new bucket count optimized for
- //! the container that is bigger than n. This suggestion can be used
- //! to create bucket arrays with a size that will usually improve
- //! container's performance. If such value does not exist, the
- //! higher possible value is returned.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- //!
- //! <b>Throws</b>: Nothing.
- static size_type suggested_upper_bucket_count(size_type n)
- { return table_type::suggested_upper_bucket_count(n); }
-
- //! <b>Effects</b>: Returns the nearest new bucket count optimized for
- //! the container that is smaller than n. This suggestion can be used
- //! to create bucket arrays with a size that will usually improve
- //! container's performance. If such value does not exist, the
- //! lower possible value is returned.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- //!
- //! <b>Throws</b>: Nothing.
- static size_type suggested_lower_bucket_count(size_type n)
- { return table_type::suggested_lower_bucket_count(n); }
+ //! @copydoc ::boost::intrusive::hashtable::incremental_rehash(const bucket_traits &)
+ bool incremental_rehash(const bucket_traits &new_bucket_traits);
+
+ //! @copydoc ::boost::intrusive::hashtable::split_count
+ size_type split_count() const;
+
+ //! @copydoc ::boost::intrusive::hashtable::suggested_upper_bucket_count
+ static size_type suggested_upper_bucket_count(size_type n);
+
+ //! @copydoc ::boost::intrusive::hashtable::suggested_lower_bucket_count
+ static size_type suggested_lower_bucket_count(size_type n);
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
};
@@ -2074,6 +882,7 @@ struct make_unordered_multiset
typedef unordered_multiset_impl
< value_traits
+ , typename packed_options::key_of_value
, typename packed_options::hash
, typename packed_options::equal
, typename packed_options::size_type
@@ -2151,6 +960,14 @@ class unordered_multiset
unordered_multiset& operator=(BOOST_RV_REF(unordered_multiset) x)
{ return static_cast<unordered_multiset&>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(const unordered_multiset &src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(src, cloner, disposer); }
+
+ template <class Cloner, class Disposer>
+ void clone_from(BOOST_RV_REF(unordered_multiset) src, Cloner cloner, Disposer disposer)
+ { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
};
#endif