forked from boostorg/intrusive
Additional checks for red-black trees, make sure root is black and the number of black nodes is equal in the left and right subtrees.
This commit is contained in:
@ -23,10 +23,6 @@
|
||||
#ifndef BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP
|
||||
#define BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
|
||||
@ -37,6 +33,10 @@
|
||||
#include <boost/intrusive/bstree_algorithms.hpp>
|
||||
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace intrusive {
|
||||
|
||||
@ -72,8 +72,14 @@ struct rbtree_node_checker
|
||||
typedef ValueTraits value_traits;
|
||||
typedef typename value_traits::node_traits node_traits;
|
||||
typedef typename node_traits::const_node_ptr const_node_ptr;
|
||||
typedef typename node_traits::node_ptr node_ptr;
|
||||
|
||||
typedef typename base_checker_t::return_type return_type;
|
||||
struct return_type
|
||||
: public base_checker_t::return_type
|
||||
{
|
||||
return_type() : black_count_(0) {}
|
||||
std::size_t black_count_;
|
||||
};
|
||||
|
||||
rbtree_node_checker(const NodePtrCompare& comp, ExtraChecker extra_checker)
|
||||
: base_checker_t(comp, extra_checker)
|
||||
@ -83,13 +89,21 @@ struct rbtree_node_checker
|
||||
const return_type& check_return_left, const return_type& check_return_right,
|
||||
return_type& check_return)
|
||||
{
|
||||
if (node_traits::get_color(p) == node_traits::red())
|
||||
{
|
||||
if (node_traits::get_left(p))
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_color(node_traits::get_left(p)) == node_traits::black());
|
||||
if (node_traits::get_right(p))
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_color(node_traits::get_right(p)) == node_traits::black());
|
||||
|
||||
if (node_traits::get_color(p) == node_traits::red()){
|
||||
//Red nodes have black children
|
||||
const node_ptr p_left(node_traits::get_left(p));
|
||||
const node_ptr p_right(node_traits::get_right(p));
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(!p_left || node_traits::get_color(p_left) == node_traits::black());
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(!p_right || node_traits::get_color(p_right) == node_traits::black());
|
||||
//Red node can't be root
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_parent(node_traits::get_parent(p)) != p);
|
||||
}
|
||||
//Every path to p contains the same number of black nodes
|
||||
const std::size_t l_black_count = check_return_left.black_count_;
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(l_black_count == check_return_right.black_count_);
|
||||
check_return.black_count_ = l_black_count +
|
||||
static_cast<std::size_t>(node_traits::get_color(p) == node_traits::black());
|
||||
base_checker_t::operator()(p, check_return_left, check_return_right, check_return);
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user