File indexing completed on 2025-07-14 08:34:42
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 static bstree_impl &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
0880 {
0881 return static_cast<bstree_impl&>
0882 (data_type::get_tree_base_from_end_iterator(end_iterator));
0883 }
0884
0885
0886
0887
0888
0889
0890
0891
0892
0893 static const bstree_impl &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
0894 {
0895 return static_cast<bstree_impl&>
0896 (data_type::get_tree_base_from_end_iterator(end_iterator));
0897 }
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907 static bstree_impl &container_from_iterator(iterator it) BOOST_NOEXCEPT
0908 { return container_from_end_iterator(it.end_iterator_from_it()); }
0909
0910
0911
0912
0913
0914
0915
0916
0917
0918 static const bstree_impl &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
0919 { return container_from_end_iterator(it.end_iterator_from_it()); }
0920
0921 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0922
0923
0924
0925
0926
0927
0928 key_compare key_comp() const;
0929
0930
0931
0932
0933
0934
0935 value_compare value_comp() const;
0936
0937 #endif
0938
0939
0940
0941
0942
0943
0944 bool empty() const BOOST_NOEXCEPT
0945 {
0946 if(ConstantTimeSize){
0947 return !this->data_type::sz_traits().get_size();
0948 }
0949 else{
0950 return algo_type::unique(this->header_ptr());
0951 }
0952 }
0953
0954
0955
0956
0957
0958
0959
0960 size_type size() const BOOST_NOEXCEPT
0961 {
0962 BOOST_IF_CONSTEXPR(constant_time_size)
0963 return this->sz_traits().get_size();
0964 else{
0965 return (size_type)node_algorithms::size(this->header_ptr());
0966 }
0967 }
0968
0969
0970
0971
0972
0973
0974 void swap(bstree_impl& other)
0975 {
0976
0977 ::boost::adl_move_swap(this->get_comp(), other.get_comp());
0978
0979 node_algorithms::swap_tree(this->header_ptr(), node_ptr(other.header_ptr()));
0980 this->sz_traits().swap(other.sz_traits());
0981 }
0982
0983
0984
0985
0986
0987
0988
0989
0990
0991
0992
0993
0994
0995
0996
0997 template <class Cloner, class Disposer>
0998 void clone_from(const bstree_impl &src, Cloner cloner, Disposer disposer)
0999 {
1000 this->clear_and_dispose(disposer);
1001 if(!src.empty()){
1002 detail::exception_disposer<bstree_impl, Disposer>
1003 rollback(*this, disposer);
1004 node_algorithms::clone
1005 (src.header_ptr()
1006 ,this->header_ptr()
1007 ,detail::node_cloner <Cloner, value_traits, AlgoType>(cloner, &this->get_value_traits())
1008 ,detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
1009 this->sz_traits().set_size(src.sz_traits().get_size());
1010 this->get_comp() = src.get_comp();
1011 rollback.release();
1012 }
1013 }
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032 template <class Cloner, class Disposer>
1033 void clone_from(BOOST_RV_REF(bstree_impl) src, Cloner cloner, Disposer disposer)
1034 {
1035 this->clear_and_dispose(disposer);
1036 if(!src.empty()){
1037 detail::exception_disposer<bstree_impl, Disposer>
1038 rollback(*this, disposer);
1039 node_algorithms::clone
1040 (src.header_ptr()
1041 ,this->header_ptr()
1042 ,detail::node_cloner <Cloner, value_traits, AlgoType, false>(cloner, &this->get_value_traits())
1043 ,detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
1044 this->sz_traits().set_size(src.sz_traits().get_size());
1045 this->get_comp() = src.get_comp();
1046 rollback.release();
1047 }
1048 }
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061 iterator insert_equal(reference value)
1062 {
1063 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1064 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1065 iterator ret(node_algorithms::insert_equal_upper_bound
1066 (this->header_ptr(), to_insert, this->key_node_comp(this->key_comp())), this->priv_value_traits_ptr());
1067 this->sz_traits().increment();
1068 return ret;
1069 }
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085 iterator insert_equal(const_iterator hint, reference value)
1086 {
1087 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1088 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1089 iterator ret(node_algorithms::insert_equal
1090 (this->header_ptr(), hint.pointed_node(), to_insert, this->key_node_comp(this->key_comp())), this->priv_value_traits_ptr());
1091 this->sz_traits().increment();
1092 return ret;
1093 }
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109 template<class Iterator>
1110 void insert_equal(Iterator b, Iterator e)
1111 {
1112 iterator iend(this->end());
1113 for (; b != e; ++b)
1114 this->insert_equal(iend, *b);
1115 }
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129 std::pair<iterator, bool> insert_unique(reference value)
1130 {
1131 insert_commit_data commit_data;
1132 std::pair<node_ptr, bool> ret =
1133 (node_algorithms::insert_unique_check
1134 (this->header_ptr(), key_of_value()(value), this->key_node_comp(this->key_comp()), commit_data));
1135 return std::pair<iterator, bool>
1136 ( ret.second ? this->insert_unique_commit(value, commit_data)
1137 : iterator(ret.first, this->priv_value_traits_ptr())
1138 , ret.second);
1139 }
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155 iterator insert_unique(const_iterator hint, reference value)
1156 {
1157 insert_commit_data commit_data;
1158 std::pair<node_ptr, bool> ret =
1159 (node_algorithms::insert_unique_check
1160 (this->header_ptr(), hint.pointed_node(), key_of_value()(value), this->key_node_comp(this->key_comp()), commit_data));
1161 return ret.second ? this->insert_unique_commit(value, commit_data)
1162 : iterator(ret.first, this->priv_value_traits_ptr());
1163 }
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178 template<class Iterator>
1179 void insert_unique(Iterator b, Iterator e)
1180 {
1181 if(this->empty()){
1182 iterator iend(this->end());
1183 for (; b != e; ++b)
1184 this->insert_unique(iend, *b);
1185 }
1186 else{
1187 for (; b != e; ++b)
1188 this->insert_unique(*b);
1189 }
1190 }
1191
1192 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206 std::pair<iterator, bool> insert_unique_check(const key_type &key, insert_commit_data &commit_data);
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222 std::pair<iterator, bool> insert_unique_check(const_iterator hint, const key_type &key, insert_commit_data &commit_data);
1223
1224
1225
1226
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 template<class KeyType, class KeyTypeKeyCompare>
1255 std::pair<iterator, bool> insert_unique_check
1256 (const KeyType &key, KeyTypeKeyCompare comp, insert_commit_data &commit_data);
1257
1258
1259
1260
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 template<class KeyType, class KeyTypeKeyCompare>
1291 std::pair<iterator, bool> insert_unique_check
1292 (const_iterator hint, const KeyType &key
1293 ,KeyTypeKeyCompare comp, insert_commit_data &commit_data);
1294
1295 #endif
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314 iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT
1315 {
1316 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1317 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1318
1319 #if !(defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) ))
1320
1321 iterator p(commit_data.node, this->priv_value_traits_ptr());
1322 if(!commit_data.link_left){
1323 ++p;
1324 }
1325
1326
1327 BOOST_ASSERT(( p == this->end() || !this->get_comp()(*p, value) ));
1328 BOOST_ASSERT(( p == this->begin() || !this->get_comp()(value, *--p) ));
1329 #endif
1330
1331 node_algorithms::insert_unique_commit
1332 (this->header_ptr(), to_insert, commit_data);
1333 this->sz_traits().increment();
1334 return iterator(to_insert, this->priv_value_traits_ptr());
1335 }
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351 iterator insert_before(const_iterator pos, reference value) BOOST_NOEXCEPT
1352 {
1353 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1354 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1355 this->sz_traits().increment();
1356 return iterator(node_algorithms::insert_before
1357 (this->header_ptr(), pos.pointed_node(), to_insert), this->priv_value_traits_ptr());
1358 }
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374 void push_back(reference value) BOOST_NOEXCEPT
1375 {
1376 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1377 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1378 this->sz_traits().increment();
1379 node_algorithms::push_back(this->header_ptr(), to_insert);
1380 }
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396 void push_front(reference value) BOOST_NOEXCEPT
1397 {
1398 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
1399 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(to_insert));
1400 this->sz_traits().increment();
1401 node_algorithms::push_front(this->header_ptr(), to_insert);
1402 }
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412 iterator erase(const_iterator i) BOOST_NOEXCEPT
1413 {
1414 const_iterator ret(i);
1415 ++ret;
1416 node_ptr to_erase(i.pointed_node());
1417 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(to_erase));
1418 node_algorithms::erase(this->header_ptr(), to_erase);
1419 this->sz_traits().decrement();
1420 BOOST_IF_CONSTEXPR(safemode_or_autounlink)
1421 node_algorithms::init(to_erase);
1422 return ret.unconst();
1423 }
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434 iterator erase(const_iterator b, const_iterator e) BOOST_NOEXCEPT
1435 { size_type n; return this->private_erase(b, e, n); }
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447 size_type erase(const key_type &key) BOOST_NOEXCEPT
1448 { return this->erase(key, this->key_comp()); }
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465 template<class KeyType, class KeyTypeKeyCompare>
1466 BOOST_INTRUSIVE_DOC1ST(size_type
1467 , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
1468 erase(const KeyType& key, KeyTypeKeyCompare comp)
1469 {
1470 std::pair<iterator,iterator> p = this->equal_range(key, comp);
1471 size_type n;
1472 this->private_erase(p.first, p.second, n);
1473 return n;
1474 }
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487 template<class Disposer>
1488 iterator erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT
1489 {
1490 node_ptr to_erase(i.pointed_node());
1491 iterator ret(this->erase(i));
1492 disposer(this->get_value_traits().to_value_ptr(to_erase));
1493 return ret;
1494 }
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509 template<class Disposer>
1510 size_type erase_and_dispose(const key_type &key, Disposer disposer)
1511 {
1512 std::pair<iterator,iterator> p = this->equal_range(key);
1513 size_type n;
1514 this->private_erase(p.first, p.second, n, disposer);
1515 return n;
1516 }
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530 template<class Disposer>
1531 iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer) BOOST_NOEXCEPT
1532 { size_type n; return this->private_erase(b, e, n, disposer); }
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552 template<class KeyType, class KeyTypeKeyCompare, class Disposer>
1553 BOOST_INTRUSIVE_DOC1ST(size_type
1554 , typename detail::disable_if_convertible<KeyTypeKeyCompare BOOST_INTRUSIVE_I const_iterator BOOST_INTRUSIVE_I size_type>::type)
1555 erase_and_dispose(const KeyType& key, KeyTypeKeyCompare comp, Disposer disposer)
1556 {
1557 std::pair<iterator,iterator> p = this->equal_range(key, comp);
1558 size_type n;
1559 this->private_erase(p.first, p.second, n, disposer);
1560 return n;
1561 }
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572 void clear() BOOST_NOEXCEPT
1573 {
1574 BOOST_IF_CONSTEXPR(safemode_or_autounlink){
1575 this->clear_and_dispose(detail::null_disposer());
1576 }
1577 else{
1578 node_algorithms::init_header(this->header_ptr());
1579 this->sz_traits().set_size(0);
1580 }
1581 }
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592 template<class Disposer>
1593 void clear_and_dispose(Disposer disposer) BOOST_NOEXCEPT
1594 {
1595 node_algorithms::clear_and_dispose(this->header_ptr()
1596 , detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
1597 node_algorithms::init_header(this->header_ptr());
1598 this->sz_traits().set_size(0);
1599 }
1600
1601
1602
1603
1604
1605
1606
1607 size_type count(const key_type &key) const
1608 { return size_type(this->count(key, this->key_comp())); }
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620 template<class KeyType, class KeyTypeKeyCompare>
1621 size_type count(const KeyType &key, KeyTypeKeyCompare comp) const
1622 {
1623 std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
1624 size_type n = 0;
1625 for(; ret.first != ret.second; ++ret.first){ ++n; }
1626 return n;
1627 }
1628
1629 #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1630
1631
1632
1633 size_type count(const key_type &key)
1634 { return size_type(this->count(key, this->key_comp())); }
1635
1636 template<class KeyType, class KeyTypeKeyCompare>
1637 size_type count(const KeyType &key, KeyTypeKeyCompare comp)
1638 {
1639 std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
1640 size_type n = 0;
1641 for(; ret.first != ret.second; ++ret.first){ ++n; }
1642 return n;
1643 }
1644
1645 #else
1646
1647
1648
1649
1650
1651
1652
1653 iterator lower_bound(const key_type &key);
1654
1655
1656
1657
1658
1659
1660
1661 const_iterator lower_bound(const key_type &key) const;
1662
1663
1664 template<class KeyType, class KeyTypeKeyCompare>
1665 iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp);
1666
1667
1668 template<class KeyType, class KeyTypeKeyCompare>
1669 const_iterator lower_bound(const KeyType &key, KeyTypeKeyCompare comp) const;
1670
1671
1672
1673
1674
1675
1676
1677 iterator upper_bound(const key_type &key);
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689 template<class KeyType, class KeyTypeKeyCompare>
1690 iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp);
1691
1692
1693 const_iterator upper_bound(const key_type &key) const;
1694
1695
1696 template<class KeyType, class KeyTypeKeyCompare>
1697 const_iterator upper_bound(const KeyType &key, KeyTypeKeyCompare comp) const;
1698
1699
1700
1701
1702
1703
1704
1705 iterator find(const key_type &key);
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717 template<class KeyType, class KeyTypeKeyCompare>
1718 iterator find(const KeyType &key, KeyTypeKeyCompare comp);
1719
1720
1721 const_iterator find(const key_type &key) const;
1722
1723
1724 template<class KeyType, class KeyTypeKeyCompare>
1725 const_iterator find(const KeyType &key, KeyTypeKeyCompare comp) const;
1726
1727
1728
1729
1730
1731
1732
1733
1734 std::pair<iterator,iterator> equal_range(const key_type &key);
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747 template<class KeyType, class KeyTypeKeyCompare>
1748 std::pair<iterator,iterator> equal_range(const KeyType &key, KeyTypeKeyCompare comp);
1749
1750
1751 std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const;
1752
1753
1754 template<class KeyType, class KeyTypeKeyCompare>
1755 std::pair<const_iterator, const_iterator>
1756 equal_range(const KeyType &key, KeyTypeKeyCompare comp) const;
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780 std::pair<iterator,iterator> bounded_range
1781 (const key_type &lower_key, const key_type &upper_value, bool left_closed, bool right_closed);
1782
1783
1784
1785
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 template<class KeyType, class KeyTypeKeyCompare>
1812 std::pair<iterator,iterator> bounded_range
1813 (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed);
1814
1815
1816 std::pair<const_iterator,const_iterator> bounded_range
1817 (const key_type &lower_key, const key_type &upper_key, bool left_closed, bool right_closed) const;
1818
1819
1820 template<class KeyType, class KeyTypeKeyCompare>
1821 std::pair<const_iterator,const_iterator> bounded_range
1822 (const KeyType &lower_key, const KeyType &upper_key, KeyTypeKeyCompare comp, bool left_closed, bool right_closed) const;
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836 static iterator s_iterator_to(reference value) BOOST_NOEXCEPT;
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850 static const_iterator s_iterator_to(const_reference value) BOOST_NOEXCEPT;
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861 iterator iterator_to(reference value) BOOST_NOEXCEPT;
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872 const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT;
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885 static void init_node(reference value) BOOST_NOEXCEPT;
1886
1887 #endif
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899 pointer unlink_leftmost_without_rebalance() BOOST_NOEXCEPT
1900 {
1901 node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
1902 (this->header_ptr()));
1903 if(!to_be_disposed)
1904 return 0;
1905 this->sz_traits().decrement();
1906 BOOST_IF_CONSTEXPR(safemode_or_autounlink)
1907 node_algorithms::init(to_be_disposed);
1908 return this->get_value_traits().to_value_ptr(to_be_disposed);
1909 }
1910
1911 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927 void replace_node(iterator replace_this, reference with_this) BOOST_NOEXCEPT;
1928
1929
1930
1931
1932
1933
1934 void rebalance() BOOST_NOEXCEPT;
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945 iterator rebalance_subtree(iterator r) BOOST_NOEXCEPT;
1946
1947 #endif
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961 static void remove_node(reference value) BOOST_NOEXCEPT
1962 {
1963 BOOST_INTRUSIVE_STATIC_ASSERT((!constant_time_size));
1964 node_ptr to_remove(value_traits::to_node_ptr(value));
1965 node_algorithms::unlink(to_remove);
1966 BOOST_IF_CONSTEXPR(safemode_or_autounlink)
1967 node_algorithms::init(to_remove);
1968 }
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1986 template<class T, class ...Options2> void merge_unique(bstree<T, Options2...> &);
1987 #else
1988 template<class Compare2>
1989 void merge_unique(bstree_impl
1990 <ValueTraits, VoidOrKeyOfValue, Compare2, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &source)
1991 #endif
1992 {
1993 node_ptr it (node_algorithms::begin_node(source.header_ptr()))
1994 , itend(node_algorithms::end_node (source.header_ptr()));
1995
1996 while(it != itend){
1997 node_ptr const p(it);
1998 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p));
1999 it = node_algorithms::next_node(it);
2000 if( node_algorithms::transfer_unique(this->header_ptr(), this->key_node_comp(this->key_comp()), source.header_ptr(), p) ){
2001 source.sz_traits().decrement();
2002 this->sz_traits().increment();
2003 }
2004 }
2005 }
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2022 template<class T, class ...Options2> void merge_equal(bstree<T, Options2...> &);
2023 #else
2024 template<class Compare2>
2025 void merge_equal(bstree_impl
2026 <ValueTraits, VoidOrKeyOfValue, Compare2, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &source)
2027 #endif
2028 {
2029 node_ptr it (node_algorithms::begin_node(source.header_ptr()))
2030 , itend(node_algorithms::end_node (source.header_ptr()));
2031
2032 while(it != itend){
2033 node_ptr const p(it);
2034 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || !node_algorithms::unique(p));
2035 it = node_algorithms::next_node(it);
2036 node_algorithms::transfer_equal(this->header_ptr(), this->key_node_comp(this->key_comp()), source.header_ptr(), p);
2037 source.sz_traits().decrement();
2038 this->sz_traits().increment();
2039 }
2040 }
2041
2042
2043
2044
2045
2046
2047
2048 template <class ExtraChecker>
2049 void check(ExtraChecker extra_checker) const
2050 {
2051 typedef detail::key_nodeptr_comp<key_compare, value_traits, key_of_value> nodeptr_comp_t;
2052 nodeptr_comp_t nodeptr_comp(this->key_comp(), &this->get_value_traits());
2053 typedef typename get_node_checker<AlgoType, ValueTraits, nodeptr_comp_t, ExtraChecker>::type node_checker_t;
2054 typename node_checker_t::return_type checker_return;
2055 node_algorithms::check(this->header_ptr(), node_checker_t(nodeptr_comp, extra_checker), checker_return);
2056 BOOST_INTRUSIVE_INVARIANT_ASSERT(!constant_time_size || this->sz_traits().get_size() == checker_return.node_count);
2057 }
2058
2059
2060
2061
2062
2063
2064
2065 void check() const
2066 {
2067 check(detail::empty_node_checker<ValueTraits>());
2068 }
2069
2070 friend bool operator==(const bstree_impl &x, const bstree_impl &y)
2071 {
2072 if(constant_time_size && x.size() != y.size()){
2073 return false;
2074 }
2075 return boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
2076 }
2077
2078 friend bool operator!=(const bstree_impl &x, const bstree_impl &y)
2079 { return !(x == y); }
2080
2081 friend bool operator<(const bstree_impl &x, const bstree_impl &y)
2082 { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
2083
2084 friend bool operator>(const bstree_impl &x, const bstree_impl &y)
2085 { return y < x; }
2086
2087 friend bool operator<=(const bstree_impl &x, const bstree_impl &y)
2088 { return !(x > y); }
2089
2090 friend bool operator>=(const bstree_impl &x, const bstree_impl &y)
2091 { return !(x < y); }
2092
2093 friend void swap(bstree_impl &x, bstree_impl &y)
2094 { x.swap(y); }
2095
2096
2097 private:
2098 template<class Disposer>
2099 iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer)
2100 {
2101 for(n = 0; b != e; ++n)
2102 this->erase_and_dispose(b++, disposer);
2103 return b.unconst();
2104 }
2105
2106 iterator private_erase(const_iterator b, const_iterator e, size_type &n)
2107 {
2108 for(n = 0; b != e; ++n)
2109 this->erase(b++);
2110 return b.unconst();
2111 }
2112
2113 };
2114
2115
2116
2117 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2118 template<class T, class ...Options>
2119 #else
2120 template<class T, class O1 = void, class O2 = void
2121 , class O3 = void, class O4 = void
2122 , class O5 = void, class O6 = void>
2123 #endif
2124 struct make_bstree
2125 {
2126
2127 typedef typename pack_options
2128 < bstree_defaults,
2129 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2130 O1, O2, O3, O4, O5, O6
2131 #else
2132 Options...
2133 #endif
2134 >::type packed_options;
2135
2136 typedef typename detail::get_value_traits
2137 <T, typename packed_options::proto_value_traits>::type value_traits;
2138
2139 typedef bstree_impl
2140 < value_traits
2141 , typename packed_options::key_of_value
2142 , typename packed_options::compare
2143 , typename packed_options::size_type
2144 , packed_options::constant_time_size
2145 , BsTreeAlgorithms
2146 , typename packed_options::header_holder_type
2147 > implementation_defined;
2148
2149 typedef implementation_defined type;
2150 };
2151
2152
2153 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
2154
2155 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2156 template<class T, class O1, class O2, class O3, class O4, class O5, class O6>
2157 #else
2158 template<class T, class ...Options>
2159 #endif
2160 class bstree
2161 : public make_bstree<T,
2162 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2163 O1, O2, O3, O4, O5, O6
2164 #else
2165 Options...
2166 #endif
2167 >::type
2168 {
2169 typedef typename make_bstree
2170 <T,
2171 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
2172 O1, O2, O3, O4, O5, O6
2173 #else
2174 Options...
2175 #endif
2176 >::type Base;
2177 BOOST_MOVABLE_BUT_NOT_COPYABLE(bstree)
2178
2179 public:
2180 typedef typename Base::key_compare key_compare;
2181 typedef typename Base::value_traits value_traits;
2182 typedef typename Base::iterator iterator;
2183 typedef typename Base::const_iterator const_iterator;
2184
2185
2186 BOOST_INTRUSIVE_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
2187
2188 inline bstree()
2189 : Base()
2190 {}
2191
2192 inline explicit bstree( const key_compare &cmp, const value_traits &v_traits = value_traits())
2193 : Base(cmp, v_traits)
2194 {}
2195
2196 template<class Iterator>
2197 inline bstree( bool unique, Iterator b, Iterator e
2198 , const key_compare &cmp = key_compare()
2199 , const value_traits &v_traits = value_traits())
2200 : Base(unique, b, e, cmp, v_traits)
2201 {}
2202
2203 inline bstree(BOOST_RV_REF(bstree) x)
2204 : Base(BOOST_MOVE_BASE(Base, x))
2205 {}
2206
2207 inline bstree& operator=(BOOST_RV_REF(bstree) x)
2208 { return static_cast<bstree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
2209
2210 template <class Cloner, class Disposer>
2211 inline void clone_from(const bstree &src, Cloner cloner, Disposer disposer)
2212 { Base::clone_from(src, cloner, disposer); }
2213
2214 template <class Cloner, class Disposer>
2215 inline void clone_from(BOOST_RV_REF(bstree) src, Cloner cloner, Disposer disposer)
2216 { Base::clone_from(BOOST_MOVE_BASE(Base, src), cloner, disposer); }
2217
2218 inline static bstree &container_from_end_iterator(iterator end_iterator) BOOST_NOEXCEPT
2219 { return static_cast<bstree &>(Base::container_from_end_iterator(end_iterator)); }
2220
2221 inline static const bstree &container_from_end_iterator(const_iterator end_iterator) BOOST_NOEXCEPT
2222 { return static_cast<const bstree &>(Base::container_from_end_iterator(end_iterator)); }
2223
2224 inline static bstree &container_from_iterator(iterator it) BOOST_NOEXCEPT
2225 { return static_cast<bstree &>(Base::container_from_iterator(it)); }
2226
2227 inline static const bstree &container_from_iterator(const_iterator it) BOOST_NOEXCEPT
2228 { return static_cast<const bstree &>(Base::container_from_iterator(it)); }
2229 };
2230
2231 #endif
2232 }
2233 }
2234
2235 #include <boost/intrusive/detail/config_end.hpp>
2236
2237 #endif