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
|
#ifndef BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP
|
||||||
#define 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/detail/config_begin.hpp>
|
||||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
|
|
||||||
@@ -37,6 +33,10 @@
|
|||||||
#include <boost/intrusive/bstree_algorithms.hpp>
|
#include <boost/intrusive/bstree_algorithms.hpp>
|
||||||
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
|
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||||
|
# pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace intrusive {
|
namespace intrusive {
|
||||||
|
|
||||||
@@ -72,8 +72,14 @@ struct rbtree_node_checker
|
|||||||
typedef ValueTraits value_traits;
|
typedef ValueTraits value_traits;
|
||||||
typedef typename value_traits::node_traits node_traits;
|
typedef typename value_traits::node_traits node_traits;
|
||||||
typedef typename node_traits::const_node_ptr const_node_ptr;
|
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)
|
rbtree_node_checker(const NodePtrCompare& comp, ExtraChecker extra_checker)
|
||||||
: base_checker_t(comp, 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,
|
const return_type& check_return_left, const return_type& check_return_right,
|
||||||
return_type& check_return)
|
return_type& check_return)
|
||||||
{
|
{
|
||||||
if (node_traits::get_color(p) == node_traits::red())
|
|
||||||
{
|
if (node_traits::get_color(p) == node_traits::red()){
|
||||||
if (node_traits::get_left(p))
|
//Red nodes have black children
|
||||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_color(node_traits::get_left(p)) == node_traits::black());
|
const node_ptr p_left(node_traits::get_left(p));
|
||||||
if (node_traits::get_right(p))
|
const node_ptr p_right(node_traits::get_right(p));
|
||||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(node_traits::get_color(node_traits::get_right(p)) == node_traits::black());
|
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);
|
base_checker_t::operator()(p, check_return_left, check_return_right, check_return);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user