annotate DEPENDENCIES/generic/include/boost/intrusive/rbtree_algorithms.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 /////////////////////////////////////////////////////////////////////////////
Chris@16 2 //
Chris@16 3 // (C) Copyright Olaf Krzikalla 2004-2006.
Chris@101 4 // (C) Copyright Ion Gaztanaga 2006-2014.
Chris@16 5 //
Chris@16 6 // Distributed under the Boost Software License, Version 1.0.
Chris@16 7 // (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 8 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9 //
Chris@16 10 // See http://www.boost.org/libs/intrusive for documentation.
Chris@16 11 //
Chris@16 12 /////////////////////////////////////////////////////////////////////////////
Chris@16 13 //
Chris@16 14 // The tree destruction algorithm is based on Julienne Walker and The EC Team code:
Chris@16 15 //
Chris@16 16 // This code is in the public domain. Anyone may use it or change it in any way that
Chris@16 17 // they see fit. The author assumes no responsibility for damages incurred through
Chris@16 18 // use of the original code or any variations thereof.
Chris@16 19 //
Chris@16 20 // It is requested, but not required, that due credit is given to the original author
Chris@16 21 // and anyone who has modified the code through a header comment, such as this one.
Chris@16 22
Chris@16 23 #ifndef BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP
Chris@16 24 #define BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP
Chris@16 25
Chris@16 26 #include <boost/intrusive/detail/config_begin.hpp>
Chris@101 27 #include <boost/intrusive/intrusive_fwd.hpp>
Chris@16 28
Chris@16 29 #include <cstddef>
Chris@16 30
Chris@16 31 #include <boost/intrusive/detail/assert.hpp>
Chris@101 32 #include <boost/intrusive/detail/algo_type.hpp>
Chris@16 33 #include <boost/intrusive/bstree_algorithms.hpp>
Chris@101 34 #include <boost/intrusive/detail/ebo_functor_holder.hpp>
Chris@101 35
Chris@101 36 #if defined(BOOST_HAS_PRAGMA_ONCE)
Chris@101 37 # pragma once
Chris@101 38 #endif
Chris@16 39
Chris@16 40 namespace boost {
Chris@16 41 namespace intrusive {
Chris@16 42
Chris@16 43 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 44
Chris@16 45 template<class NodeTraits, class F>
Chris@16 46 struct rbtree_node_cloner
Chris@101 47 //Use public inheritance to avoid MSVC bugs with closures
Chris@101 48 : public detail::ebo_functor_holder<F>
Chris@16 49 {
Chris@16 50 typedef typename NodeTraits::node_ptr node_ptr;
Chris@16 51 typedef detail::ebo_functor_holder<F> base_t;
Chris@16 52
Chris@101 53 explicit rbtree_node_cloner(F f)
Chris@16 54 : base_t(f)
Chris@16 55 {}
Chris@16 56
Chris@16 57 node_ptr operator()(const node_ptr & p)
Chris@16 58 {
Chris@16 59 node_ptr n = base_t::get()(p);
Chris@16 60 NodeTraits::set_color(n, NodeTraits::get_color(p));
Chris@16 61 return n;
Chris@16 62 }
Chris@16 63 };
Chris@16 64
Chris@101 65 namespace detail {
Chris@101 66
Chris@101 67 template<class ValueTraits, class NodePtrCompare, class ExtraChecker>
Chris@101 68 struct rbtree_node_checker
Chris@101 69 : public bstree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker>
Chris@16 70 {
Chris@101 71 typedef bstree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker> base_checker_t;
Chris@101 72 typedef ValueTraits value_traits;
Chris@101 73 typedef typename value_traits::node_traits node_traits;
Chris@101 74 typedef typename node_traits::const_node_ptr const_node_ptr;
Chris@101 75 typedef typename node_traits::node_ptr node_ptr;
Chris@16 76
Chris@101 77 struct return_type
Chris@101 78 : public base_checker_t::return_type
Chris@16 79 {
Chris@101 80 return_type() : black_count_(0) {}
Chris@101 81 std::size_t black_count_;
Chris@101 82 };
Chris@101 83
Chris@101 84 rbtree_node_checker(const NodePtrCompare& comp, ExtraChecker extra_checker)
Chris@101 85 : base_checker_t(comp, extra_checker)
Chris@101 86 {}
Chris@101 87
Chris@101 88 void operator () (const const_node_ptr& p,
Chris@101 89 const return_type& check_return_left, const return_type& check_return_right,
Chris@101 90 return_type& check_return)
Chris@101 91 {
Chris@101 92
Chris@101 93 if (node_traits::get_color(p) == node_traits::red()){
Chris@101 94 //Red nodes have black children
Chris@101 95 const node_ptr p_left(node_traits::get_left(p));
Chris@101 96 const node_ptr p_right(node_traits::get_right(p));
Chris@101 97 BOOST_INTRUSIVE_INVARIANT_ASSERT(!p_left || node_traits::get_color(p_left) == node_traits::black());
Chris@101 98 BOOST_INTRUSIVE_INVARIANT_ASSERT(!p_right || node_traits::get_color(p_right) == node_traits::black());
Chris@101 99 //Red node can't be root
Chris@101 100 BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_parent(node_traits::get_parent(p)) != p);
Chris@101 101 }
Chris@101 102 //Every path to p contains the same number of black nodes
Chris@101 103 const std::size_t l_black_count = check_return_left.black_count_;
Chris@101 104 BOOST_INTRUSIVE_INVARIANT_ASSERT(l_black_count == check_return_right.black_count_);
Chris@101 105 check_return.black_count_ = l_black_count +
Chris@101 106 static_cast<std::size_t>(node_traits::get_color(p) == node_traits::black());
Chris@101 107 base_checker_t::operator()(p, check_return_left, check_return_right, check_return);
Chris@16 108 }
Chris@16 109 };
Chris@16 110
Chris@101 111 } // namespace detail
Chris@101 112
Chris@16 113 #endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 114
Chris@16 115 //! rbtree_algorithms provides basic algorithms to manipulate
Chris@16 116 //! nodes forming a red-black tree. The insertion and deletion algorithms are
Chris@16 117 //! based on those in Cormen, Leiserson, and Rivest, Introduction to Algorithms
Chris@16 118 //! (MIT Press, 1990), except that
Chris@16 119 //!
Chris@16 120 //! (1) the header node is maintained with links not only to the root
Chris@16 121 //! but also to the leftmost node of the tree, to enable constant time
Chris@16 122 //! begin(), and to the rightmost node of the tree, to enable linear time
Chris@16 123 //! performance when used with the generic set algorithms (set_union,
Chris@16 124 //! etc.);
Chris@16 125 //!
Chris@16 126 //! (2) when a node being deleted has two children its successor node is
Chris@16 127 //! relinked into its place, rather than copied, so that the only
Chris@16 128 //! pointers invalidated are those referring to the deleted node.
Chris@16 129 //!
Chris@16 130 //! rbtree_algorithms is configured with a NodeTraits class, which encapsulates the
Chris@16 131 //! information about the node to be manipulated. NodeTraits must support the
Chris@16 132 //! following interface:
Chris@16 133 //!
Chris@16 134 //! <b>Typedefs</b>:
Chris@16 135 //!
Chris@16 136 //! <tt>node</tt>: The type of the node that forms the binary search tree
Chris@16 137 //!
Chris@16 138 //! <tt>node_ptr</tt>: A pointer to a node
Chris@16 139 //!
Chris@16 140 //! <tt>const_node_ptr</tt>: A pointer to a const node
Chris@16 141 //!
Chris@16 142 //! <tt>color</tt>: The type that can store the color of a node
Chris@16 143 //!
Chris@16 144 //! <b>Static functions</b>:
Chris@16 145 //!
Chris@16 146 //! <tt>static node_ptr get_parent(const_node_ptr n);</tt>
Chris@16 147 //!
Chris@16 148 //! <tt>static void set_parent(node_ptr n, node_ptr parent);</tt>
Chris@16 149 //!
Chris@16 150 //! <tt>static node_ptr get_left(const_node_ptr n);</tt>
Chris@16 151 //!
Chris@16 152 //! <tt>static void set_left(node_ptr n, node_ptr left);</tt>
Chris@16 153 //!
Chris@16 154 //! <tt>static node_ptr get_right(const_node_ptr n);</tt>
Chris@16 155 //!
Chris@16 156 //! <tt>static void set_right(node_ptr n, node_ptr right);</tt>
Chris@16 157 //!
Chris@16 158 //! <tt>static color get_color(const_node_ptr n);</tt>
Chris@16 159 //!
Chris@16 160 //! <tt>static void set_color(node_ptr n, color c);</tt>
Chris@16 161 //!
Chris@16 162 //! <tt>static color black();</tt>
Chris@16 163 //!
Chris@16 164 //! <tt>static color red();</tt>
Chris@16 165 template<class NodeTraits>
Chris@16 166 class rbtree_algorithms
Chris@16 167 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 168 : public bstree_algorithms<NodeTraits>
Chris@16 169 #endif
Chris@16 170 {
Chris@16 171 public:
Chris@16 172 typedef NodeTraits node_traits;
Chris@16 173 typedef typename NodeTraits::node node;
Chris@16 174 typedef typename NodeTraits::node_ptr node_ptr;
Chris@16 175 typedef typename NodeTraits::const_node_ptr const_node_ptr;
Chris@16 176 typedef typename NodeTraits::color color;
Chris@16 177
Chris@16 178 /// @cond
Chris@16 179 private:
Chris@16 180
Chris@16 181 typedef bstree_algorithms<NodeTraits> bstree_algo;
Chris@16 182
Chris@16 183 /// @endcond
Chris@16 184
Chris@16 185 public:
Chris@16 186
Chris@16 187 //! This type is the information that will be
Chris@16 188 //! filled by insert_unique_check
Chris@16 189 typedef typename bstree_algo::insert_commit_data insert_commit_data;
Chris@16 190
Chris@16 191 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 192
Chris@16 193 //! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const const_node_ptr&)
Chris@16 194 static node_ptr get_header(const const_node_ptr & n);
Chris@16 195
Chris@16 196 //! @copydoc ::boost::intrusive::bstree_algorithms::begin_node
Chris@16 197 static node_ptr begin_node(const const_node_ptr & header);
Chris@16 198
Chris@16 199 //! @copydoc ::boost::intrusive::bstree_algorithms::end_node
Chris@16 200 static node_ptr end_node(const const_node_ptr & header);
Chris@16 201
Chris@16 202 //! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree
Chris@16 203 static void swap_tree(const node_ptr & header1, const node_ptr & header2);
Chris@101 204
Chris@16 205 #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 206
Chris@16 207 //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&)
Chris@16 208 static void swap_nodes(const node_ptr & node1, const node_ptr & node2)
Chris@16 209 {
Chris@16 210 if(node1 == node2)
Chris@16 211 return;
Chris@16 212
Chris@16 213 node_ptr header1(bstree_algo::get_header(node1)), header2(bstree_algo::get_header(node2));
Chris@16 214 swap_nodes(node1, header1, node2, header2);
Chris@16 215 }
Chris@16 216
Chris@16 217 //! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&,const node_ptr&,const node_ptr&)
Chris@16 218 static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2)
Chris@16 219 {
Chris@16 220 if(node1 == node2) return;
Chris@16 221
Chris@16 222 bstree_algo::swap_nodes(node1, header1, node2, header2);
Chris@16 223 //Swap color
Chris@16 224 color c = NodeTraits::get_color(node1);
Chris@16 225 NodeTraits::set_color(node1, NodeTraits::get_color(node2));
Chris@16 226 NodeTraits::set_color(node2, c);
Chris@16 227 }
Chris@16 228
Chris@16 229 //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&)
Chris@16 230 static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node)
Chris@16 231 {
Chris@16 232 if(node_to_be_replaced == new_node)
Chris@16 233 return;
Chris@16 234 replace_node(node_to_be_replaced, bstree_algo::get_header(node_to_be_replaced), new_node);
Chris@16 235 }
Chris@16 236
Chris@16 237 //! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&,const node_ptr&)
Chris@16 238 static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node)
Chris@16 239 {
Chris@16 240 bstree_algo::replace_node(node_to_be_replaced, header, new_node);
Chris@16 241 NodeTraits::set_color(new_node, NodeTraits::get_color(node_to_be_replaced));
Chris@16 242 }
Chris@16 243
Chris@16 244 //! @copydoc ::boost::intrusive::bstree_algorithms::unlink(const node_ptr&)
Chris@16 245 static void unlink(const node_ptr& node)
Chris@16 246 {
Chris@16 247 node_ptr x = NodeTraits::get_parent(node);
Chris@16 248 if(x){
Chris@16 249 while(!is_header(x))
Chris@16 250 x = NodeTraits::get_parent(x);
Chris@16 251 erase(x, node);
Chris@16 252 }
Chris@16 253 }
Chris@16 254
Chris@16 255 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 256 //! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance
Chris@16 257 static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header);
Chris@16 258
Chris@16 259 //! @copydoc ::boost::intrusive::bstree_algorithms::unique(const const_node_ptr&)
Chris@16 260 static bool unique(const const_node_ptr & node);
Chris@16 261
Chris@16 262 //! @copydoc ::boost::intrusive::bstree_algorithms::size(const const_node_ptr&)
Chris@16 263 static std::size_t size(const const_node_ptr & header);
Chris@16 264
Chris@16 265 //! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const node_ptr&)
Chris@16 266 static node_ptr next_node(const node_ptr & node);
Chris@16 267
Chris@16 268 //! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const node_ptr&)
Chris@16 269 static node_ptr prev_node(const node_ptr & node);
Chris@16 270
Chris@16 271 //! @copydoc ::boost::intrusive::bstree_algorithms::init(const node_ptr&)
Chris@16 272 static void init(const node_ptr & node);
Chris@16 273 #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 274
Chris@16 275 //! @copydoc ::boost::intrusive::bstree_algorithms::init_header(const node_ptr&)
Chris@16 276 static void init_header(const node_ptr & header)
Chris@16 277 {
Chris@16 278 bstree_algo::init_header(header);
Chris@16 279 NodeTraits::set_color(header, NodeTraits::red());
Chris@16 280 }
Chris@16 281
Chris@16 282 //! @copydoc ::boost::intrusive::bstree_algorithms::erase(const node_ptr&,const node_ptr&)
Chris@16 283 static node_ptr erase(const node_ptr & header, const node_ptr & z)
Chris@16 284 {
Chris@16 285 typename bstree_algo::data_for_rebalance info;
Chris@101 286 bstree_algo::erase(header, z, info);
Chris@16 287
Chris@101 288 color new_z_color;
Chris@101 289 if(info.y != z){
Chris@101 290 new_z_color = NodeTraits::get_color(info.y);
Chris@101 291 NodeTraits::set_color(info.y, NodeTraits::get_color(z));
Chris@101 292 }
Chris@101 293 else{
Chris@101 294 new_z_color = NodeTraits::get_color(z);
Chris@101 295 }
Chris@101 296 //Rebalance rbtree if needed
Chris@101 297 if(new_z_color != NodeTraits::red()){
Chris@16 298 rebalance_after_erasure(header, info.x, info.x_parent);
Chris@16 299 }
Chris@16 300 return z;
Chris@16 301 }
Chris@16 302
Chris@16 303 //! @copydoc ::boost::intrusive::bstree_algorithms::clone(const const_node_ptr&,const node_ptr&,Cloner,Disposer)
Chris@16 304 template <class Cloner, class Disposer>
Chris@16 305 static void clone
Chris@16 306 (const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer)
Chris@16 307 {
Chris@16 308 rbtree_node_cloner<NodeTraits, Cloner> new_cloner(cloner);
Chris@16 309 bstree_algo::clone(source_header, target_header, new_cloner, disposer);
Chris@16 310 }
Chris@16 311
Chris@16 312 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 313 //! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const node_ptr&,Disposer)
Chris@16 314 template<class Disposer>
Chris@16 315 static void clear_and_dispose(const node_ptr & header, Disposer disposer);
Chris@16 316
Chris@16 317 //! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
Chris@16 318 template<class KeyType, class KeyNodePtrCompare>
Chris@16 319 static node_ptr lower_bound
Chris@16 320 (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
Chris@16 321
Chris@16 322 //! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
Chris@16 323 template<class KeyType, class KeyNodePtrCompare>
Chris@16 324 static node_ptr upper_bound
Chris@16 325 (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
Chris@16 326
Chris@16 327 //! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare)
Chris@16 328 template<class KeyType, class KeyNodePtrCompare>
Chris@16 329 static node_ptr find
Chris@16 330 (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
Chris@16 331
Chris@16 332 //! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
Chris@16 333 template<class KeyType, class KeyNodePtrCompare>
Chris@16 334 static std::pair<node_ptr, node_ptr> equal_range
Chris@16 335 (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
Chris@16 336
Chris@16 337 //! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool)
Chris@16 338 template<class KeyType, class KeyNodePtrCompare>
Chris@16 339 static std::pair<node_ptr, node_ptr> bounded_range
Chris@16 340 (const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
Chris@16 341 , bool left_closed, bool right_closed);
Chris@16 342
Chris@16 343 //! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
Chris@16 344 template<class KeyType, class KeyNodePtrCompare>
Chris@16 345 static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
Chris@101 346
Chris@16 347 #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 348
Chris@16 349 //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(const node_ptr&,const node_ptr&,NodePtrCompare)
Chris@16 350 template<class NodePtrCompare>
Chris@16 351 static node_ptr insert_equal_upper_bound
Chris@16 352 (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp)
Chris@16 353 {
Chris@16 354 bstree_algo::insert_equal_upper_bound(h, new_node, comp);
Chris@16 355 rebalance_after_insertion(h, new_node);
Chris@16 356 return new_node;
Chris@16 357 }
Chris@16 358
Chris@16 359 //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(const node_ptr&,const node_ptr&,NodePtrCompare)
Chris@16 360 template<class NodePtrCompare>
Chris@16 361 static node_ptr insert_equal_lower_bound
Chris@16 362 (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp)
Chris@16 363 {
Chris@16 364 bstree_algo::insert_equal_lower_bound(h, new_node, comp);
Chris@16 365 rebalance_after_insertion(h, new_node);
Chris@16 366 return new_node;
Chris@16 367 }
Chris@16 368
Chris@16 369 //! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(const node_ptr&,const node_ptr&,const node_ptr&,NodePtrCompare)
Chris@16 370 template<class NodePtrCompare>
Chris@16 371 static node_ptr insert_equal
Chris@16 372 (const node_ptr & header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp)
Chris@16 373 {
Chris@16 374 bstree_algo::insert_equal(header, hint, new_node, comp);
Chris@16 375 rebalance_after_insertion(header, new_node);
Chris@16 376 return new_node;
Chris@16 377 }
Chris@16 378
Chris@16 379 //! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(const node_ptr&,const node_ptr&,const node_ptr&)
Chris@16 380 static node_ptr insert_before
Chris@16 381 (const node_ptr & header, const node_ptr & pos, const node_ptr & new_node)
Chris@16 382 {
Chris@16 383 bstree_algo::insert_before(header, pos, new_node);
Chris@16 384 rebalance_after_insertion(header, new_node);
Chris@16 385 return new_node;
Chris@16 386 }
Chris@16 387
Chris@16 388 //! @copydoc ::boost::intrusive::bstree_algorithms::push_back(const node_ptr&,const node_ptr&)
Chris@16 389 static void push_back(const node_ptr & header, const node_ptr & new_node)
Chris@16 390 {
Chris@16 391 bstree_algo::push_back(header, new_node);
Chris@16 392 rebalance_after_insertion(header, new_node);
Chris@16 393 }
Chris@16 394
Chris@16 395 //! @copydoc ::boost::intrusive::bstree_algorithms::push_front(const node_ptr&,const node_ptr&)
Chris@16 396 static void push_front(const node_ptr & header, const node_ptr & new_node)
Chris@16 397 {
Chris@16 398 bstree_algo::push_front(header, new_node);
Chris@16 399 rebalance_after_insertion(header, new_node);
Chris@16 400 }
Chris@16 401
Chris@16 402 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 403 //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&)
Chris@16 404 template<class KeyType, class KeyNodePtrCompare>
Chris@16 405 static std::pair<node_ptr, bool> insert_unique_check
Chris@16 406 (const const_node_ptr & header, const KeyType &key
Chris@16 407 ,KeyNodePtrCompare comp, insert_commit_data &commit_data);
Chris@16 408
Chris@16 409 //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&)
Chris@16 410 template<class KeyType, class KeyNodePtrCompare>
Chris@16 411 static std::pair<node_ptr, bool> insert_unique_check
Chris@16 412 (const const_node_ptr & header, const node_ptr &hint, const KeyType &key
Chris@16 413 ,KeyNodePtrCompare comp, insert_commit_data &commit_data);
Chris@16 414 #endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
Chris@16 415
Chris@16 416 //! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(const node_ptr&,const node_ptr&,const insert_commit_data&)
Chris@16 417 static void insert_unique_commit
Chris@16 418 (const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data)
Chris@16 419 {
Chris@16 420 bstree_algo::insert_unique_commit(header, new_value, commit_data);
Chris@16 421 rebalance_after_insertion(header, new_value);
Chris@16 422 }
Chris@16 423
Chris@16 424 //! @copydoc ::boost::intrusive::bstree_algorithms::is_header
Chris@16 425 static bool is_header(const const_node_ptr & p)
Chris@16 426 {
Chris@16 427 return NodeTraits::get_color(p) == NodeTraits::red() &&
Chris@16 428 bstree_algo::is_header(p);
Chris@16 429 }
Chris@16 430
Chris@16 431 /// @cond
Chris@16 432 private:
Chris@16 433
Chris@16 434 static void rebalance_after_erasure(const node_ptr & header, node_ptr x, node_ptr x_parent)
Chris@16 435 {
Chris@101 436 while(1){
Chris@101 437 if(x_parent == header || (x && NodeTraits::get_color(x) != NodeTraits::black())){
Chris@101 438 break;
Chris@101 439 }
Chris@101 440 //Don't cache x_is_leftchild or similar because x can be null and
Chris@101 441 //equal to both x_parent_left and x_parent_right
Chris@101 442 const node_ptr x_parent_left(NodeTraits::get_left(x_parent));
Chris@101 443 if(x == x_parent_left){ //x is left child
Chris@16 444 node_ptr w = NodeTraits::get_right(x_parent);
Chris@101 445 BOOST_INTRUSIVE_INVARIANT_ASSERT(w);
Chris@16 446 if(NodeTraits::get_color(w) == NodeTraits::red()){
Chris@16 447 NodeTraits::set_color(w, NodeTraits::black());
Chris@16 448 NodeTraits::set_color(x_parent, NodeTraits::red());
Chris@101 449 bstree_algo::rotate_left(x_parent, w, NodeTraits::get_parent(x_parent), header);
Chris@16 450 w = NodeTraits::get_right(x_parent);
Chris@16 451 }
Chris@101 452 node_ptr const w_left (NodeTraits::get_left(w));
Chris@101 453 node_ptr const w_right(NodeTraits::get_right(w));
Chris@101 454 if((!w_left || NodeTraits::get_color(w_left) == NodeTraits::black()) &&
Chris@101 455 (!w_right || NodeTraits::get_color(w_right) == NodeTraits::black())){
Chris@16 456 NodeTraits::set_color(w, NodeTraits::red());
Chris@16 457 x = x_parent;
Chris@16 458 x_parent = NodeTraits::get_parent(x_parent);
Chris@16 459 }
Chris@16 460 else {
Chris@101 461 if(!w_right || NodeTraits::get_color(w_right) == NodeTraits::black()){
Chris@101 462 NodeTraits::set_color(w_left, NodeTraits::black());
Chris@16 463 NodeTraits::set_color(w, NodeTraits::red());
Chris@101 464 bstree_algo::rotate_right(w, w_left, NodeTraits::get_parent(w), header);
Chris@16 465 w = NodeTraits::get_right(x_parent);
Chris@16 466 }
Chris@16 467 NodeTraits::set_color(w, NodeTraits::get_color(x_parent));
Chris@16 468 NodeTraits::set_color(x_parent, NodeTraits::black());
Chris@101 469 const node_ptr new_wright(NodeTraits::get_right(w));
Chris@101 470 if(new_wright)
Chris@101 471 NodeTraits::set_color(new_wright, NodeTraits::black());
Chris@101 472 bstree_algo::rotate_left(x_parent, NodeTraits::get_right(x_parent), NodeTraits::get_parent(x_parent), header);
Chris@16 473 break;
Chris@16 474 }
Chris@16 475 }
Chris@16 476 else {
Chris@16 477 // same as above, with right_ <-> left_.
Chris@101 478 node_ptr w = x_parent_left;
Chris@16 479 if(NodeTraits::get_color(w) == NodeTraits::red()){
Chris@16 480 NodeTraits::set_color(w, NodeTraits::black());
Chris@16 481 NodeTraits::set_color(x_parent, NodeTraits::red());
Chris@101 482 bstree_algo::rotate_right(x_parent, w, NodeTraits::get_parent(x_parent), header);
Chris@16 483 w = NodeTraits::get_left(x_parent);
Chris@16 484 }
Chris@101 485 node_ptr const w_left (NodeTraits::get_left(w));
Chris@101 486 node_ptr const w_right(NodeTraits::get_right(w));
Chris@101 487 if((!w_right || NodeTraits::get_color(w_right) == NodeTraits::black()) &&
Chris@101 488 (!w_left || NodeTraits::get_color(w_left) == NodeTraits::black())){
Chris@16 489 NodeTraits::set_color(w, NodeTraits::red());
Chris@16 490 x = x_parent;
Chris@16 491 x_parent = NodeTraits::get_parent(x_parent);
Chris@16 492 }
Chris@16 493 else {
Chris@101 494 if(!w_left || NodeTraits::get_color(w_left) == NodeTraits::black()){
Chris@101 495 NodeTraits::set_color(w_right, NodeTraits::black());
Chris@16 496 NodeTraits::set_color(w, NodeTraits::red());
Chris@101 497 bstree_algo::rotate_left(w, w_right, NodeTraits::get_parent(w), header);
Chris@16 498 w = NodeTraits::get_left(x_parent);
Chris@16 499 }
Chris@16 500 NodeTraits::set_color(w, NodeTraits::get_color(x_parent));
Chris@16 501 NodeTraits::set_color(x_parent, NodeTraits::black());
Chris@101 502 const node_ptr new_wleft(NodeTraits::get_left(w));
Chris@101 503 if(new_wleft)
Chris@101 504 NodeTraits::set_color(new_wleft, NodeTraits::black());
Chris@101 505 bstree_algo::rotate_right(x_parent, NodeTraits::get_left(x_parent), NodeTraits::get_parent(x_parent), header);
Chris@16 506 break;
Chris@16 507 }
Chris@16 508 }
Chris@16 509 }
Chris@16 510 if(x)
Chris@16 511 NodeTraits::set_color(x, NodeTraits::black());
Chris@16 512 }
Chris@16 513
Chris@16 514 static void rebalance_after_insertion(const node_ptr & header, node_ptr p)
Chris@16 515 {
Chris@16 516 NodeTraits::set_color(p, NodeTraits::red());
Chris@101 517 while(1){
Chris@16 518 node_ptr p_parent(NodeTraits::get_parent(p));
Chris@101 519 const node_ptr p_grandparent(NodeTraits::get_parent(p_parent));
Chris@101 520 if(p_parent == header || NodeTraits::get_color(p_parent) == NodeTraits::black() || p_grandparent == header){
Chris@101 521 break;
Chris@101 522 }
Chris@101 523
Chris@101 524 NodeTraits::set_color(p_grandparent, NodeTraits::red());
Chris@101 525 node_ptr const p_grandparent_left (NodeTraits::get_left (p_grandparent));
Chris@101 526 bool const p_parent_is_left_child = p_parent == p_grandparent_left;
Chris@101 527 node_ptr const x(p_parent_is_left_child ? NodeTraits::get_right(p_grandparent) : p_grandparent_left);
Chris@101 528
Chris@101 529 if(x && NodeTraits::get_color(x) == NodeTraits::red()){
Chris@101 530 NodeTraits::set_color(x, NodeTraits::black());
Chris@101 531 NodeTraits::set_color(p_parent, NodeTraits::black());
Chris@101 532 p = p_grandparent;
Chris@101 533 }
Chris@101 534 else{ //Final step
Chris@101 535 const bool p_is_left_child(NodeTraits::get_left(p_parent) == p);
Chris@101 536 if(p_parent_is_left_child){ //p_parent is left child
Chris@101 537 if(!p_is_left_child){ //p is right child
Chris@101 538 bstree_algo::rotate_left_no_parent_fix(p_parent, p);
Chris@101 539 //No need to link p and p_grandparent:
Chris@101 540 // [NodeTraits::set_parent(p, p_grandparent) + NodeTraits::set_left(p_grandparent, p)]
Chris@101 541 //as p_grandparent is not the header, another rotation is coming and p_parent
Chris@101 542 //will be the left child of p_grandparent
Chris@101 543 p_parent = p;
Chris@101 544 }
Chris@101 545 bstree_algo::rotate_right(p_grandparent, p_parent, NodeTraits::get_parent(p_grandparent), header);
Chris@16 546 }
Chris@101 547 else{ //p_parent is right child
Chris@101 548 if(p_is_left_child){ //p is left child
Chris@101 549 bstree_algo::rotate_right_no_parent_fix(p_parent, p);
Chris@101 550 //No need to link p and p_grandparent:
Chris@101 551 // [NodeTraits::set_parent(p, p_grandparent) + NodeTraits::set_right(p_grandparent, p)]
Chris@101 552 //as p_grandparent is not the header, another rotation is coming and p_parent
Chris@101 553 //will be the right child of p_grandparent
Chris@101 554 p_parent = p;
Chris@16 555 }
Chris@101 556 bstree_algo::rotate_left(p_grandparent, p_parent, NodeTraits::get_parent(p_grandparent), header);
Chris@16 557 }
Chris@101 558 NodeTraits::set_color(p_parent, NodeTraits::black());
Chris@101 559 break;
Chris@16 560 }
Chris@16 561 }
Chris@16 562 NodeTraits::set_color(NodeTraits::get_parent(header), NodeTraits::black());
Chris@16 563 }
Chris@16 564 /// @endcond
Chris@16 565 };
Chris@16 566
Chris@16 567 /// @cond
Chris@16 568
Chris@16 569 template<class NodeTraits>
Chris@16 570 struct get_algo<RbTreeAlgorithms, NodeTraits>
Chris@16 571 {
Chris@16 572 typedef rbtree_algorithms<NodeTraits> type;
Chris@16 573 };
Chris@16 574
Chris@101 575 template <class ValueTraits, class NodePtrCompare, class ExtraChecker>
Chris@101 576 struct get_node_checker<RbTreeAlgorithms, ValueTraits, NodePtrCompare, ExtraChecker>
Chris@101 577 {
Chris@101 578 typedef detail::rbtree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker> type;
Chris@101 579 };
Chris@101 580
Chris@16 581 /// @endcond
Chris@16 582
Chris@16 583 } //namespace intrusive
Chris@16 584 } //namespace boost
Chris@16 585
Chris@16 586 #include <boost/intrusive/detail/config_end.hpp>
Chris@16 587
Chris@16 588 #endif //BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP