xo-ordinaltree: scaffold key_compare parameter

This commit is contained in:
Roland Conybeare 2025-12-06 00:51:31 -05:00
commit 13d5023ac6
7 changed files with 50 additions and 19 deletions

View file

@ -57,9 +57,12 @@ namespace xo {
template <typename Key,
typename Value,
typename Reduce,
typename Compare,
typename Allocator>
class RedBlackTree : public xo::gc::gc_allocator_traits<Allocator>::object_interface_type {
static_assert(ordered_key<Key>);
static_assert(std::default_initializable<Compare>);
static_assert(std::predicate<Compare, Key, Key>);
static_assert(valid_rbtree_reduce_functor<Reduce, Value>);
public:
@ -67,7 +70,7 @@ namespace xo {
using mapped_type = Value;
using value_type = std::pair<Key const, Value>;
// using key_compare = Compare // not yet
using key_compare = Compare;
using allocator_type = Allocator;
using allocator_traits = xo::gc::gc_allocator_traits<Allocator>;
@ -76,7 +79,7 @@ namespace xo {
**/
using GcObjectInterface = allocator_traits::object_interface_type;
using ReducedValue = typename Reduce::value_type;
using RbUtil = detail::RbTreeUtil<Key, Value, Reduce, GcObjectInterface>;
using RbUtil = detail::RbTreeUtil<Key, Value, Reduce, Compare, GcObjectInterface>;
using RbNode = detail::Node<Key, Value, Reduce, GcObjectInterface>;
using RbTreeLhs = detail::RedBlackTreeLhs<RedBlackTree>;
using RbTreeConstLhs = detail::RedBlackTreeConstLhs<RedBlackTree>;
@ -92,15 +95,21 @@ namespace xo {
using Direction = detail::Direction;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using iterator = detail::Iterator<Key, Value, Reduce, GcObjectInterface>;
using const_iterator = detail::ConstIterator<Key, Value, Reduce, GcObjectInterface>;
using iterator = detail::Iterator<Key, Value,
Reduce, Compare,
GcObjectInterface>;
using const_iterator = detail::ConstIterator<Key, Value,
Reduce, Compare,
GcObjectInterface>;
using Reflect = xo::reflect::Reflect;
using TaggedPtr = xo::reflect::TaggedPtr;
public:
explicit RedBlackTree(const allocator_type & alloc = allocator_type{},
explicit RedBlackTree(const key_compare & compare = key_compare{},
const allocator_type & alloc = allocator_type{},
bool debug_flag = false) :
compare_{compare},
node_alloc_{alloc},
debug_flag_{debug_flag} {}
#ifdef NOT_YET // need copy_from
@ -126,7 +135,8 @@ namespace xo {
{}
#endif
static RedBlackTree * make(allocator_type kvpair_alloc = allocator_type{},
static RedBlackTree * make(key_compare compare = key_compare{},
allocator_type kvpair_alloc = allocator_type{},
bool debug_flag = false)
{
tree_allocator_type tree_alloc(kvpair_alloc);
@ -135,7 +145,7 @@ namespace xo {
try {
// placement new
tree_allocator_traits::construct(tree_alloc, tree, kvpair_alloc, debug_flag);
tree_allocator_traits::construct(tree_alloc, tree, compare, kvpair_alloc, debug_flag);
return tree;
} catch(...) {
tree_allocator_traits::deallocate(tree_alloc, tree, 1);
@ -670,6 +680,8 @@ namespace xo {
}
private:
/** key comparison */
key_compare compare_;
/** allocator state **/
node_allocator_type node_alloc_;
/** number of nodes in this tree. Each node holds one (key,value) pair **/
@ -688,10 +700,11 @@ namespace xo {
template <typename Key,
typename Value,
typename Reduce,
typename Compare,
typename Allocator>
inline std::ostream &
operator<<(std::ostream & os,
RedBlackTree<Key, Value, Reduce, Allocator> const & tree)
RedBlackTree<Key, Value, Reduce, Compare, Allocator> const & tree)
{
tree.display(os);
return os;
@ -700,11 +713,12 @@ namespace xo {
template <typename Key,
typename Value,
typename Reduce,
typename Compare,
typename GcObjectInterface,
bool IsConst>
inline std::ostream &
operator<<(std::ostream & os,
detail::IteratorBase<Key, Value, Reduce, GcObjectInterface, IsConst> const & iter)
detail::IteratorBase<Key, Value, Reduce, Compare, GcObjectInterface, IsConst> const & iter)
{
iter.print(os);
return os;

View file

@ -51,11 +51,12 @@ namespace xo {
template <typename Key,
typename Value,
typename Reduce,
typename Compare,
typename GcObjectInterface,
bool IsConst>
class IteratorBase {
public:
using RbUtil = RbTreeUtil<Key, Value, Reduce, GcObjectInterface>;
using RbUtil = RbTreeUtil<Key, Value, Reduce, Compare, GcObjectInterface>;
using RbNode = Node<Key, Value, Reduce, GcObjectInterface>;
using Traits = NodeTypeTraits<Key, Value, Reduce, GcObjectInterface, IsConst>;
using ReducedValue = typename Reduce::value_type;
@ -238,16 +239,21 @@ namespace xo {
template <typename Key,
typename Value,
typename Reduce,
typename Compare,
typename GcObjectInterface>
class Iterator : public IteratorBase<Key,
Value,
Reduce,
Compare,
GcObjectInterface,
false /*!IsConst*/> {
public:
using iterator_concept = std::bidirectional_iterator_tag;
using RbIteratorBase = IteratorBase<Key, Value, Reduce, GcObjectInterface, false /*!IsConst*/>;
using RbIteratorBase = IteratorBase<Key, Value,
Reduce, Compare,
GcObjectInterface,
false /*!IsConst*/>;
using RbNode = typename RbIteratorBase::RbNode;
using RbUtil = typename RbIteratorBase::RbUtil;
using ReducedValue = typename Reduce::value_type;
@ -308,12 +314,17 @@ namespace xo {
template <typename Key,
typename Value,
typename Reduce,
typename Compare,
typename GcObjectInterface>
class ConstIterator : public IteratorBase<Key, Value, Reduce, GcObjectInterface, true /*IsConst*/> {
class ConstIterator : public IteratorBase<Key, Value,
Reduce, Compare,
GcObjectInterface, true /*IsConst*/> {
public:
using iterator_concept = std::bidirectional_iterator_tag;
using RbIteratorBase = IteratorBase<Key, Value, Reduce, GcObjectInterface, true /*IsConst*/>;
using RbIteratorBase = IteratorBase<Key, Value,
Reduce, Compare,
GcObjectInterface, true /*IsConst*/>;
using RbNode = typename RbIteratorBase::RbNode;
using RbUtil = typename RbIteratorBase::RbUtil;
using ReducedValue = typename Reduce::value_type;

View file

@ -20,7 +20,9 @@ namespace xo {
namespace tree {
namespace detail {
/** see xo/ordinaltree/rbtree/RbTreeUtil.hpp */
template <typename Key, typename Value, typename Reduce, typename GcObjectInterface>
template <typename Key, typename Value,
typename Reduce, typename Compare,
typename GcObjectInterface>
class RbTreeUtil;
/* xo::tree::detail::Node

View file

@ -19,6 +19,7 @@ namespace xo {
template <typename Key,
typename Value,
typename Reduce,
typename Compare,
typename GcObjectInterface>
class RbTreeUtil {
public:

View file

@ -21,7 +21,7 @@ namespace xo {
template <typename Key,
typename Value,
typename Reduce = NullReduce<Key>,
//typename Compare = std::less<Key>,
typename Compare = std::less<Key>,
typename Allocator = std::allocator<std::pair<const Key, Value>>>
class RedBlackTree;

View file

@ -56,6 +56,7 @@ namespace xo {
using RbTree = RedBlackTree<int,
double,
SumReduce<double>,
std::less<int>,
xo::gc::allocator<std::pair<const int, double>>>;
constexpr bool c_debug_flag = false;
@ -124,6 +125,7 @@ namespace xo {
using RbTree = RedBlackTree<int,
double,
SumReduce<double>,
std::less<int>,
xo::gc::allocator<std::pair<const int, double>>>;
constexpr bool c_debug_flag = false;
@ -160,9 +162,10 @@ namespace xo {
REQUIRE(gc->native_gc_statistics().n_gc() == 0);
RbTree::key_compare compare;
xo::gc::allocator<RbTree> allocator(gc.get());
gp<RbTree> rbtree = RbTree::make(allocator, c_debug_flag);
gp<RbTree> rbtree = RbTree::make(compare, allocator, c_debug_flag);
gc->add_gc_root_dwim(&rbtree);
@ -197,7 +200,7 @@ namespace xo {
}
REQUIRE(rbtree->verify_ok(debug_flag));
}
if (n > 0) {
@ -259,7 +262,7 @@ namespace xo {
&rgen);
REQUIRE(rbtree->verify_ok(debug_flag));
if (tc.do_extra_gc_) {
REQUIRE(gc->gc_in_progress() == false);
gc->request_gc(gc::generation::nursery);

View file

@ -127,7 +127,7 @@ namespace {
TEST_CASE("rbtree", "[redblacktree]")
{
constexpr bool c_debug_flag = false;
RbTree rbtree{RbTree::allocator_type{}, c_debug_flag};
RbTree rbtree{RbTree::key_compare{}, RbTree::allocator_type{}, c_debug_flag};
REQUIRE(rbtree.size() == 0);