annotate DEPENDENCIES/generic/include/boost/container/detail/tree.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
rev   line source
Chris@16 1 //////////////////////////////////////////////////////////////////////////////
Chris@16 2 //
Chris@16 3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
Chris@16 4 // Software License, Version 1.0. (See accompanying file
Chris@16 5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6 //
Chris@16 7 // See http://www.boost.org/libs/container for documentation.
Chris@16 8 //
Chris@16 9 //////////////////////////////////////////////////////////////////////////////
Chris@16 10
Chris@16 11 #ifndef BOOST_CONTAINER_TREE_HPP
Chris@16 12 #define BOOST_CONTAINER_TREE_HPP
Chris@16 13
Chris@16 14 #include "config_begin.hpp"
Chris@16 15 #include <boost/container/detail/workaround.hpp>
Chris@16 16 #include <boost/container/container_fwd.hpp>
Chris@16 17
Chris@16 18 #include <boost/move/utility.hpp>
Chris@16 19 #include <boost/intrusive/pointer_traits.hpp>
Chris@16 20 #include <boost/type_traits/has_trivial_destructor.hpp>
Chris@16 21 #include <boost/detail/no_exceptions_support.hpp>
Chris@16 22 #include <boost/intrusive/rbtree.hpp>
Chris@16 23 #include <boost/container/detail/utilities.hpp>
Chris@16 24 #include <boost/container/detail/iterators.hpp>
Chris@16 25 #include <boost/container/detail/algorithms.hpp>
Chris@16 26 #include <boost/container/detail/node_alloc_holder.hpp>
Chris@16 27 #include <boost/container/detail/destroyers.hpp>
Chris@16 28 #include <boost/container/detail/pair.hpp>
Chris@16 29 #include <boost/container/detail/type_traits.hpp>
Chris@16 30 #include <boost/container/allocator_traits.hpp>
Chris@16 31 #include <boost/detail/no_exceptions_support.hpp>
Chris@16 32 #ifndef BOOST_CONTAINER_PERFECT_FORWARDING
Chris@16 33 #include <boost/container/detail/preprocessor.hpp>
Chris@16 34 #endif
Chris@16 35
Chris@16 36 #include <utility> //std::pair
Chris@16 37 #include <iterator>
Chris@16 38 #include <algorithm>
Chris@16 39
Chris@16 40 namespace boost {
Chris@16 41 namespace container {
Chris@16 42 namespace container_detail {
Chris@16 43
Chris@16 44 template<class Key, class Value, class KeyCompare, class KeyOfValue>
Chris@16 45 struct tree_value_compare
Chris@16 46 : public KeyCompare
Chris@16 47 {
Chris@16 48 typedef Value value_type;
Chris@16 49 typedef KeyCompare key_compare;
Chris@16 50 typedef KeyOfValue key_of_value;
Chris@16 51 typedef Key key_type;
Chris@16 52
Chris@16 53 explicit tree_value_compare(const key_compare &kcomp)
Chris@16 54 : KeyCompare(kcomp)
Chris@16 55 {}
Chris@16 56
Chris@16 57 tree_value_compare()
Chris@16 58 : KeyCompare()
Chris@16 59 {}
Chris@16 60
Chris@16 61 const key_compare &key_comp() const
Chris@16 62 { return static_cast<const key_compare &>(*this); }
Chris@16 63
Chris@16 64 key_compare &key_comp()
Chris@16 65 { return static_cast<key_compare &>(*this); }
Chris@16 66
Chris@16 67 template<class T>
Chris@16 68 struct is_key
Chris@16 69 {
Chris@16 70 static const bool value = is_same<const T, const key_type>::value;
Chris@16 71 };
Chris@16 72
Chris@16 73 template<class T>
Chris@16 74 typename enable_if_c<is_key<T>::value, const key_type &>::type
Chris@16 75 key_forward(const T &key) const
Chris@16 76 { return key; }
Chris@16 77
Chris@16 78 template<class T>
Chris@16 79 typename enable_if_c<!is_key<T>::value, const key_type &>::type
Chris@16 80 key_forward(const T &key) const
Chris@16 81 { return KeyOfValue()(key); }
Chris@16 82
Chris@16 83 template<class KeyType, class KeyType2>
Chris@16 84 bool operator()(const KeyType &key1, const KeyType2 &key2) const
Chris@16 85 { return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
Chris@16 86 };
Chris@16 87
Chris@16 88 template<class VoidPointer>
Chris@16 89 struct rbtree_hook
Chris@16 90 {
Chris@16 91 typedef typename container_detail::bi::make_set_base_hook
Chris@16 92 < container_detail::bi::void_pointer<VoidPointer>
Chris@16 93 , container_detail::bi::link_mode<container_detail::bi::normal_link>
Chris@16 94 , container_detail::bi::optimize_size<true>
Chris@16 95 >::type type;
Chris@16 96 };
Chris@16 97
Chris@16 98 //This trait is used to type-pun std::pair because in C++03
Chris@16 99 //compilers std::pair is useless for C++11 features
Chris@16 100 template<class T>
Chris@16 101 struct rbtree_internal_data_type
Chris@16 102 {
Chris@16 103 typedef T type;
Chris@16 104 };
Chris@16 105
Chris@16 106 template<class T1, class T2>
Chris@16 107 struct rbtree_internal_data_type< std::pair<T1, T2> >
Chris@16 108 {
Chris@16 109 typedef pair<T1, T2> type;
Chris@16 110 };
Chris@16 111
Chris@16 112
Chris@16 113 //The node to be store in the tree
Chris@16 114 template <class T, class VoidPointer>
Chris@16 115 struct rbtree_node
Chris@16 116 : public rbtree_hook<VoidPointer>::type
Chris@16 117 {
Chris@16 118 private:
Chris@16 119 //BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
Chris@16 120 rbtree_node();
Chris@16 121
Chris@16 122 public:
Chris@16 123 typedef typename rbtree_hook<VoidPointer>::type hook_type;
Chris@16 124
Chris@16 125 typedef T value_type;
Chris@16 126 typedef typename rbtree_internal_data_type<T>::type internal_type;
Chris@16 127
Chris@16 128 typedef rbtree_node<T, VoidPointer> node_type;
Chris@16 129
Chris@16 130 T &get_data()
Chris@16 131 {
Chris@16 132 T* ptr = reinterpret_cast<T*>(&this->m_data);
Chris@16 133 return *ptr;
Chris@16 134 }
Chris@16 135
Chris@16 136 const T &get_data() const
Chris@16 137 {
Chris@16 138 const T* ptr = reinterpret_cast<const T*>(&this->m_data);
Chris@16 139 return *ptr;
Chris@16 140 }
Chris@16 141
Chris@16 142 internal_type m_data;
Chris@16 143
Chris@16 144 template<class A, class B>
Chris@16 145 void do_assign(const std::pair<const A, B> &p)
Chris@16 146 {
Chris@16 147 const_cast<A&>(m_data.first) = p.first;
Chris@16 148 m_data.second = p.second;
Chris@16 149 }
Chris@16 150
Chris@16 151 template<class A, class B>
Chris@16 152 void do_assign(const pair<const A, B> &p)
Chris@16 153 {
Chris@16 154 const_cast<A&>(m_data.first) = p.first;
Chris@16 155 m_data.second = p.second;
Chris@16 156 }
Chris@16 157
Chris@16 158 template<class V>
Chris@16 159 void do_assign(const V &v)
Chris@16 160 { m_data = v; }
Chris@16 161
Chris@16 162 template<class A, class B>
Chris@16 163 void do_move_assign(std::pair<const A, B> &p)
Chris@16 164 {
Chris@16 165 const_cast<A&>(m_data.first) = ::boost::move(p.first);
Chris@16 166 m_data.second = ::boost::move(p.second);
Chris@16 167 }
Chris@16 168
Chris@16 169 template<class A, class B>
Chris@16 170 void do_move_assign(pair<const A, B> &p)
Chris@16 171 {
Chris@16 172 const_cast<A&>(m_data.first) = ::boost::move(p.first);
Chris@16 173 m_data.second = ::boost::move(p.second);
Chris@16 174 }
Chris@16 175
Chris@16 176 template<class V>
Chris@16 177 void do_move_assign(V &v)
Chris@16 178 { m_data = ::boost::move(v); }
Chris@16 179 };
Chris@16 180
Chris@16 181 template<class Node, class Icont>
Chris@16 182 class insert_equal_end_hint_functor
Chris@16 183 {
Chris@16 184 Icont &icont_;
Chris@16 185
Chris@16 186 public:
Chris@16 187 insert_equal_end_hint_functor(Icont &icont)
Chris@16 188 : icont_(icont)
Chris@16 189 {}
Chris@16 190
Chris@16 191 void operator()(Node &n)
Chris@16 192 { this->icont_.insert_equal(this->icont_.cend(), n); }
Chris@16 193 };
Chris@16 194
Chris@16 195 template<class Node, class Icont>
Chris@16 196 class push_back_functor
Chris@16 197 {
Chris@16 198 Icont &icont_;
Chris@16 199
Chris@16 200 public:
Chris@16 201 push_back_functor(Icont &icont)
Chris@16 202 : icont_(icont)
Chris@16 203 {}
Chris@16 204
Chris@16 205 void operator()(Node &n)
Chris@16 206 { this->icont_.push_back(n); }
Chris@16 207 };
Chris@16 208
Chris@16 209 }//namespace container_detail {
Chris@16 210
Chris@16 211 namespace container_detail {
Chris@16 212
Chris@16 213 template<class A, class ValueCompare>
Chris@16 214 struct intrusive_rbtree_type
Chris@16 215 {
Chris@16 216 typedef typename boost::container::
Chris@16 217 allocator_traits<A>::value_type value_type;
Chris@16 218 typedef typename boost::container::
Chris@16 219 allocator_traits<A>::void_pointer void_pointer;
Chris@16 220 typedef typename boost::container::
Chris@16 221 allocator_traits<A>::size_type size_type;
Chris@16 222 typedef typename container_detail::rbtree_node
Chris@16 223 <value_type, void_pointer> node_type;
Chris@16 224 typedef node_compare<ValueCompare, node_type> node_compare_type;
Chris@16 225 typedef typename container_detail::bi::make_rbtree
Chris@16 226 <node_type
Chris@16 227 ,container_detail::bi::compare<node_compare_type>
Chris@16 228 ,container_detail::bi::base_hook<typename rbtree_hook<void_pointer>::type>
Chris@16 229 ,container_detail::bi::constant_time_size<true>
Chris@16 230 ,container_detail::bi::size_type<size_type>
Chris@16 231 >::type container_type;
Chris@16 232 typedef container_type type ;
Chris@16 233 };
Chris@16 234
Chris@16 235 } //namespace container_detail {
Chris@16 236
Chris@16 237 namespace container_detail {
Chris@16 238
Chris@16 239 template <class Key, class Value, class KeyOfValue,
Chris@16 240 class KeyCompare, class A>
Chris@16 241 class rbtree
Chris@16 242 : protected container_detail::node_alloc_holder
Chris@16 243 < A
Chris@16 244 , typename container_detail::intrusive_rbtree_type
Chris@16 245 <A, tree_value_compare<Key, Value, KeyCompare, KeyOfValue>
Chris@16 246 >::type
Chris@16 247 , tree_value_compare<Key, Value, KeyCompare, KeyOfValue>
Chris@16 248 >
Chris@16 249 {
Chris@16 250 typedef tree_value_compare
Chris@16 251 <Key, Value, KeyCompare, KeyOfValue> ValComp;
Chris@16 252 typedef typename container_detail::intrusive_rbtree_type
Chris@16 253 < A, ValComp>::type Icont;
Chris@16 254 typedef container_detail::node_alloc_holder
Chris@16 255 <A, Icont, ValComp> AllocHolder;
Chris@16 256 typedef typename AllocHolder::NodePtr NodePtr;
Chris@16 257 typedef rbtree < Key, Value, KeyOfValue
Chris@16 258 , KeyCompare, A> ThisType;
Chris@16 259 typedef typename AllocHolder::NodeAlloc NodeAlloc;
Chris@16 260 typedef typename AllocHolder::ValAlloc ValAlloc;
Chris@16 261 typedef typename AllocHolder::Node Node;
Chris@16 262 typedef typename Icont::iterator iiterator;
Chris@16 263 typedef typename Icont::const_iterator iconst_iterator;
Chris@16 264 typedef container_detail::allocator_destroyer<NodeAlloc> Destroyer;
Chris@16 265 typedef typename AllocHolder::allocator_v1 allocator_v1;
Chris@16 266 typedef typename AllocHolder::allocator_v2 allocator_v2;
Chris@16 267 typedef typename AllocHolder::alloc_version alloc_version;
Chris@16 268
Chris@16 269 class RecyclingCloner;
Chris@16 270 friend class RecyclingCloner;
Chris@16 271
Chris@16 272 class RecyclingCloner
Chris@16 273 {
Chris@16 274 public:
Chris@16 275 RecyclingCloner(AllocHolder &holder, Icont &irbtree)
Chris@16 276 : m_holder(holder), m_icont(irbtree)
Chris@16 277 {}
Chris@16 278
Chris@16 279 NodePtr operator()(const Node &other) const
Chris@16 280 {
Chris@16 281 if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
Chris@16 282 //First recycle a node (this can't throw)
Chris@16 283 BOOST_TRY{
Chris@16 284 //This can throw
Chris@16 285 p->do_assign(other.m_data);
Chris@16 286 return p;
Chris@16 287 }
Chris@16 288 BOOST_CATCH(...){
Chris@16 289 //If there is an exception destroy the whole source
Chris@16 290 m_holder.destroy_node(p);
Chris@16 291 while((p = m_icont.unlink_leftmost_without_rebalance())){
Chris@16 292 m_holder.destroy_node(p);
Chris@16 293 }
Chris@16 294 BOOST_RETHROW
Chris@16 295 }
Chris@16 296 BOOST_CATCH_END
Chris@16 297 }
Chris@16 298 else{
Chris@16 299 return m_holder.create_node(other.m_data);
Chris@16 300 }
Chris@16 301 }
Chris@16 302
Chris@16 303 AllocHolder &m_holder;
Chris@16 304 Icont &m_icont;
Chris@16 305 };
Chris@16 306
Chris@16 307 class RecyclingMoveCloner;
Chris@16 308 friend class RecyclingMoveCloner;
Chris@16 309
Chris@16 310 class RecyclingMoveCloner
Chris@16 311 {
Chris@16 312 public:
Chris@16 313 RecyclingMoveCloner(AllocHolder &holder, Icont &irbtree)
Chris@16 314 : m_holder(holder), m_icont(irbtree)
Chris@16 315 {}
Chris@16 316
Chris@16 317 NodePtr operator()(const Node &other) const
Chris@16 318 {
Chris@16 319 if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
Chris@16 320 //First recycle a node (this can't throw)
Chris@16 321 BOOST_TRY{
Chris@16 322 //This can throw
Chris@16 323 p->do_move_assign(const_cast<Node &>(other).m_data);
Chris@16 324 return p;
Chris@16 325 }
Chris@16 326 BOOST_CATCH(...){
Chris@16 327 //If there is an exception destroy the whole source
Chris@16 328 m_holder.destroy_node(p);
Chris@16 329 while((p = m_icont.unlink_leftmost_without_rebalance())){
Chris@16 330 m_holder.destroy_node(p);
Chris@16 331 }
Chris@16 332 BOOST_RETHROW
Chris@16 333 }
Chris@16 334 BOOST_CATCH_END
Chris@16 335 }
Chris@16 336 else{
Chris@16 337 return m_holder.create_node(other.m_data);
Chris@16 338 }
Chris@16 339 }
Chris@16 340
Chris@16 341 AllocHolder &m_holder;
Chris@16 342 Icont &m_icont;
Chris@16 343 };
Chris@16 344
Chris@16 345 BOOST_COPYABLE_AND_MOVABLE(rbtree)
Chris@16 346
Chris@16 347 public:
Chris@16 348
Chris@16 349 typedef Key key_type;
Chris@16 350 typedef Value value_type;
Chris@16 351 typedef A allocator_type;
Chris@16 352 typedef KeyCompare key_compare;
Chris@16 353 typedef ValComp value_compare;
Chris@16 354 typedef typename boost::container::
Chris@16 355 allocator_traits<A>::pointer pointer;
Chris@16 356 typedef typename boost::container::
Chris@16 357 allocator_traits<A>::const_pointer const_pointer;
Chris@16 358 typedef typename boost::container::
Chris@16 359 allocator_traits<A>::reference reference;
Chris@16 360 typedef typename boost::container::
Chris@16 361 allocator_traits<A>::const_reference const_reference;
Chris@16 362 typedef typename boost::container::
Chris@16 363 allocator_traits<A>::size_type size_type;
Chris@16 364 typedef typename boost::container::
Chris@16 365 allocator_traits<A>::difference_type difference_type;
Chris@16 366 typedef difference_type rbtree_difference_type;
Chris@16 367 typedef pointer rbtree_pointer;
Chris@16 368 typedef const_pointer rbtree_const_pointer;
Chris@16 369 typedef reference rbtree_reference;
Chris@16 370 typedef const_reference rbtree_const_reference;
Chris@16 371 typedef NodeAlloc stored_allocator_type;
Chris@16 372
Chris@16 373 private:
Chris@16 374
Chris@16 375 template<class KeyValueCompare>
Chris@16 376 struct key_node_compare
Chris@16 377 : private KeyValueCompare
Chris@16 378 {
Chris@16 379 key_node_compare(const KeyValueCompare &comp)
Chris@16 380 : KeyValueCompare(comp)
Chris@16 381 {}
Chris@16 382
Chris@16 383 template<class T>
Chris@16 384 struct is_node
Chris@16 385 {
Chris@16 386 static const bool value = is_same<T, Node>::value;
Chris@16 387 };
Chris@16 388
Chris@16 389 template<class T>
Chris@16 390 typename enable_if_c<is_node<T>::value, const value_type &>::type
Chris@16 391 key_forward(const T &node) const
Chris@16 392 { return node.get_data(); }
Chris@16 393
Chris@16 394 template<class T>
Chris@16 395 typename enable_if_c<!is_node<T>::value, const T &>::type
Chris@16 396 key_forward(const T &key) const
Chris@16 397 { return key; }
Chris@16 398
Chris@16 399 template<class KeyType, class KeyType2>
Chris@16 400 bool operator()(const KeyType &key1, const KeyType2 &key2) const
Chris@16 401 { return KeyValueCompare::operator()(this->key_forward(key1), this->key_forward(key2)); }
Chris@16 402 };
Chris@16 403
Chris@16 404 typedef key_node_compare<value_compare> KeyNodeCompare;
Chris@16 405
Chris@16 406 public:
Chris@16 407 typedef container_detail::iterator<iiterator, false> iterator;
Chris@16 408 typedef container_detail::iterator<iiterator, true > const_iterator;
Chris@16 409 typedef std::reverse_iterator<iterator> reverse_iterator;
Chris@16 410 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
Chris@16 411
Chris@16 412 rbtree()
Chris@16 413 : AllocHolder(ValComp(key_compare()))
Chris@16 414 {}
Chris@16 415
Chris@16 416 explicit rbtree(const key_compare& comp, const allocator_type& a = allocator_type())
Chris@16 417 : AllocHolder(a, ValComp(comp))
Chris@16 418 {}
Chris@16 419
Chris@16 420 explicit rbtree(const allocator_type& a)
Chris@16 421 : AllocHolder(a)
Chris@16 422 {}
Chris@16 423
Chris@16 424 template <class InputIterator>
Chris@16 425 rbtree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
Chris@16 426 const allocator_type& a
Chris@16 427 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 428 , typename container_detail::enable_if_c
Chris@16 429 < container_detail::is_input_iterator<InputIterator>::value
Chris@16 430 || container_detail::is_same<alloc_version, allocator_v1>::value
Chris@16 431 >::type * = 0
Chris@16 432 #endif
Chris@16 433 )
Chris@16 434 : AllocHolder(a, value_compare(comp))
Chris@16 435 {
Chris@16 436 //Use cend() as hint to achieve linear time for
Chris@16 437 //ordered ranges as required by the standard
Chris@16 438 //for the constructor
Chris@16 439 const const_iterator end_it(this->cend());
Chris@16 440 if(unique_insertion){
Chris@16 441 for ( ; first != last; ++first){
Chris@16 442 this->insert_unique(end_it, *first);
Chris@16 443 }
Chris@16 444 }
Chris@16 445 else{
Chris@16 446 for ( ; first != last; ++first){
Chris@16 447 this->insert_equal(end_it, *first);
Chris@16 448 }
Chris@16 449 }
Chris@16 450 }
Chris@16 451
Chris@16 452 template <class InputIterator>
Chris@16 453 rbtree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
Chris@16 454 const allocator_type& a
Chris@16 455 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 456 , typename container_detail::enable_if_c
Chris@16 457 < !(container_detail::is_input_iterator<InputIterator>::value
Chris@16 458 || container_detail::is_same<alloc_version, allocator_v1>::value)
Chris@16 459 >::type * = 0
Chris@16 460 #endif
Chris@16 461 )
Chris@16 462 : AllocHolder(a, value_compare(comp))
Chris@16 463 {
Chris@16 464 if(unique_insertion){
Chris@16 465 //Use cend() as hint to achieve linear time for
Chris@16 466 //ordered ranges as required by the standard
Chris@16 467 //for the constructor
Chris@16 468 const const_iterator end_it(this->cend());
Chris@16 469 for ( ; first != last; ++first){
Chris@16 470 this->insert_unique(end_it, *first);
Chris@16 471 }
Chris@16 472 }
Chris@16 473 else{
Chris@16 474 //Optimized allocation and construction
Chris@16 475 this->allocate_many_and_construct
Chris@16 476 ( first, std::distance(first, last)
Chris@16 477 , insert_equal_end_hint_functor<Node, Icont>(this->icont()));
Chris@16 478 }
Chris@16 479 }
Chris@16 480
Chris@16 481 template <class InputIterator>
Chris@16 482 rbtree( ordered_range_t, InputIterator first, InputIterator last
Chris@16 483 , const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
Chris@16 484 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 485 , typename container_detail::enable_if_c
Chris@16 486 < container_detail::is_input_iterator<InputIterator>::value
Chris@16 487 || container_detail::is_same<alloc_version, allocator_v1>::value
Chris@16 488 >::type * = 0
Chris@16 489 #endif
Chris@16 490 )
Chris@16 491 : AllocHolder(a, value_compare(comp))
Chris@16 492 {
Chris@16 493 for ( ; first != last; ++first){
Chris@16 494 this->push_back_impl(*first);
Chris@16 495 }
Chris@16 496 }
Chris@16 497
Chris@16 498 template <class InputIterator>
Chris@16 499 rbtree( ordered_range_t, InputIterator first, InputIterator last
Chris@16 500 , const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
Chris@16 501 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
Chris@16 502 , typename container_detail::enable_if_c
Chris@16 503 < !(container_detail::is_input_iterator<InputIterator>::value
Chris@16 504 || container_detail::is_same<alloc_version, allocator_v1>::value)
Chris@16 505 >::type * = 0
Chris@16 506 #endif
Chris@16 507 )
Chris@16 508 : AllocHolder(a, value_compare(comp))
Chris@16 509 {
Chris@16 510 //Optimized allocation and construction
Chris@16 511 this->allocate_many_and_construct
Chris@16 512 ( first, std::distance(first, last)
Chris@16 513 , container_detail::push_back_functor<Node, Icont>(this->icont()));
Chris@16 514 }
Chris@16 515
Chris@16 516 rbtree(const rbtree& x)
Chris@16 517 : AllocHolder(x, x.value_comp())
Chris@16 518 {
Chris@16 519 this->icont().clone_from
Chris@16 520 (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
Chris@16 521 }
Chris@16 522
Chris@16 523 rbtree(BOOST_RV_REF(rbtree) x)
Chris@16 524 : AllocHolder(::boost::move(static_cast<AllocHolder&>(x)), x.value_comp())
Chris@16 525 {}
Chris@16 526
Chris@16 527 rbtree(const rbtree& x, const allocator_type &a)
Chris@16 528 : AllocHolder(a, x.value_comp())
Chris@16 529 {
Chris@16 530 this->icont().clone_from
Chris@16 531 (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
Chris@16 532 }
Chris@16 533
Chris@16 534 rbtree(BOOST_RV_REF(rbtree) x, const allocator_type &a)
Chris@16 535 : AllocHolder(a, x.value_comp())
Chris@16 536 {
Chris@16 537 if(this->node_alloc() == x.node_alloc()){
Chris@16 538 this->icont().swap(x.icont());
Chris@16 539 }
Chris@16 540 else{
Chris@16 541 this->icont().clone_from
Chris@16 542 (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
Chris@16 543 }
Chris@16 544 }
Chris@16 545
Chris@16 546 ~rbtree()
Chris@16 547 {} //AllocHolder clears the tree
Chris@16 548
Chris@16 549 rbtree& operator=(BOOST_COPY_ASSIGN_REF(rbtree) x)
Chris@16 550 {
Chris@16 551 if (&x != this){
Chris@16 552 NodeAlloc &this_alloc = this->get_stored_allocator();
Chris@16 553 const NodeAlloc &x_alloc = x.get_stored_allocator();
Chris@16 554 container_detail::bool_<allocator_traits<NodeAlloc>::
Chris@16 555 propagate_on_container_copy_assignment::value> flag;
Chris@16 556 if(flag && this_alloc != x_alloc){
Chris@16 557 this->clear();
Chris@16 558 }
Chris@16 559 this->AllocHolder::copy_assign_alloc(x);
Chris@16 560 //Transfer all the nodes to a temporary tree
Chris@16 561 //If anything goes wrong, all the nodes will be destroyed
Chris@16 562 //automatically
Chris@16 563 Icont other_tree(::boost::move(this->icont()));
Chris@16 564
Chris@16 565 //Now recreate the source tree reusing nodes stored by other_tree
Chris@16 566 this->icont().clone_from
Chris@16 567 (x.icont()
Chris@16 568 , RecyclingCloner(*this, other_tree)
Chris@16 569 , Destroyer(this->node_alloc()));
Chris@16 570
Chris@16 571 //If there are remaining nodes, destroy them
Chris@16 572 NodePtr p;
Chris@16 573 while((p = other_tree.unlink_leftmost_without_rebalance())){
Chris@16 574 AllocHolder::destroy_node(p);
Chris@16 575 }
Chris@16 576 }
Chris@16 577 return *this;
Chris@16 578 }
Chris@16 579
Chris@16 580 rbtree& operator=(BOOST_RV_REF(rbtree) x)
Chris@16 581 {
Chris@16 582 if (&x != this){
Chris@16 583 NodeAlloc &this_alloc = this->get_stored_allocator();
Chris@16 584 const NodeAlloc &x_alloc = x.get_stored_allocator();
Chris@16 585 //If allocators are equal we can just swap pointers
Chris@16 586 if(this_alloc == x_alloc){
Chris@16 587 //Destroy and swap pointers
Chris@16 588 this->clear();
Chris@16 589 this->icont() = ::boost::move(x.icont());
Chris@16 590 //Move allocator if needed
Chris@16 591 this->AllocHolder::move_assign_alloc(x);
Chris@16 592 }
Chris@16 593 //If unequal allocators, then do a one by one move
Chris@16 594 else{
Chris@16 595 //Transfer all the nodes to a temporary tree
Chris@16 596 //If anything goes wrong, all the nodes will be destroyed
Chris@16 597 //automatically
Chris@16 598 Icont other_tree(::boost::move(this->icont()));
Chris@16 599
Chris@16 600 //Now recreate the source tree reusing nodes stored by other_tree
Chris@16 601 this->icont().clone_from
Chris@16 602 (x.icont()
Chris@16 603 , RecyclingMoveCloner(*this, other_tree)
Chris@16 604 , Destroyer(this->node_alloc()));
Chris@16 605
Chris@16 606 //If there are remaining nodes, destroy them
Chris@16 607 NodePtr p;
Chris@16 608 while((p = other_tree.unlink_leftmost_without_rebalance())){
Chris@16 609 AllocHolder::destroy_node(p);
Chris@16 610 }
Chris@16 611 }
Chris@16 612 }
Chris@16 613 return *this;
Chris@16 614 }
Chris@16 615
Chris@16 616 public:
Chris@16 617 // accessors:
Chris@16 618 value_compare value_comp() const
Chris@16 619 { return this->icont().value_comp().value_comp(); }
Chris@16 620
Chris@16 621 key_compare key_comp() const
Chris@16 622 { return this->icont().value_comp().value_comp().key_comp(); }
Chris@16 623
Chris@16 624 allocator_type get_allocator() const
Chris@16 625 { return allocator_type(this->node_alloc()); }
Chris@16 626
Chris@16 627 const stored_allocator_type &get_stored_allocator() const
Chris@16 628 { return this->node_alloc(); }
Chris@16 629
Chris@16 630 stored_allocator_type &get_stored_allocator()
Chris@16 631 { return this->node_alloc(); }
Chris@16 632
Chris@16 633 iterator begin()
Chris@16 634 { return iterator(this->icont().begin()); }
Chris@16 635
Chris@16 636 const_iterator begin() const
Chris@16 637 { return this->cbegin(); }
Chris@16 638
Chris@16 639 iterator end()
Chris@16 640 { return iterator(this->icont().end()); }
Chris@16 641
Chris@16 642 const_iterator end() const
Chris@16 643 { return this->cend(); }
Chris@16 644
Chris@16 645 reverse_iterator rbegin()
Chris@16 646 { return reverse_iterator(end()); }
Chris@16 647
Chris@16 648 const_reverse_iterator rbegin() const
Chris@16 649 { return this->crbegin(); }
Chris@16 650
Chris@16 651 reverse_iterator rend()
Chris@16 652 { return reverse_iterator(begin()); }
Chris@16 653
Chris@16 654 const_reverse_iterator rend() const
Chris@16 655 { return this->crend(); }
Chris@16 656
Chris@16 657 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
Chris@16 658 //!
Chris@16 659 //! <b>Throws</b>: Nothing.
Chris@16 660 //!
Chris@16 661 //! <b>Complexity</b>: Constant.
Chris@16 662 const_iterator cbegin() const
Chris@16 663 { return const_iterator(this->non_const_icont().begin()); }
Chris@16 664
Chris@16 665 //! <b>Effects</b>: Returns a const_iterator to the end of the container.
Chris@16 666 //!
Chris@16 667 //! <b>Throws</b>: Nothing.
Chris@16 668 //!
Chris@16 669 //! <b>Complexity</b>: Constant.
Chris@16 670 const_iterator cend() const
Chris@16 671 { return const_iterator(this->non_const_icont().end()); }
Chris@16 672
Chris@16 673 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
Chris@16 674 //! of the reversed container.
Chris@16 675 //!
Chris@16 676 //! <b>Throws</b>: Nothing.
Chris@16 677 //!
Chris@16 678 //! <b>Complexity</b>: Constant.
Chris@16 679 const_reverse_iterator crbegin() const
Chris@16 680 { return const_reverse_iterator(cend()); }
Chris@16 681
Chris@16 682 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
Chris@16 683 //! of the reversed container.
Chris@16 684 //!
Chris@16 685 //! <b>Throws</b>: Nothing.
Chris@16 686 //!
Chris@16 687 //! <b>Complexity</b>: Constant.
Chris@16 688 const_reverse_iterator crend() const
Chris@16 689 { return const_reverse_iterator(cbegin()); }
Chris@16 690
Chris@16 691 bool empty() const
Chris@16 692 { return !this->size(); }
Chris@16 693
Chris@16 694 size_type size() const
Chris@16 695 { return this->icont().size(); }
Chris@16 696
Chris@16 697 size_type max_size() const
Chris@16 698 { return AllocHolder::max_size(); }
Chris@16 699
Chris@16 700 void swap(ThisType& x)
Chris@16 701 { AllocHolder::swap(x); }
Chris@16 702
Chris@16 703 public:
Chris@16 704
Chris@16 705 typedef typename Icont::insert_commit_data insert_commit_data;
Chris@16 706
Chris@16 707 // insert/erase
Chris@16 708 std::pair<iterator,bool> insert_unique_check
Chris@16 709 (const key_type& key, insert_commit_data &data)
Chris@16 710 {
Chris@16 711 std::pair<iiterator, bool> ret =
Chris@16 712 this->icont().insert_unique_check(key, KeyNodeCompare(value_comp()), data);
Chris@16 713 return std::pair<iterator, bool>(iterator(ret.first), ret.second);
Chris@16 714 }
Chris@16 715
Chris@16 716 std::pair<iterator,bool> insert_unique_check
Chris@16 717 (const_iterator hint, const key_type& key, insert_commit_data &data)
Chris@16 718 {
Chris@16 719 std::pair<iiterator, bool> ret =
Chris@16 720 this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(value_comp()), data);
Chris@16 721 return std::pair<iterator, bool>(iterator(ret.first), ret.second);
Chris@16 722 }
Chris@16 723
Chris@16 724 iterator insert_unique_commit(const value_type& v, insert_commit_data &data)
Chris@16 725 {
Chris@16 726 NodePtr tmp = AllocHolder::create_node(v);
Chris@16 727 scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
Chris@16 728 iterator ret(this->icont().insert_unique_commit(*tmp, data));
Chris@16 729 destroy_deallocator.release();
Chris@16 730 return ret;
Chris@16 731 }
Chris@16 732
Chris@16 733 template<class MovableConvertible>
Chris@16 734 iterator insert_unique_commit
Chris@16 735 (BOOST_FWD_REF(MovableConvertible) mv, insert_commit_data &data)
Chris@16 736 {
Chris@16 737 NodePtr tmp = AllocHolder::create_node(boost::forward<MovableConvertible>(mv));
Chris@16 738 scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
Chris@16 739 iterator ret(this->icont().insert_unique_commit(*tmp, data));
Chris@16 740 destroy_deallocator.release();
Chris@16 741 return ret;
Chris@16 742 }
Chris@16 743
Chris@16 744 std::pair<iterator,bool> insert_unique(const value_type& v)
Chris@16 745 {
Chris@16 746 insert_commit_data data;
Chris@16 747 std::pair<iterator,bool> ret =
Chris@16 748 this->insert_unique_check(KeyOfValue()(v), data);
Chris@16 749 if(ret.second){
Chris@16 750 ret.first = this->insert_unique_commit(v, data);
Chris@16 751 }
Chris@16 752 return ret;
Chris@16 753 }
Chris@16 754
Chris@16 755 template<class MovableConvertible>
Chris@16 756 std::pair<iterator,bool> insert_unique(BOOST_FWD_REF(MovableConvertible) mv)
Chris@16 757 {
Chris@16 758 insert_commit_data data;
Chris@16 759 std::pair<iterator,bool> ret =
Chris@16 760 this->insert_unique_check(KeyOfValue()(mv), data);
Chris@16 761 if(ret.second){
Chris@16 762 ret.first = this->insert_unique_commit(boost::forward<MovableConvertible>(mv), data);
Chris@16 763 }
Chris@16 764 return ret;
Chris@16 765 }
Chris@16 766
Chris@16 767 private:
Chris@16 768
Chris@16 769 template<class MovableConvertible>
Chris@16 770 void push_back_impl(BOOST_FWD_REF(MovableConvertible) mv)
Chris@16 771 {
Chris@16 772 NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
Chris@16 773 //push_back has no-throw guarantee so avoid any deallocator/destroyer
Chris@16 774 this->icont().push_back(*tmp);
Chris@16 775 }
Chris@16 776
Chris@16 777 std::pair<iterator, bool> emplace_unique_impl(NodePtr p)
Chris@16 778 {
Chris@16 779 value_type &v = p->get_data();
Chris@16 780 insert_commit_data data;
Chris@16 781 scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(p, this->node_alloc());
Chris@16 782 std::pair<iterator,bool> ret =
Chris@16 783 this->insert_unique_check(KeyOfValue()(v), data);
Chris@16 784 if(!ret.second){
Chris@16 785 return ret;
Chris@16 786 }
Chris@16 787 //No throw insertion part, release rollback
Chris@16 788 destroy_deallocator.release();
Chris@16 789 return std::pair<iterator,bool>
Chris@16 790 ( iterator(iiterator(this->icont().insert_unique_commit(*p, data)))
Chris@16 791 , true );
Chris@16 792 }
Chris@16 793
Chris@16 794 iterator emplace_unique_hint_impl(const_iterator hint, NodePtr p)
Chris@16 795 {
Chris@16 796 value_type &v = p->get_data();
Chris@16 797 insert_commit_data data;
Chris@16 798 std::pair<iterator,bool> ret =
Chris@16 799 this->insert_unique_check(hint, KeyOfValue()(v), data);
Chris@16 800 if(!ret.second){
Chris@16 801 Destroyer(this->node_alloc())(p);
Chris@16 802 return ret.first;
Chris@16 803 }
Chris@16 804 return iterator(iiterator(this->icont().insert_unique_commit(*p, data)));
Chris@16 805 }
Chris@16 806
Chris@16 807 public:
Chris@16 808
Chris@16 809 #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
Chris@16 810
Chris@16 811 template <class... Args>
Chris@16 812 std::pair<iterator, bool> emplace_unique(Args&&... args)
Chris@16 813 { return this->emplace_unique_impl(AllocHolder::create_node(boost::forward<Args>(args)...)); }
Chris@16 814
Chris@16 815 template <class... Args>
Chris@16 816 iterator emplace_hint_unique(const_iterator hint, Args&&... args)
Chris@16 817 { return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(boost::forward<Args>(args)...)); }
Chris@16 818
Chris@16 819 template <class... Args>
Chris@16 820 iterator emplace_equal(Args&&... args)
Chris@16 821 {
Chris@16 822 NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
Chris@16 823 scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
Chris@16 824 iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));
Chris@16 825 destroy_deallocator.release();
Chris@16 826 return ret;
Chris@16 827 }
Chris@16 828
Chris@16 829 template <class... Args>
Chris@16 830 iterator emplace_hint_equal(const_iterator hint, Args&&... args)
Chris@16 831 {
Chris@16 832 NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
Chris@16 833 scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
Chris@16 834 iterator ret(this->icont().insert_equal(hint.get(), *tmp));
Chris@16 835 destroy_deallocator.release();
Chris@16 836 return ret;
Chris@16 837 }
Chris@16 838
Chris@16 839 #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
Chris@16 840
Chris@16 841 #define BOOST_PP_LOCAL_MACRO(n) \
Chris@16 842 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
Chris@16 843 std::pair<iterator, bool> emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
Chris@16 844 { \
Chris@16 845 return this->emplace_unique_impl \
Chris@16 846 (AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
Chris@16 847 } \
Chris@16 848 \
Chris@16 849 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
Chris@16 850 iterator emplace_hint_unique(const_iterator hint \
Chris@16 851 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
Chris@16 852 { \
Chris@16 853 return this->emplace_unique_hint_impl \
Chris@16 854 (hint, AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
Chris@16 855 } \
Chris@16 856 \
Chris@16 857 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
Chris@16 858 iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
Chris@16 859 { \
Chris@16 860 NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
Chris@16 861 scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); \
Chris@16 862 iterator ret(this->icont().insert_equal(this->icont().end(), *tmp)); \
Chris@16 863 destroy_deallocator.release(); \
Chris@16 864 return ret; \
Chris@16 865 } \
Chris@16 866 \
Chris@16 867 BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
Chris@16 868 iterator emplace_hint_equal(const_iterator hint \
Chris@16 869 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
Chris@16 870 { \
Chris@16 871 NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
Chris@16 872 scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); \
Chris@16 873 iterator ret(this->icont().insert_equal(hint.get(), *tmp)); \
Chris@16 874 destroy_deallocator.release(); \
Chris@16 875 return ret; \
Chris@16 876 } \
Chris@16 877 //!
Chris@16 878 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
Chris@16 879 #include BOOST_PP_LOCAL_ITERATE()
Chris@16 880
Chris@16 881 #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
Chris@16 882
Chris@16 883 iterator insert_unique(const_iterator hint, const value_type& v)
Chris@16 884 {
Chris@16 885 insert_commit_data data;
Chris@16 886 std::pair<iterator,bool> ret =
Chris@16 887 this->insert_unique_check(hint, KeyOfValue()(v), data);
Chris@16 888 if(!ret.second)
Chris@16 889 return ret.first;
Chris@16 890 return this->insert_unique_commit(v, data);
Chris@16 891 }
Chris@16 892
Chris@16 893 template<class MovableConvertible>
Chris@16 894 iterator insert_unique(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv)
Chris@16 895 {
Chris@16 896 insert_commit_data data;
Chris@16 897 std::pair<iterator,bool> ret =
Chris@16 898 this->insert_unique_check(hint, KeyOfValue()(mv), data);
Chris@16 899 if(!ret.second)
Chris@16 900 return ret.first;
Chris@16 901 return this->insert_unique_commit(boost::forward<MovableConvertible>(mv), data);
Chris@16 902 }
Chris@16 903
Chris@16 904 template <class InputIterator>
Chris@16 905 void insert_unique(InputIterator first, InputIterator last)
Chris@16 906 {
Chris@16 907 for( ; first != last; ++first)
Chris@16 908 this->insert_unique(*first);
Chris@16 909 }
Chris@16 910
Chris@16 911 iterator insert_equal(const value_type& v)
Chris@16 912 {
Chris@16 913 NodePtr tmp(AllocHolder::create_node(v));
Chris@16 914 scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
Chris@16 915 iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));
Chris@16 916 destroy_deallocator.release();
Chris@16 917 return ret;
Chris@16 918 }
Chris@16 919
Chris@16 920 template<class MovableConvertible>
Chris@16 921 iterator insert_equal(BOOST_FWD_REF(MovableConvertible) mv)
Chris@16 922 {
Chris@16 923 NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
Chris@16 924 scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
Chris@16 925 iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));
Chris@16 926 destroy_deallocator.release();
Chris@16 927 return ret;
Chris@16 928 }
Chris@16 929
Chris@16 930 iterator insert_equal(const_iterator hint, const value_type& v)
Chris@16 931 {
Chris@16 932 NodePtr tmp(AllocHolder::create_node(v));
Chris@16 933 scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
Chris@16 934 iterator ret(this->icont().insert_equal(hint.get(), *tmp));
Chris@16 935 destroy_deallocator.release();
Chris@16 936 return ret;
Chris@16 937 }
Chris@16 938
Chris@16 939 template<class MovableConvertible>
Chris@16 940 iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv)
Chris@16 941 {
Chris@16 942 NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
Chris@16 943 scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
Chris@16 944 iterator ret(this->icont().insert_equal(hint.get(), *tmp));
Chris@16 945 destroy_deallocator.release();
Chris@16 946 return ret;
Chris@16 947 }
Chris@16 948
Chris@16 949 template <class InputIterator>
Chris@16 950 void insert_equal(InputIterator first, InputIterator last)
Chris@16 951 {
Chris@16 952 for( ; first != last; ++first)
Chris@16 953 this->insert_equal(*first);
Chris@16 954 }
Chris@16 955
Chris@16 956 iterator erase(const_iterator position)
Chris@16 957 { return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc()))); }
Chris@16 958
Chris@16 959 size_type erase(const key_type& k)
Chris@16 960 { return AllocHolder::erase_key(k, KeyNodeCompare(value_comp()), alloc_version()); }
Chris@16 961
Chris@16 962 iterator erase(const_iterator first, const_iterator last)
Chris@16 963 { return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
Chris@16 964
Chris@16 965 void clear()
Chris@16 966 { AllocHolder::clear(alloc_version()); }
Chris@16 967
Chris@16 968 // set operations:
Chris@16 969 iterator find(const key_type& k)
Chris@16 970 { return iterator(this->icont().find(k, KeyNodeCompare(value_comp()))); }
Chris@16 971
Chris@16 972 const_iterator find(const key_type& k) const
Chris@16 973 { return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(value_comp()))); }
Chris@16 974
Chris@16 975 size_type count(const key_type& k) const
Chris@16 976 { return size_type(this->icont().count(k, KeyNodeCompare(value_comp()))); }
Chris@16 977
Chris@16 978 iterator lower_bound(const key_type& k)
Chris@16 979 { return iterator(this->icont().lower_bound(k, KeyNodeCompare(value_comp()))); }
Chris@16 980
Chris@16 981 const_iterator lower_bound(const key_type& k) const
Chris@16 982 { return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(value_comp()))); }
Chris@16 983
Chris@16 984 iterator upper_bound(const key_type& k)
Chris@16 985 { return iterator(this->icont().upper_bound(k, KeyNodeCompare(value_comp()))); }
Chris@16 986
Chris@16 987 const_iterator upper_bound(const key_type& k) const
Chris@16 988 { return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(value_comp()))); }
Chris@16 989
Chris@16 990 std::pair<iterator,iterator> equal_range(const key_type& k)
Chris@16 991 {
Chris@16 992 std::pair<iiterator, iiterator> ret =
Chris@16 993 this->icont().equal_range(k, KeyNodeCompare(value_comp()));
Chris@16 994 return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second));
Chris@16 995 }
Chris@16 996
Chris@16 997 std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
Chris@16 998 {
Chris@16 999 std::pair<iiterator, iiterator> ret =
Chris@16 1000 this->non_const_icont().equal_range(k, KeyNodeCompare(value_comp()));
Chris@16 1001 return std::pair<const_iterator,const_iterator>
Chris@16 1002 (const_iterator(ret.first), const_iterator(ret.second));
Chris@16 1003 }
Chris@16 1004 };
Chris@16 1005
Chris@16 1006 template <class Key, class Value, class KeyOfValue,
Chris@16 1007 class KeyCompare, class A>
Chris@16 1008 inline bool
Chris@16 1009 operator==(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
Chris@16 1010 const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
Chris@16 1011 {
Chris@16 1012 return x.size() == y.size() &&
Chris@16 1013 std::equal(x.begin(), x.end(), y.begin());
Chris@16 1014 }
Chris@16 1015
Chris@16 1016 template <class Key, class Value, class KeyOfValue,
Chris@16 1017 class KeyCompare, class A>
Chris@16 1018 inline bool
Chris@16 1019 operator<(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
Chris@16 1020 const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
Chris@16 1021 {
Chris@16 1022 return std::lexicographical_compare(x.begin(), x.end(),
Chris@16 1023 y.begin(), y.end());
Chris@16 1024 }
Chris@16 1025
Chris@16 1026 template <class Key, class Value, class KeyOfValue,
Chris@16 1027 class KeyCompare, class A>
Chris@16 1028 inline bool
Chris@16 1029 operator!=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
Chris@16 1030 const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
Chris@16 1031 return !(x == y);
Chris@16 1032 }
Chris@16 1033
Chris@16 1034 template <class Key, class Value, class KeyOfValue,
Chris@16 1035 class KeyCompare, class A>
Chris@16 1036 inline bool
Chris@16 1037 operator>(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
Chris@16 1038 const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
Chris@16 1039 return y < x;
Chris@16 1040 }
Chris@16 1041
Chris@16 1042 template <class Key, class Value, class KeyOfValue,
Chris@16 1043 class KeyCompare, class A>
Chris@16 1044 inline bool
Chris@16 1045 operator<=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
Chris@16 1046 const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
Chris@16 1047 return !(y < x);
Chris@16 1048 }
Chris@16 1049
Chris@16 1050 template <class Key, class Value, class KeyOfValue,
Chris@16 1051 class KeyCompare, class A>
Chris@16 1052 inline bool
Chris@16 1053 operator>=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
Chris@16 1054 const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) {
Chris@16 1055 return !(x < y);
Chris@16 1056 }
Chris@16 1057
Chris@16 1058
Chris@16 1059 template <class Key, class Value, class KeyOfValue,
Chris@16 1060 class KeyCompare, class A>
Chris@16 1061 inline void
Chris@16 1062 swap(rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
Chris@16 1063 rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
Chris@16 1064 {
Chris@16 1065 x.swap(y);
Chris@16 1066 }
Chris@16 1067
Chris@16 1068 } //namespace container_detail {
Chris@16 1069 } //namespace container {
Chris@16 1070 /*
Chris@16 1071 //!has_trivial_destructor_after_move<> == true_type
Chris@16 1072 //!specialization for optimizations
Chris@16 1073 template <class K, class V, class KOV,
Chris@16 1074 class C, class A>
Chris@16 1075 struct has_trivial_destructor_after_move
Chris@16 1076 <boost::container::container_detail::rbtree<K, V, KOV, C, A> >
Chris@16 1077 {
Chris@16 1078 static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
Chris@16 1079 };
Chris@16 1080 */
Chris@16 1081 } //namespace boost {
Chris@16 1082
Chris@16 1083 #include <boost/container/detail/config_end.hpp>
Chris@16 1084
Chris@16 1085 #endif //BOOST_CONTAINER_TREE_HPP