diff --git a/include/boost/container/detail/tree.hpp b/include/boost/container/detail/tree.hpp index f67ae8b..912c925 100644 --- a/include/boost/container/detail/tree.hpp +++ b/include/boost/container/detail/tree.hpp @@ -159,87 +159,95 @@ class push_back_functor namespace dtl { -template< class NodeType, class NodeCompareType - , class SizeType, class HookType +template< class NodeType + , class KeyOfNode + , class KeyCompare + , class HookType , boost::container::tree_type_enum tree_type_value> struct intrusive_tree_dispatch; -template +template struct intrusive_tree_dispatch - + { typedef typename dtl::bi::make_rbtree + ,dtl::bi::key_of_value + ,dtl::bi::compare ,dtl::bi::base_hook ,dtl::bi::constant_time_size - ,dtl::bi::size_type >::type type; }; -template +template struct intrusive_tree_dispatch - + { typedef typename dtl::bi::make_avltree + ,dtl::bi::key_of_value + ,dtl::bi::compare ,dtl::bi::base_hook ,dtl::bi::constant_time_size - ,dtl::bi::size_type >::type type; }; -template +template struct intrusive_tree_dispatch - + { typedef typename dtl::bi::make_sgtree + ,dtl::bi::key_of_value + ,dtl::bi::compare ,dtl::bi::base_hook ,dtl::bi::floating_point - ,dtl::bi::size_type >::type type; }; -template +template struct intrusive_tree_dispatch - + { typedef typename dtl::bi::make_splaytree + ,dtl::bi::key_of_value + ,dtl::bi::compare ,dtl::bi::base_hook ,dtl::bi::constant_time_size - ,dtl::bi::size_type >::type type; }; -template +template < class Allocator + , class KeyOfValue + , class KeyCompare + , boost::container::tree_type_enum tree_type_value + , bool OptimizeSize> struct intrusive_tree_type { private: typedef typename boost::container:: - allocator_traits::value_type value_type; + allocator_traits::value_type value_type; typedef typename boost::container:: - allocator_traits::void_pointer void_pointer; - typedef typename boost::container:: - allocator_traits::size_type size_type; + allocator_traits::void_pointer void_pointer; typedef base_node > node_t; - typedef value_to_node_compare - node_compare_type; + > node_t; //Deducing the hook type from node_t (e.g. node_t::hook_type) would //provoke an early instantiation of node_t that could ruin recursive //tree definitions, so retype the complete type to avoid any problem. typedef typename intrusive_tree_hook ::type hook_type; + , OptimizeSize>::type hook_type; + + typedef key_of_node + key_of_node_t; + public: typedef typename intrusive_tree_dispatch - < node_t, node_compare_type - , size_type, hook_type + < node_t + , key_of_node_t + , KeyCompare + , hook_type , tree_type_value>::type type; }; @@ -327,57 +335,6 @@ class RecyclingCloner intrusive_container &m_icont; }; - -template -struct key_node_compare - : public boost::intrusive::detail::ebo_functor_holder -{ - BOOST_CONTAINER_FORCEINLINE explicit key_node_compare(const KeyCompare &comp) - : base_t(comp) - {} - - typedef boost::intrusive::detail::ebo_functor_holder base_t; - typedef KeyCompare key_compare; - typedef KeyOfValue key_of_value; - typedef typename KeyOfValue::type key_type; - - - template - BOOST_CONTAINER_FORCEINLINE static const key_type & - key_from(const base_node > &n) - { - return key_of_value()(n.get_data()); - } - - template - BOOST_CONTAINER_FORCEINLINE static const T & - key_from(const T &t) - { - return t; - } - - BOOST_CONTAINER_FORCEINLINE const key_compare &key_comp() const - { return static_cast(*this); } - - BOOST_CONTAINER_FORCEINLINE key_compare &key_comp() - { return static_cast(*this); } - - BOOST_CONTAINER_FORCEINLINE bool operator()(const key_type &key1, const key_type &key2) const - { return this->key_comp()(key1, key2); } - - template - BOOST_CONTAINER_FORCEINLINE bool operator()(const key_type &key1, const U &nonkey2) const - { return this->key_comp()(key1, this->key_from(nonkey2)); } - - template - BOOST_CONTAINER_FORCEINLINE bool operator()(const U &nonkey1, const key_type &key2) const - { return this->key_comp()(this->key_from(nonkey1), key2); } - - template - BOOST_CONTAINER_FORCEINLINE bool operator()(const U &nonkey1, const V &nonkey2) const - { return this->key_comp()(this->key_from(nonkey1), this->key_from(nonkey2)); } -}; - template struct get_tree_opt { @@ -414,17 +371,24 @@ struct tree_key_of_value, int> typedef dtl::select1st type; }; + +template +struct make_intrusive_tree_type + : dtl::intrusive_tree_type + < typename real_allocator::type + , typename tree_key_of_value::type + , Compare + , get_tree_opt::type::tree_type + , get_tree_opt::type::optimize_size + > +{}; + + template class tree : public dtl::node_alloc_holder < typename real_allocator::type - , typename dtl::intrusive_tree_type - < typename real_allocator::type - , tree_value_compare - ::type>::pointer, Compare, typename tree_key_of_value::type> - , get_tree_opt::type::tree_type - , get_tree_opt::type::optimize_size - >::type + , typename make_intrusive_tree_type::type > { typedef tree < T, KeyOfValue @@ -440,11 +404,8 @@ class tree , Compare , key_of_value_t> ValComp; typedef typename get_tree_opt::type options_type; - typedef typename dtl::intrusive_tree_type - < allocator_type, ValComp - , options_type::tree_type - , options_type::optimize_size - >::type Icont; + typedef typename make_intrusive_tree_type + ::type Icont; typedef dtl::node_alloc_holder AllocHolder; typedef typename AllocHolder::NodePtr NodePtr; @@ -497,7 +458,7 @@ class tree private: - typedef key_node_compare KeyNodeCompare; + typedef key_node_pred KeyNodeCompare; public: @@ -771,11 +732,11 @@ class tree // accessors: BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE value_compare value_comp() const - { return this->icont().value_comp().predicate(); } + { return value_compare(this->key_comp()); } BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE key_compare key_comp() const - { return this->icont().value_comp().predicate().key_comp(); } + { return this->icont().key_comp(); } BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const @@ -886,7 +847,7 @@ class tree (const key_type& key, insert_commit_data &data) { std::pair ret = - this->icont().insert_unique_check(key, KeyNodeCompare(key_comp()), data); + this->icont().insert_unique_check(key, data); return std::pair(iterator(ret.first), ret.second); } @@ -895,7 +856,7 @@ class tree { BOOST_ASSERT((priv_is_linked)(hint)); std::pair ret = - this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(key_comp()), data); + this->icont().insert_unique_check(hint.get(), key, data); return std::pair(iterator(ret.first), ret.second); } @@ -1037,8 +998,8 @@ class tree insert_commit_data data; const key_type & k = key; //Support emulated rvalue references std::pair ret = - hint == const_iterator() ? this->icont().insert_unique_check( k, KeyNodeCompare(key_comp()), data) - : this->icont().insert_unique_check(hint.get(), k, KeyNodeCompare(key_comp()), data); + hint == const_iterator() ? this->icont().insert_unique_check( k, data) + : this->icont().insert_unique_check(hint.get(), k, data); if(ret.second){ ret.first = this->icont().insert_unique_commit (*AllocHolder::create_node(try_emplace_t(), boost::forward(key), boost::forward(args)...), data); @@ -1085,8 +1046,8 @@ class tree insert_commit_data data;\ const key_type & k = key;\ std::pair ret =\ - hint == const_iterator() ? this->icont().insert_unique_check( k, KeyNodeCompare(key_comp()), data)\ - : this->icont().insert_unique_check(hint.get(), k, KeyNodeCompare(key_comp()), data);\ + hint == const_iterator() ? this->icont().insert_unique_check( k, data)\ + : this->icont().insert_unique_check(hint.get(), k, data);\ if(ret.second){\ ret.first = this->icont().insert_unique_commit\ (*AllocHolder::create_node(try_emplace_t(), boost::forward(key) BOOST_MOVE_I##N BOOST_MOVE_FWD##N), data);\ @@ -1145,8 +1106,8 @@ class tree insert_commit_data data; const key_type & k = key; //Support emulated rvalue references std::pair ret = - hint == const_iterator() ? this->icont().insert_unique_check(k, KeyNodeCompare(key_comp()), data) - : this->icont().insert_unique_check(hint.get(), k, KeyNodeCompare(key_comp()), data); + hint == const_iterator() ? this->icont().insert_unique_check(k, data) + : this->icont().insert_unique_check(hint.get(), k, data); if(ret.second){ ret.first = this->priv_insert_or_assign_commit(boost::forward(key), boost::forward(obj), data); } @@ -1163,7 +1124,7 @@ class tree } BOOST_CONTAINER_FORCEINLINE size_type erase(const key_type& k) - { return AllocHolder::erase_key(k, KeyNodeCompare(key_comp()), alloc_version()); } + { return AllocHolder::erase_key(k, alloc_version()); } size_type erase_unique(const key_type& k) { @@ -1262,33 +1223,33 @@ class tree // so splay implementations can to their rebalancing when searching in non-const versions BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE iterator find(const key_type& k) - { return iterator(this->icont().find(k, KeyNodeCompare(key_comp()))); } + { return iterator(this->icont().find(k)); } BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE const_iterator find(const key_type& k) const - { return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(key_comp()))); } + { return const_iterator(this->non_const_icont().find(k)); } template BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_transparent::type find(const K& k) - { return iterator(this->icont().find(k, KeyNodeCompare(key_comp()))); } + { return iterator(this->icont().find(k, KeyNodeCompare())); } template BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_transparent::type find(const K& k) const - { return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(key_comp()))); } + { return const_iterator(this->non_const_icont().find(k, KeyNodeCompare())); } BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE size_type count(const key_type& k) const - { return size_type(this->icont().count(k, KeyNodeCompare(key_comp()))); } + { return size_type(this->icont().count(k)); } template BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_transparent::type count(const K& k) const - { return size_type(this->icont().count(k, KeyNodeCompare(key_comp()))); } + { return size_type(this->icont().count(k, KeyNodeCompare())); } BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE bool contains(const key_type& x) const @@ -1302,49 +1263,48 @@ class tree BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& k) - { return iterator(this->icont().lower_bound(k, KeyNodeCompare(key_comp()))); } + { return iterator(this->icont().lower_bound(k)); } BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const key_type& k) const - { return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(key_comp()))); } + { return const_iterator(this->non_const_icont().lower_bound(k)); } template BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_transparent::type lower_bound(const K& k) - { return iterator(this->icont().lower_bound(k, KeyNodeCompare(key_comp()))); } + { return iterator(this->icont().lower_bound(k, KeyNodeCompare())); } template BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_transparent::type lower_bound(const K& k) const - { return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(key_comp()))); } + { return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare())); } BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const key_type& k) - { return iterator(this->icont().upper_bound(k, KeyNodeCompare(key_comp()))); } + { return iterator(this->icont().upper_bound(k)); } BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const key_type& k) const - { return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(key_comp()))); } + { return const_iterator(this->non_const_icont().upper_bound(k)); } template BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_transparent::type upper_bound(const K& k) - { return iterator(this->icont().upper_bound(k, KeyNodeCompare(key_comp()))); } + { return iterator(this->icont().upper_bound(k, KeyNodeCompare())); } template BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_transparent::type upper_bound(const K& k) const - { return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(key_comp()))); } + { return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare())); } BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_CONTAINER_FORCEINLINE std::pair equal_range(const key_type& k) { - std::pair ret = - this->icont().equal_range(k, KeyNodeCompare(key_comp())); + std::pair ret = this->icont().equal_range(k); return std::pair(iterator(ret.first), iterator(ret.second)); } @@ -1352,7 +1312,7 @@ class tree std::pair equal_range(const key_type& k) const { std::pair ret = - this->non_const_icont().equal_range(k, KeyNodeCompare(key_comp())); + this->non_const_icont().equal_range(k); return std::pair (const_iterator(ret.first), const_iterator(ret.second)); } @@ -1363,7 +1323,7 @@ class tree equal_range(const K& k) { std::pair ret = - this->icont().equal_range(k, KeyNodeCompare(key_comp())); + this->icont().equal_range(k, KeyNodeCompare()); return std::pair(iterator(ret.first), iterator(ret.second)); } @@ -1373,7 +1333,7 @@ class tree equal_range(const K& k) const { std::pair ret = - this->non_const_icont().equal_range(k, KeyNodeCompare(key_comp())); + this->non_const_icont().equal_range(k, KeyNodeCompare()); return std::pair (const_iterator(ret.first), const_iterator(ret.second)); } @@ -1382,7 +1342,7 @@ class tree std::pair lower_bound_range(const key_type& k) { std::pair ret = - this->icont().lower_bound_range(k, KeyNodeCompare(key_comp())); + this->icont().lower_bound_range(k); return std::pair(iterator(ret.first), iterator(ret.second)); } @@ -1390,7 +1350,7 @@ class tree std::pair lower_bound_range(const key_type& k) const { std::pair ret = - this->non_const_icont().lower_bound_range(k, KeyNodeCompare(key_comp())); + this->non_const_icont().lower_bound_range(k); return std::pair (const_iterator(ret.first), const_iterator(ret.second)); } @@ -1401,7 +1361,7 @@ class tree lower_bound_range(const K& k) { std::pair ret = - this->icont().lower_bound_range(k, KeyNodeCompare(key_comp())); + this->icont().lower_bound_range(k, KeyNodeCompare()); return std::pair(iterator(ret.first), iterator(ret.second)); } @@ -1411,7 +1371,7 @@ class tree lower_bound_range(const K& k) const { std::pair ret = - this->non_const_icont().lower_bound_range(k, KeyNodeCompare(key_comp())); + this->non_const_icont().lower_bound_range(k, KeyNodeCompare()); return std::pair (const_iterator(ret.first), const_iterator(ret.second)); }