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