annotate DEPENDENCIES/generic/include/boost/intrusive/bstree.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 /////////////////////////////////////////////////////////////////////////////
Chris@16 2 //
Chris@101 3 // (C) Copyright Ion Gaztanaga 2013-2014
Chris@16 4 //
Chris@16 5 // Distributed under the Boost Software License, Version 1.0.
Chris@16 6 // (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 //
Chris@16 9 // See http://www.boost.org/libs/intrusive for documentation.
Chris@16 10 //
Chris@16 11 /////////////////////////////////////////////////////////////////////////////
Chris@16 12 #ifndef BOOST_INTRUSIVE_BSTREE_HPP
Chris@16 13 #define BOOST_INTRUSIVE_BSTREE_HPP
Chris@16 14
Chris@16 15 #include <boost/intrusive/detail/config_begin.hpp>
Chris@101 16 #include <boost/intrusive/intrusive_fwd.hpp>
Chris@16 17
Chris@16 18 #include <boost/intrusive/detail/assert.hpp>
Chris@16 19 #include <boost/static_assert.hpp>
Chris@16 20 #include <boost/intrusive/intrusive_fwd.hpp>
Chris@101 21 #include <boost/intrusive/bs_set_hook.hpp>
Chris@16 22 #include <boost/intrusive/detail/tree_node.hpp>
Chris@101 23 #include <boost/intrusive/detail/tree_iterator.hpp>
Chris@16 24 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
Chris@16 25 #include <boost/intrusive/detail/mpl.hpp>
Chris@16 26 #include <boost/intrusive/pointer_traits.hpp>
Chris@101 27 #include <boost/intrusive/detail/is_stateful_value_traits.hpp>
Chris@101 28 #include <boost/intrusive/detail/empty_node_checker.hpp>
Chris@101 29 #include <boost/intrusive/detail/default_header_holder.hpp>
Chris@101 30 #include <boost/intrusive/detail/reverse_iterator.hpp>
Chris@101 31 #include <boost/intrusive/detail/exception_disposer.hpp>
Chris@101 32 #include <boost/intrusive/detail/node_cloner_disposer.hpp>
Chris@101 33 #include <boost/intrusive/detail/key_nodeptr_comp.hpp>
Chris@101 34 #include <boost/intrusive/detail/simple_disposers.hpp>
Chris@101 35 #include <boost/intrusive/detail/size_holder.hpp>
Chris@101 36 #include <boost/intrusive/detail/algo_type.hpp>
Chris@101 37 #include <boost/intrusive/detail/algorithm.hpp>
Chris@101 38
Chris@101 39 #include <boost/intrusive/detail/get_value_traits.hpp>
Chris@16 40 #include <boost/intrusive/bstree_algorithms.hpp>
Chris@16 41 #include <boost/intrusive/link_mode.hpp>
Chris@101 42 #include <boost/intrusive/parent_from_member.hpp>
Chris@101 43 #include <boost/move/utility_core.hpp>
Chris@101 44 #include <boost/move/adl_move_swap.hpp>
Chris@101 45
Chris@101 46 #include <boost/intrusive/detail/minimal_pair_header.hpp>
Chris@101 47 #include <cstddef> //size_t...
Chris@101 48 #include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal_to
Chris@101 49
Chris@101 50 #if defined(BOOST_HAS_PRAGMA_ONCE)
Chris@101 51 # pragma once
Chris@101 52 #endif
Chris@16 53
Chris@16 54 namespace boost {
Chris@16 55 namespace intrusive {
Chris@16 56
Chris@16 57 /// @cond
Chris@16 58
Chris@101 59 struct default_bstree_hook_applier
Chris@101 60 { template <class T> struct apply{ typedef typename T::default_bstree_hook type; }; };
Chris@101 61
Chris@101 62 template<>
Chris@101 63 struct is_default_hook_tag<default_bstree_hook_applier>
Chris@101 64 { static const bool value = true; };
Chris@101 65
Chris@16 66 struct bstree_defaults
Chris@16 67 {
Chris@101 68 typedef default_bstree_hook_applier proto_value_traits;
Chris@16 69 static const bool constant_time_size = true;
Chris@16 70 typedef std::size_t size_type;
Chris@16 71 typedef void compare;
Chris@16 72 static const bool floating_point = true; //For sgtree
Chris@16 73 typedef void priority; //For treap
Chris@101 74 typedef void header_holder_type;
Chris@16 75 };
Chris@16 76
Chris@101 77 template<class ValueTraits, algo_types AlgoType, typename HeaderHolder>
Chris@16 78 struct bstbase3
Chris@16 79 {
Chris@16 80 typedef ValueTraits value_traits;
Chris@101 81 typedef typename value_traits::node_traits node_traits;
Chris@16 82 typedef typename node_traits::node node_type;
Chris@16 83 typedef typename get_algo<AlgoType, node_traits>::type node_algorithms;
Chris@16 84 typedef typename node_traits::node_ptr node_ptr;
Chris@16 85 typedef typename node_traits::const_node_ptr const_node_ptr;
Chris@101 86 typedef tree_iterator<value_traits, false> iterator;
Chris@101 87 typedef tree_iterator<value_traits, true> const_iterator;
Chris@101 88 typedef boost::intrusive::reverse_iterator<iterator> reverse_iterator;
Chris@101 89 typedef boost::intrusive::reverse_iterator<const_iterator> const_reverse_iterator;
Chris@101 90 typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer;
Chris@101 91 typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer;
Chris@16 92 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::element_type) value_type;
Chris@16 93 typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type;
Chris@16 94 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference) reference;
Chris@16 95 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::reference) const_reference;
Chris@16 96 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::difference_type) difference_type;
Chris@101 97 typedef typename detail::get_header_holder_type
Chris@101 98 < value_traits,HeaderHolder >::type header_holder_type;
Chris@101 99
Chris@101 100 static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
Chris@101 101 static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
Chris@101 102 static const bool has_container_from_iterator =
Chris@101 103 detail::is_same< header_holder_type, detail::default_header_holder< node_traits > >::value;
Chris@101 104
Chris@101 105 struct holder_t : public ValueTraits
Chris@101 106 {
Chris@101 107 explicit holder_t(const ValueTraits &vtraits)
Chris@101 108 : ValueTraits(vtraits)
Chris@101 109 {}
Chris@101 110 header_holder_type root;
Chris@101 111 } holder;
Chris@101 112
Chris@101 113 static bstbase3 &get_tree_base_from_end_iterator(const const_iterator &end_iterator)
Chris@101 114 {
Chris@101 115 BOOST_STATIC_ASSERT(has_container_from_iterator);
Chris@101 116 node_ptr p = end_iterator.pointed_node();
Chris@101 117 header_holder_type* h = header_holder_type::get_holder(p);
Chris@101 118 holder_t *holder = get_parent_from_member<holder_t, header_holder_type>(h, &holder_t::root);
Chris@101 119 bstbase3 *base = get_parent_from_member<bstbase3, holder_t> (holder, &bstbase3::holder);
Chris@101 120 return *base;
Chris@101 121 }
Chris@101 122
Chris@101 123 bstbase3(const ValueTraits &vtraits)
Chris@101 124 : holder(vtraits)
Chris@101 125 {
Chris@101 126 node_algorithms::init_header(this->header_ptr());
Chris@101 127 }
Chris@101 128
Chris@101 129 node_ptr header_ptr()
Chris@101 130 { return holder.root.get_node(); }
Chris@101 131
Chris@101 132 const_node_ptr header_ptr() const
Chris@101 133 { return holder.root.get_node(); }
Chris@101 134
Chris@101 135 const value_traits &get_value_traits() const
Chris@101 136 { return this->holder; }
Chris@101 137
Chris@101 138 value_traits &get_value_traits()
Chris@101 139 { return this->holder; }
Chris@101 140
Chris@101 141 typedef typename boost::intrusive::value_traits_pointers
Chris@101 142 <ValueTraits>::const_value_traits_ptr const_value_traits_ptr;
Chris@101 143
Chris@101 144 const_value_traits_ptr priv_value_traits_ptr() const
Chris@101 145 { return pointer_traits<const_value_traits_ptr>::pointer_to(this->get_value_traits()); }
Chris@16 146
Chris@16 147 iterator begin()
Chris@101 148 { return iterator(node_algorithms::begin_node(this->header_ptr()), this->priv_value_traits_ptr()); }
Chris@16 149
Chris@16 150 const_iterator begin() const
Chris@16 151 { return cbegin(); }
Chris@16 152
Chris@16 153 const_iterator cbegin() const
Chris@101 154 { return const_iterator(node_algorithms::begin_node(this->header_ptr()), this->priv_value_traits_ptr()); }
Chris@16 155
Chris@16 156 iterator end()
Chris@101 157 { return iterator(node_algorithms::end_node(this->header_ptr()), this->priv_value_traits_ptr()); }
Chris@16 158
Chris@16 159 const_iterator end() const
Chris@16 160 { return cend(); }
Chris@16 161
Chris@16 162 const_iterator cend() const
Chris@101 163 { return const_iterator(node_algorithms::end_node(this->header_ptr()), this->priv_value_traits_ptr()); }
Chris@101 164
Chris@101 165 iterator root()
Chris@101 166 { return iterator(node_algorithms::root_node(this->header_ptr()), this->priv_value_traits_ptr()); }
Chris@101 167
Chris@101 168 const_iterator root() const
Chris@101 169 { return croot(); }
Chris@101 170
Chris@101 171 const_iterator croot() const
Chris@101 172 { return const_iterator(node_algorithms::root_node(this->header_ptr()), this->priv_value_traits_ptr()); }
Chris@16 173
Chris@16 174 reverse_iterator rbegin()
Chris@16 175 { return reverse_iterator(end()); }
Chris@16 176
Chris@16 177 const_reverse_iterator rbegin() const
Chris@16 178 { return const_reverse_iterator(end()); }
Chris@16 179
Chris@16 180 const_reverse_iterator crbegin() const
Chris@16 181 { return const_reverse_iterator(end()); }
Chris@16 182
Chris@16 183 reverse_iterator rend()
Chris@16 184 { return reverse_iterator(begin()); }
Chris@16 185
Chris@16 186 const_reverse_iterator rend() const
Chris@16 187 { return const_reverse_iterator(begin()); }
Chris@16 188
Chris@16 189 const_reverse_iterator crend() const
Chris@16 190 { return const_reverse_iterator(begin()); }
Chris@16 191
Chris@16 192 void replace_node(iterator replace_this, reference with_this)
Chris@16 193 {
Chris@101 194 node_algorithms::replace_node( get_value_traits().to_node_ptr(*replace_this)
Chris@16 195 , this->header_ptr()
Chris@101 196 , get_value_traits().to_node_ptr(with_this));
Chris@16 197 if(safemode_or_autounlink)
Chris@16 198 node_algorithms::init(replace_this.pointed_node());
Chris@16 199 }
Chris@16 200
Chris@16 201 void rebalance()
Chris@16 202 { node_algorithms::rebalance(this->header_ptr()); }
Chris@16 203
Chris@16 204 iterator rebalance_subtree(iterator root)
Chris@101 205 { return iterator(node_algorithms::rebalance_subtree(root.pointed_node()), this->priv_value_traits_ptr()); }
Chris@16 206
Chris@16 207 static iterator s_iterator_to(reference value)
Chris@16 208 {
Chris@16 209 BOOST_STATIC_ASSERT((!stateful_value_traits));
Chris@101 210 return iterator (value_traits::to_node_ptr(value), const_value_traits_ptr());
Chris@16 211 }
Chris@16 212
Chris@16 213 static const_iterator s_iterator_to(const_reference value)
Chris@16 214 {
Chris@16 215 BOOST_STATIC_ASSERT((!stateful_value_traits));
Chris@101 216 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());
Chris@16 217 }
Chris@16 218
Chris@16 219 iterator iterator_to(reference value)
Chris@101 220 { return iterator (this->get_value_traits().to_node_ptr(value), this->priv_value_traits_ptr()); }
Chris@16 221
Chris@16 222 const_iterator iterator_to(const_reference value) const
Chris@101 223 { 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()); }
Chris@16 224
Chris@16 225 static void init_node(reference value)
Chris@16 226 { node_algorithms::init(value_traits::to_node_ptr(value)); }
Chris@16 227
Chris@16 228 };
Chris@16 229
Chris@101 230 template<class Less, class T>
Chris@101 231 struct get_compare
Chris@101 232 {
Chris@101 233 typedef Less type;
Chris@101 234 };
Chris@101 235
Chris@101 236 template<class T>
Chris@101 237 struct get_compare<void, T>
Chris@101 238 {
Chris@101 239 typedef ::std::less<T> type;
Chris@101 240 };
Chris@101 241
Chris@101 242 template<class ValueTraits, class VoidOrKeyComp, algo_types AlgoType, typename HeaderHolder>
Chris@16 243 struct bstbase2
Chris@101 244 //Put the (possibly empty) functor in the first position to get EBO in MSVC
Chris@101 245 //Use public inheritance to avoid MSVC bugs with closures
Chris@101 246 : public detail::ebo_functor_holder<typename get_compare< VoidOrKeyComp
Chris@101 247 , typename ValueTraits::value_type
Chris@16 248 >::type>
Chris@101 249 , public bstbase3<ValueTraits, AlgoType, HeaderHolder>
Chris@16 250 {
Chris@101 251 typedef bstbase3<ValueTraits, AlgoType, HeaderHolder> treeheader_t;
Chris@101 252 typedef typename treeheader_t::value_traits value_traits;
Chris@16 253 typedef typename treeheader_t::node_algorithms node_algorithms;
Chris@101 254 typedef typename get_compare
Chris@101 255 < VoidOrKeyComp, typename value_traits::value_type>::type value_compare;
Chris@16 256 typedef BOOST_INTRUSIVE_IMPDEF(value_compare) key_compare;
Chris@16 257 typedef typename treeheader_t::iterator iterator;
Chris@16 258 typedef typename treeheader_t::const_iterator const_iterator;
Chris@16 259 typedef typename treeheader_t::node_ptr node_ptr;
Chris@16 260 typedef typename treeheader_t::const_node_ptr const_node_ptr;
Chris@16 261
Chris@16 262 bstbase2(const value_compare &comp, const ValueTraits &vtraits)
Chris@101 263 : detail::ebo_functor_holder<value_compare>(comp), treeheader_t(vtraits)
Chris@16 264 {}
Chris@16 265
Chris@16 266 const value_compare &comp() const
Chris@16 267 { return this->get(); }
Chris@101 268
Chris@16 269 value_compare &comp()
Chris@16 270 { return this->get(); }
Chris@16 271
Chris@101 272 typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer;
Chris@101 273 typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer;
Chris@16 274 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::element_type) value_type;
Chris@16 275 typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type;
Chris@16 276 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference) reference;
Chris@16 277 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::reference) const_reference;
Chris@16 278 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::difference_type) difference_type;
Chris@16 279 typedef typename node_algorithms::insert_commit_data insert_commit_data;
Chris@16 280
Chris@16 281 value_compare value_comp() const
Chris@16 282 { return this->comp(); }
Chris@16 283
Chris@16 284 key_compare key_comp() const
Chris@16 285 { return this->comp(); }
Chris@16 286
Chris@101 287 //lower_bound
Chris@16 288 iterator lower_bound(const_reference value)
Chris@16 289 { return this->lower_bound(value, this->comp()); }
Chris@16 290
Chris@16 291 const_iterator lower_bound(const_reference value) const
Chris@16 292 { return this->lower_bound(value, this->comp()); }
Chris@16 293
Chris@16 294 template<class KeyType, class KeyValueCompare>
Chris@16 295 iterator lower_bound(const KeyType &key, KeyValueCompare comp)
Chris@16 296 {
Chris@101 297 detail::key_nodeptr_comp<KeyValueCompare, value_traits>
Chris@101 298 key_node_comp(comp, &this->get_value_traits());
Chris@16 299 return iterator(node_algorithms::lower_bound
Chris@101 300 (this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
Chris@16 301 }
Chris@16 302
Chris@16 303 template<class KeyType, class KeyValueCompare>
Chris@16 304 const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const
Chris@16 305 {
Chris@101 306 detail::key_nodeptr_comp<KeyValueCompare, value_traits>
Chris@101 307 key_node_comp(comp, &this->get_value_traits());
Chris@16 308 return const_iterator(node_algorithms::lower_bound
Chris@101 309 (this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
Chris@16 310 }
Chris@16 311
Chris@101 312 //upper_bound
Chris@16 313 iterator upper_bound(const_reference value)
Chris@16 314 { return this->upper_bound(value, this->comp()); }
Chris@16 315
Chris@16 316 template<class KeyType, class KeyValueCompare>
Chris@16 317 iterator upper_bound(const KeyType &key, KeyValueCompare comp)
Chris@16 318 {
Chris@101 319 detail::key_nodeptr_comp<KeyValueCompare, value_traits>
Chris@101 320 key_node_comp(comp, &this->get_value_traits());
Chris@16 321 return iterator(node_algorithms::upper_bound
Chris@101 322 (this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
Chris@16 323 }
Chris@16 324
Chris@16 325 const_iterator upper_bound(const_reference value) const
Chris@16 326 { return this->upper_bound(value, this->comp()); }
Chris@16 327
Chris@16 328 template<class KeyType, class KeyValueCompare>
Chris@16 329 const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const
Chris@16 330 {
Chris@101 331 detail::key_nodeptr_comp<KeyValueCompare, value_traits>
Chris@101 332 key_node_comp(comp, &this->get_value_traits());
Chris@16 333 return const_iterator(node_algorithms::upper_bound
Chris@101 334 (this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
Chris@16 335 }
Chris@16 336
Chris@101 337 //find
Chris@16 338 iterator find(const_reference value)
Chris@16 339 { return this->find(value, this->comp()); }
Chris@16 340
Chris@16 341 template<class KeyType, class KeyValueCompare>
Chris@16 342 iterator find(const KeyType &key, KeyValueCompare comp)
Chris@16 343 {
Chris@101 344 detail::key_nodeptr_comp<KeyValueCompare, value_traits>
Chris@101 345 key_node_comp(comp, &this->get_value_traits());
Chris@16 346 return iterator
Chris@101 347 (node_algorithms::find(this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
Chris@16 348 }
Chris@16 349
Chris@16 350 const_iterator find(const_reference value) const
Chris@16 351 { return this->find(value, this->comp()); }
Chris@16 352
Chris@16 353 template<class KeyType, class KeyValueCompare>
Chris@16 354 const_iterator find(const KeyType &key, KeyValueCompare comp) const
Chris@16 355 {
Chris@101 356 detail::key_nodeptr_comp<KeyValueCompare, value_traits>
Chris@101 357 key_node_comp(comp, &this->get_value_traits());
Chris@16 358 return const_iterator
Chris@101 359 (node_algorithms::find(this->header_ptr(), key, key_node_comp), this->priv_value_traits_ptr());
Chris@16 360 }
Chris@16 361
Chris@101 362 //equal_range
Chris@16 363 std::pair<iterator,iterator> equal_range(const_reference value)
Chris@16 364 { return this->equal_range(value, this->comp()); }
Chris@16 365
Chris@16 366 template<class KeyType, class KeyValueCompare>
Chris@16 367 std::pair<iterator,iterator> equal_range(const KeyType &key, KeyValueCompare comp)
Chris@16 368 {
Chris@101 369 detail::key_nodeptr_comp<KeyValueCompare, value_traits>
Chris@101 370 key_node_comp(comp, &this->get_value_traits());
Chris@16 371 std::pair<node_ptr, node_ptr> ret
Chris@16 372 (node_algorithms::equal_range(this->header_ptr(), key, key_node_comp));
Chris@101 373 return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr())
Chris@101 374 , iterator(ret.second, this->priv_value_traits_ptr()));
Chris@16 375 }
Chris@16 376
Chris@16 377 std::pair<const_iterator, const_iterator>
Chris@16 378 equal_range(const_reference value) const
Chris@16 379 { return this->equal_range(value, this->comp()); }
Chris@16 380
Chris@16 381 template<class KeyType, class KeyValueCompare>
Chris@16 382 std::pair<const_iterator, const_iterator>
Chris@16 383 equal_range(const KeyType &key, KeyValueCompare comp) const
Chris@16 384 {
Chris@101 385 detail::key_nodeptr_comp<KeyValueCompare, value_traits>
Chris@101 386 key_node_comp(comp, &this->get_value_traits());
Chris@16 387 std::pair<node_ptr, node_ptr> ret
Chris@16 388 (node_algorithms::equal_range(this->header_ptr(), key, key_node_comp));
Chris@101 389 return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr())
Chris@101 390 , const_iterator(ret.second, this->priv_value_traits_ptr()));
Chris@16 391 }
Chris@16 392
Chris@101 393 //lower_bound_range
Chris@101 394 std::pair<iterator,iterator> lower_bound_range(const_reference value)
Chris@101 395 { return this->lower_bound_range(value, this->comp()); }
Chris@101 396
Chris@101 397 template<class KeyType, class KeyValueCompare>
Chris@101 398 std::pair<iterator,iterator> lower_bound_range(const KeyType &key, KeyValueCompare comp)
Chris@101 399 {
Chris@101 400 detail::key_nodeptr_comp<KeyValueCompare, value_traits>
Chris@101 401 key_node_comp(comp, &this->get_value_traits());
Chris@101 402 std::pair<node_ptr, node_ptr> ret
Chris@101 403 (node_algorithms::lower_bound_range(this->header_ptr(), key, key_node_comp));
Chris@101 404 return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr())
Chris@101 405 , iterator(ret.second, this->priv_value_traits_ptr()));
Chris@101 406 }
Chris@101 407
Chris@101 408 std::pair<const_iterator, const_iterator>
Chris@101 409 lower_bound_range(const_reference value) const
Chris@101 410 { return this->lower_bound_range(value, this->comp()); }
Chris@101 411
Chris@101 412 template<class KeyType, class KeyValueCompare>
Chris@101 413 std::pair<const_iterator, const_iterator>
Chris@101 414 lower_bound_range(const KeyType &key, KeyValueCompare comp) const
Chris@101 415 {
Chris@101 416 detail::key_nodeptr_comp<KeyValueCompare, value_traits>
Chris@101 417 key_node_comp(comp, &this->get_value_traits());
Chris@101 418 std::pair<node_ptr, node_ptr> ret
Chris@101 419 (node_algorithms::lower_bound_range(this->header_ptr(), key, key_node_comp));
Chris@101 420 return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr())
Chris@101 421 , const_iterator(ret.second, this->priv_value_traits_ptr()));
Chris@101 422 }
Chris@101 423
Chris@101 424 //bounded_range
Chris@16 425 std::pair<iterator,iterator> bounded_range
Chris@16 426 (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed)
Chris@16 427 { return this->bounded_range(lower_value, upper_value, this->comp(), left_closed, right_closed); }
Chris@16 428
Chris@16 429 template<class KeyType, class KeyValueCompare>
Chris@16 430 std::pair<iterator,iterator> bounded_range
Chris@16 431 (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed)
Chris@16 432 {
Chris@101 433 detail::key_nodeptr_comp<KeyValueCompare, value_traits>
Chris@101 434 key_node_comp(comp, &this->get_value_traits());
Chris@16 435 std::pair<node_ptr, node_ptr> ret
Chris@16 436 (node_algorithms::bounded_range
Chris@16 437 (this->header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed));
Chris@101 438 return std::pair<iterator, iterator>( iterator(ret.first, this->priv_value_traits_ptr())
Chris@101 439 , iterator(ret.second, this->priv_value_traits_ptr()));
Chris@16 440 }
Chris@16 441
Chris@16 442 std::pair<const_iterator,const_iterator> bounded_range
Chris@16 443 (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const
Chris@16 444 { return this->bounded_range(lower_value, upper_value, this->comp(), left_closed, right_closed); }
Chris@16 445
Chris@16 446 template<class KeyType, class KeyValueCompare>
Chris@16 447 std::pair<const_iterator,const_iterator> bounded_range
Chris@16 448 (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const
Chris@16 449 {
Chris@101 450 detail::key_nodeptr_comp<KeyValueCompare, value_traits>
Chris@101 451 key_node_comp(comp, &this->get_value_traits());
Chris@16 452 std::pair<node_ptr, node_ptr> ret
Chris@16 453 (node_algorithms::bounded_range
Chris@16 454 (this->header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed));
Chris@101 455 return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->priv_value_traits_ptr())
Chris@101 456 , const_iterator(ret.second, this->priv_value_traits_ptr()));
Chris@16 457 }
Chris@16 458
Chris@101 459 //insert_unique_check
Chris@16 460 template<class KeyType, class KeyValueCompare>
Chris@16 461 std::pair<iterator, bool> insert_unique_check
Chris@16 462 (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
Chris@16 463 {
Chris@101 464 detail::key_nodeptr_comp<KeyValueCompare, value_traits>
Chris@101 465 ocomp(key_value_comp, &this->get_value_traits());
Chris@16 466 std::pair<node_ptr, bool> ret =
Chris@16 467 (node_algorithms::insert_unique_check
Chris@16 468 (this->header_ptr(), key, ocomp, commit_data));
Chris@101 469 return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
Chris@16 470 }
Chris@16 471
Chris@16 472 template<class KeyType, class KeyValueCompare>
Chris@16 473 std::pair<iterator, bool> insert_unique_check
Chris@16 474 (const_iterator hint, const KeyType &key
Chris@16 475 ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
Chris@16 476 {
Chris@101 477 detail::key_nodeptr_comp<KeyValueCompare, value_traits>
Chris@101 478 ocomp(key_value_comp, &this->get_value_traits());
Chris@16 479 std::pair<node_ptr, bool> ret =
Chris@16 480 (node_algorithms::insert_unique_check
Chris@16 481 (this->header_ptr(), hint.pointed_node(), key, ocomp, commit_data));
Chris@101 482 return std::pair<iterator, bool>(iterator(ret.first, this->priv_value_traits_ptr()), ret.second);
Chris@16 483 }
Chris@16 484 };
Chris@16 485
Chris@101 486 //Due to MSVC's EBO implementation, to save space and maintain the ABI, we must put the non-empty size member
Chris@101 487 //in the first position, but if size is not going to be stored then we'll use an specialization
Chris@101 488 //that doesn't inherit from size_holder
Chris@101 489 template<class ValueTraits, class VoidOrKeyComp, bool ConstantTimeSize, class SizeType, algo_types AlgoType, typename HeaderHolder>
Chris@101 490 struct bstbase_hack
Chris@101 491 : public detail::size_holder<ConstantTimeSize, SizeType>
Chris@101 492 , public bstbase2 < ValueTraits, VoidOrKeyComp, AlgoType, HeaderHolder>
Chris@101 493 {
Chris@101 494 typedef bstbase2< ValueTraits, VoidOrKeyComp, AlgoType, HeaderHolder> base_type;
Chris@101 495 typedef typename base_type::value_compare value_compare;
Chris@101 496 typedef SizeType size_type;
Chris@101 497 typedef typename base_type::node_traits node_traits;
Chris@101 498 typedef typename get_algo
Chris@101 499 <AlgoType, node_traits>::type algo_type;
Chris@101 500
Chris@101 501 bstbase_hack(const value_compare & comp, const ValueTraits &vtraits)
Chris@101 502 : base_type(comp, vtraits)
Chris@101 503 {
Chris@101 504 this->sz_traits().set_size(size_type(0));
Chris@101 505 }
Chris@101 506
Chris@101 507 typedef detail::size_holder<ConstantTimeSize, SizeType> size_traits;
Chris@101 508
Chris@101 509 size_traits &sz_traits()
Chris@101 510 { return static_cast<size_traits &>(*this); }
Chris@101 511
Chris@101 512 const size_traits &sz_traits() const
Chris@101 513 { return static_cast<const size_traits &>(*this); }
Chris@101 514 };
Chris@101 515
Chris@101 516 //Specialization for ConstantTimeSize == false
Chris@101 517 template<class ValueTraits, class VoidOrKeyComp, class SizeType, algo_types AlgoType, typename HeaderHolder>
Chris@101 518 struct bstbase_hack<ValueTraits, VoidOrKeyComp, false, SizeType, AlgoType, HeaderHolder>
Chris@101 519 : public bstbase2 < ValueTraits, VoidOrKeyComp, AlgoType, HeaderHolder>
Chris@101 520 {
Chris@101 521 typedef bstbase2< ValueTraits, VoidOrKeyComp, AlgoType, HeaderHolder> base_type;
Chris@101 522 typedef typename base_type::value_compare value_compare;
Chris@101 523 bstbase_hack(const value_compare & comp, const ValueTraits &vtraits)
Chris@101 524 : base_type(comp, vtraits)
Chris@101 525 {}
Chris@101 526
Chris@101 527 typedef detail::size_holder<true, SizeType> size_traits;
Chris@101 528
Chris@101 529 size_traits &sz_traits()
Chris@101 530 { return s_size_traits; }
Chris@101 531
Chris@101 532 const size_traits &sz_traits() const
Chris@101 533 { return s_size_traits; }
Chris@101 534
Chris@101 535 static size_traits s_size_traits;
Chris@101 536 };
Chris@101 537
Chris@101 538 template<class ValueTraits, class VoidOrKeyComp, class SizeType, algo_types AlgoType, typename HeaderHolder>
Chris@101 539 detail::size_holder<true, SizeType> bstbase_hack<ValueTraits, VoidOrKeyComp, false, SizeType, AlgoType, HeaderHolder>::s_size_traits;
Chris@101 540
Chris@101 541 //This class will
Chris@101 542 template<class ValueTraits, class VoidOrKeyComp, bool ConstantTimeSize, class SizeType, algo_types AlgoType, typename HeaderHolder>
Chris@16 543 struct bstbase
Chris@101 544 : public bstbase_hack< ValueTraits, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder>
Chris@16 545 {
Chris@101 546 typedef bstbase_hack< ValueTraits, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder> base_type;
Chris@101 547 typedef ValueTraits value_traits;
Chris@16 548 typedef typename base_type::value_compare value_compare;
Chris@101 549 typedef value_compare key_compare;
Chris@16 550 typedef typename base_type::const_reference const_reference;
Chris@16 551 typedef typename base_type::reference reference;
Chris@16 552 typedef typename base_type::iterator iterator;
Chris@16 553 typedef typename base_type::const_iterator const_iterator;
Chris@16 554 typedef typename base_type::node_traits node_traits;
Chris@16 555 typedef typename get_algo
Chris@101 556 <AlgoType, node_traits>::type node_algorithms;
Chris@16 557 typedef SizeType size_type;
Chris@16 558
Chris@16 559 bstbase(const value_compare & comp, const ValueTraits &vtraits)
Chris@16 560 : base_type(comp, vtraits)
Chris@16 561 {}
Chris@16 562
Chris@101 563 //Detach all inserted nodes. This will add exception safety to bstree_impl
Chris@101 564 //constructors inserting elements.
Chris@101 565 ~bstbase()
Chris@16 566 {
Chris@101 567 if(is_safe_autounlink<value_traits::link_mode>::value){
Chris@101 568 node_algorithms::clear_and_dispose
Chris@101 569 ( this->header_ptr()
Chris@101 570 , detail::node_disposer<detail::null_disposer, value_traits, AlgoType>
Chris@101 571 (detail::null_disposer(), &this->get_value_traits()));
Chris@101 572 node_algorithms::init(this->header_ptr());
Chris@16 573 }
Chris@16 574 }
Chris@16 575 };
Chris@16 576
Chris@16 577
Chris@16 578 /// @endcond
Chris@16 579
Chris@16 580 //! The class template bstree is an unbalanced intrusive binary search tree
Chris@16 581 //! container. The no-throw guarantee holds only, if the value_compare object
Chris@16 582 //! doesn't throw.
Chris@16 583 //!
Chris@16 584 //! The complexity guarantees only hold if the tree is balanced, logarithmic
Chris@16 585 //! complexity would increase to linear if the tree is totally unbalanced.
Chris@16 586 //!
Chris@16 587 //! The template parameter \c T is the type to be managed by the container.
Chris@16 588 //! The user can specify additional options and if no options are provided
Chris@16 589 //! default options are used.
Chris@16 590 //!
Chris@16 591 //! The container supports the following options:
Chris@16 592 //! \c base_hook<>/member_hook<>/value_traits<>,
Chris@16 593 //! \c constant_time_size<>, \c size_type<> and
Chris@16 594 //! \c compare<>.
Chris@16 595 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 596 template<class T, class ...Options>
Chris@16 597 #else
Chris@101 598 template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
Chris@16 599 #endif
Chris@16 600 class bstree_impl
Chris@101 601 : public bstbase<ValueTraits, VoidKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder>
Chris@16 602 {
Chris@16 603 public:
Chris@16 604 /// @cond
Chris@101 605 typedef bstbase<ValueTraits, VoidKeyComp, ConstantTimeSize, SizeType, AlgoType, HeaderHolder> data_type;
Chris@101 606 typedef tree_iterator<ValueTraits, false> iterator_type;
Chris@101 607 typedef tree_iterator<ValueTraits, true> const_iterator_type;
Chris@16 608 /// @endcond
Chris@16 609
Chris@101 610 typedef BOOST_INTRUSIVE_IMPDEF(ValueTraits) value_traits;
Chris@101 611 typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer;
Chris@101 612 typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer;
Chris@16 613 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::element_type) value_type;
Chris@16 614 typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type;
Chris@16 615 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference) reference;
Chris@16 616 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::reference) const_reference;
Chris@16 617 typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::difference_type) difference_type;
Chris@16 618 typedef BOOST_INTRUSIVE_IMPDEF(SizeType) size_type;
Chris@16 619 typedef BOOST_INTRUSIVE_IMPDEF(typename data_type::value_compare) value_compare;
Chris@16 620 typedef BOOST_INTRUSIVE_IMPDEF(value_compare) key_compare;
Chris@16 621 typedef BOOST_INTRUSIVE_IMPDEF(iterator_type) iterator;
Chris@16 622 typedef BOOST_INTRUSIVE_IMPDEF(const_iterator_type) const_iterator;
Chris@101 623 typedef BOOST_INTRUSIVE_IMPDEF(boost::intrusive::reverse_iterator<iterator>) reverse_iterator;
Chris@101 624 typedef BOOST_INTRUSIVE_IMPDEF(boost::intrusive::reverse_iterator<const_iterator>) const_reverse_iterator;
Chris@101 625 typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::node_traits) node_traits;
Chris@16 626 typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::node) node;
Chris@16 627 typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::node_ptr) node_ptr;
Chris@16 628 typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::const_node_ptr) const_node_ptr;
Chris@16 629 /// @cond
Chris@16 630 typedef typename get_algo<AlgoType, node_traits>::type algo_type;
Chris@16 631 /// @endcond
Chris@16 632 typedef BOOST_INTRUSIVE_IMPDEF(algo_type) node_algorithms;
Chris@16 633
Chris@16 634 static const bool constant_time_size = ConstantTimeSize;
Chris@101 635 static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
Chris@16 636 /// @cond
Chris@16 637 private:
Chris@16 638
Chris@16 639 //noncopyable
Chris@16 640 BOOST_MOVABLE_BUT_NOT_COPYABLE(bstree_impl)
Chris@16 641
Chris@101 642 static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
Chris@16 643
Chris@16 644 //Constant-time size is incompatible with auto-unlink hooks!
Chris@101 645 BOOST_STATIC_ASSERT(!(constant_time_size && ((int)value_traits::link_mode == (int)auto_unlink)));
Chris@16 646
Chris@16 647
Chris@16 648 protected:
Chris@16 649
Chris@16 650
Chris@16 651 /// @endcond
Chris@16 652
Chris@16 653 public:
Chris@16 654
Chris@16 655 typedef typename node_algorithms::insert_commit_data insert_commit_data;
Chris@16 656
Chris@16 657 //! <b>Effects</b>: Constructs an empty container.
Chris@16 658 //!
Chris@16 659 //! <b>Complexity</b>: Constant.
Chris@16 660 //!
Chris@16 661 //! <b>Throws</b>: If value_traits::node_traits::node
Chris@16 662 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
Chris@101 663 //! or the copy constructor of the value_compare object throws. Basic guarantee.
Chris@16 664 explicit bstree_impl( const value_compare &cmp = value_compare()
Chris@16 665 , const value_traits &v_traits = value_traits())
Chris@16 666 : data_type(cmp, v_traits)
Chris@101 667 {}
Chris@16 668
Chris@16 669 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
Chris@16 670 //! cmp must be a comparison function that induces a strict weak ordering.
Chris@16 671 //!
Chris@16 672 //! <b>Effects</b>: Constructs an empty container and inserts elements from
Chris@16 673 //! [b, e).
Chris@16 674 //!
Chris@16 675 //! <b>Complexity</b>: Linear in N if [b, e) is already sorted using
Chris@16 676 //! comp and otherwise N * log N, where N is the distance between first and last.
Chris@16 677 //!
Chris@16 678 //! <b>Throws</b>: If value_traits::node_traits::node
Chris@16 679 //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
Chris@16 680 //! or the copy constructor/operator() of the value_compare object throws. Basic guarantee.
Chris@16 681 template<class Iterator>
Chris@16 682 bstree_impl( bool unique, Iterator b, Iterator e
Chris@16 683 , const value_compare &cmp = value_compare()
Chris@16 684 , const value_traits &v_traits = value_traits())
Chris@16 685 : data_type(cmp, v_traits)
Chris@16 686 {
Chris@101 687 //bstbase releases elements in case of exceptions
Chris@16 688 if(unique)
Chris@16 689 this->insert_unique(b, e);
Chris@16 690 else
Chris@16 691 this->insert_equal(b, e);
Chris@16 692 }
Chris@16 693
Chris@16 694 //! <b>Effects</b>: to-do
Chris@16 695 //!
Chris@16 696 bstree_impl(BOOST_RV_REF(bstree_impl) x)
Chris@101 697 : data_type(::boost::move(x.comp()), ::boost::move(x.get_value_traits()))
Chris@16 698 {
Chris@16 699 this->swap(x);
Chris@16 700 }
Chris@16 701
Chris@16 702 //! <b>Effects</b>: to-do
Chris@16 703 //!
Chris@16 704 bstree_impl& operator=(BOOST_RV_REF(bstree_impl) x)
Chris@16 705 { this->swap(x); return *this; }
Chris@16 706
Chris@16 707 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 708 //! <b>Effects</b>: Detaches all elements from this. The objects in the set
Chris@16 709 //! are not deleted (i.e. no destructors are called), but the nodes according to
Chris@16 710 //! the value_traits template parameter are reinitialized and thus can be reused.
Chris@16 711 //!
Chris@16 712 //! <b>Complexity</b>: Linear to elements contained in *this.
Chris@16 713 //!
Chris@16 714 //! <b>Throws</b>: Nothing.
Chris@16 715 ~bstree_impl()
Chris@16 716 {}
Chris@16 717
Chris@16 718 //! <b>Effects</b>: Returns an iterator pointing to the beginning of the container.
Chris@16 719 //!
Chris@16 720 //! <b>Complexity</b>: Constant.
Chris@16 721 //!
Chris@16 722 //! <b>Throws</b>: Nothing.
Chris@16 723 iterator begin();
Chris@16 724
Chris@16 725 //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the container.
Chris@16 726 //!
Chris@16 727 //! <b>Complexity</b>: Constant.
Chris@16 728 //!
Chris@16 729 //! <b>Throws</b>: Nothing.
Chris@16 730 const_iterator begin() const;
Chris@16 731
Chris@16 732 //! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the container.
Chris@16 733 //!
Chris@16 734 //! <b>Complexity</b>: Constant.
Chris@16 735 //!
Chris@16 736 //! <b>Throws</b>: Nothing.
Chris@16 737 const_iterator cbegin() const;
Chris@16 738
Chris@16 739 //! <b>Effects</b>: Returns an iterator pointing to the end of the container.
Chris@16 740 //!
Chris@16 741 //! <b>Complexity</b>: Constant.
Chris@16 742 //!
Chris@16 743 //! <b>Throws</b>: Nothing.
Chris@16 744 iterator end();
Chris@16 745
Chris@16 746 //! <b>Effects</b>: Returns a const_iterator pointing to the end of the container.
Chris@16 747 //!
Chris@16 748 //! <b>Complexity</b>: Constant.
Chris@16 749 //!
Chris@16 750 //! <b>Throws</b>: Nothing.
Chris@16 751 const_iterator end() const;
Chris@16 752
Chris@16 753 //! <b>Effects</b>: Returns a const_iterator pointing to the end of the container.
Chris@16 754 //!
Chris@16 755 //! <b>Complexity</b>: Constant.
Chris@16 756 //!
Chris@16 757 //! <b>Throws</b>: Nothing.
Chris@16 758 const_iterator cend() const;
Chris@16 759
Chris@16 760 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning of the
Chris@16 761 //! reversed container.
Chris@16 762 //!
Chris@16 763 //! <b>Complexity</b>: Constant.
Chris@16 764 //!
Chris@16 765 //! <b>Throws</b>: Nothing.
Chris@16 766 reverse_iterator rbegin();
Chris@16 767
Chris@16 768 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
Chris@16 769 //! of the reversed container.
Chris@16 770 //!
Chris@16 771 //! <b>Complexity</b>: Constant.
Chris@16 772 //!
Chris@16 773 //! <b>Throws</b>: Nothing.
Chris@16 774 const_reverse_iterator rbegin() const;
Chris@16 775
Chris@16 776 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
Chris@16 777 //! of the reversed container.
Chris@16 778 //!
Chris@16 779 //! <b>Complexity</b>: Constant.
Chris@16 780 //!
Chris@16 781 //! <b>Throws</b>: Nothing.
Chris@16 782 const_reverse_iterator crbegin() const;
Chris@16 783
Chris@16 784 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
Chris@16 785 //! of the reversed container.
Chris@16 786 //!
Chris@16 787 //! <b>Complexity</b>: Constant.
Chris@16 788 //!
Chris@16 789 //! <b>Throws</b>: Nothing.
Chris@16 790 reverse_iterator rend();
Chris@16 791
Chris@16 792 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
Chris@16 793 //! of the reversed container.
Chris@16 794 //!
Chris@16 795 //! <b>Complexity</b>: Constant.
Chris@16 796 //!
Chris@16 797 //! <b>Throws</b>: Nothing.
Chris@16 798 const_reverse_iterator rend() const;
Chris@16 799
Chris@16 800 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
Chris@16 801 //! of the reversed container.
Chris@16 802 //!
Chris@16 803 //! <b>Complexity</b>: Constant.
Chris@16 804 //!
Chris@16 805 //! <b>Throws</b>: Nothing.
Chris@16 806 const_reverse_iterator crend() const;
Chris@16 807
Chris@16 808 #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 809
Chris@16 810 //! <b>Precondition</b>: end_iterator must be a valid end iterator
Chris@16 811 //! of the container.
Chris@16 812 //!
Chris@16 813 //! <b>Effects</b>: Returns a const reference to the container associated to the end iterator
Chris@16 814 //!
Chris@16 815 //! <b>Throws</b>: Nothing.
Chris@16 816 //!
Chris@16 817 //! <b>Complexity</b>: Constant.
Chris@16 818 static bstree_impl &container_from_end_iterator(iterator end_iterator)
Chris@16 819 {
Chris@101 820 return static_cast<bstree_impl&>
Chris@101 821 (data_type::get_tree_base_from_end_iterator(end_iterator));
Chris@16 822 }
Chris@16 823
Chris@16 824 //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
Chris@16 825 //! of the container.
Chris@16 826 //!
Chris@16 827 //! <b>Effects</b>: Returns a const reference to the container associated to the iterator
Chris@16 828 //!
Chris@16 829 //! <b>Throws</b>: Nothing.
Chris@16 830 //!
Chris@16 831 //! <b>Complexity</b>: Constant.
Chris@16 832 static const bstree_impl &container_from_end_iterator(const_iterator end_iterator)
Chris@16 833 {
Chris@101 834 return static_cast<bstree_impl&>
Chris@101 835 (data_type::get_tree_base_from_end_iterator(end_iterator));
Chris@16 836 }
Chris@16 837
Chris@16 838 //! <b>Precondition</b>: it must be a valid iterator
Chris@16 839 //! of the container.
Chris@16 840 //!
Chris@16 841 //! <b>Effects</b>: Returns a const reference to the container associated to the iterator
Chris@16 842 //!
Chris@16 843 //! <b>Throws</b>: Nothing.
Chris@16 844 //!
Chris@16 845 //! <b>Complexity</b>: Logarithmic.
Chris@16 846 static bstree_impl &container_from_iterator(iterator it)
Chris@16 847 { return container_from_end_iterator(it.end_iterator_from_it()); }
Chris@16 848
Chris@16 849 //! <b>Precondition</b>: it must be a valid end const_iterator
Chris@16 850 //! of container.
Chris@16 851 //!
Chris@16 852 //! <b>Effects</b>: Returns a const reference to the container associated to the end iterator
Chris@16 853 //!
Chris@16 854 //! <b>Throws</b>: Nothing.
Chris@16 855 //!
Chris@16 856 //! <b>Complexity</b>: Logarithmic.
Chris@16 857 static const bstree_impl &container_from_iterator(const_iterator it)
Chris@16 858 { return container_from_end_iterator(it.end_iterator_from_it()); }
Chris@16 859
Chris@16 860 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 861
Chris@16 862 //! <b>Effects</b>: Returns the key_compare object used by the container.
Chris@16 863 //!
Chris@16 864 //! <b>Complexity</b>: Constant.
Chris@16 865 //!
Chris@16 866 //! <b>Throws</b>: If value_compare copy-constructor throws.
Chris@16 867 key_compare key_comp() const;
Chris@101 868
Chris@16 869 //! <b>Effects</b>: Returns the value_compare object used by the container.
Chris@16 870 //!
Chris@16 871 //! <b>Complexity</b>: Constant.
Chris@16 872 //!
Chris@16 873 //! <b>Throws</b>: If value_compare copy-constructor throws.
Chris@16 874 value_compare value_comp() const;
Chris@16 875
Chris@101 876 #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@101 877
Chris@16 878 //! <b>Effects</b>: Returns true if the container is empty.
Chris@16 879 //!
Chris@16 880 //! <b>Complexity</b>: Constant.
Chris@16 881 //!
Chris@16 882 //! <b>Throws</b>: Nothing.
Chris@101 883 bool empty() const
Chris@101 884 {
Chris@101 885 if(ConstantTimeSize){
Chris@101 886 return !this->data_type::sz_traits().get_size();
Chris@101 887 }
Chris@101 888 else{
Chris@101 889 return algo_type::unique(this->header_ptr());
Chris@101 890 }
Chris@101 891 }
Chris@16 892
Chris@16 893 //! <b>Effects</b>: Returns the number of elements stored in the container.
Chris@16 894 //!
Chris@16 895 //! <b>Complexity</b>: Linear to elements contained in *this
Chris@16 896 //! if constant-time size option is disabled. Constant time otherwise.
Chris@16 897 //!
Chris@16 898 //! <b>Throws</b>: Nothing.
Chris@16 899 size_type size() const
Chris@16 900 {
Chris@16 901 if(constant_time_size)
Chris@16 902 return this->sz_traits().get_size();
Chris@16 903 else{
Chris@16 904 return (size_type)node_algorithms::size(this->header_ptr());
Chris@16 905 }
Chris@16 906 }
Chris@16 907
Chris@16 908 //! <b>Effects</b>: Swaps the contents of two containers.
Chris@16 909 //!
Chris@16 910 //! <b>Complexity</b>: Constant.
Chris@16 911 //!
Chris@16 912 //! <b>Throws</b>: If the comparison functor's swap call throws.
Chris@16 913 void swap(bstree_impl& other)
Chris@16 914 {
Chris@16 915 //This can throw
Chris@101 916 ::boost::adl_move_swap(this->comp(), this->comp());
Chris@16 917 //These can't throw
Chris@16 918 node_algorithms::swap_tree(this->header_ptr(), node_ptr(other.header_ptr()));
Chris@16 919 if(constant_time_size){
Chris@16 920 size_type backup = this->sz_traits().get_size();
Chris@16 921 this->sz_traits().set_size(other.sz_traits().get_size());
Chris@16 922 other.sz_traits().set_size(backup);
Chris@16 923 }
Chris@16 924 }
Chris@16 925
Chris@16 926 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 927 //! Cloner should yield to nodes equivalent to the original nodes.
Chris@16 928 //!
Chris@16 929 //! <b>Effects</b>: Erases all the elements from *this
Chris@16 930 //! calling Disposer::operator()(pointer), clones all the
Chris@16 931 //! elements from src calling Cloner::operator()(const_reference )
Chris@16 932 //! and inserts them on *this. Copies the predicate from the source container.
Chris@16 933 //!
Chris@16 934 //! If cloner throws, all cloned elements are unlinked and disposed
Chris@16 935 //! calling Disposer::operator()(pointer).
Chris@16 936 //!
Chris@16 937 //! <b>Complexity</b>: Linear to erased plus inserted elements.
Chris@16 938 //!
Chris@16 939 //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
Chris@16 940 template <class Cloner, class Disposer>
Chris@16 941 void clone_from(const bstree_impl &src, Cloner cloner, Disposer disposer)
Chris@16 942 {
Chris@16 943 this->clear_and_dispose(disposer);
Chris@16 944 if(!src.empty()){
Chris@16 945 detail::exception_disposer<bstree_impl, Disposer>
Chris@16 946 rollback(*this, disposer);
Chris@16 947 node_algorithms::clone
Chris@101 948 (src.header_ptr()
Chris@101 949 ,this->header_ptr()
Chris@101 950 ,detail::node_cloner <Cloner, value_traits, AlgoType>(cloner, &this->get_value_traits())
Chris@101 951 ,detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
Chris@101 952 this->sz_traits().set_size(src.sz_traits().get_size());
Chris@101 953 this->comp() = src.comp();
Chris@101 954 rollback.release();
Chris@101 955 }
Chris@101 956 }
Chris@101 957
Chris@101 958 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@101 959 //! Cloner should yield to nodes equivalent to the original nodes.
Chris@101 960 //!
Chris@101 961 //! <b>Effects</b>: Erases all the elements from *this
Chris@101 962 //! calling Disposer::operator()(pointer), clones all the
Chris@101 963 //! elements from src calling Cloner::operator()(const_reference )
Chris@101 964 //! and inserts them on *this. Copies the predicate from the source container.
Chris@101 965 //!
Chris@101 966 //! If cloner throws, all cloned elements are unlinked and disposed
Chris@101 967 //! calling Disposer::operator()(pointer).
Chris@101 968 //!
Chris@101 969 //! <b>Complexity</b>: Linear to erased plus inserted elements.
Chris@101 970 //!
Chris@101 971 //! <b>Throws</b>: If cloner throws or predicate copy assignment throws. Basic guarantee.
Chris@101 972 //!
Chris@101 973 //! <b>Note</b>: This version can modify the source container, useful to implement
Chris@101 974 //! move semantics.
Chris@101 975 template <class Cloner, class Disposer>
Chris@101 976 void clone_from(bstree_impl &src, Cloner cloner, Disposer disposer)
Chris@101 977 {
Chris@101 978 this->clear_and_dispose(disposer);
Chris@101 979 if(!src.empty()){
Chris@101 980 detail::exception_disposer<bstree_impl, Disposer>
Chris@101 981 rollback(*this, disposer);
Chris@101 982 node_algorithms::clone
Chris@101 983 (src.header_ptr()
Chris@101 984 ,this->header_ptr()
Chris@101 985 ,detail::node_cloner <Cloner, value_traits, AlgoType, false>(cloner, &this->get_value_traits())
Chris@101 986 ,detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
Chris@16 987 this->sz_traits().set_size(src.sz_traits().get_size());
Chris@16 988 this->comp() = src.comp();
Chris@16 989 rollback.release();
Chris@16 990 }
Chris@16 991 }
Chris@16 992
Chris@16 993 //! <b>Requires</b>: value must be an lvalue
Chris@16 994 //!
Chris@16 995 //! <b>Effects</b>: Inserts value into the container before the upper bound.
Chris@16 996 //!
Chris@16 997 //! <b>Complexity</b>: Average complexity for insert element is at
Chris@16 998 //! most logarithmic.
Chris@16 999 //!
Chris@16 1000 //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
Chris@16 1001 //!
Chris@16 1002 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 1003 //! No copy-constructors are called.
Chris@16 1004 iterator insert_equal(reference value)
Chris@16 1005 {
Chris@101 1006 detail::key_nodeptr_comp<value_compare, value_traits>
Chris@101 1007 key_node_comp(this->comp(), &this->get_value_traits());
Chris@101 1008 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
Chris@16 1009 if(safemode_or_autounlink)
Chris@16 1010 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
Chris@16 1011 iterator ret(node_algorithms::insert_equal_upper_bound
Chris@101 1012 (this->header_ptr(), to_insert, key_node_comp), this->priv_value_traits_ptr());
Chris@16 1013 this->sz_traits().increment();
Chris@16 1014 return ret;
Chris@16 1015 }
Chris@16 1016
Chris@16 1017 //! <b>Requires</b>: value must be an lvalue, and "hint" must be
Chris@16 1018 //! a valid iterator.
Chris@16 1019 //!
Chris@16 1020 //! <b>Effects</b>: Inserts x into the container, using "hint" as a hint to
Chris@16 1021 //! where it will be inserted. If "hint" is the upper_bound
Chris@16 1022 //! the insertion takes constant time (two comparisons in the worst case)
Chris@16 1023 //!
Chris@16 1024 //! <b>Complexity</b>: Logarithmic in general, but it is amortized
Chris@16 1025 //! constant time if t is inserted immediately before hint.
Chris@16 1026 //!
Chris@16 1027 //! <b>Throws</b>: If the internal value_compare ordering function throws. Strong guarantee.
Chris@16 1028 //!
Chris@16 1029 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 1030 //! No copy-constructors are called.
Chris@16 1031 iterator insert_equal(const_iterator hint, reference value)
Chris@16 1032 {
Chris@101 1033 detail::key_nodeptr_comp<value_compare, value_traits>
Chris@101 1034 key_node_comp(this->comp(), &this->get_value_traits());
Chris@101 1035 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
Chris@16 1036 if(safemode_or_autounlink)
Chris@16 1037 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
Chris@16 1038 iterator ret(node_algorithms::insert_equal
Chris@101 1039 (this->header_ptr(), hint.pointed_node(), to_insert, key_node_comp), this->priv_value_traits_ptr());
Chris@16 1040 this->sz_traits().increment();
Chris@16 1041 return ret;
Chris@16 1042 }
Chris@16 1043
Chris@16 1044 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
Chris@16 1045 //! of type value_type.
Chris@16 1046 //!
Chris@16 1047 //! <b>Effects</b>: Inserts a each element of a range into the container
Chris@16 1048 //! before the upper bound of the key of each element.
Chris@16 1049 //!
Chris@16 1050 //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
Chris@16 1051 //! size of the range. However, it is linear in N if the range is already sorted
Chris@16 1052 //! by value_comp().
Chris@16 1053 //!
Chris@16 1054 //! <b>Throws</b>: Nothing.
Chris@16 1055 //!
Chris@16 1056 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 1057 //! No copy-constructors are called.
Chris@16 1058 template<class Iterator>
Chris@16 1059 void insert_equal(Iterator b, Iterator e)
Chris@16 1060 {
Chris@16 1061 iterator iend(this->end());
Chris@16 1062 for (; b != e; ++b)
Chris@16 1063 this->insert_equal(iend, *b);
Chris@16 1064 }
Chris@16 1065
Chris@16 1066 //! <b>Requires</b>: value must be an lvalue
Chris@16 1067 //!
Chris@16 1068 //! <b>Effects</b>: Inserts value into the container if the value
Chris@16 1069 //! is not already present.
Chris@16 1070 //!
Chris@16 1071 //! <b>Complexity</b>: Average complexity for insert element is at
Chris@16 1072 //! most logarithmic.
Chris@16 1073 //!
Chris@16 1074 //! <b>Throws</b>: Nothing.
Chris@16 1075 //!
Chris@16 1076 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 1077 //! No copy-constructors are called.
Chris@16 1078 std::pair<iterator, bool> insert_unique(reference value)
Chris@16 1079 {
Chris@16 1080 insert_commit_data commit_data;
Chris@16 1081 std::pair<iterator, bool> ret = this->insert_unique_check(value, this->comp(), commit_data);
Chris@16 1082 if(!ret.second)
Chris@16 1083 return ret;
Chris@16 1084 return std::pair<iterator, bool> (this->insert_unique_commit(value, commit_data), true);
Chris@16 1085 }
Chris@16 1086
Chris@16 1087 //! <b>Requires</b>: value must be an lvalue, and "hint" must be
Chris@16 1088 //! a valid iterator
Chris@16 1089 //!
Chris@16 1090 //! <b>Effects</b>: Tries to insert x into the container, using "hint" as a hint
Chris@16 1091 //! to where it will be inserted.
Chris@16 1092 //!
Chris@16 1093 //! <b>Complexity</b>: Logarithmic in general, but it is amortized
Chris@16 1094 //! constant time (two comparisons in the worst case)
Chris@16 1095 //! if t is inserted immediately before hint.
Chris@16 1096 //!
Chris@16 1097 //! <b>Throws</b>: Nothing.
Chris@16 1098 //!
Chris@16 1099 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 1100 //! No copy-constructors are called.
Chris@16 1101 iterator insert_unique(const_iterator hint, reference value)
Chris@16 1102 {
Chris@16 1103 insert_commit_data commit_data;
Chris@16 1104 std::pair<iterator, bool> ret = this->insert_unique_check(hint, value, this->comp(), commit_data);
Chris@16 1105 if(!ret.second)
Chris@16 1106 return ret.first;
Chris@16 1107 return this->insert_unique_commit(value, commit_data);
Chris@16 1108 }
Chris@16 1109
Chris@16 1110 //! <b>Requires</b>: Dereferencing iterator must yield an lvalue
Chris@16 1111 //! of type value_type.
Chris@16 1112 //!
Chris@16 1113 //! <b>Effects</b>: Tries to insert each element of a range into the container.
Chris@16 1114 //!
Chris@16 1115 //! <b>Complexity</b>: Insert range is in general O(N * log(N)), where N is the
Chris@16 1116 //! size of the range. However, it is linear in N if the range is already sorted
Chris@16 1117 //! by value_comp().
Chris@16 1118 //!
Chris@16 1119 //! <b>Throws</b>: Nothing.
Chris@16 1120 //!
Chris@16 1121 //! <b>Note</b>: Does not affect the validity of iterators and references.
Chris@16 1122 //! No copy-constructors are called.
Chris@16 1123 template<class Iterator>
Chris@16 1124 void insert_unique(Iterator b, Iterator e)
Chris@16 1125 {
Chris@16 1126 if(this->empty()){
Chris@16 1127 iterator iend(this->end());
Chris@16 1128 for (; b != e; ++b)
Chris@16 1129 this->insert_unique(iend, *b);
Chris@16 1130 }
Chris@16 1131 else{
Chris@16 1132 for (; b != e; ++b)
Chris@16 1133 this->insert_unique(*b);
Chris@16 1134 }
Chris@16 1135 }
Chris@16 1136
Chris@16 1137 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 1138
Chris@16 1139 //! <b>Requires</b>: key_value_comp must be a comparison function that induces
Chris@16 1140 //! the same strict weak ordering as value_compare. The difference is that
Chris@16 1141 //! key_value_comp compares an arbitrary key with the contained values.
Chris@16 1142 //!
Chris@16 1143 //! <b>Effects</b>: Checks if a value can be inserted in the container, using
Chris@16 1144 //! a user provided key instead of the value itself.
Chris@16 1145 //!
Chris@16 1146 //! <b>Returns</b>: If there is an equivalent value
Chris@16 1147 //! returns a pair containing an iterator to the already present value
Chris@16 1148 //! and false. If the value can be inserted returns true in the returned
Chris@16 1149 //! pair boolean and fills "commit_data" that is meant to be used with
Chris@16 1150 //! the "insert_commit" function.
Chris@16 1151 //!
Chris@16 1152 //! <b>Complexity</b>: Average complexity is at most logarithmic.
Chris@16 1153 //!
Chris@16 1154 //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
Chris@16 1155 //!
Chris@16 1156 //! <b>Notes</b>: This function is used to improve performance when constructing
Chris@16 1157 //! a value_type is expensive: if there is an equivalent value
Chris@16 1158 //! the constructed object must be discarded. Many times, the part of the
Chris@16 1159 //! node that is used to impose the order is much cheaper to construct
Chris@16 1160 //! than the value_type and this function offers the possibility to use that
Chris@16 1161 //! part to check if the insertion will be successful.
Chris@16 1162 //!
Chris@16 1163 //! If the check is successful, the user can construct the value_type and use
Chris@16 1164 //! "insert_commit" to insert the object in constant-time. This gives a total
Chris@16 1165 //! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
Chris@16 1166 //!
Chris@16 1167 //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
Chris@16 1168 //! objects are inserted or erased from the container.
Chris@16 1169 template<class KeyType, class KeyValueCompare>
Chris@16 1170 std::pair<iterator, bool> insert_unique_check
Chris@16 1171 (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data);
Chris@16 1172
Chris@16 1173 //! <b>Requires</b>: key_value_comp must be a comparison function that induces
Chris@16 1174 //! the same strict weak ordering as value_compare. The difference is that
Chris@16 1175 //! key_value_comp compares an arbitrary key with the contained values.
Chris@16 1176 //!
Chris@16 1177 //! <b>Effects</b>: Checks if a value can be inserted in the container, using
Chris@16 1178 //! a user provided key instead of the value itself, using "hint"
Chris@16 1179 //! as a hint to where it will be inserted.
Chris@16 1180 //!
Chris@16 1181 //! <b>Returns</b>: If there is an equivalent value
Chris@16 1182 //! returns a pair containing an iterator to the already present value
Chris@16 1183 //! and false. If the value can be inserted returns true in the returned
Chris@16 1184 //! pair boolean and fills "commit_data" that is meant to be used with
Chris@16 1185 //! the "insert_commit" function.
Chris@16 1186 //!
Chris@16 1187 //! <b>Complexity</b>: Logarithmic in general, but it's amortized
Chris@16 1188 //! constant time if t is inserted immediately before hint.
Chris@16 1189 //!
Chris@16 1190 //! <b>Throws</b>: If the key_value_comp ordering function throws. Strong guarantee.
Chris@16 1191 //!
Chris@16 1192 //! <b>Notes</b>: This function is used to improve performance when constructing
Chris@16 1193 //! a value_type is expensive: if there is an equivalent value
Chris@16 1194 //! the constructed object must be discarded. Many times, the part of the
Chris@16 1195 //! constructing that is used to impose the order is much cheaper to construct
Chris@16 1196 //! than the value_type and this function offers the possibility to use that key
Chris@16 1197 //! to check if the insertion will be successful.
Chris@16 1198 //!
Chris@16 1199 //! If the check is successful, the user can construct the value_type and use
Chris@16 1200 //! "insert_commit" to insert the object in constant-time. This can give a total
Chris@16 1201 //! constant-time complexity to the insertion: check(O(1)) + commit(O(1)).
Chris@16 1202 //!
Chris@16 1203 //! "commit_data" remains valid for a subsequent "insert_commit" only if no more
Chris@16 1204 //! objects are inserted or erased from the container.
Chris@16 1205 template<class KeyType, class KeyValueCompare>
Chris@16 1206 std::pair<iterator, bool> insert_unique_check
Chris@16 1207 (const_iterator hint, const KeyType &key
Chris@16 1208 ,KeyValueCompare key_value_comp, insert_commit_data &commit_data);
Chris@16 1209
Chris@16 1210 #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 1211
Chris@16 1212 //! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
Chris@16 1213 //! must have been obtained from a previous call to "insert_check".
Chris@16 1214 //! No objects should have been inserted or erased from the container between
Chris@16 1215 //! the "insert_check" that filled "commit_data" and the call to "insert_commit".
Chris@16 1216 //!
Chris@16 1217 //! <b>Effects</b>: Inserts the value in the container using the information obtained
Chris@16 1218 //! from the "commit_data" that a previous "insert_check" filled.
Chris@16 1219 //!
Chris@16 1220 //! <b>Returns</b>: An iterator to the newly inserted object.
Chris@16 1221 //!
Chris@16 1222 //! <b>Complexity</b>: Constant time.
Chris@16 1223 //!
Chris@16 1224 //! <b>Throws</b>: Nothing.
Chris@16 1225 //!
Chris@16 1226 //! <b>Notes</b>: This function has only sense if a "insert_check" has been
Chris@16 1227 //! previously executed to fill "commit_data". No value should be inserted or
Chris@16 1228 //! erased between the "insert_check" and "insert_commit" calls.
Chris@16 1229 iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
Chris@16 1230 {
Chris@101 1231 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
Chris@16 1232 if(safemode_or_autounlink)
Chris@16 1233 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
Chris@16 1234 node_algorithms::insert_unique_commit
Chris@16 1235 (this->header_ptr(), to_insert, commit_data);
Chris@16 1236 this->sz_traits().increment();
Chris@101 1237 return iterator(to_insert, this->priv_value_traits_ptr());
Chris@16 1238 }
Chris@16 1239
Chris@16 1240 //! <b>Requires</b>: value must be an lvalue, "pos" must be
Chris@16 1241 //! a valid iterator (or end) and must be the succesor of value
Chris@16 1242 //! once inserted according to the predicate
Chris@16 1243 //!
Chris@16 1244 //! <b>Effects</b>: Inserts x into the container before "pos".
Chris@16 1245 //!
Chris@16 1246 //! <b>Complexity</b>: Constant time.
Chris@16 1247 //!
Chris@16 1248 //! <b>Throws</b>: Nothing.
Chris@16 1249 //!
Chris@16 1250 //! <b>Note</b>: This function does not check preconditions so if "pos" is not
Chris@16 1251 //! the successor of "value" container ordering invariant will be broken.
Chris@16 1252 //! This is a low-level function to be used only for performance reasons
Chris@16 1253 //! by advanced users.
Chris@16 1254 iterator insert_before(const_iterator pos, reference value)
Chris@16 1255 {
Chris@101 1256 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
Chris@16 1257 if(safemode_or_autounlink)
Chris@16 1258 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
Chris@16 1259 this->sz_traits().increment();
Chris@16 1260 return iterator(node_algorithms::insert_before
Chris@101 1261 (this->header_ptr(), pos.pointed_node(), to_insert), this->priv_value_traits_ptr());
Chris@16 1262 }
Chris@16 1263
Chris@16 1264 //! <b>Requires</b>: value must be an lvalue, and it must be no less
Chris@16 1265 //! than the greatest inserted key
Chris@16 1266 //!
Chris@16 1267 //! <b>Effects</b>: Inserts x into the container in the last position.
Chris@16 1268 //!
Chris@16 1269 //! <b>Complexity</b>: Constant time.
Chris@16 1270 //!
Chris@16 1271 //! <b>Throws</b>: Nothing.
Chris@16 1272 //!
Chris@16 1273 //! <b>Note</b>: This function does not check preconditions so if value is
Chris@16 1274 //! less than the greatest inserted key container ordering invariant will be broken.
Chris@16 1275 //! This function is slightly more efficient than using "insert_before".
Chris@16 1276 //! This is a low-level function to be used only for performance reasons
Chris@16 1277 //! by advanced users.
Chris@16 1278 void push_back(reference value)
Chris@16 1279 {
Chris@101 1280 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
Chris@16 1281 if(safemode_or_autounlink)
Chris@16 1282 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
Chris@16 1283 this->sz_traits().increment();
Chris@16 1284 node_algorithms::push_back(this->header_ptr(), to_insert);
Chris@16 1285 }
Chris@16 1286
Chris@16 1287 //! <b>Requires</b>: value must be an lvalue, and it must be no greater
Chris@16 1288 //! than the minimum inserted key
Chris@16 1289 //!
Chris@16 1290 //! <b>Effects</b>: Inserts x into the container in the first position.
Chris@16 1291 //!
Chris@16 1292 //! <b>Complexity</b>: Constant time.
Chris@16 1293 //!
Chris@16 1294 //! <b>Throws</b>: Nothing.
Chris@16 1295 //!
Chris@16 1296 //! <b>Note</b>: This function does not check preconditions so if value is
Chris@16 1297 //! greater than the minimum inserted key container ordering invariant will be broken.
Chris@16 1298 //! This function is slightly more efficient than using "insert_before".
Chris@16 1299 //! This is a low-level function to be used only for performance reasons
Chris@16 1300 //! by advanced users.
Chris@16 1301 void push_front(reference value)
Chris@16 1302 {
Chris@101 1303 node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
Chris@16 1304 if(safemode_or_autounlink)
Chris@16 1305 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
Chris@16 1306 this->sz_traits().increment();
Chris@16 1307 node_algorithms::push_front(this->header_ptr(), to_insert);
Chris@16 1308 }
Chris@16 1309
Chris@101 1310 //! <b>Effects</b>: Erases the element pointed to by i.
Chris@16 1311 //!
Chris@16 1312 //! <b>Complexity</b>: Average complexity for erase element is constant time.
Chris@16 1313 //!
Chris@16 1314 //! <b>Throws</b>: Nothing.
Chris@16 1315 //!
Chris@16 1316 //! <b>Note</b>: Invalidates the iterators (but not the references)
Chris@16 1317 //! to the erased elements. No destructors are called.
Chris@16 1318 iterator erase(const_iterator i)
Chris@16 1319 {
Chris@16 1320 const_iterator ret(i);
Chris@16 1321 ++ret;
Chris@16 1322 node_ptr to_erase(i.pointed_node());
Chris@16 1323 if(safemode_or_autounlink)
Chris@16 1324 BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
Chris@16 1325 node_algorithms::erase(this->header_ptr(), to_erase);
Chris@16 1326 this->sz_traits().decrement();
Chris@16 1327 if(safemode_or_autounlink)
Chris@16 1328 node_algorithms::init(to_erase);
Chris@16 1329 return ret.unconst();
Chris@16 1330 }
Chris@16 1331
Chris@16 1332 //! <b>Effects</b>: Erases the range pointed to by b end e.
Chris@16 1333 //!
Chris@16 1334 //! <b>Complexity</b>: Average complexity for erase range is at most
Chris@16 1335 //! O(log(size() + N)), where N is the number of elements in the range.
Chris@16 1336 //!
Chris@16 1337 //! <b>Throws</b>: Nothing.
Chris@16 1338 //!
Chris@16 1339 //! <b>Note</b>: Invalidates the iterators (but not the references)
Chris@16 1340 //! to the erased elements. No destructors are called.
Chris@16 1341 iterator erase(const_iterator b, const_iterator e)
Chris@16 1342 { size_type n; return this->private_erase(b, e, n); }
Chris@16 1343
Chris@16 1344 //! <b>Effects</b>: Erases all the elements with the given value.
Chris@16 1345 //!
Chris@16 1346 //! <b>Returns</b>: The number of erased elements.
Chris@16 1347 //!
Chris@16 1348 //! <b>Complexity</b>: O(log(size() + N).
Chris@16 1349 //!
Chris@16 1350 //! <b>Throws</b>: Nothing.
Chris@16 1351 //!
Chris@16 1352 //! <b>Note</b>: Invalidates the iterators (but not the references)
Chris@16 1353 //! to the erased elements. No destructors are called.
Chris@16 1354 size_type erase(const_reference value)
Chris@16 1355 { return this->erase(value, this->comp()); }
Chris@16 1356
Chris@16 1357 //! <b>Effects</b>: Erases all the elements with the given key.
Chris@16 1358 //! according to the comparison functor "comp".
Chris@16 1359 //!
Chris@16 1360 //! <b>Returns</b>: The number of erased elements.
Chris@16 1361 //!
Chris@16 1362 //! <b>Complexity</b>: O(log(size() + N).
Chris@16 1363 //!
Chris@16 1364 //! <b>Throws</b>: Nothing.
Chris@16 1365 //!
Chris@16 1366 //! <b>Note</b>: Invalidates the iterators (but not the references)
Chris@16 1367 //! to the erased elements. No destructors are called.
Chris@16 1368 template<class KeyType, class KeyValueCompare>
Chris@16 1369 size_type erase(const KeyType& key, KeyValueCompare comp
Chris@16 1370 /// @cond
Chris@16 1371 , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
Chris@16 1372 /// @endcond
Chris@16 1373 )
Chris@16 1374 {
Chris@16 1375 std::pair<iterator,iterator> p = this->equal_range(key, comp);
Chris@16 1376 size_type n;
Chris@16 1377 this->private_erase(p.first, p.second, n);
Chris@16 1378 return n;
Chris@16 1379 }
Chris@16 1380
Chris@16 1381 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 1382 //!
Chris@101 1383 //! <b>Effects</b>: Erases the element pointed to by i.
Chris@16 1384 //! Disposer::operator()(pointer) is called for the removed element.
Chris@16 1385 //!
Chris@16 1386 //! <b>Complexity</b>: Average complexity for erase element is constant time.
Chris@16 1387 //!
Chris@16 1388 //! <b>Throws</b>: Nothing.
Chris@16 1389 //!
Chris@16 1390 //! <b>Note</b>: Invalidates the iterators
Chris@16 1391 //! to the erased elements.
Chris@16 1392 template<class Disposer>
Chris@16 1393 iterator erase_and_dispose(const_iterator i, Disposer disposer)
Chris@16 1394 {
Chris@16 1395 node_ptr to_erase(i.pointed_node());
Chris@16 1396 iterator ret(this->erase(i));
Chris@101 1397 disposer(this->get_value_traits().to_value_ptr(to_erase));
Chris@16 1398 return ret;
Chris@16 1399 }
Chris@16 1400
Chris@16 1401 #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1402 template<class Disposer>
Chris@16 1403 iterator erase_and_dispose(iterator i, Disposer disposer)
Chris@16 1404 { return this->erase_and_dispose(const_iterator(i), disposer); }
Chris@16 1405 #endif
Chris@16 1406
Chris@16 1407 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 1408 //!
Chris@16 1409 //! <b>Effects</b>: Erases all the elements with the given value.
Chris@16 1410 //! Disposer::operator()(pointer) is called for the removed elements.
Chris@16 1411 //!
Chris@16 1412 //! <b>Returns</b>: The number of erased elements.
Chris@16 1413 //!
Chris@16 1414 //! <b>Complexity</b>: O(log(size() + N).
Chris@16 1415 //!
Chris@16 1416 //! <b>Throws</b>: Nothing.
Chris@16 1417 //!
Chris@16 1418 //! <b>Note</b>: Invalidates the iterators (but not the references)
Chris@16 1419 //! to the erased elements. No destructors are called.
Chris@16 1420 template<class Disposer>
Chris@16 1421 size_type erase_and_dispose(const_reference value, Disposer disposer)
Chris@16 1422 {
Chris@16 1423 std::pair<iterator,iterator> p = this->equal_range(value);
Chris@16 1424 size_type n;
Chris@16 1425 this->private_erase(p.first, p.second, n, disposer);
Chris@16 1426 return n;
Chris@16 1427 }
Chris@16 1428
Chris@16 1429 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 1430 //!
Chris@16 1431 //! <b>Effects</b>: Erases the range pointed to by b end e.
Chris@16 1432 //! Disposer::operator()(pointer) is called for the removed elements.
Chris@16 1433 //!
Chris@16 1434 //! <b>Complexity</b>: Average complexity for erase range is at most
Chris@16 1435 //! O(log(size() + N)), where N is the number of elements in the range.
Chris@16 1436 //!
Chris@16 1437 //! <b>Throws</b>: Nothing.
Chris@16 1438 //!
Chris@16 1439 //! <b>Note</b>: Invalidates the iterators
Chris@16 1440 //! to the erased elements.
Chris@16 1441 template<class Disposer>
Chris@16 1442 iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
Chris@16 1443 { size_type n; return this->private_erase(b, e, n, disposer); }
Chris@16 1444
Chris@16 1445 //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
Chris@16 1446 //!
Chris@16 1447 //! <b>Effects</b>: Erases all the elements with the given key.
Chris@16 1448 //! according to the comparison functor "comp".
Chris@16 1449 //! Disposer::operator()(pointer) is called for the removed elements.
Chris@16 1450 //!
Chris@16 1451 //! <b>Returns</b>: The number of erased elements.
Chris@16 1452 //!
Chris@16 1453 //! <b>Complexity</b>: O(log(size() + N).
Chris@16 1454 //!
Chris@16 1455 //! <b>Throws</b>: Nothing.
Chris@16 1456 //!
Chris@16 1457 //! <b>Note</b>: Invalidates the iterators
Chris@16 1458 //! to the erased elements.
Chris@16 1459 template<class KeyType, class KeyValueCompare, class Disposer>
Chris@16 1460 size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
Chris@16 1461 /// @cond
Chris@16 1462 , typename detail::enable_if_c<!detail::is_convertible<KeyValueCompare, const_iterator>::value >::type * = 0
Chris@16 1463 /// @endcond
Chris@16 1464 )
Chris@16 1465 {
Chris@16 1466 std::pair<iterator,iterator> p = this->equal_range(key, comp);
Chris@16 1467 size_type n;
Chris@16 1468 this->private_erase(p.first, p.second, n, disposer);
Chris@16 1469 return n;
Chris@16 1470 }
Chris@16 1471
Chris@16 1472 //! <b>Effects</b>: Erases all of the elements.
Chris@16 1473 //!
Chris@16 1474 //! <b>Complexity</b>: Linear to the number of elements on the container.
Chris@16 1475 //! if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
Chris@16 1476 //!
Chris@16 1477 //! <b>Throws</b>: Nothing.
Chris@16 1478 //!
Chris@16 1479 //! <b>Note</b>: Invalidates the iterators (but not the references)
Chris@16 1480 //! to the erased elements. No destructors are called.
Chris@16 1481 void clear()
Chris@16 1482 {
Chris@16 1483 if(safemode_or_autounlink){
Chris@16 1484 this->clear_and_dispose(detail::null_disposer());
Chris@16 1485 }
Chris@16 1486 else{
Chris@16 1487 node_algorithms::init_header(this->header_ptr());
Chris@16 1488 this->sz_traits().set_size(0);
Chris@16 1489 }
Chris@16 1490 }
Chris@16 1491
Chris@16 1492 //! <b>Effects</b>: Erases all of the elements calling disposer(p) for
Chris@16 1493 //! each node to be erased.
Chris@16 1494 //! <b>Complexity</b>: Average complexity for is at most O(log(size() + N)),
Chris@16 1495 //! where N is the number of elements in the container.
Chris@16 1496 //!
Chris@16 1497 //! <b>Throws</b>: Nothing.
Chris@16 1498 //!
Chris@16 1499 //! <b>Note</b>: Invalidates the iterators (but not the references)
Chris@16 1500 //! to the erased elements. Calls N times to disposer functor.
Chris@16 1501 template<class Disposer>
Chris@16 1502 void clear_and_dispose(Disposer disposer)
Chris@16 1503 {
Chris@16 1504 node_algorithms::clear_and_dispose(this->header_ptr()
Chris@101 1505 , detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
Chris@16 1506 node_algorithms::init_header(this->header_ptr());
Chris@16 1507 this->sz_traits().set_size(0);
Chris@16 1508 }
Chris@16 1509
Chris@16 1510 //! <b>Effects</b>: Returns the number of contained elements with the given value
Chris@16 1511 //!
Chris@16 1512 //! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
Chris@16 1513 //! to number of objects with the given value.
Chris@16 1514 //!
Chris@101 1515 //! <b>Throws</b>: If `value_compare` throws.
Chris@101 1516 size_type count(const_reference value) const
Chris@101 1517 { return size_type(this->count(value, this->comp())); }
Chris@16 1518
Chris@16 1519 //! <b>Effects</b>: Returns the number of contained elements with the given key
Chris@16 1520 //!
Chris@16 1521 //! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
Chris@16 1522 //! to number of objects with the given key.
Chris@16 1523 //!
Chris@101 1524 //! <b>Throws</b>: If `comp` throws.
Chris@16 1525 template<class KeyType, class KeyValueCompare>
Chris@101 1526 size_type count(const KeyType &key, KeyValueCompare comp) const
Chris@101 1527 {
Chris@101 1528 std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
Chris@101 1529 size_type n = 0;
Chris@101 1530 for(; ret.first != ret.second; ++ret.first){ ++n; }
Chris@101 1531 return n;
Chris@101 1532 }
Chris@101 1533
Chris@101 1534 #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@101 1535
Chris@101 1536 //Add non-const overloads to theoretically const members
Chris@101 1537 //as some algorithms have different behavior when non-const versions are used (like splay trees).
Chris@101 1538 size_type count(const_reference value)
Chris@101 1539 { return size_type(this->count(value, this->comp())); }
Chris@101 1540
Chris@101 1541 template<class KeyType, class KeyValueCompare>
Chris@101 1542 size_type count(const KeyType &key, KeyValueCompare comp)
Chris@101 1543 {
Chris@101 1544 std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
Chris@101 1545 size_type n = 0;
Chris@101 1546 for(; ret.first != ret.second; ++ret.first){ ++n; }
Chris@101 1547 return n;
Chris@101 1548 }
Chris@101 1549
Chris@101 1550 #else //defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1551
Chris@16 1552 //! <b>Effects</b>: Returns an iterator to the first element whose
Chris@16 1553 //! key is not less than k or end() if that element does not exist.
Chris@16 1554 //!
Chris@16 1555 //! <b>Complexity</b>: Logarithmic.
Chris@16 1556 //!
Chris@101 1557 //! <b>Throws</b>: If `value_compare` throws.
Chris@16 1558 iterator lower_bound(const_reference value);
Chris@16 1559
Chris@16 1560 //! <b>Effects</b>: Returns an iterator to the first element whose
Chris@16 1561 //! key is not less than k or end() if that element does not exist.
Chris@16 1562 //!
Chris@16 1563 //! <b>Complexity</b>: Logarithmic.
Chris@16 1564 //!
Chris@101 1565 //! <b>Throws</b>: If `value_compare` throws.
Chris@16 1566 const_iterator lower_bound(const_reference value) const;
Chris@16 1567
Chris@16 1568 //! <b>Effects</b>: Returns an iterator to the first element whose
Chris@16 1569 //! key is not less than k or end() if that element does not exist.
Chris@16 1570 //!
Chris@16 1571 //! <b>Complexity</b>: Logarithmic.
Chris@16 1572 //!
Chris@101 1573 //! <b>Throws</b>: If `comp` throws.
Chris@16 1574 template<class KeyType, class KeyValueCompare>
Chris@16 1575 iterator lower_bound(const KeyType &key, KeyValueCompare comp);
Chris@101 1576
Chris@16 1577 //! <b>Effects</b>: Returns a const iterator to the first element whose
Chris@16 1578 //! key is not less than k or end() if that element does not exist.
Chris@16 1579 //!
Chris@16 1580 //! <b>Complexity</b>: Logarithmic.
Chris@16 1581 //!
Chris@101 1582 //! <b>Throws</b>: If `comp` throws.
Chris@16 1583 template<class KeyType, class KeyValueCompare>
Chris@16 1584 const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const;
Chris@16 1585
Chris@16 1586 //! <b>Effects</b>: Returns an iterator to the first element whose
Chris@16 1587 //! key is greater than k or end() if that element does not exist.
Chris@16 1588 //!
Chris@16 1589 //! <b>Complexity</b>: Logarithmic.
Chris@16 1590 //!
Chris@101 1591 //! <b>Throws</b>: If `value_compare` throws.
Chris@16 1592 iterator upper_bound(const_reference value);
Chris@16 1593
Chris@16 1594 //! <b>Effects</b>: Returns an iterator to the first element whose
Chris@16 1595 //! key is greater than k according to comp or end() if that element
Chris@16 1596 //! does not exist.
Chris@16 1597 //!
Chris@16 1598 //! <b>Complexity</b>: Logarithmic.
Chris@16 1599 //!
Chris@101 1600 //! <b>Throws</b>: If `comp` throws.
Chris@16 1601 template<class KeyType, class KeyValueCompare>
Chris@16 1602 iterator upper_bound(const KeyType &key, KeyValueCompare comp);
Chris@16 1603
Chris@16 1604 //! <b>Effects</b>: Returns an iterator to the first element whose
Chris@16 1605 //! key is greater than k or end() if that element does not exist.
Chris@16 1606 //!
Chris@16 1607 //! <b>Complexity</b>: Logarithmic.
Chris@16 1608 //!
Chris@101 1609 //! <b>Throws</b>: If `value_compare` throws.
Chris@16 1610 const_iterator upper_bound(const_reference value) const;
Chris@16 1611
Chris@16 1612 //! <b>Effects</b>: Returns an iterator to the first element whose
Chris@16 1613 //! key is greater than k according to comp or end() if that element
Chris@16 1614 //! does not exist.
Chris@16 1615 //!
Chris@16 1616 //! <b>Complexity</b>: Logarithmic.
Chris@16 1617 //!
Chris@101 1618 //! <b>Throws</b>: If `comp` throws.
Chris@16 1619 template<class KeyType, class KeyValueCompare>
Chris@16 1620 const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const;
Chris@16 1621
Chris@16 1622 //! <b>Effects</b>: Finds an iterator to the first element whose key is
Chris@16 1623 //! k or end() if that element does not exist.
Chris@16 1624 //!
Chris@16 1625 //! <b>Complexity</b>: Logarithmic.
Chris@16 1626 //!
Chris@101 1627 //! <b>Throws</b>: If `value_compare` throws.
Chris@16 1628 iterator find(const_reference value);
Chris@16 1629
Chris@16 1630 //! <b>Effects</b>: Finds an iterator to the first element whose key is
Chris@16 1631 //! k or end() if that element does not exist.
Chris@16 1632 //!
Chris@16 1633 //! <b>Complexity</b>: Logarithmic.
Chris@16 1634 //!
Chris@101 1635 //! <b>Throws</b>: If `comp` throws.
Chris@16 1636 template<class KeyType, class KeyValueCompare>
Chris@16 1637 iterator find(const KeyType &key, KeyValueCompare comp);
Chris@16 1638
Chris@16 1639 //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
Chris@16 1640 //! k or end() if that element does not exist.
Chris@16 1641 //!
Chris@16 1642 //! <b>Complexity</b>: Logarithmic.
Chris@16 1643 //!
Chris@101 1644 //! <b>Throws</b>: If `value_compare` throws.
Chris@16 1645 const_iterator find(const_reference value) const;
Chris@16 1646
Chris@16 1647 //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
Chris@16 1648 //! k or end() if that element does not exist.
Chris@16 1649 //!
Chris@16 1650 //! <b>Complexity</b>: Logarithmic.
Chris@16 1651 //!
Chris@101 1652 //! <b>Throws</b>: If `comp` throws.
Chris@16 1653 template<class KeyType, class KeyValueCompare>
Chris@16 1654 const_iterator find(const KeyType &key, KeyValueCompare comp) const;
Chris@16 1655
Chris@16 1656 //! <b>Effects</b>: Finds a range containing all elements whose key is k or
Chris@16 1657 //! an empty range that indicates the position where those elements would be
Chris@16 1658 //! if they there is no elements with key k.
Chris@16 1659 //!
Chris@16 1660 //! <b>Complexity</b>: Logarithmic.
Chris@16 1661 //!
Chris@101 1662 //! <b>Throws</b>: If `value_compare` throws.
Chris@16 1663 std::pair<iterator,iterator> equal_range(const_reference value);
Chris@16 1664
Chris@16 1665 //! <b>Effects</b>: Finds a range containing all elements whose key is k or
Chris@16 1666 //! an empty range that indicates the position where those elements would be
Chris@16 1667 //! if they there is no elements with key k.
Chris@16 1668 //!
Chris@16 1669 //! <b>Complexity</b>: Logarithmic.
Chris@16 1670 //!
Chris@101 1671 //! <b>Throws</b>: If `comp` throws.
Chris@16 1672 template<class KeyType, class KeyValueCompare>
Chris@16 1673 std::pair<iterator,iterator> equal_range(const KeyType &key, KeyValueCompare comp);
Chris@16 1674
Chris@16 1675 //! <b>Effects</b>: Finds a range containing all elements whose key is k or
Chris@16 1676 //! an empty range that indicates the position where those elements would be
Chris@16 1677 //! if they there is no elements with key k.
Chris@16 1678 //!
Chris@16 1679 //! <b>Complexity</b>: Logarithmic.
Chris@16 1680 //!
Chris@101 1681 //! <b>Throws</b>: If `value_compare` throws.
Chris@16 1682 std::pair<const_iterator, const_iterator>
Chris@16 1683 equal_range(const_reference value) const;
Chris@16 1684
Chris@16 1685 //! <b>Effects</b>: Finds a range containing all elements whose key is k or
Chris@16 1686 //! an empty range that indicates the position where those elements would be
Chris@16 1687 //! if they there is no elements with key k.
Chris@16 1688 //!
Chris@16 1689 //! <b>Complexity</b>: Logarithmic.
Chris@16 1690 //!
Chris@101 1691 //! <b>Throws</b>: If `comp` throws.
Chris@16 1692 template<class KeyType, class KeyValueCompare>
Chris@16 1693 std::pair<const_iterator, const_iterator>
Chris@16 1694 equal_range(const KeyType &key, KeyValueCompare comp) const;
Chris@16 1695
Chris@16 1696 //! <b>Requires</b>: 'lower_value' must not be greater than 'upper_value'. If
Chris@16 1697 //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false.
Chris@16 1698 //!
Chris@16 1699 //! <b>Effects</b>: Returns an a pair with the following criteria:
Chris@16 1700 //!
Chris@16 1701 //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise
Chris@16 1702 //!
Chris@16 1703 //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise
Chris@16 1704 //!
Chris@16 1705 //! <b>Complexity</b>: Logarithmic.
Chris@16 1706 //!
Chris@101 1707 //! <b>Throws</b>: If `value_compare` throws.
Chris@16 1708 //!
Chris@16 1709 //! <b>Note</b>: This function can be more efficient than calling upper_bound
Chris@16 1710 //! and lower_bound for lower_value and upper_value.
Chris@16 1711 //!
Chris@16 1712 //! <b>Note</b>: Experimental function, the interface might change in future releases.
Chris@16 1713 std::pair<iterator,iterator> bounded_range
Chris@16 1714 (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
Chris@16 1715
Chris@16 1716 //! <b>Requires</b>: KeyValueCompare is a function object that induces a strict weak
Chris@16 1717 //! ordering compatible with the strict weak ordering used to create the
Chris@101 1718 //! the container.
Chris@16 1719 //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If
Chris@16 1720 //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false.
Chris@16 1721 //!
Chris@16 1722 //! <b>Effects</b>: Returns an a pair with the following criteria:
Chris@16 1723 //!
Chris@16 1724 //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise
Chris@16 1725 //!
Chris@16 1726 //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise
Chris@16 1727 //!
Chris@16 1728 //! <b>Complexity</b>: Logarithmic.
Chris@16 1729 //!
Chris@101 1730 //! <b>Throws</b>: If `comp` throws.
Chris@16 1731 //!
Chris@16 1732 //! <b>Note</b>: This function can be more efficient than calling upper_bound
Chris@16 1733 //! and lower_bound for lower_key and upper_key.
Chris@16 1734 //!
Chris@16 1735 //! <b>Note</b>: Experimental function, the interface might change in future releases.
Chris@16 1736 template<class KeyType, class KeyValueCompare>
Chris@16 1737 std::pair<iterator,iterator> bounded_range
Chris@16 1738 (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
Chris@16 1739
Chris@16 1740 //! <b>Requires</b>: 'lower_value' must not be greater than 'upper_value'. If
Chris@16 1741 //! 'lower_value' == 'upper_value', ('left_closed' || 'right_closed') must be false.
Chris@16 1742 //!
Chris@16 1743 //! <b>Effects</b>: Returns an a pair with the following criteria:
Chris@16 1744 //!
Chris@16 1745 //! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise
Chris@16 1746 //!
Chris@16 1747 //! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise
Chris@16 1748 //!
Chris@16 1749 //! <b>Complexity</b>: Logarithmic.
Chris@16 1750 //!
Chris@101 1751 //! <b>Throws</b>: If `value_compare` throws.
Chris@16 1752 //!
Chris@16 1753 //! <b>Note</b>: This function can be more efficient than calling upper_bound
Chris@16 1754 //! and lower_bound for lower_value and upper_value.
Chris@16 1755 //!
Chris@16 1756 //! <b>Note</b>: Experimental function, the interface might change in future releases.
Chris@16 1757 std::pair<const_iterator,const_iterator> bounded_range
Chris@16 1758 (const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
Chris@16 1759
Chris@16 1760 //! <b>Requires</b>: KeyValueCompare is a function object that induces a strict weak
Chris@16 1761 //! ordering compatible with the strict weak ordering used to create the
Chris@101 1762 //! the container.
Chris@16 1763 //! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If
Chris@16 1764 //! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false.
Chris@16 1765 //!
Chris@16 1766 //! <b>Effects</b>: Returns an a pair with the following criteria:
Chris@16 1767 //!
Chris@16 1768 //! first = lower_bound(lower_key, comp) if left_closed, upper_bound(lower_key, comp) otherwise
Chris@16 1769 //!
Chris@16 1770 //! second = upper_bound(upper_key, comp) if right_closed, lower_bound(upper_key, comp) otherwise
Chris@16 1771 //!
Chris@16 1772 //! <b>Complexity</b>: Logarithmic.
Chris@16 1773 //!
Chris@101 1774 //! <b>Throws</b>: If `comp` throws.
Chris@16 1775 //!
Chris@16 1776 //! <b>Note</b>: This function can be more efficient than calling upper_bound
Chris@16 1777 //! and lower_bound for lower_key and upper_key.
Chris@16 1778 //!
Chris@16 1779 //! <b>Note</b>: Experimental function, the interface might change in future releases.
Chris@16 1780 template<class KeyType, class KeyValueCompare>
Chris@16 1781 std::pair<const_iterator,const_iterator> bounded_range
Chris@16 1782 (const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
Chris@16 1783
Chris@16 1784 //! <b>Requires</b>: value must be an lvalue and shall be in a set of
Chris@16 1785 //! appropriate type. Otherwise the behavior is undefined.
Chris@16 1786 //!
Chris@16 1787 //! <b>Effects</b>: Returns: a valid iterator i belonging to the set
Chris@16 1788 //! that points to the value
Chris@16 1789 //!
Chris@16 1790 //! <b>Complexity</b>: Constant.
Chris@16 1791 //!
Chris@16 1792 //! <b>Throws</b>: Nothing.
Chris@16 1793 //!
Chris@16 1794 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
Chris@16 1795 //! is stateless.
Chris@16 1796 static iterator s_iterator_to(reference value);
Chris@16 1797
Chris@16 1798 //! <b>Requires</b>: value must be an lvalue and shall be in a set of
Chris@16 1799 //! appropriate type. Otherwise the behavior is undefined.
Chris@16 1800 //!
Chris@16 1801 //! <b>Effects</b>: Returns: a valid const_iterator i belonging to the
Chris@16 1802 //! set that points to the value
Chris@16 1803 //!
Chris@16 1804 //! <b>Complexity</b>: Constant.
Chris@16 1805 //!
Chris@16 1806 //! <b>Throws</b>: Nothing.
Chris@16 1807 //!
Chris@16 1808 //! <b>Note</b>: This static function is available only if the <i>value traits</i>
Chris@16 1809 //! is stateless.
Chris@16 1810 static const_iterator s_iterator_to(const_reference value);
Chris@16 1811
Chris@16 1812 //! <b>Requires</b>: value must be an lvalue and shall be in a set of
Chris@16 1813 //! appropriate type. Otherwise the behavior is undefined.
Chris@16 1814 //!
Chris@16 1815 //! <b>Effects</b>: Returns: a valid iterator i belonging to the set
Chris@16 1816 //! that points to the value
Chris@16 1817 //!
Chris@16 1818 //! <b>Complexity</b>: Constant.
Chris@16 1819 //!
Chris@16 1820 //! <b>Throws</b>: Nothing.
Chris@16 1821 iterator iterator_to(reference value);
Chris@16 1822
Chris@16 1823 //! <b>Requires</b>: value must be an lvalue and shall be in a set of
Chris@16 1824 //! appropriate type. Otherwise the behavior is undefined.
Chris@16 1825 //!
Chris@16 1826 //! <b>Effects</b>: Returns: a valid const_iterator i belonging to the
Chris@16 1827 //! set that points to the value
Chris@16 1828 //!
Chris@16 1829 //! <b>Complexity</b>: Constant.
Chris@16 1830 //!
Chris@16 1831 //! <b>Throws</b>: Nothing.
Chris@16 1832 const_iterator iterator_to(const_reference value) const;
Chris@16 1833
Chris@16 1834 //! <b>Requires</b>: value shall not be in a container.
Chris@16 1835 //!
Chris@16 1836 //! <b>Effects</b>: init_node puts the hook of a value in a well-known default
Chris@16 1837 //! state.
Chris@16 1838 //!
Chris@16 1839 //! <b>Throws</b>: Nothing.
Chris@16 1840 //!
Chris@16 1841 //! <b>Complexity</b>: Constant time.
Chris@16 1842 //!
Chris@16 1843 //! <b>Note</b>: This function puts the hook in the well-known default state
Chris@16 1844 //! used by auto_unlink and safe hooks.
Chris@16 1845 static void init_node(reference value);
Chris@16 1846
Chris@16 1847 #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1848
Chris@16 1849 //! <b>Effects</b>: Unlinks the leftmost node from the container.
Chris@16 1850 //!
Chris@16 1851 //! <b>Complexity</b>: Average complexity is constant time.
Chris@16 1852 //!
Chris@16 1853 //! <b>Throws</b>: Nothing.
Chris@16 1854 //!
Chris@16 1855 //! <b>Notes</b>: This function breaks the container and the container can
Chris@16 1856 //! only be used for more unlink_leftmost_without_rebalance calls.
Chris@16 1857 //! This function is normally used to achieve a step by step
Chris@16 1858 //! controlled destruction of the container.
Chris@16 1859 pointer unlink_leftmost_without_rebalance()
Chris@16 1860 {
Chris@16 1861 node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
Chris@16 1862 (this->header_ptr()));
Chris@16 1863 if(!to_be_disposed)
Chris@16 1864 return 0;
Chris@16 1865 this->sz_traits().decrement();
Chris@16 1866 if(safemode_or_autounlink)//If this is commented does not work with normal_link
Chris@16 1867 node_algorithms::init(to_be_disposed);
Chris@101 1868 return this->get_value_traits().to_value_ptr(to_be_disposed);
Chris@16 1869 }
Chris@16 1870
Chris@16 1871 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1872
Chris@16 1873 //! <b>Requires</b>: replace_this must be a valid iterator of *this
Chris@16 1874 //! and with_this must not be inserted in any container.
Chris@16 1875 //!
Chris@16 1876 //! <b>Effects</b>: Replaces replace_this in its position in the
Chris@16 1877 //! container with with_this. The container does not need to be rebalanced.
Chris@16 1878 //!
Chris@16 1879 //! <b>Complexity</b>: Constant.
Chris@16 1880 //!
Chris@16 1881 //! <b>Throws</b>: Nothing.
Chris@16 1882 //!
Chris@16 1883 //! <b>Note</b>: This function will break container ordering invariants if
Chris@16 1884 //! with_this is not equivalent to *replace_this according to the
Chris@16 1885 //! ordering rules. This function is faster than erasing and inserting
Chris@16 1886 //! the node, since no rebalancing or comparison is needed.
Chris@16 1887 void replace_node(iterator replace_this, reference with_this);
Chris@16 1888
Chris@16 1889 //! <b>Effects</b>: Rebalances the tree.
Chris@16 1890 //!
Chris@16 1891 //! <b>Throws</b>: Nothing.
Chris@16 1892 //!
Chris@16 1893 //! <b>Complexity</b>: Linear.
Chris@16 1894 void rebalance();
Chris@16 1895
Chris@16 1896 //! <b>Requires</b>: old_root is a node of a tree.
Chris@16 1897 //!
Chris@16 1898 //! <b>Effects</b>: Rebalances the subtree rooted at old_root.
Chris@16 1899 //!
Chris@16 1900 //! <b>Returns</b>: The new root of the subtree.
Chris@16 1901 //!
Chris@16 1902 //! <b>Throws</b>: Nothing.
Chris@16 1903 //!
Chris@16 1904 //! <b>Complexity</b>: Linear to the elements in the subtree.
Chris@16 1905 iterator rebalance_subtree(iterator root);
Chris@16 1906
Chris@16 1907 #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1908
Chris@16 1909 //! <b>Effects</b>: removes "value" from the container.
Chris@16 1910 //!
Chris@16 1911 //! <b>Throws</b>: Nothing.
Chris@16 1912 //!
Chris@16 1913 //! <b>Complexity</b>: Logarithmic time.
Chris@16 1914 //!
Chris@16 1915 //! <b>Note</b>: This static function is only usable with non-constant
Chris@16 1916 //! time size containers that have stateless comparison functors.
Chris@16 1917 //!
Chris@16 1918 //! If the user calls
Chris@16 1919 //! this function with a constant time size container or stateful comparison
Chris@16 1920 //! functor a compilation error will be issued.
Chris@16 1921 static void remove_node(reference value)
Chris@16 1922 {
Chris@16 1923 BOOST_STATIC_ASSERT((!constant_time_size));
Chris@16 1924 node_ptr to_remove(value_traits::to_node_ptr(value));
Chris@16 1925 node_algorithms::unlink(to_remove);
Chris@16 1926 if(safemode_or_autounlink)
Chris@16 1927 node_algorithms::init(to_remove);
Chris@16 1928 }
Chris@16 1929
Chris@101 1930 //! <b>Effects</b>: Asserts the integrity of the container with additional checks provided by the user.
Chris@101 1931 //!
Chris@101 1932 //! <b>Complexity</b>: Linear time.
Chris@101 1933 //!
Chris@101 1934 //! <b>Note</b>: The method might not have effect when asserts are turned off (e.g., with NDEBUG).
Chris@101 1935 //! Experimental function, interface might change in future versions.
Chris@101 1936 template <class ExtraChecker>
Chris@101 1937 void check(ExtraChecker extra_checker) const
Chris@101 1938 {
Chris@101 1939 typedef detail::key_nodeptr_comp<value_compare, value_traits> nodeptr_comp_t;
Chris@101 1940 nodeptr_comp_t nodeptr_comp(this->comp(), &this->get_value_traits());
Chris@101 1941 typedef typename get_node_checker<AlgoType, ValueTraits, nodeptr_comp_t, ExtraChecker>::type node_checker_t;
Chris@101 1942 typename node_checker_t::return_type checker_return;
Chris@101 1943 node_algorithms::check(this->header_ptr(), node_checker_t(nodeptr_comp, extra_checker), checker_return);
Chris@101 1944 if (constant_time_size)
Chris@101 1945 BOOST_INTRUSIVE_INVARIANT_ASSERT(this->sz_traits().get_size() == checker_return.node_count);
Chris@101 1946 }
Chris@101 1947
Chris@101 1948 //! <b>Effects</b>: Asserts the integrity of the container.
Chris@101 1949 //!
Chris@101 1950 //! <b>Complexity</b>: Linear time.
Chris@101 1951 //!
Chris@101 1952 //! <b>Note</b>: The method has no effect when asserts are turned off (e.g., with NDEBUG).
Chris@101 1953 //! Experimental function, interface might change in future versions.
Chris@101 1954 void check() const
Chris@101 1955 {
Chris@101 1956 check(detail::empty_node_checker<ValueTraits>());
Chris@101 1957 }
Chris@101 1958
Chris@16 1959 /// @cond
Chris@16 1960 private:
Chris@16 1961 template<class Disposer>
Chris@16 1962 iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer)
Chris@16 1963 {
Chris@16 1964 for(n = 0; b != e; ++n)
Chris@16 1965 this->erase_and_dispose(b++, disposer);
Chris@16 1966 return b.unconst();
Chris@16 1967 }
Chris@16 1968
Chris@16 1969 iterator private_erase(const_iterator b, const_iterator e, size_type &n)
Chris@16 1970 {
Chris@16 1971 for(n = 0; b != e; ++n)
Chris@16 1972 this->erase(b++);
Chris@16 1973 return b.unconst();
Chris@16 1974 }
Chris@16 1975 /// @endcond
Chris@16 1976 };
Chris@16 1977
Chris@16 1978 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1979 template<class T, class ...Options>
Chris@16 1980 #else
Chris@101 1981 template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
Chris@16 1982 #endif
Chris@16 1983 inline bool operator<
Chris@16 1984 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1985 (const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
Chris@16 1986 #else
Chris@101 1987 ( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
Chris@101 1988 , const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
Chris@16 1989 #endif
Chris@101 1990 { return ::boost::intrusive::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
Chris@16 1991
Chris@16 1992 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1993 template<class T, class ...Options>
Chris@16 1994 #else
Chris@101 1995 template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
Chris@16 1996 #endif
Chris@16 1997 bool operator==
Chris@16 1998 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 1999 (const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
Chris@16 2000 #else
Chris@101 2001 ( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
Chris@101 2002 , const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
Chris@16 2003 #endif
Chris@16 2004 {
Chris@101 2005 typedef bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> tree_type;
Chris@16 2006
Chris@16 2007 if(tree_type::constant_time_size && x.size() != y.size()){
Chris@16 2008 return false;
Chris@16 2009 }
Chris@101 2010 return boost::intrusive::algo_equal(x.cbegin(), x.cend(), y.cbegin(), y.cend());
Chris@16 2011 }
Chris@16 2012
Chris@16 2013 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2014 template<class T, class ...Options>
Chris@16 2015 #else
Chris@101 2016 template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
Chris@16 2017 #endif
Chris@16 2018 inline bool operator!=
Chris@16 2019 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2020 (const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
Chris@16 2021 #else
Chris@101 2022 ( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
Chris@101 2023 , const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
Chris@16 2024 #endif
Chris@16 2025 { return !(x == y); }
Chris@16 2026
Chris@16 2027 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2028 template<class T, class ...Options>
Chris@16 2029 #else
Chris@101 2030 template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
Chris@16 2031 #endif
Chris@16 2032 inline bool operator>
Chris@16 2033 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2034 (const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
Chris@16 2035 #else
Chris@101 2036 ( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
Chris@101 2037 , const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
Chris@16 2038 #endif
Chris@16 2039 { return y < x; }
Chris@16 2040
Chris@16 2041 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2042 template<class T, class ...Options>
Chris@16 2043 #else
Chris@101 2044 template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
Chris@16 2045 #endif
Chris@16 2046 inline bool operator<=
Chris@16 2047 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2048 (const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
Chris@16 2049 #else
Chris@101 2050 ( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
Chris@101 2051 , const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
Chris@16 2052 #endif
Chris@16 2053 { return !(y < x); }
Chris@16 2054
Chris@16 2055 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2056 template<class T, class ...Options>
Chris@16 2057 #else
Chris@101 2058 template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
Chris@16 2059 #endif
Chris@16 2060 inline bool operator>=
Chris@16 2061 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2062 (const bstree_impl<T, Options...> &x, const bstree_impl<T, Options...> &y)
Chris@16 2063 #else
Chris@101 2064 ( const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
Chris@101 2065 , const bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
Chris@16 2066 #endif
Chris@16 2067 { return !(x < y); }
Chris@16 2068
Chris@16 2069 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2070 template<class T, class ...Options>
Chris@16 2071 #else
Chris@101 2072 template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTimeSize, algo_types AlgoType, typename HeaderHolder>
Chris@16 2073 #endif
Chris@16 2074 inline void swap
Chris@16 2075 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
Chris@16 2076 (bstree_impl<T, Options...> &x, bstree_impl<T, Options...> &y)
Chris@16 2077 #else
Chris@101 2078 ( bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &x
Chris@101 2079 , bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType, HeaderHolder> &y)
Chris@16 2080 #endif
Chris@16 2081 { x.swap(y); }
Chris@16 2082
Chris@16 2083 //! Helper metafunction to define a \c bstree that yields to the same type when the
Chris@16 2084 //! same options (either explicitly or implicitly) are used.
Chris@16 2085 #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
Chris@16 2086 template<class T, class ...Options>
Chris@16 2087 #else
Chris@16 2088 template<class T, class O1 = void, class O2 = void
Chris@101 2089 , class O3 = void, class O4 = void
Chris@101 2090 , class O5 = void>
Chris@16 2091 #endif
Chris@16 2092 struct make_bstree
Chris@16 2093 {
Chris@16 2094 /// @cond
Chris@16 2095 typedef typename pack_options
Chris@16 2096 < bstree_defaults,
Chris@16 2097 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
Chris@101 2098 O1, O2, O3, O4, O5
Chris@16 2099 #else
Chris@16 2100 Options...
Chris@16 2101 #endif
Chris@16 2102 >::type packed_options;
Chris@16 2103
Chris@16 2104 typedef typename detail::get_value_traits
Chris@16 2105 <T, typename packed_options::proto_value_traits>::type value_traits;
Chris@16 2106
Chris@16 2107 typedef bstree_impl
Chris@16 2108 < value_traits
Chris@16 2109 , typename packed_options::compare
Chris@16 2110 , typename packed_options::size_type
Chris@16 2111 , packed_options::constant_time_size
Chris@16 2112 , BsTreeAlgorithms
Chris@101 2113 , typename packed_options::header_holder_type
Chris@16 2114 > implementation_defined;
Chris@16 2115 /// @endcond
Chris@16 2116 typedef implementation_defined type;
Chris@16 2117 };
Chris@16 2118
Chris@16 2119
Chris@16 2120 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 2121
Chris@16 2122 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
Chris@101 2123 template<class T, class O1, class O2, class O3, class O4, class O5>
Chris@16 2124 #else
Chris@16 2125 template<class T, class ...Options>
Chris@16 2126 #endif
Chris@16 2127 class bstree
Chris@16 2128 : public make_bstree<T,
Chris@16 2129 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
Chris@101 2130 O1, O2, O3, O4, O5
Chris@16 2131 #else
Chris@16 2132 Options...
Chris@16 2133 #endif
Chris@16 2134 >::type
Chris@16 2135 {
Chris@16 2136 typedef typename make_bstree
Chris@16 2137 <T,
Chris@16 2138 #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
Chris@101 2139 O1, O2, O3, O4, O5
Chris@16 2140 #else
Chris@16 2141 Options...
Chris@16 2142 #endif
Chris@16 2143 >::type Base;
Chris@16 2144 BOOST_MOVABLE_BUT_NOT_COPYABLE(bstree)
Chris@16 2145
Chris@16 2146 public:
Chris@16 2147 typedef typename Base::value_compare value_compare;
Chris@16 2148 typedef typename Base::value_traits value_traits;
Chris@16 2149 typedef typename Base::iterator iterator;
Chris@16 2150 typedef typename Base::const_iterator const_iterator;
Chris@16 2151
Chris@16 2152 //Assert if passed value traits are compatible with the type
Chris@101 2153 BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
Chris@16 2154
Chris@16 2155 bstree( const value_compare &cmp = value_compare()
Chris@16 2156 , const value_traits &v_traits = value_traits())
Chris@16 2157 : Base(cmp, v_traits)
Chris@16 2158 {}
Chris@16 2159
Chris@16 2160 template<class Iterator>
Chris@16 2161 bstree( bool unique, Iterator b, Iterator e
Chris@16 2162 , const value_compare &cmp = value_compare()
Chris@16 2163 , const value_traits &v_traits = value_traits())
Chris@16 2164 : Base(unique, b, e, cmp, v_traits)
Chris@16 2165 {}
Chris@16 2166
Chris@16 2167 bstree(BOOST_RV_REF(bstree) x)
Chris@101 2168 : Base(BOOST_MOVE_BASE(Base, x))
Chris@16 2169 {}
Chris@16 2170
Chris@16 2171 bstree& operator=(BOOST_RV_REF(bstree) x)
Chris@101 2172 { return static_cast<bstree &>(this->Base::operator=(BOOST_MOVE_BASE(Base, x))); }
Chris@16 2173
Chris@16 2174 static bstree &container_from_end_iterator(iterator end_iterator)
Chris@16 2175 { return static_cast<bstree &>(Base::container_from_end_iterator(end_iterator)); }
Chris@16 2176
Chris@16 2177 static const bstree &container_from_end_iterator(const_iterator end_iterator)
Chris@16 2178 { return static_cast<const bstree &>(Base::container_from_end_iterator(end_iterator)); }
Chris@16 2179
Chris@16 2180 static bstree &container_from_iterator(iterator it)
Chris@16 2181 { return static_cast<bstree &>(Base::container_from_iterator(it)); }
Chris@16 2182
Chris@16 2183 static const bstree &container_from_iterator(const_iterator it)
Chris@16 2184 { return static_cast<const bstree &>(Base::container_from_iterator(it)); }
Chris@16 2185 };
Chris@16 2186
Chris@16 2187 #endif
Chris@16 2188 } //namespace intrusive
Chris@16 2189 } //namespace boost
Chris@16 2190
Chris@16 2191 #include <boost/intrusive/detail/config_end.hpp>
Chris@16 2192
Chris@16 2193 #endif //BOOST_INTRUSIVE_BSTREE_HPP