File indexing completed on 2025-09-18 08:47:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_INTRUSIVE_BSTREE_HPP
0013 #define BOOST_INTRUSIVE_BSTREE_HPP
0014
0015 #include <boost/intrusive/detail/config_begin.hpp>
0016 #include <boost/intrusive/intrusive_fwd.hpp>
0017
0018 #include <boost/intrusive/detail/assert.hpp>
0019 #include <boost/intrusive/intrusive_fwd.hpp>
0020 #include <boost/intrusive/bs_set_hook.hpp>
0021 #include <boost/intrusive/detail/tree_node.hpp>
0022 #include <boost/intrusive/detail/tree_iterator.hpp>
0023 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
0024 #include <boost/intrusive/detail/mpl.hpp>
0025 #include <boost/intrusive/pointer_traits.hpp>
0026 #include <boost/intrusive/detail/is_stateful_value_traits.hpp>
0027 #include <boost/intrusive/detail/empty_node_checker.hpp>
0028 #include <boost/intrusive/detail/default_header_holder.hpp>
0029 #include <boost/intrusive/detail/reverse_iterator.hpp>
0030 #include <boost/intrusive/detail/exception_disposer.hpp>
0031 #include <boost/intrusive/detail/node_cloner_disposer.hpp>
0032 #include <boost/intrusive/detail/key_nodeptr_comp.hpp>
0033 #include <boost/intrusive/detail/simple_disposers.hpp>
0034 #include <boost/intrusive/detail/size_holder.hpp>
0035 #include <boost/intrusive/detail/algo_type.hpp>
0036 #include <boost/intrusive/detail/algorithm.hpp>
0037 #include <boost/intrusive/detail/tree_value_compare.hpp>
0038
0039 #include <boost/intrusive/detail/get_value_traits.hpp>
0040 #include <boost/intrusive/bstree_algorithms.hpp>
0041 #include <boost/intrusive/link_mode.hpp>
0042 #include <boost/intrusive/parent_from_member.hpp>
0043 #include <boost/move/utility_core.hpp>
0044 #include <boost/move/adl_move_swap.hpp>
0045
0046 #include <boost/intrusive/detail/minimal_pair_header.hpp>
0047 #include <cstddef> //size_t...
0048 #include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal_to
0049
0050 #if defined(BOOST_HAS_PRAGMA_ONCE)
0051 # pragma once
0052 #endif
0053
0054 namespace boost {
0055 namespace intrusive {
0056
0057
0058
0059 struct default_bstree_hook_applier
0060 { template <class T> struct apply{ typedef typename T::default_bstree_hook type; }; };
0061
0062 template<>
0063 struct is_default_hook_tag<default_bstree_hook_applier>
0064 { static const bool value = true; };
0065
0066 struct bstree_defaults
0067 {
0068 typedef default_bstree_hook_applier proto_value_traits;
0069 static const bool constant_time_size = true;
0070 typedef std::size_t size_type;
0071 typedef void compare;
0072 typedef void key_of_value;
0073 static const bool floating_point = true;
0074 typedef void priority;
0075 typedef void header_holder_type;
0076 };
0077
0078 template<class ValueTraits, algo_types AlgoType, typename HeaderHolder>
0079 struct bstbase3
0080 {
0081 typedef ValueTraits value_traits;
0082 typedef typename value_traits::node_traits node_traits;
0083 typedef typename node_traits::node node_type;
0084 typedef typename get_algo<AlgoType, node_traits>::type node_algorithms;
0085 typedef typename node_traits::node_ptr node_ptr;
0086 typedef typename node_traits::const_node_ptr const_node_ptr;
0087 typedef tree_iterator<value_traits, false> iterator;
0088 typedef tree_iterator<value_traits, true> const_iterator;
0089 typedef boost::intrusive::reverse_iterator<iterator> reverse_iterator;
0090 typedef boost::intrusive::reverse_iterator<const_iterator> const_reverse_iterator;
0091 typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer;
0092 typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer;
0093 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::element_type) value_type;
0094 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference) reference;
0095 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::reference) const_reference;
0096 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::difference_type) difference_type;
0097 typedef typename detail::get_header_holder_type
0098 < value_traits,HeaderHolder >::type header_holder_type;
0099
0100 static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
0101 static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
0102 static const bool has_container_from_iterator =
0103 detail::is_same< header_holder_type, detail::default_header_holder< node_traits > >::value;
0104
0105 struct holder_t : public ValueTraits
0106 {
0107 inline explicit holder_t(const ValueTraits &vtraits)
0108 : ValueTraits(vtraits)
0109 {}
0110 header_holder_type root;
0111 } holder;
0112
0113 static bstbase3 &get_tree_base_from_end_iterator(const const_iterator &end_iterator)
0114 {
0115 BOOST_INTRUSIVE_STATIC_ASSERT(has_container_from_iterator);
0116 node_ptr p = end_iterator.pointed_node();
0117 header_holder_type* h = header_holder_type::get_holder(p);
0118 holder_t *holder = get_parent_from_member<holder_t, header_holder_type>(h, &holder_t::root);
0119 bstbase3 *base = get_parent_from_member<bstbase3, holder_t> (holder, &bstbase3::holder);
0120 return *base;
0121 }
0122
0123 inline bstbase3(const ValueTraits &vtraits)
0124 : holder(vtraits)
0125 {
0126 node_algorithms::init_header(this->header_ptr());
0127 }
0128
0129 inline node_ptr header_ptr()
0130 { return holder.root.get_node(); }
0131
0132 inline const_node_ptr header_ptr() const
0133 { return holder.root.get_node(); }
0134
0135 inline const value_traits &get_value_traits() const
0136 { return this->holder; }
0137
0138 inline value_traits &get_value_traits()
0139 { return this->holder; }
0140
0141 typedef typename boost::intrusive::value_traits_pointers
0142 <ValueTraits>::const_value_traits_ptr const_value_traits_ptr;
0143
0144 inline const_value_traits_ptr priv_value_traits_ptr() const
0145 { return pointer_traits<const_value_traits_ptr>::pointer_to(this->get_value_traits()); }
0146
0147 inline iterator begin() BOOST_NOEXCEPT
0148 { return iterator(node_algorithms::begin_node(this->header_ptr()), this->priv_value_traits_ptr()); }
0149
0150 inline const_iterator begin() const BOOST_NOEXCEPT
0151 { return cbegin(); }
0152
0153 inline const_iterator cbegin() const BOOST_NOEXCEPT
0154 { return const_iterator(node_algorithms::begin_node(this->header_ptr()), this->priv_value_traits_ptr()); }
0155
0156 inline iterator end() BOOST_NOEXCEPT
0157 { return iterator(node_algorithms::end_node(this->header_ptr()), this->priv_value_traits_ptr()); }
0158
0159 inline const_iterator end() const BOOST_NOEXCEPT
0160 { return cend(); }
0161
0162 inline const_iterator cend() const BOOST_NOEXCEPT
0163 { return const_iterator(node_algorithms::end_node(this->header_ptr()), this->priv_value_traits_ptr()); }
0164
0165 inline iterator root()
0166 { return iterator(node_algorithms::root_node(this->header_ptr()), this->priv_value_traits_ptr()); }
0167
0168 inline const_iterator root() const
0169 { return croot(); }
0170
0171 inline const_iterator croot() const
0172 { return const_iterator(node_algorithms::root_node(this->header_ptr()), this->priv_value_traits_ptr()); }
0173
0174 inline reverse_iterator rbegin()
0175 { return reverse_iterator(end()); }
0176
0177 inline const_reverse_iterator rbegin() const
0178 { return const_reverse_iterator(end()); }
0179
0180 inline const_reverse_iterator crbegin() const
0181 { return const_reverse_iterator(end()); }
0182
0183 inline reverse_iterator rend()
0184 { return reverse_iterator(begin()); }
0185
0186 inline const_reverse_iterator rend() const
0187 { return const_reverse_iterator(begin()); }
0188
0189 inline const_reverse_iterator crend() const
0190 { return const_reverse_iterator(begin()); }
0191
0192 void replace_node(iterator replace_this, reference with_this)
0193 {
0194 node_algorithms::replace_node( get_value_traits().to_node_ptr(*replace_this)
0195 , this->header_ptr()
0196 , get_value_traits().to_node_ptr(with_this));
0197 BOOST_IF_CONSTEXPR(safemode_or_autounlink)
0198 node_algorithms::init(replace_this.pointed_node());
0199 }
0200
0201 inline void rebalance() BOOST_NOEXCEPT
0202 { node_algorithms::rebalance(this->header_ptr()); }
0203
0204 iterator rebalance_subtree(iterator r) BOOST_NOEXCEPT
0205 { return iterator(node_algorithms::rebalance_subtree(r.pointed_node()), this->priv_value_traits_ptr()); }
0206
0207 static iterator s_iterator_to(reference value) BOOST_NOEXCEPT
0208 {
0209 BOOST_INTRUSIVE_STATIC_ASSERT((!stateful_value_traits));
0210 return iterator (value_traits::to_node_ptr(value), const_value_traits_ptr());
0211 }
0212
0213 static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT
0214 {
0215 BOOST_INTRUSIVE_STATIC_ASSERT((!stateful_value_traits));
0216 return const_iterator (value_traits::to_node_ptr(*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value))), const_value_traits_ptr());
0217 }
0218
0219 iterator iterator_to(reference value) BOOST_NOEXCEPT
0220 { return iterator (this->get_value_traits().to_node_ptr(value), this->priv_value_traits_ptr()); }
0221
0222 const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT
0223 { return const_iterator (this->get_value_traits().to_node_ptr(*pointer_traits<pointer>::const_cast_from(pointer_traits<const_pointer>::pointer_to(value))), this->priv_value_traits_ptr()); }
0224
0225 inline static void init_node(reference value)
0226 { node_algorithms::init(value_traits::to_node_ptr(value)); }
0227
0228 };
0229
0230 template<class Less, class T>
0231 struct get_compare
0232 {
0233 typedef Less type;
0234 };
0235
0236 template<class T>
0237 struct get_compare<void, T>
0238 {
0239 typedef ::std::less<T> type;
0240 };
0241
0242 template<class KeyOfValue, class T>
0243 struct get_key_of_value
0244 {
0245 typedef KeyOfValue type;
0246 };
0247
0248 template<class T>
0249 struct get_key_of_value<void, T>
0250 {
0251 typedef ::boost::intrusive::detail::identity<T> type;
0252 };
0253
0254 template<class ValuePtr, class VoidOrKeyOfValue, class VoidOrKeyComp>
0255 struct bst_key_types
0256 {
0257 typedef typename
0258 boost::movelib::pointer_element<ValuePtr>::type value_type;
0259 typedef typename get_key_of_value
0260 < VoidOrKeyOfValue, value_type>::type key_of_value;
0261 typedef typename key_of_value::type key_type;
0262 typedef typename get_compare< VoidOrKeyComp
0263 , key_type
0264 >::type key_compare;
0265 typedef tree_value_compare
0266 <ValuePtr, key_compare, key_of_value> value_compare;
0267 };
0268
0269 template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, algo_types AlgoType, typename HeaderHolder>
0270 struct bstbase2
0271
0272
0273 : public detail::ebo_functor_holder
0274 < typename bst_key_types
0275 < typename ValueTraits::pointer
0276 , VoidOrKeyOfValue
0277 , VoidOrKeyComp
0278
0279 >::value_compare
0280 >
0281 , public bstbase3<ValueTraits, AlgoType, HeaderHolder>
0282 {
0283 typedef bstbase3<ValueTraits, AlgoType, HeaderHolder> treeheader_t;
0284 typedef bst_key_types< typename ValueTraits::pointer
0285 , VoidOrKeyOfValue
0286 , VoidOrKeyComp> key_types;
0287 typedef typename treeheader_t::value_traits value_traits;
0288 typedef typename treeheader_t::node_algorithms node_algorithms;
0289 typedef typename ValueTraits::value_type value_type;
0290 typedef typename key_types::key_type key_type;
0291 typedef typename key_types::key_of_value key_of_value;
0292 typedef typename key_types::key_compare key_compare;
0293 typedef typename key_types::value_compare value_compare;
0294 typedef typename treeheader_t::iterator iterator;
0295 typedef typename treeheader_t::const_iterator const_iterator;
0296 typedef typename treeheader_t::node_ptr node_ptr;
0297 typedef typename treeheader_t::const_node_ptr const_node_ptr;
0298
0299 bstbase2(const key_compare &comp, const ValueTraits &vtraits)
0300 : detail::ebo_functor_holder<value_compare>(value_compare(comp)), treeheader_t(vtraits)
0301 {}
0302
0303 const value_compare &get_comp() const
0304 { return this->get(); }
0305
0306 value_compare &get_comp()
0307 { return this->get(); }
0308
0309 typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer;
0310 typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer;
0311 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference) reference;
0312 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::reference) const_reference;
0313 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::difference_type) difference_type;
0314 typedef typename node_algorithms::insert_commit_data insert_commit_data;
0315
0316 inline value_compare value_comp() const
0317 { return this->get_comp(); }
0318
0319 inline key_compare key_comp() const
0320 { return this->get_comp().key_comp(); }
0321
0322
0323 inline iterator lower_bound(const key_type &key)
0324 { return this->lower_bound(key, this->key_comp()); }
0325
0326 inline const_iterator lower_bound(const key_type &key) const
0327 { return this->lower_bound(key, this->key_comp()); }
0328
0329 template<class KeyType, class KeyTypeKeyCompare>
0330 iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp)
0331 {
0332 return iterator(node_algorithms::lower_bound
0333 (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
0334 }
0335
0336 template<class KeyType, class KeyTypeKeyCompare>
0337 const_iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp) const
0338 {
0339 return const_iterator(node_algorithms::lower_bound
0340 (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
0341 }
0342
0343
0344 inline iterator upper_bound(const key_type &key)
0345 { return this->upper_bound(key, this->key_comp()); }
0346
0347 template<class KeyType, class KeyTypeKeyCompare>
0348 iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp)
0349 {
0350 return iterator(node_algorithms::upper_bound
0351 (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
0352 }
0353
0354 inline const_iterator upper_bound(const key_type &key) const
0355 { return this->upper_bound(key, this->key_comp()); }
0356
0357 template<class KeyType, class KeyTypeKeyCompare>
0358 const_iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp) const
0359 {
0360 return const_iterator(node_algorithms::upper_bound
0361 (this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
0362 }
0363
0364 template<class KeyTypeKeyCompare>
0365 struct key_node_comp_ret
0366 { typedef detail::key_nodeptr_comp<KeyTypeKeyCompare, value_traits, key_of_value> type; };
0367
0368 template<class KeyTypeKeyCompare>
0369 inline typename key_node_comp_ret<KeyTypeKeyCompare>::type key_node_comp(KeyTypeKeyCompare comp) const
0370 {
0371 return detail::key_nodeptr_comp<KeyTypeKeyCompare, value_traits, key_of_value>(comp, &this->get_value_traits());
0372 }
0373
0374
0375 inline iterator find(const key_type &key)
0376 { return this->find(key, this->key_comp()); }
0377
0378 template<class KeyType, class KeyTypeKeyCompare>
0379 iterator find(const KeyType &key, KeyTypeKeyCompare comp)
0380 {
0381 return iterator
0382 (node_algorithms::find(this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
0383 }
0384
0385 inline const_iterator find(const key_type &key) const
0386 { return this->find(key, this->key_comp()); }
0387
0388 template<class KeyType, class KeyTypeKeyCompare>
0389 const_iterator find(const KeyType &key, KeyTypeKeyCompare comp) const
0390 {
0391 return const_iterator
0392 (node_algorithms::find(this->header_ptr(), key, this->key_node_comp(comp)), this->priv_value_traits_ptr());
0393 }
0394
0395
0396 inline std::pair<iterator,iterator> equal_range(const key_type &key)
0397 { return this->equal_range(key, this->key_comp()); }
0398
0399 template<class KeyType, class KeyTypeKeyCompare>
0400 std::pair<iterator,iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp)
0401 {
0402 std::pair<node_ptr, node_ptr> ret =
0403 node_algorithms::equal_range(this->header_ptr(), key, this->key_node_comp(comp));
0404 return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr())
0405 , iterator(ret.second, this->priv_value_traits_ptr()));
0406 }
0407
0408 inline std::pair<const_iterator, const_iterator>
0409 equal_range(const key_type &key) const
0410 { return this->equal_range(key, this->key_comp()); }
0411
0412 template<class KeyType, class KeyTypeKeyCompare>
0413 std::pair<const_iterator, const_iterator>
0414 equal_range(const KeyType &key, KeyTypeKeyCompare comp) const
0415 {
0416 std::pair<node_ptr, node_ptr> ret =
0417 node_algorithms::equal_range(this->header_ptr(), key, this->key_node_comp(comp));
0418 return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr())
0419 , const_iterator(ret.second, this->priv_value_traits_ptr()));
0420 }
0421
0422
0423 inline std::pair<iterator,iterator> lower_bound_range(const key_type &key)
0424 { return this->lower_bound_range(key, this->key_comp()); }
0425
0426 template<class KeyType, class KeyTypeKeyCompare>
0427 std::pair<iterator,iterator> lower_bound_range(const KeyType &key, KeyTypeKeyCompare comp)
0428 {
0429 std::pair<node_ptr, node_ptr> ret =
0430 node_algorithms::lower_bound_range(this->header_ptr(), key, this->key_node_comp(comp));
0431 return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr())
0432 , iterator(ret.second, this->priv_value_traits_ptr()));
0433 }
0434
0435 inline std::pair<const_iterator, const_iterator>
0436 lower_bound_range(const key_type &key) const
0437 { return this->lower_bound_range(key, this->key_comp()); }
0438
0439 template<class KeyType, class KeyTypeKeyCompare>
0440 std::pair<const_iterator, const_iterator>
0441 lower_bound_range(const KeyType &key, KeyTypeKeyCompare comp) const
0442 {
0443 std::pair<node_ptr, node_ptr> ret =
0444 node_algorithms::lower_bound_range(this->header_ptr(), key, this->key_node_comp(comp));
0445 return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr())
0446 , const_iterator(ret.second, this->priv_value_traits_ptr()));
0447 }
0448
0449
0450 inline std::pair<iterator,iterator> bounded_range
0451 (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed)
0452 { return this->bounded_range(lower_key, upper_key, this->key_comp(), left_closed, right_closed); }
0453
0454 template<class KeyType, class KeyTypeKeyCompare>
0455 std::pair<iterator,iterator> bounded_range
0456 (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed)
0457 {
0458 std::pair<node_ptr, node_ptr> ret =
0459 node_algorithms::bounded_range
0460 (this->header_ptr(), lower_key, upper_key, this->key_node_comp(comp), left_closed, right_closed);
0461 return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr())
0462 , iterator(ret.second, this->priv_value_traits_ptr()));
0463 }
0464
0465 inline std::pair<const_iterator,const_iterator> bounded_range
0466 (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const
0467 { return this->bounded_range(lower_key, upper_key, this->key_comp(), left_closed, right_closed); }
0468
0469 template<class KeyType, class KeyTypeKeyCompare>
0470 std::pair<const_iterator,const_iterator> bounded_range
0471 (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const
0472 {
0473 std::pair<node_ptr, node_ptr> ret =
0474 node_algorithms::bounded_range
0475 (this->header_ptr(), lower_key, upper_key, this->key_node_comp(comp), left_closed, right_closed);
0476 return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr())
0477 , const_iterator(ret.second, this->priv_value_traits_ptr()));
0478 }
0479
0480
0481 inline std::pair<iterator, bool> insert_unique_check
0482 (const key_type &key, insert_commit_data &commit_data)
0483 { return this->insert_unique_check(key, this->key_comp(), commit_data); }
0484
0485 inline std::pair<iterator, bool> insert_unique_check
0486 (const_iterator hint, const key_type &key, insert_commit_data &commit_data)
0487 { return this->insert_unique_check(hint, key, this->key_comp(), commit_data); }
0488
0489 template<class KeyType, class KeyTypeKeyCompare>
0490 BOOST_INTRUSIVE_DOC1ST(std::pair<iterator BOOST_INTRUSIVE_I bool>
0491 , typename detail::disable_if_convertible
0492 <KeyType BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I
0493 std::pair<iterator BOOST_INTRUSIVE_I bool> >::type)
0494 insert_unique_check
0495 (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
0496 {
0497 std::pair<node_ptr, bool> ret =
0498 (node_algorithms::insert_unique_check
0499 (this->header_ptr(), key, this->key_node_comp(comp), commit_data));
0500 return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
0501 }
0502
0503 template<class KeyType, class KeyTypeKeyCompare>
0504 std::pair<iterator, bool> insert_unique_check
0505 (const_iterator hint, const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data)
0506 {
0507 std::pair<node_ptr, bool> ret =
0508 (node_algorithms::insert_unique_check
0509 (this->header_ptr(), hint.pointed_node(), key, this->key_node_comp(comp), commit_data));
0510 return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
0511 }
0512 };
0513
0514
0515
0516
0517 template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, bool ConstantTimeSize, class SizeType, algo_types AlgoType, typename HeaderHolder>
0518 struct bstbase_hack
0519 : public detail::size_holder<ConstantTimeSize, SizeType>
0520 , public bstbase2 < ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder>
0521 {
0522 typedef bstbase2< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder> base_type;
0523 typedef typename base_type::key_compare key_compare;
0524 typedef typename base_type::value_compare value_compare;
0525 typedef SizeType size_type;
0526 typedef typename base_type::node_traits node_traits;
0527 typedef typename get_algo
0528 <AlgoType, node_traits>::type algo_type;
0529
0530 inline bstbase_hack(const key_compare & comp, const ValueTraits &vtraits)
0531 : base_type(comp, vtraits)
0532 {
0533 this->sz_traits().set_size(size_type(0));
0534 }
0535
0536 typedef detail::size_holder<ConstantTimeSize, SizeType> size_traits;
0537
0538 inline size_traits &sz_traits()
0539 { return static_cast<size_traits &>(*this); }
0540
0541 inline const size_traits &sz_traits() const
0542 { return static_cast<const size_traits &>(*this); }
0543 };
0544
0545
0546 template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, algo_types AlgoType, typename HeaderHolder>
0547 struct bstbase_hack<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, false, SizeType, AlgoType, HeaderHolder>
0548 : public bstbase2 < ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder>
0549 {
0550 typedef bstbase2< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, AlgoType, HeaderHolder> base_type;
0551 typedef typename base_type::value_compare value_compare;
0552 typedef typename base_type::key_compare key_compare;
0553 inline bstbase_hack(const key_compare & comp, const ValueTraits &vtraits)
0554 : base_type(comp, vtraits)
0555 {}
0556
0557 typedef detail::size_holder<false, SizeType> size_traits;
0558
0559 inline size_traits sz_traits() const
0560 { return size_traits(); }
0561 };
0562
0563
0564 template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, bool ConstantTimeSize, class SizeType, algo_types AlgoType, typename HeaderHolder>
0565 struct bstbase
0566 : public bstbase_hack< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder>
0567 {
0568 typedef bstbase_hack< ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder> base_type;
0569 typedef ValueTraits value_traits;
0570 typedef typename base_type::value_compare value_compare;
0571 typedef typename base_type::key_compare key_compare;
0572 typedef typename base_type::const_reference const_reference;
0573 typedef typename base_type::reference reference;
0574 typedef typename base_type::iterator iterator;
0575 typedef typename base_type::const_iterator const_iterator;
0576 typedef typename base_type::node_traits node_traits;
0577 typedef typename get_algo
0578 <AlgoType, node_traits>::type node_algorithms;
0579 typedef SizeType size_type;
0580
0581 inline bstbase(const key_compare & comp, const ValueTraits &vtraits)
0582 : base_type(comp, vtraits)
0583 {}
0584
0585
0586
0587 ~bstbase()
0588 {
0589 if(is_safe_autounlink<value_traits::link_mode>::value){
0590 node_algorithms::clear_and_dispose
0591 ( this->header_ptr()
0592 , detail::node_disposer<detail::null_disposer, value_traits, AlgoType>
0593 (detail::null_disposer(), &this->get_value_traits()));
0594 node_algorithms::init(this->header_ptr());
0595 }
0596 }
0597 };
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
0618 template<class T, class ...Options>
0619 #else
0620 template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
0621 #endif
0622 class bstree_impl
0623 : public bstbase<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder>
0624 {
0625 public:
0626
0627 typedef bstbase<ValueTraits, VoidOrKeyOfValue, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder> data_type;
0628 typedef tree_iterator<ValueTraits, false> iterator_type;
0629 typedef tree_iterator<ValueTraits, true> const_iterator_type;
0630
0631
0632 typedef BOOST_INTRUSIVE_IMPDEF(ValueTraits) value_traits;
0633 typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer;
0634 typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer;
0635 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::element_type) value_type;
0636 typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::key_type) key_type;
0637 typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::key_of_value) key_of_value;
0638 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference) reference;
0639 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::reference) const_reference;
0640 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::difference_type) difference_type;
0641 typedef BOOST_INTRUSIVE_IMPDEF(SizeType) size_type;
0642 typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::value_compare) value_compare;
0643 typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::key_compare) key_compare;
0644 typedef BOOST_INTRUSIVE_IMPDEF(iterator_type) iterator;
0645 typedef BOOST_INTRUSIVE_IMPDEF(const_iterator_type) const_iterator;
0646 typedef BOOST_INTRUSIVE_IMPDEF(boost::intrusive::reverse_iterator<iterator>) reverse_iterator;
0647 typedef BOOST_INTRUSIVE_IMPDEF(boost::intrusive::reverse_iterator<const_iterator>) const_reverse_iterator;
0648 typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::node_traits) node_traits;
0649 typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::node) node;
0650 typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::node_ptr) node_ptr;
0651 typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::const_node_ptr) const_node_ptr;
0652
0653 typedef typename get_algo<AlgoType, node_traits>::type algo_type;
0654
0655 typedef BOOST_INTRUSIVE_IMPDEF(algo_type) node_algorithms;
0656
0657 static const bool constant_time_size = ConstantTimeSize;
0658 static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
0659
0660 private:
0661
0662
0663 BOOST_MOVABLE_BUT_NOT_COPYABLE(bstree_impl)
0664
0665 static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
0666
0667
0668 BOOST_INTRUSIVE_STATIC_ASSERT(!(constant_time_size && ((int)value_traits::link_mode == (int)auto_unlink)));
0669
0670
0671 protected:
0672
0673
0674
0675
0676 public:
0677
0678 typedef typename node_algorithms::insert_commit_data insert_commit_data;
0679
0680
0681
0682
0683
0684
0685
0686
0687 bstree_impl()
0688 : data_type(key_compare(), value_traits())
0689 {}
0690
0691
0692
0693
0694
0695
0696
0697
0698 explicit bstree_impl( const key_compare &cmp, const value_traits &v_traits = value_traits())
0699 : data_type(cmp, v_traits)
0700 {}
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714 template<class Iterator>
0715 bstree_impl( bool unique, Iterator b, Iterator e
0716 , const key_compare &cmp = key_compare()
0717 , const value_traits &v_traits = value_traits())
0718 : data_type(cmp, v_traits)
0719 {
0720
0721 if(unique)
0722 this->insert_unique(b, e);
0723 else
0724 this->insert_equal(b, e);
0725 }
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736 bstree_impl(BOOST_RV_REF(bstree_impl) x)
0737 : data_type(::boost::move(x.get_comp()), ::boost::move(x.get_value_traits()))
0738 {
0739 this->swap(x);
0740 }
0741
0742
0743
0744 inline bstree_impl& operator=(BOOST_RV_REF(bstree_impl) x)
0745 { this->swap(x); return *this; }
0746
0747 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0748
0749
0750
0751
0752
0753
0754
0755 ~bstree_impl()
0756 {}
0757
0758
0759
0760
0761
0762
0763 iterator begin() BOOST_NOEXCEPT;
0764
0765
0766
0767
0768
0769
0770 const_iterator begin() const BOOST_NOEXCEPT;
0771
0772
0773
0774
0775
0776
0777 const_iterator cbegin() const BOOST_NOEXCEPT;
0778
0779
0780
0781
0782
0783
0784 iterator end() BOOST_NOEXCEPT;
0785
0786
0787
0788
0789
0790
0791 const_iterator end() const BOOST_NOEXCEPT;
0792
0793
0794
0795
0796
0797
0798 const_iterator cend() const BOOST_NOEXCEPT;
0799
0800
0801
0802
0803
0804
0805
0806 reverse_iterator rbegin() BOOST_NOEXCEPT;
0807
0808
0809
0810
0811
0812
0813
0814 const_reverse_iterator rbegin() const BOOST_NOEXCEPT;
0815
0816
0817
0818
0819
0820
0821
0822 const_reverse_iterator crbegin() const BOOST_NOEXCEPT;
0823
0824
0825
0826
0827
0828
0829
0830 reverse_iterator rend() BOOST_NOEXCEPT;
0831
0832
0833
0834
0835
0836
0837
0838 const_reverse_iterator rend() const BOOST_NOEXCEPT;
0839
0840
0841
0842
0843
0844
0845
0846 const_reverse_iterator crend() const BOOST_NOEXCEPT;
0847
0848
0849
0850
0851
0852
0853 iterator root() BOOST_NOEXCEPT;
0854
0855
0856
0857
0858
0859
0860 const_iterator root() const BOOST_NOEXCEPT;
0861
0862
0863
0864
0865
0866
0867 const_iterator croot() const BOOST_NOEXCEPT;
0868
0869 #endif
0870
0871
0872
0873
0874
0875
0876
0877
0878
0879 BOOST_INTRUSIVE_NO_DANGLING
0880 static bstree_impl& container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
0881 {
0882 return static_cast<bstree_impl&>
0883 (data_type::get_tree_base_from_end_iterator(end_iterator));
0884 }
0885
0886
0887
0888
0889
0890
0891
0892
0893
0894 BOOST_INTRUSIVE_NO_DANGLING
0895 static const bstree_impl & container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
0896 {
0897 return static_cast<bstree_impl&>
0898 (data_type::get_tree_base_from_end_iterator(end_iterator));
0899 }
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909 BOOST_INTRUSIVE_NO_DANGLING
0910 static bstree_impl & container_from_iterator(iterator it) BOOST_NOEXCEPT
0911 { return container_from_end_iterator(it.end_iterator_from_it()); }
0912
0913
0914
0915
0916
0917
0918
0919
0920
0921 BOOST_INTRUSIVE_NO_DANGLING
0922 static const bstree_impl & container_from_iterator(const_iterator it) BOOST_NOEXCEPT
0923 { return container_from_end_iterator(it.end_iterator_from_it()); }
0924
0925 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0926
0927
0928
0929
0930
0931
0932 key_compare key_comp() const;
0933
0934
0935
0936
0937
0938
0939 value_compare value_comp() const;
0940
0941 #endif
0942
0943
0944
0945
0946
0947
0948 bool empty() const BOOST_NOEXCEPT
0949 {
0950 if(ConstantTimeSize){
0951 return !this->data_type::sz_traits().get_size();
0952 }
0953 else{
0954 return algo_type::unique(this->header_ptr());
0955 }
0956 }
0957
0958
0959
0960
0961
0962
0963
0964 size_type size() const BOOST_NOEXCEPT
0965 {
0966 BOOST_IF_CONSTEXPR(constant_time_size)
0967 return this->sz_traits().get_size();
0968 else{
0969 return (size_type)node_algorithms::size(this->header_ptr());
0970 }
0971 }
0972
0973
0974
0975
0976
0977
0978 void swap(bstree_impl& other)
0979 {
0980
0981 ::boost::adl_move_swap(this->get_comp(), other.get_comp());
0982
0983 node_algorithms::swap_tree(this->header_ptr(), node_ptr(other.header_ptr()));
0984 this->sz_traits().swap(other.sz_traits());
0985 }
0986
0987
0988
0989
0990
0991
0992
0993
0994
0995
0996
0997
0998
0999
1000
1001 template <class Cloner, class Disposer>
1002 void clone_from(const bstree_impl &src, Cloner cloner, Disposer disposer)
1003 {
1004 this->clear_and_dispose(disposer);
1005 if(!src.empty()){
1006 detail::exception_disposer<bstree_impl, Disposer>
1007 rollback(*this, disposer);
1008 node_algorithms::clone
1009 (src.header_ptr()
1010 ,this->header_ptr()
1011 ,detail::node_cloner <Cloner, value_traits, AlgoType>(cloner, &this->get_value_traits())
1012 ,detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
1013 this->sz_traits().set_size(src.sz_traits().get_size());
1014 this->get_comp() = src.get_comp();
1015 rollback.release();
1016 }
1017 }
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036 template <class Cloner, class Disposer>
1037 void clone_from(BOOST_RV_REF(bstree_impl) src, Cloner cloner, Disposer disposer)
1038 {
1039 this->clear_and_dispose(disposer);
1040 if(!src.empty()){
1041 detail::exception_disposer<bstree_impl, Disposer>
1042 rollback(*this, disposer);
1043 node_algorithms::clone
1044 (src.header_ptr()
1045 ,this->header_ptr()
1046 ,detail::node_cloner <Cloner, value_traits, AlgoType, false>(cloner, &this->get_value_traits())
1047 ,detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
1048 this->sz_traits().set_size(src.sz_traits().get_size());
1049 this->get_comp() = src.get_comp();
1050 rollback.release();
1051 }
1052 }
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065 iterator insert_equal(reference value)
1066 {
1067 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1068 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1069 iterator ret(node_algorithms::insert_equal_upper_bound
1070 (this->header_ptr(), to_insert, this->key_node_comp(this->key_comp())), this->priv_value_traits_ptr());
1071 this->sz_traits().increment();
1072 return ret;
1073 }
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089 iterator insert_equal(const_iterator hint, reference value)
1090 {
1091 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1092 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1093 iterator ret(node_algorithms::insert_equal
1094 (this->header_ptr(), hint.pointed_node(), to_insert, this->key_node_comp(this->key_comp())), this->priv_value_traits_ptr());
1095 this->sz_traits().increment();
1096 return ret;
1097 }
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113 template<class Iterator>
1114 void insert_equal(Iterator b, Iterator e)
1115 {
1116 iterator iend(this->end());
1117 for (; b != e; ++b)
1118 this->insert_equal(iend, *b);
1119 }
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133 std::pair<iterator, bool> insert_unique(reference value)
1134 {
1135 insert_commit_data commit_data;
1136 std::pair<node_ptr, bool> ret =
1137 (node_algorithms::insert_unique_check
1138 (this->header_ptr(), key_of_value()(value), this->key_node_comp(this->key_comp()), commit_data));
1139 return std::pair<iterator, bool>
1140 ( ret.second ? this->insert_unique_commit(value, commit_data)
1141 : iterator(ret.first, this->priv_value_traits_ptr())
1142 , ret.second);
1143 }
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159 iterator insert_unique(const_iterator hint, reference value)
1160 {
1161 insert_commit_data commit_data;
1162 std::pair<node_ptr, bool> ret =
1163 (node_algorithms::insert_unique_check
1164 (this->header_ptr(), hint.pointed_node(), key_of_value()(value), this->key_node_comp(this->key_comp()), commit_data));
1165 return ret.second ? this->insert_unique_commit(value, commit_data)
1166 : iterator(ret.first, this->priv_value_traits_ptr());
1167 }
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182 template<class Iterator>
1183 void insert_unique(Iterator b, Iterator e)
1184 {
1185 if(this->empty()){
1186 iterator iend(this->end());
1187 for (; b != e; ++b)
1188 this->insert_unique(iend, *b);
1189 }
1190 else{
1191 for (; b != e; ++b)
1192 this->insert_unique(*b);
1193 }
1194 }
1195
1196 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210 std::pair<iterator, bool> insert_unique_check(const key_type &key, insert_commit_data &commit_data);
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226 std::pair<iterator, bool> insert_unique_check(const_iterator hint, const key_type &key, insert_commit_data &commit_data);
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258 template<class KeyType, class KeyTypeKeyCompare>
1259 std::pair<iterator, bool> insert_unique_check
1260 (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data);
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294 template<class KeyType, class KeyTypeKeyCompare>
1295 std::pair<iterator, bool> insert_unique_check
1296 (const_iterator hint, const KeyType &key
1297 ,KeyTypeKeyCompare comp, insert_commit_data &commit_data);
1298
1299 #endif
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318 iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT
1319 {
1320 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1321 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1322
1323 #if !(defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) ))
1324
1325 iterator p(commit_data.node, this->priv_value_traits_ptr());
1326 if(!commit_data.link_left){
1327 ++p;
1328 }
1329
1330
1331 BOOST_ASSERT(( p == this->end() || !this->get_comp()(*p, value) ));
1332 BOOST_ASSERT(( p == this->begin() || !this->get_comp()(value, *--p) ));
1333 #endif
1334
1335 node_algorithms::insert_unique_commit
1336 (this->header_ptr(), to_insert, commit_data);
1337 this->sz_traits().increment();
1338 return iterator(to_insert, this->priv_value_traits_ptr());
1339 }
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355 iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT
1356 {
1357 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1358 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1359 this->sz_traits().increment();
1360 return iterator(node_algorithms::insert_before
1361 (this->header_ptr(), pos.pointed_node(), to_insert), this->priv_value_traits_ptr());
1362 }
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378 void push_back(reference value) BOOST_NOEXCEPT
1379 {
1380 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1381 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1382 this->sz_traits().increment();
1383 node_algorithms::push_back(this->header_ptr(), to_insert);
1384 }
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400 void push_front(reference value) BOOST_NOEXCEPT
1401 {
1402 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1403 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1404 this->sz_traits().increment();
1405 node_algorithms::push_front(this->header_ptr(), to_insert);
1406 }
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416 iterator erase(const_iterator i) BOOST_NOEXCEPT
1417 {
1418 const_iterator ret(i);
1419 ++ret;
1420 node_ptr to_erase(i.pointed_node());
1421 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(to_erase));
1422 node_algorithms::erase(this->header_ptr(), to_erase);
1423 this->sz_traits().decrement();
1424 BOOST_IF_CONSTEXPR(safemode_or_autounlink)
1425 node_algorithms::init(to_erase);
1426 return ret.unconst();
1427 }
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438 iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT
1439 { size_type n; return this->private_erase(b, e, n); }
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451 size_type erase(const key_type &key) BOOST_NOEXCEPT
1452 { return this->erase(key, this->key_comp()); }
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469 template<class KeyType, class KeyTypeKeyCompare>
1470 BOOST_INTRUSIVE_DOC1ST(size_type
1471 , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
1472 erase(const KeyType& key, KeyTypeKeyCompare comp)
1473 {
1474 std::pair<iterator,iterator> p = this->equal_range(key, comp);
1475 size_type n;
1476 this->private_erase(p.first, p.second, n);
1477 return n;
1478 }
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491 template<class Disposer>
1492 iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT
1493 {
1494 node_ptr to_erase(i.pointed_node());
1495 iterator ret(this->erase(i));
1496 disposer(this->get_value_traits().to_value_ptr(to_erase));
1497 return ret;
1498 }
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513 template<class Disposer>
1514 size_type erase_and_dispose(const key_type &key, Disposer disposer)
1515 {
1516 std::pair<iterator,iterator> p = this->equal_range(key);
1517 size_type n;
1518 this->private_erase(p.first, p.second, n, disposer);
1519 return n;
1520 }
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534 template<class Disposer>
1535 iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT
1536 { size_type n; return this->private_erase(b, e, n, disposer); }
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556 template<class KeyType, class KeyTypeKeyCompare, class Disposer>
1557 BOOST_INTRUSIVE_DOC1ST(size_type
1558 , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
1559 erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer)
1560 {
1561 std::pair<iterator,iterator> p = this->equal_range(key, comp);
1562 size_type n;
1563 this->private_erase(p.first, p.second, n, disposer);
1564 return n;
1565 }
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576 void clear() BOOST_NOEXCEPT
1577 {
1578 BOOST_IF_CONSTEXPR(safemode_or_autounlink){
1579 this->clear_and_dispose(detail::null_disposer());
1580 }
1581 else{
1582 node_algorithms::init_header(this->header_ptr());
1583 this->sz_traits().set_size(0);
1584 }
1585 }
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596 template<class Disposer>
1597 void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT
1598 {
1599 node_algorithms::clear_and_dispose(this->header_ptr()
1600 , detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
1601 node_algorithms::init_header(this->header_ptr());
1602 this->sz_traits().set_size(0);
1603 }
1604
1605
1606
1607
1608
1609
1610
1611 size_type count(const key_type &key) const
1612 { return size_type(this->count(key, this->key_comp())); }
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624 template<class KeyType, class KeyTypeKeyCompare>
1625 size_type count(const KeyType &key, KeyTypeKeyCompare comp) const
1626 {
1627 std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
1628 size_type n = 0;
1629 for(; ret.first != ret.second; ++ret.first){ ++n; }
1630 return n;
1631 }
1632
1633 #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1634
1635
1636
1637 size_type count(const key_type &key)
1638 { return size_type(this->count(key, this->key_comp())); }
1639
1640 template<class KeyType, class KeyTypeKeyCompare>
1641 size_type count(const KeyType &key, KeyTypeKeyCompare comp)
1642 {
1643 std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
1644 size_type n = 0;
1645 for(; ret.first != ret.second; ++ret.first){ ++n; }
1646 return n;
1647 }
1648
1649 #else
1650
1651
1652
1653
1654
1655
1656
1657 iterator lower_bound(const key_type &key);
1658
1659
1660
1661
1662
1663
1664
1665 const_iterator lower_bound(const key_type &key) const;
1666
1667
1668 template<class KeyType, class KeyTypeKeyCompare>
1669 iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp);
1670
1671
1672 template<class KeyType, class KeyTypeKeyCompare>
1673 const_iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp) const;
1674
1675
1676
1677
1678
1679
1680
1681 iterator upper_bound(const key_type &key);
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693 template<class KeyType, class KeyTypeKeyCompare>
1694 iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp);
1695
1696
1697 const_iterator upper_bound(const key_type &key) const;
1698
1699
1700 template<class KeyType, class KeyTypeKeyCompare>
1701 const_iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp) const;
1702
1703
1704
1705
1706
1707
1708
1709 iterator find(const key_type &key);
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721 template<class KeyType, class KeyTypeKeyCompare>
1722 iterator find(const KeyType &key, KeyTypeKeyCompare comp);
1723
1724
1725 const_iterator find(const key_type &key) const;
1726
1727
1728 template<class KeyType, class KeyTypeKeyCompare>
1729 const_iterator find(const KeyType &key, KeyTypeKeyCompare comp) const;
1730
1731
1732
1733
1734
1735
1736
1737
1738 std::pair<iterator,iterator> equal_range(const key_type &key);
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751 template<class KeyType, class KeyTypeKeyCompare>
1752 std::pair<iterator,iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp);
1753
1754
1755 std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const;
1756
1757
1758 template<class KeyType, class KeyTypeKeyCompare>
1759 std::pair<const_iterator, const_iterator>
1760 equal_range(const KeyType &key, KeyTypeKeyCompare comp) const;
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784 std::pair<iterator,iterator> bounded_range
1785 (const key_type &lower_key, const key_type &upper_value, bool left_closed, bool right_closed);
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815 template<class KeyType, class KeyTypeKeyCompare>
1816 std::pair<iterator,iterator> bounded_range
1817 (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
1818
1819
1820 std::pair<const_iterator,const_iterator> bounded_range
1821 (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
1822
1823
1824 template<class KeyType, class KeyTypeKeyCompare>
1825 std::pair<const_iterator,const_iterator> bounded_range
1826 (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840 static iterator s_iterator_to(reference value) BOOST_NOEXCEPT;
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854 static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT;
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865 iterator iterator_to(reference value) BOOST_NOEXCEPT;
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876 const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT;
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889 static void init_node(reference value) BOOST_NOEXCEPT;
1890
1891 #endif
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903 pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT
1904 {
1905 node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
1906 (this->header_ptr()));
1907 if(!to_be_disposed)
1908 return 0;
1909 this->sz_traits().decrement();
1910 BOOST_IF_CONSTEXPR(safemode_or_autounlink)
1911 node_algorithms::init(to_be_disposed);
1912 return this->get_value_traits().to_value_ptr(to_be_disposed);
1913 }
1914
1915 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931 void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT;
1932
1933
1934
1935
1936
1937
1938 void rebalance() BOOST_NOEXCEPT;
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949 iterator rebalance_subtree(iterator r) BOOST_NOEXCEPT;
1950
1951 #endif
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965 static void remove_node(reference value) BOOST_NOEXCEPT
1966 {
1967 BOOST_INTRUSIVE_STATIC_ASSERT((!constant_time_size));
1968 node_ptr to_remove(value_traits::to_node_ptr(value));
1969 node_algorithms::unlink(to_remove);
1970 BOOST_IF_CONSTEXPR(safemode_or_autounlink)
1971 node_algorithms::init(to_remove);
1972 }
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1990 template<class T, class ...Options2> void merge_unique(bstree<T, Options2...> &);
1991 #else
1992 template<class Compare2>
1993 void merge_unique(bstree_impl
1994 <ValueTraits, VoidOrKeyOfValue, Compare2, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &source)
1995 #endif
1996 {
1997 node_ptr it (node_algorithms::begin_node(source.header_ptr()))
1998 , itend(node_algorithms::end_node (source.header_ptr()));
1999
2000 while(it != itend){
2001 node_ptr const p(it);
2002 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p));
2003 it = node_algorithms::next_node(it);
2004 if( node_algorithms::transfer_unique(this->header_ptr(), this->key_node_comp(this->key_comp()), source.header_ptr(), p) ){
2005 source.sz_traits().decrement();
2006 this->sz_traits().increment();
2007 }
2008 }
2009 }
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2026 template<class T, class ...Options2> void merge_equal(bstree<T, Options2...> &);
2027 #else
2028 template<class Compare2>
2029 void merge_equal(bstree_impl
2030 <ValueTraits, VoidOrKeyOfValue, Compare2, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &source)
2031 #endif
2032 {
2033 node_ptr it (node_algorithms::begin_node(source.header_ptr()))
2034 , itend(node_algorithms::end_node (source.header_ptr()));
2035
2036 while(it != itend){
2037 node_ptr const p(it);
2038 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p));
2039 it = node_algorithms::next_node(it);
2040 node_algorithms::transfer_equal(this->header_ptr(), this->key_node_comp(this->key_comp()), source.header_ptr(), p);
2041 source.sz_traits().decrement();
2042 this->sz_traits().increment();
2043 }
2044 }
2045
2046
2047
2048
2049
2050
2051
2052 template <class ExtraChecker>
2053 void check(ExtraChecker extra_checker) const
2054 {
2055 typedef detail::key_nodeptr_comp<key_compare, value_traits, key_of_value> nodeptr_comp_t;
2056 nodeptr_comp_t nodeptr_comp(this->key_comp(), &this->get_value_traits());
2057 typedef typename get_node_checker<AlgoType, ValueTraits, nodeptr_comp_t, ExtraChecker>::type node_checker_t;
2058 typename node_checker_t::return_type checker_return;
2059 node_algorithms::check(this->header_ptr(), node_checker_t(nodeptr_comp, extra_checker), checker_return);
2060 BOOST_INTRUSIVE_INVARIANT_ASSERT(!constant_time_size || this->sz_traits().get_size() == checker_return.node_count);
2061 }
2062
2063
2064
2065
2066
2067
2068
2069 void check() const
2070 {
2071 check(detail::empty_node_checker<ValueTraits>());
2072 }
2073
2074 friend bool operator==(const bstree_impl &x, const bstree_impl &y)
2075 {
2076 if(constant_time_size && x.size() != y.size()){
2077 return false;
2078 }
2079 return boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
2080 }
2081
2082 friend bool operator!=(const bstree_impl &x, const bstree_impl &y)
2083 { return !(x == y); }
2084
2085 friend bool operator<(const bstree_impl &x, const bstree_impl &y)
2086 { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
2087
2088 friend bool operator>(const bstree_impl &x, const bstree_impl &y)
2089 { return y < x; }
2090
2091 friend bool operator<=(const bstree_impl &x, const bstree_impl &y)
2092 { return !(x > y); }
2093
2094 friend bool operator>=(const bstree_impl &x, const bstree_impl &y)
2095 { return !(x < y); }
2096
2097 friend void swap(bstree_impl &x, bstree_impl &y)
2098 { x.swap(y); }
2099
2100
2101 private:
2102 template<class Disposer>
2103 iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer)
2104 {
2105 for(n = 0; b != e; ++n)
2106 this->erase_and_dispose(b++, disposer);
2107 return b.unconst();
2108 }
2109
2110 iterator private_erase(const_iterator b, const_iterator e, size_type &n)
2111 {
2112 for(n = 0; b != e; ++n)
2113 this->erase(b++);
2114 return b.unconst();
2115 }
2116
2117 };
2118
2119
2120
2121 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2122 template<class T, class ...Options>
2123 #else
2124 template<class T, class O1 = void, class O2 = void
2125 , class O3 = void, class O4 = void
2126 , class O5 = void, class O6 = void>
2127 #endif
2128 struct make_bstree
2129 {
2130
2131 typedef typename pack_options
2132 < bstree_defaults,
2133 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2134 O1, O2, O3, O4, O5, O6
2135 #else
2136 Options...
2137 #endif
2138 >::type packed_options;
2139
2140 typedef typename detail::get_value_traits
2141 <T, typename packed_options::proto_value_traits>::type value_traits;
2142
2143 typedef bstree_impl
2144 < value_traits
2145 , typename packed_options::key_of_value
2146 , typename packed_options::compare
2147 , typename packed_options::size_type
2148 , packed_options::constant_time_size
2149 , BsTreeAlgorithms
2150 , typename packed_options::header_holder_type
2151 > implementation_defined;
2152
2153 typedef implementation_defined type;
2154 };
2155
2156
2157 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
2158
2159 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2160 template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
2161 #else
2162 template<class T, class ...Options>
2163 #endif
2164 class bstree
2165 : public make_bstree<T,
2166 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2167 O1, O2, O3, O4, O5, O6
2168 #else
2169 Options...
2170 #endif
2171 >::type
2172 {
2173 typedef typename make_bstree
2174 <T,
2175 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2176 O1, O2, O3, O4, O5, O6
2177 #else
2178 Options...
2179 #endif
2180 >::type Base;
2181 BOOST_MOVABLE_BUT_NOT_COPYABLE(bstree)
2182
2183 public:
2184 typedef typename Base::key_compare key_compare;
2185 typedef typename Base::value_traits value_traits;
2186 typedef typename Base::iterator iterator;
2187 typedef typename Base::const_iterator const_iterator;
2188
2189
2190 BOOST_INTRUSIVE_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
2191
2192 inline bstree()
2193 : Base()
2194 {}
2195
2196 inline explicit bstree( const key_compare &cmp, const value_traits &v_traits = value_traits())
2197 : Base(cmp, v_traits)
2198 {}
2199
2200 template<class Iterator>
2201 inline bstree( bool unique, Iterator b, Iterator e
2202 , const key_compare &cmp = key_compare()
2203 , const value_traits &v_traits = value_traits())
2204 : Base(unique, b, e, cmp, v_traits)
2205 {}
2206
2207 inline bstree(BOOST_RV_REF(bstree) x)
2208 : Base(BOOST_MOVE_BASE(Base, x))
2209 {}
2210
2211 inline bstree& operator=(BOOST_RV_REF(bstree) x)
2212 { return static_cast<bstree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
2213
2214 template <class Cloner, class Disposer>
2215 inline void clone_from(const bstree &src, Cloner cloner, Disposer disposer)
2216 { Base::clone_from(src, cloner, disposer); }
2217
2218 template <class Cloner, class Disposer>
2219 inline void clone_from(BOOST_RV_REF(bstree) src, Cloner cloner, Disposer disposer)
2220 { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
2221
2222 BOOST_INTRUSIVE_NO_DANGLING
2223 inline static bstree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
2224 { return static_cast<bstree &>(Base::container_from_end_iterator(end_iterator)); }
2225
2226 BOOST_INTRUSIVE_NO_DANGLING
2227 inline static const bstree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
2228 { return static_cast<const bstree &>(Base::container_from_end_iterator(end_iterator)); }
2229
2230 BOOST_INTRUSIVE_NO_DANGLING
2231 inline static bstree &container_from_iterator(iterator it) BOOST_NOEXCEPT
2232 { return static_cast<bstree &>(Base::container_from_iterator(it)); }
2233
2234 BOOST_INTRUSIVE_NO_DANGLING
2235 inline static const bstree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
2236 { return static_cast<const bstree &>(Base::container_from_iterator(it)); }
2237 };
2238
2239 #endif
2240 }
2241 }
2242
2243 #include <boost/intrusive/detail/config_end.hpp>
2244
2245 #endif