diff --git a/doc/intrusive.qbk b/doc/intrusive.qbk index f1675a9..b745e50 100644 --- a/doc/intrusive.qbk +++ b/doc/intrusive.qbk @@ -3885,6 +3885,7 @@ to be inserted in intrusive containers are allocated using `std::vector` or `std * Fixed bugs: * [@https://github.com/boostorg/intrusive/pull/33 GitHub Pull #33: ['Fix compilation in case if key is void*, again]] + * [@https://github.com/boostorg/intrusive/issues/35 GitHub Issue #35: ['key_of_value on treap_set seems to be broken in 1.69]] [endsect] diff --git a/include/boost/intrusive/detail/hashtable_node.hpp b/include/boost/intrusive/detail/hashtable_node.hpp index d3b11d1..45e17f3 100644 --- a/include/boost/intrusive/detail/hashtable_node.hpp +++ b/include/boost/intrusive/detail/hashtable_node.hpp @@ -34,7 +34,6 @@ namespace boost { namespace intrusive { -namespace detail { template struct bucket_impl : public Slist @@ -149,8 +148,6 @@ struct get_slist_impl {}; }; -} //namespace detail { - template class hashtable_iterator { @@ -169,12 +166,12 @@ class hashtable_iterator 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 + typedef typename get_slist_impl + < typename reduced_slist_node_traits ::type >::type slist_impl; typedef typename slist_impl::iterator siterator; typedef typename slist_impl::const_iterator const_siterator; - typedef detail::bucket_impl bucket_type; + typedef bucket_impl bucket_type; typedef typename pointer_traits ::template rebind_pointer diff --git a/include/boost/intrusive/hashtable.hpp b/include/boost/intrusive/hashtable.hpp index 36835a9..1fada98 100644 --- a/include/boost/intrusive/hashtable.hpp +++ b/include/boost/intrusive/hashtable.hpp @@ -292,7 +292,7 @@ struct unordered_bucket_impl typedef typename get_slist_impl_from_supposed_value_traits ::type slist_impl; - typedef detail::bucket_impl implementation_defined; + typedef bucket_impl implementation_defined; typedef implementation_defined type; }; @@ -569,7 +569,7 @@ struct unordered_default_bucket_traits typedef typename detail:: get_slist_impl_from_supposed_value_traits ::type slist_impl; - typedef detail::bucket_traits_impl + typedef bucket_traits_impl implementation_defined; typedef implementation_defined type; }; @@ -604,10 +604,10 @@ struct downcast_node_to_value_t : public detail::node_to_value { typedef detail::node_to_value base_t; - typedef typename base_t::result_type result_type; + typedef typename base_t::result_type result_type; typedef ValueTraits value_traits; - typedef typename detail::get_slist_impl - ::type >::type slist_impl; typedef typename detail::add_const_if_c @@ -669,7 +669,7 @@ struct bucket_plus_vtraits typedef typename value_traits::node_traits node_traits; typedef unordered_group_adapter group_traits; typedef typename slist_impl::iterator siterator; - typedef detail::bucket_impl bucket_type; + typedef bucket_impl bucket_type; typedef detail::group_functions group_functions_t; typedef typename slist_impl::node_algorithms node_algorithms; typedef typename slist_impl::node_ptr slist_node_ptr; @@ -1135,7 +1135,7 @@ struct bucket_hash_equal_t typedef BucketTraits bucket_traits; typedef typename bucket_plus_vtraits_t::slist_impl slist_impl; typedef typename slist_impl::iterator siterator; - typedef detail::bucket_impl bucket_type; + typedef bucket_impl bucket_type; typedef typename detail::unordered_bucket_ptr_impl::type bucket_ptr; template @@ -1386,8 +1386,8 @@ struct hashdata_internal typedef typename node_traits::node_ptr node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr; typedef detail::node_functions node_functions_t; - typedef typename detail::get_slist_impl - ::type >::type slist_impl; typedef typename slist_impl::node_algorithms node_algorithms; @@ -1697,7 +1697,7 @@ class hashtable_impl typedef SizeType size_type; typedef typename internal_type::key_equal key_equal; typedef typename internal_type::hasher hasher; - typedef detail::bucket_impl bucket_type; + typedef bucket_impl bucket_type; typedef typename internal_type::bucket_ptr bucket_ptr; typedef typename slist_impl::iterator siterator; typedef typename slist_impl::const_iterator const_siterator; @@ -3528,8 +3528,8 @@ struct make_bucket_traits typedef typename PackedOptions::bucket_traits specified_bucket_traits; //Real bucket traits must be calculated from options and calculated value_traits - typedef typename detail::get_slist_impl - ::type >::type slist_impl; @@ -3538,7 +3538,7 @@ struct make_bucket_traits < specified_bucket_traits , default_bucket_traits >::value - , detail::bucket_traits_impl + , bucket_traits_impl , specified_bucket_traits >::type type; }; diff --git a/include/boost/intrusive/intrusive_fwd.hpp b/include/boost/intrusive/intrusive_fwd.hpp index f51276d..37cdb66 100644 --- a/include/boost/intrusive/intrusive_fwd.hpp +++ b/include/boost/intrusive/intrusive_fwd.hpp @@ -384,6 +384,7 @@ template , class O4 = void , class O5 = void , class O6 = void + , class O7 = void > #else template @@ -399,6 +400,7 @@ template , class O4 = void , class O5 = void , class O6 = void + , class O7 = void > #else template @@ -414,6 +416,7 @@ template , class O4 = void , class O5 = void , class O6 = void + , class O7 = void > #else template diff --git a/include/boost/intrusive/options.hpp b/include/boost/intrusive/options.hpp index 6523ffb..8bf9ca8 100644 --- a/include/boost/intrusive/options.hpp +++ b/include/boost/intrusive/options.hpp @@ -17,7 +17,6 @@ #include #include #include -#include #if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once @@ -70,6 +69,15 @@ BOOST_INTRUSIVE_OPTION_TYPE(compare, Compare, Compare, compare) //!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 specifies a function object +//!that specifies the type of the priority of a treap +//!container and an operator to obtain it from a value type. +//! +//!This function object must the define a `type` member typedef and +//!a member with signature `type [const&] operator()(const value_type &) const` +//!that will return the priority from a value_type of a treap container +BOOST_INTRUSIVE_OPTION_TYPE(priority_of_value, PrioOfValue, PrioOfValue, priority_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. diff --git a/include/boost/intrusive/priority_compare.hpp b/include/boost/intrusive/priority_compare.hpp index f5589ce..3cf2b1c 100644 --- a/include/boost/intrusive/priority_compare.hpp +++ b/include/boost/intrusive/priority_compare.hpp @@ -60,14 +60,14 @@ struct priority_compare /// @cond template -struct get_prio +struct get_prio_comp { typedef PrioComp type; }; template -struct get_prio +struct get_prio_comp { typedef ::boost::intrusive::priority_compare type; }; diff --git a/include/boost/intrusive/treap.hpp b/include/boost/intrusive/treap.hpp index c6f63ff..c6b4eb2 100644 --- a/include/boost/intrusive/treap.hpp +++ b/include/boost/intrusive/treap.hpp @@ -50,6 +50,20 @@ struct treap_defaults : bstree_defaults { typedef void priority; + typedef void priority_of_value; +}; + +template +struct treap_prio_types +{ + typedef typename + boost::movelib::pointer_element::type value_type; + typedef typename get_key_of_value + < VoidOrPrioOfValue, value_type>::type priority_of_value; + typedef typename priority_of_value::type priority_type; + typedef typename get_prio_comp< VoidOrPrioComp + , priority_type + >::type priority_compare; }; /// @endcond @@ -70,17 +84,14 @@ struct treap_defaults #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class treap_impl /// @cond : public bstree_impl //Use public inheritance to avoid MSVC bugs with closures , public detail::ebo_functor_holder - < typename get_prio - < VoidOrPrioComp - , typename bstree_impl - ::key_type>::type + < typename treap_prio_types::priority_compare > /// @endcond { @@ -91,12 +102,12 @@ class treap_impl , ConstantTimeSize, BsTreeAlgorithms , HeaderHolder> tree_type; typedef tree_type implementation_defined; - typedef get_prio - < VoidOrPrioComp - , typename tree_type::key_type> get_prio_type; + typedef treap_prio_types + < typename ValueTraits::pointer + , VoidOrPrioOfValue, VoidOrPrioComp> treap_prio_types_t; typedef detail::ebo_functor_holder - prio_base; + prio_base; /// @endcond @@ -120,17 +131,22 @@ class treap_impl typedef typename implementation_defined::node_ptr node_ptr; typedef typename implementation_defined::const_node_ptr const_node_ptr; typedef BOOST_INTRUSIVE_IMPDEF(treap_algorithms) node_algorithms; - typedef BOOST_INTRUSIVE_IMPDEF(typename get_prio_type::type) priority_compare; + typedef BOOST_INTRUSIVE_IMPDEF + (typename treap_prio_types_t::priority_type) priority_type; + typedef BOOST_INTRUSIVE_IMPDEF + (typename treap_prio_types_t::priority_of_value) priority_of_value; + typedef BOOST_INTRUSIVE_IMPDEF + (typename treap_prio_types_t::priority_compare) priority_compare; static const bool constant_time_size = implementation_defined::constant_time_size; static const bool stateful_value_traits = implementation_defined::stateful_value_traits; static const bool safemode_or_autounlink = is_safe_autounlink::value; - typedef detail::key_nodeptr_comp key_node_prio_comp_t; + typedef detail::key_nodeptr_comp prio_node_prio_comp_t; - template - detail::key_nodeptr_comp key_node_prio_comp(KeyPrioComp keypriocomp) const - { return detail::key_nodeptr_comp(keypriocomp, &this->get_value_traits()); } + template + detail::key_nodeptr_comp prio_node_prio_comp(PrioPrioComp priopriocomp) const + { return detail::key_nodeptr_comp(priopriocomp, &this->get_value_traits()); } /// @cond private: @@ -421,7 +437,7 @@ class treap_impl ( this->tree_type::header_ptr() , to_insert , this->key_node_comp(this->key_comp()) - , this->key_node_prio_comp(this->priv_pcomp())) + , this->prio_node_prio_comp(this->priv_pcomp())) , this->priv_value_traits_ptr()); this->tree_type::sz_traits().increment(); return ret; @@ -451,7 +467,7 @@ class treap_impl , hint.pointed_node() , to_insert , this->key_node_comp(this->key_comp()) - , this->key_node_prio_comp(this->priv_pcomp())) + , this->prio_node_prio_comp(this->priv_pcomp())) , this->priv_value_traits_ptr()); this->tree_type::sz_traits().increment(); return ret; @@ -496,7 +512,7 @@ class treap_impl std::pair insert_unique(reference value) { insert_commit_data commit_data; - std::pair ret = this->insert_unique_check(key_of_value()(value), commit_data); + std::pair ret = this->insert_unique_check(key_of_value()(value), priority_of_value()(value), commit_data); if(!ret.second) return ret; return std::pair (this->insert_unique_commit(value, commit_data), true); @@ -520,7 +536,7 @@ class treap_impl iterator insert_unique(const_iterator hint, reference value) { insert_commit_data commit_data; - std::pair ret = this->insert_unique_check(hint, key_of_value()(value), commit_data); + std::pair ret = this->insert_unique_check(hint, key_of_value()(value), priority_of_value()(value), commit_data); if(!ret.second) return ret.first; return this->insert_unique_commit(value, commit_data); @@ -581,8 +597,8 @@ class treap_impl //! "commit_data" remains valid for a subsequent "insert_commit" only if no more //! objects are inserted or erased from the container. std::pair insert_unique_check - ( const key_type &key, insert_commit_data &commit_data) - { return this->insert_unique_check(key, this->key_comp(), this->priv_pcomp(), commit_data); } + ( const key_type &key, const priority_type &prio, insert_commit_data &commit_data) + { return this->insert_unique_check(key, this->key_comp(), prio, this->priv_pcomp(), commit_data); } //! Effects: Checks if a value can be inserted in the container, using //! a user provided key instead of the value itself, using "hint" @@ -613,14 +629,14 @@ class treap_impl //! "commit_data" remains valid for a subsequent "insert_commit" only if no more //! objects are inserted or erased from the container. std::pair insert_unique_check - ( const_iterator hint, const key_type &key, insert_commit_data &commit_data) - { return this->insert_unique_check(hint, key, this->key_comp(), this->priv_pcomp(), commit_data); } + ( const_iterator hint, const key_type &key, const priority_type &prio, insert_commit_data &commit_data) + { return this->insert_unique_check(hint, key, this->key_comp(), prio, this->priv_pcomp(), commit_data); } //! Requires: comp must be a comparison function that induces //! the same strict weak ordering as key_compare. - //! key_value_pcomp must be a comparison function that induces + //! prio_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 comp compare an arbitrary key with the contained values. + //! prio_value_pcomp and comp compare an arbitrary key/priority with the contained values. //! //! Effects: Checks if a value can be inserted in the container, using //! a user provided key instead of the value itself. @@ -633,7 +649,7 @@ class treap_impl //! //! Complexity: Average complexity is at most logarithmic. //! - //! Throws: If the comp or key_value_pcomp + //! Throws: If the comp or prio_value_pcomp //! ordering functions throw. Strong guarantee. //! //! Notes: This function is used to improve performance when constructing @@ -649,27 +665,29 @@ 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 + template BOOST_INTRUSIVE_DOC1ST(std::pair , typename detail::disable_if_convertible >::type) insert_unique_check ( const KeyType &key, KeyTypeKeyCompare comp - , KeyValuePrioCompare key_value_pcomp, insert_commit_data &commit_data) + , const PrioType &prio, PrioValuePrioCompare prio_value_pcomp, insert_commit_data &commit_data) { std::pair const ret = (node_algorithms::insert_unique_check - ( this->tree_type::header_ptr(), key - , this->key_node_comp(comp), this->key_node_prio_comp(key_value_pcomp), commit_data)); + ( this->tree_type::header_ptr() + , key, this->key_node_comp(comp) + , prio, this->prio_node_prio_comp(prio_value_pcomp) + , commit_data)); return std::pair(iterator(ret.first, this->priv_value_traits_ptr()), ret.second); } //! Requires: comp must be a comparison function that induces //! the same strict weak ordering as key_compare. - //! key_value_pcomp must be a comparison function that induces + //! prio_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 comp compare an arbitrary key with the contained values. + //! prio_value_pcomp and comp compare an arbitrary key/priority with the contained values. //! //! Effects: Checks if a value can be inserted in the container, using //! a user provided key instead of the value itself, using "hint" @@ -684,7 +702,7 @@ class treap_impl //! Complexity: Logarithmic in general, but it's amortized //! constant time if t is inserted immediately before hint. //! - //! Throws: If the comp or key_value_pcomp + //! Throws: If the comp or prio_value_pcomp //! ordering functions throw. Strong guarantee. //! //! Notes: This function is used to improve performance when constructing @@ -700,17 +718,21 @@ 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 + template std::pair insert_unique_check - ( const_iterator hint, const KeyType &key + ( const_iterator hint + , const KeyType &key , KeyTypeKeyCompare comp - , KeyValuePrioCompare key_value_pcomp + , const PrioType &prio + , PrioValuePrioCompare prio_value_pcomp , insert_commit_data &commit_data) { std::pair const ret = (node_algorithms::insert_unique_check - ( this->tree_type::header_ptr(), hint.pointed_node(), key - , this->key_node_comp(comp), this->key_node_prio_comp(key_value_pcomp), commit_data)); + ( this->tree_type::header_ptr(), hint.pointed_node() + , key, this->key_node_comp(comp) + , prio, this->prio_node_prio_comp(prio_value_pcomp) + , commit_data)); return std::pair(iterator(ret.first, this->priv_value_traits_ptr()), ret.second); } @@ -763,7 +785,7 @@ class treap_impl ( this->tree_type::header_ptr() , pos.pointed_node() , to_insert - , this->key_node_prio_comp(this->priv_pcomp()) + , this->prio_node_prio_comp(this->priv_pcomp()) ) , this->priv_value_traits_ptr()); this->tree_type::sz_traits().increment(); @@ -789,7 +811,7 @@ class treap_impl node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); node_algorithms::push_back - (this->tree_type::header_ptr(), to_insert, this->key_node_prio_comp(this->priv_pcomp())); + (this->tree_type::header_ptr(), to_insert, this->prio_node_prio_comp(this->priv_pcomp())); this->tree_type::sz_traits().increment(); } @@ -812,7 +834,7 @@ class treap_impl node_ptr to_insert(this->get_value_traits().to_node_ptr(value)); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert)); node_algorithms::push_front - (this->tree_type::header_ptr(), to_insert, this->key_node_prio_comp(this->priv_pcomp())); + (this->tree_type::header_ptr(), to_insert, this->prio_node_prio_comp(this->priv_pcomp())); this->tree_type::sz_traits().increment(); } @@ -831,7 +853,7 @@ class treap_impl node_ptr to_erase(i.pointed_node()); BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(to_erase)); node_algorithms::erase - (this->tree_type::header_ptr(), to_erase, this->key_node_prio_comp(this->priv_pcomp())); + (this->tree_type::header_ptr(), to_erase, this->prio_node_prio_comp(this->priv_pcomp())); this->tree_type::sz_traits().decrement(); if(safemode_or_autounlink) node_algorithms::init(to_erase); @@ -1013,7 +1035,7 @@ class treap_impl #else template void merge_unique(treap_impl - &source) + &source) #endif { node_ptr it (node_algorithms::begin_node(source.header_ptr())) @@ -1026,7 +1048,7 @@ class treap_impl if( node_algorithms::transfer_unique ( this->header_ptr(), this->key_node_comp(this->key_comp()) - , this->key_node_prio_comp(this->priv_pcomp()), source.header_ptr(), p) ){ + , this->prio_node_prio_comp(this->priv_pcomp()), source.header_ptr(), p) ){ this->sz_traits().increment(); source.sz_traits().decrement(); } @@ -1039,7 +1061,7 @@ class treap_impl #else template void merge_equal(treap_impl - &source) + &source) #endif { node_ptr it (node_algorithms::begin_node(source.header_ptr())) @@ -1051,7 +1073,7 @@ class treap_impl it = node_algorithms::next_node(it); node_algorithms::transfer_equal ( this->header_ptr(), this->key_node_comp(this->key_comp()) - , this->key_node_prio_comp(this->priv_pcomp()), source.header_ptr(), p); + , this->prio_node_prio_comp(this->priv_pcomp()), source.header_ptr(), p); this->sz_traits().increment(); source.sz_traits().decrement(); } @@ -1061,10 +1083,10 @@ class treap_impl template void check(ExtraChecker extra_checker) const { - typedef detail::key_nodeptr_comp nodeptr_prio_comp_t; + typedef detail::key_nodeptr_comp nodeptr_prio_comp_t; tree_type::check(detail::treap_node_extra_checker - (this->key_node_prio_comp(this->priv_pcomp()), extra_checker)); + (this->prio_node_prio_comp(this->priv_pcomp()), extra_checker)); } //! @copydoc ::boost::intrusive::bstree::check()const @@ -1222,14 +1244,15 @@ template #else template + , class O5 = void, class O6 = void + , class O7 = void> #endif struct make_treap { typedef typename pack_options < treap_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4, O5, O6 + O1, O2, O3, O4, O5, O6, O7 #else Options... #endif @@ -1242,6 +1265,7 @@ struct make_treap < value_traits , typename packed_options::key_of_value , typename packed_options::compare + , typename packed_options::priority_of_value , typename packed_options::priority , typename packed_options::size_type , packed_options::constant_time_size @@ -1254,14 +1278,14 @@ struct make_treap #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class treap : public make_treap::value)); - treap() + + BOOST_INTRUSIVE_FORCEINLINE treap() : Base() {} - explicit treap( const key_compare &cmp + BOOST_INTRUSIVE_FORCEINLINE explicit treap( const key_compare &cmp , const priority_compare &pcmp = priority_compare() , const value_traits &v_traits = value_traits()) : Base(cmp, pcmp, v_traits) {} template - treap( bool unique, Iterator b, Iterator e + BOOST_INTRUSIVE_FORCEINLINE treap( bool unique, Iterator b, Iterator e , 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) {} - treap(BOOST_RV_REF(treap) x) + BOOST_INTRUSIVE_FORCEINLINE treap(BOOST_RV_REF(treap) x) : Base(BOOST_MOVE_BASE(Base, x)) {} - treap& operator=(BOOST_RV_REF(treap) x) + BOOST_INTRUSIVE_FORCEINLINE treap& operator=(BOOST_RV_REF(treap) x) { return static_cast(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } template - void clone_from(const treap &src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const treap &src, Cloner cloner, Disposer disposer) { Base::clone_from(src, cloner, disposer); } template - void clone_from(BOOST_RV_REF(treap) src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE 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) + BOOST_INTRUSIVE_FORCEINLINE static treap &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } - static const treap &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const treap &container_from_end_iterator(const_iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } - static treap &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static treap &container_from_iterator(iterator it) { return static_cast(Base::container_from_iterator(it)); } - static const treap &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const treap &container_from_iterator(const_iterator it) { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/include/boost/intrusive/treap_algorithms.hpp b/include/boost/intrusive/treap_algorithms.hpp index e9b8b23..a75b48b 100644 --- a/include/boost/intrusive/treap_algorithms.hpp +++ b/include/boost/intrusive/treap_algorithms.hpp @@ -481,16 +481,17 @@ class treap_algorithms //! //! "commit_data" remains valid for a subsequent "insert_unique_commit" only //! if no more objects are inserted or erased from the set. - template + template static std::pair insert_unique_check - (const_node_ptr header, const KeyType &key - ,KeyNodePtrCompare comp, KeyNodePtrPrioCompare pcomp - ,insert_commit_data &commit_data) + ( const_node_ptr header + , const KeyType &key, KeyNodePtrCompare comp + , const PrioType &prio, PrioNodePtrPrioCompare pcomp + , insert_commit_data &commit_data) { std::pair ret = bstree_algo::insert_unique_check(header, key, comp, commit_data); if(ret.second) - rebalance_after_insertion_check(header, commit_data.node, key, pcomp, commit_data.rotations); + rebalance_after_insertion_check(header, commit_data.node, prio, pcomp, commit_data.rotations); return ret; } @@ -533,15 +534,17 @@ class treap_algorithms //! //! "commit_data" remains valid for a subsequent "insert_unique_commit" only //! if no more objects are inserted or erased from the set. - template + template static std::pair insert_unique_check - (const_node_ptr header, node_ptr hint, const KeyType &key - ,KeyNodePtrCompare comp, KeyNodePtrPrioCompare pcomp, insert_commit_data &commit_data) + ( const_node_ptr header, node_ptr hint + , const KeyType &key, KeyNodePtrCompare comp + , const PrioType &prio, PrioNodePtrPrioCompare pcomp + , insert_commit_data &commit_data) { std::pair ret = bstree_algo::insert_unique_check(header, hint, key, comp, commit_data); if(ret.second) - rebalance_after_insertion_check(header, commit_data.node, key, pcomp, commit_data.rotations); + rebalance_after_insertion_check(header, commit_data.node, prio, pcomp, commit_data.rotations); return ret; } @@ -570,12 +573,12 @@ class treap_algorithms } //! @copydoc ::boost::intrusive::bstree_algorithms::transfer_unique - template + template static bool transfer_unique - (node_ptr header1, NodePtrCompare comp, KeyNodePtrPrioCompare pcomp, node_ptr header2, node_ptr z) + (node_ptr header1, NodePtrCompare comp, PrioNodePtrPrioCompare pcomp, node_ptr header2, node_ptr z) { insert_commit_data commit_data; - bool const transferable = insert_unique_check(header1, z, comp, pcomp, commit_data).second; + bool const transferable = insert_unique_check(header1, z, comp, z, pcomp, commit_data).second; if(transferable){ erase(header2, z, pcomp); insert_unique_commit(header1, z, commit_data); @@ -584,9 +587,9 @@ class treap_algorithms } //! @copydoc ::boost::intrusive::bstree_algorithms::transfer_equal - template + template static void transfer_equal - (node_ptr header1, NodePtrCompare comp, KeyNodePtrPrioCompare pcomp, node_ptr header2, node_ptr z) + (node_ptr header1, NodePtrCompare comp, PrioNodePtrPrioCompare pcomp, node_ptr header2, node_ptr z) { insert_commit_data commit_data; bstree_algo::insert_equal_upper_bound_check(header1, z, comp, commit_data); diff --git a/include/boost/intrusive/treap_set.hpp b/include/boost/intrusive/treap_set.hpp index bf162ba..6c0ea3b 100644 --- a/include/boost/intrusive/treap_set.hpp +++ b/include/boost/intrusive/treap_set.hpp @@ -27,7 +27,7 @@ namespace boost { namespace intrusive { #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) -template +template class treap_multiset_impl; #endif @@ -45,16 +45,16 @@ class treap_multiset_impl; #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class treap_set_impl #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED - : public treap_impl + : public treap_impl #endif { /// @cond public: - typedef treap_impl tree_type; + typedef treap_impl tree_type; BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_set_impl) typedef tree_type implementation_defined; @@ -73,6 +73,7 @@ class treap_set_impl typedef typename implementation_defined::size_type size_type; typedef typename implementation_defined::value_compare value_compare; typedef typename implementation_defined::key_compare key_compare; + typedef typename implementation_defined::priority_type priority_type; typedef typename implementation_defined::priority_compare priority_compare; typedef typename implementation_defined::iterator iterator; typedef typename implementation_defined::const_iterator const_iterator; @@ -243,29 +244,30 @@ class treap_set_impl iterator insert(const_iterator hint, reference value) { return tree_type::insert_unique(hint, value); } - //! @copydoc ::boost::intrusive::treap::insert_unique_check(const key_type&,insert_commit_data&) - std::pair insert_check( const key_type &key, insert_commit_data &commit_data) - { return tree_type::insert_unique_check(key, commit_data); } + //! @copydoc ::boost::intrusive::treap::insert_unique_check(const key_type&,const priority_type &,insert_commit_data&) + std::pair insert_check( const key_type &key, const priority_type &prio, insert_commit_data &commit_data) + { return tree_type::insert_unique_check(key, prio, commit_data); } - //! @copydoc ::boost::intrusive::treap::insert_unique_check(const_iterator,const key_type&,insert_commit_data&) + //! @copydoc ::boost::intrusive::treap::insert_unique_check(const_iterator,const key_type&,const priority_type &,insert_commit_data&) std::pair insert_check - ( const_iterator hint, const key_type &key, insert_commit_data &commit_data) - { return tree_type::insert_unique_check(hint, key, commit_data); } + ( const_iterator hint, const key_type &key, const priority_type &prio, insert_commit_data &commit_data) + { return tree_type::insert_unique_check(hint, key, prio, commit_data); } - //! @copydoc ::boost::intrusive::treap::insert_unique_check(const KeyType&,KeyTypeKeyCompare,KeyValuePrioCompare,insert_commit_data&) - template + //! @copydoc ::boost::intrusive::treap::insert_unique_check(const KeyType&,KeyTypeKeyCompare,PrioValuePrioCompare,insert_commit_data&) + template std::pair insert_check - ( const KeyType &key, KeyTypeKeyCompare comp, KeyValuePrioCompare key_value_pcomp + ( const KeyType &key, KeyTypeKeyCompare comp, const PrioType &prio, PrioValuePrioCompare pcomp , insert_commit_data &commit_data) - { return tree_type::insert_unique_check(key, comp, key_value_pcomp, commit_data); } + { return tree_type::insert_unique_check(key, comp, prio, pcomp, commit_data); } - //! @copydoc ::boost::intrusive::treap::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,KeyValuePrioCompare,insert_commit_data&) - template + //! @copydoc ::boost::intrusive::treap::insert_unique_check(const_iterator,const KeyType&,KeyTypeKeyCompare,PrioValuePrioCompare,insert_commit_data&) + template std::pair insert_check - ( const_iterator hint, const KeyType &key - , KeyTypeKeyCompare comp, KeyValuePrioCompare key_value_pcomp + ( const_iterator hint + , const KeyType &key, KeyTypeKeyCompare comp + , const PrioType &prio, PrioValuePrioCompare pcomp , insert_commit_data &commit_data) - { return tree_type::insert_unique_check(hint, key, comp, key_value_pcomp, commit_data); } + { return tree_type::insert_unique_check(hint, key, comp, prio, pcomp, commit_data); } //! @copydoc ::boost::intrusive::treap::insert_unique(Iterator,Iterator) template @@ -455,11 +457,11 @@ class treap_set_impl #else template - void merge(treap_set_impl &source) + void merge(treap_set_impl &source) { return tree_type::merge_unique(source); } template - void merge(treap_multiset_impl &source) + void merge(treap_multiset_impl &source) { return tree_type::merge_unique(source); } #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -473,14 +475,15 @@ template #else template + , class O5 = void, class O6 = void + , class O7 = void> #endif struct make_treap_set { typedef typename pack_options < treap_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4, O5, O6 + O1, O2, O3, O4, O5, O6, O7 #else Options... #endif @@ -493,6 +496,7 @@ struct make_treap_set < value_traits , typename packed_options::key_of_value , typename packed_options::compare + , typename packed_options::priority_of_value , typename packed_options::priority , typename packed_options::size_type , packed_options::constant_time_size @@ -505,14 +509,14 @@ struct make_treap_set #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class treap_set : public make_treap_set::value)); - treap_set() + BOOST_INTRUSIVE_FORCEINLINE treap_set() : Base() {} - explicit treap_set( const key_compare &cmp + BOOST_INTRUSIVE_FORCEINLINE explicit treap_set( const key_compare &cmp , const priority_compare &pcmp = priority_compare() , const value_traits &v_traits = value_traits()) : Base(cmp, pcmp, v_traits) {} template - treap_set( Iterator b, Iterator e + BOOST_INTRUSIVE_FORCEINLINE treap_set( Iterator b, Iterator e , 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) {} - treap_set(BOOST_RV_REF(treap_set) x) + BOOST_INTRUSIVE_FORCEINLINE treap_set(BOOST_RV_REF(treap_set) x) : Base(BOOST_MOVE_BASE(Base, x)) {} - treap_set& operator=(BOOST_RV_REF(treap_set) x) + BOOST_INTRUSIVE_FORCEINLINE treap_set& operator=(BOOST_RV_REF(treap_set) x) { return static_cast(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } template - void clone_from(const treap_set &src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const treap_set &src, Cloner cloner, Disposer disposer) { Base::clone_from(src, cloner, disposer); } template - void clone_from(BOOST_RV_REF(treap_set) src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE 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) + BOOST_INTRUSIVE_FORCEINLINE static treap_set &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } - static const treap_set &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const treap_set &container_from_end_iterator(const_iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } - static treap_set &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static treap_set &container_from_iterator(iterator it) { return static_cast(Base::container_from_iterator(it)); } - static const treap_set &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const treap_set &container_from_iterator(const_iterator it) { return static_cast(Base::container_from_iterator(it)); } }; @@ -600,15 +604,15 @@ class treap_set #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) template #else -template +template #endif class treap_multiset_impl #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED - : public treap_impl + : public treap_impl #endif { /// @cond - typedef treap_impl tree_type; + typedef treap_impl tree_type; BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_multiset_impl) typedef tree_type implementation_defined; @@ -627,6 +631,7 @@ class treap_multiset_impl typedef typename implementation_defined::size_type size_type; typedef typename implementation_defined::value_compare value_compare; typedef typename implementation_defined::key_compare key_compare; + typedef typename implementation_defined::priority_type priority_type; typedef typename implementation_defined::priority_compare priority_compare; typedef typename implementation_defined::iterator iterator; typedef typename implementation_defined::const_iterator const_iterator; @@ -967,11 +972,11 @@ class treap_multiset_impl #else template - void merge(treap_multiset_impl &source) + void merge(treap_multiset_impl &source) { return tree_type::merge_equal(source); } template - void merge(treap_set_impl &source) + void merge(treap_set_impl &source) { return tree_type::merge_equal(source); } #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED @@ -985,14 +990,15 @@ template #else template + , class O5 = void, class O6 = void + , class O7 = void> #endif struct make_treap_multiset { typedef typename pack_options < treap_defaults, #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) - O1, O2, O3, O4, O5, O6 + O1, O2, O3, O4, O5, O6, O7 #else Options... #endif @@ -1005,6 +1011,7 @@ struct make_treap_multiset < value_traits , typename packed_options::key_of_value , typename packed_options::compare + , typename packed_options::priority_of_value , typename packed_options::priority , typename packed_options::size_type , packed_options::constant_time_size @@ -1017,14 +1024,14 @@ struct make_treap_multiset #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) -template +template #else template #endif class treap_multiset : public make_treap_multiset::value)); - treap_multiset() + BOOST_INTRUSIVE_FORCEINLINE treap_multiset() : Base() {} - explicit treap_multiset( const key_compare &cmp + BOOST_INTRUSIVE_FORCEINLINE explicit treap_multiset( const key_compare &cmp , const priority_compare &pcmp = priority_compare() , const value_traits &v_traits = value_traits()) : Base(cmp, pcmp, v_traits) {} template - treap_multiset( Iterator b, Iterator e + BOOST_INTRUSIVE_FORCEINLINE treap_multiset( Iterator b, Iterator e , 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) {} - treap_multiset(BOOST_RV_REF(treap_multiset) x) + BOOST_INTRUSIVE_FORCEINLINE treap_multiset(BOOST_RV_REF(treap_multiset) x) : Base(BOOST_MOVE_BASE(Base, x)) {} - treap_multiset& operator=(BOOST_RV_REF(treap_multiset) x) + BOOST_INTRUSIVE_FORCEINLINE treap_multiset& operator=(BOOST_RV_REF(treap_multiset) x) { return static_cast(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); } template - void clone_from(const treap_multiset &src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE void clone_from(const treap_multiset &src, Cloner cloner, Disposer disposer) { Base::clone_from(src, cloner, disposer); } template - void clone_from(BOOST_RV_REF(treap_multiset) src, Cloner cloner, Disposer disposer) + BOOST_INTRUSIVE_FORCEINLINE 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) + BOOST_INTRUSIVE_FORCEINLINE static treap_multiset &container_from_end_iterator(iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } - static const treap_multiset &container_from_end_iterator(const_iterator end_iterator) + BOOST_INTRUSIVE_FORCEINLINE static const treap_multiset &container_from_end_iterator(const_iterator end_iterator) { return static_cast(Base::container_from_end_iterator(end_iterator)); } - static treap_multiset &container_from_iterator(iterator it) + BOOST_INTRUSIVE_FORCEINLINE static treap_multiset &container_from_iterator(iterator it) { return static_cast(Base::container_from_iterator(it)); } - static const treap_multiset &container_from_iterator(const_iterator it) + BOOST_INTRUSIVE_FORCEINLINE static const treap_multiset &container_from_iterator(const_iterator it) { return static_cast(Base::container_from_iterator(it)); } }; diff --git a/test/bs_test_common.hpp b/test/bs_test_common.hpp index 4574c86..69f7f75 100644 --- a/test/bs_test_common.hpp +++ b/test/bs_test_common.hpp @@ -54,6 +54,10 @@ struct tree_rebinder_common typedef typename detail::if_c < Map, key_of_value >, void >::type key_of_value_opt; + + typedef typename detail::if_c + < Map, priority_of_value >, void + >::type prio_of_value_opt; }; diff --git a/test/generic_set_test.hpp b/test/generic_set_test.hpp index bb73db8..9236019 100644 --- a/test/generic_set_test.hpp +++ b/test/generic_set_test.hpp @@ -197,6 +197,7 @@ void test_generic_set::test_insert_advanced typedef typename ContainerDefiner::template container <>::type set_type; typedef typename set_type::key_of_value key_of_value; + typedef typename set_type::priority_of_value priority_of_value; typedef typename set_type::value_type value_type; typedef priority_compare<> prio_comp_t; { @@ -205,10 +206,10 @@ void test_generic_set::test_insert_advanced testset.check(); value_type v(1); typename set_type::insert_commit_data data; - BOOST_TEST ((!testset.insert_check(1, any_less(), prio_comp_t(), data).second)); - BOOST_TEST ((!testset.insert_check(testset.begin(), 1, any_less(), prio_comp_t(), data).second)); - BOOST_TEST ((!testset.insert_check(key_of_value()(v), data).second)); - BOOST_TEST ((!testset.insert_check(testset.begin(), key_of_value()(v), data).second)); + BOOST_TEST ((!testset.insert_check(1, any_less(), 1, prio_comp_t(), data).second)); + BOOST_TEST ((!testset.insert_check(testset.begin(), 1, any_less(), 1, prio_comp_t(), data).second)); + BOOST_TEST ((!testset.insert_check(key_of_value()(v), priority_of_value()(v), data).second)); + BOOST_TEST ((!testset.insert_check(testset.begin(), key_of_value()(v), priority_of_value()(v), data).second)); } } diff --git a/test/int_holder.hpp b/test/int_holder.hpp index d1209cc..785a367 100644 --- a/test/int_holder.hpp +++ b/test/int_holder.hpp @@ -102,6 +102,15 @@ struct int_holder_key_of_value { return tv.get_int_holder(); } }; +template +struct int_priority_of_value +{ + typedef int type; + + type operator()(const ValueType &tv) const + { return tv.int_value(); } +}; + } //namespace boost{ } //namespace intrusive{ diff --git a/test/treap_multiset_test.cpp b/test/treap_multiset_test.cpp index 923ecd0..79d6e49 100644 --- a/test/treap_multiset_test.cpp +++ b/test/treap_multiset_test.cpp @@ -9,12 +9,13 @@ // See http://www.boost.org/libs/intrusive for documentation. // ///////////////////////////////////////////////////////////////////////////// -#include + #include "itestvalue.hpp" #include "bptr_value.hpp" #include "smart_ptr.hpp" #include "bs_test_common.hpp" #include "generic_multiset_test.hpp" +#include using namespace boost::intrusive; @@ -35,6 +36,7 @@ struct rebinder , constant_time_size , typename common_t::holder_opt , typename common_t::key_of_value_opt + , typename common_t::prio_of_value_opt , Option1 , Option2 > type; diff --git a/test/treap_set_test.cpp b/test/treap_set_test.cpp index 471d5eb..f798777 100644 --- a/test/treap_set_test.cpp +++ b/test/treap_set_test.cpp @@ -10,11 +10,11 @@ // ///////////////////////////////////////////////////////////////////////////// #include "itestvalue.hpp" -#include #include "bptr_value.hpp" #include "smart_ptr.hpp" #include "bs_test_common.hpp" #include "generic_set_test.hpp" +#include using namespace boost::intrusive; @@ -35,6 +35,7 @@ struct rebinder , constant_time_size , typename common_t::holder_opt , typename common_t::key_of_value_opt + , typename common_t::prio_of_value_opt , Option1 , Option2 > type;