xo-ordinaltree: 3-way comparison scaffolding. wip
This commit is contained in:
parent
13d5023ac6
commit
1d3999a6bd
5 changed files with 50 additions and 12 deletions
|
|
@ -8,6 +8,7 @@
|
|||
# include <format>
|
||||
#endif
|
||||
#include <chrono>
|
||||
#include <compare>
|
||||
#include <cstdint>
|
||||
#include <time.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace xo {
|
|||
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(three_way_comparator<Compare, Key>); // std::less doesn't deliver this
|
||||
static_assert(valid_rbtree_reduce_functor<Reduce, Value>);
|
||||
|
||||
public:
|
||||
|
|
@ -373,7 +373,8 @@ namespace xo {
|
|||
//scope log(XO_DEBUG(true), tag("variant", "autoinsert"), tag("key", k));
|
||||
|
||||
std::pair<bool, RbNode *> insert_result
|
||||
= RbUtil::template insert_aux<node_allocator_type>(this->node_alloc_,
|
||||
= RbUtil::template insert_aux<node_allocator_type>(this->compare_,
|
||||
this->node_alloc_,
|
||||
value_type(k, Value() /*used iff creating new node*/),
|
||||
false /*allow_replace_flag*/,
|
||||
this->reduce_fn_,
|
||||
|
|
@ -512,7 +513,8 @@ namespace xo {
|
|||
RbNode * adj_root = this->root_;
|
||||
|
||||
std::pair<bool, RbNode *> insert_result
|
||||
= RbUtil::insert_aux(this->node_alloc_,
|
||||
= RbUtil::insert_aux(this->compare_,
|
||||
this->node_alloc_,
|
||||
std::move(kv_pair),
|
||||
true /*allow_replace_flag*/,
|
||||
this->reduce_fn_,
|
||||
|
|
|
|||
|
|
@ -788,7 +788,8 @@ namespace xo {
|
|||
*/
|
||||
template <typename NodeAllocator>
|
||||
static std::pair<bool, RbNode *>
|
||||
insert_aux(NodeAllocator & alloc,
|
||||
insert_aux(Compare const & key_cmp,
|
||||
NodeAllocator & alloc,
|
||||
value_type const & kv_pair,
|
||||
bool allow_replace_flag,
|
||||
Reduce const & reduce_fn,
|
||||
|
|
@ -804,7 +805,9 @@ namespace xo {
|
|||
Direction d = D_Invalid;
|
||||
|
||||
while (N) {
|
||||
if (kv_pair.first == N->key()) {
|
||||
auto cmp = key_cmp(kv_pair.first, N->key());
|
||||
|
||||
if (cmp == 0) { // kv_pair.first == N->key()) {
|
||||
if(allow_replace_flag) {
|
||||
/* match on this key already present in tree
|
||||
* -> just update assoc'd value
|
||||
|
|
@ -825,7 +828,7 @@ namespace xo {
|
|||
return std::make_pair(false, N);
|
||||
}
|
||||
|
||||
d = ((kv_pair.first < N->key()) ? D_Left : D_Right);
|
||||
d = (cmp < 0 /*(kv_pair.first < N->key())*/ ? D_Left : D_Right);
|
||||
|
||||
/* insert into left subtree somewhere */
|
||||
RbNode * C = N->child(d);
|
||||
|
|
|
|||
|
|
@ -6,22 +6,44 @@
|
|||
#pragma once
|
||||
|
||||
#include "NullReduce.hpp"
|
||||
#include <compare>
|
||||
|
||||
namespace xo {
|
||||
namespace tree {
|
||||
/* red-black tree with order statistics
|
||||
/**
|
||||
* Wrapper to workaround concept requirements that prevent
|
||||
* std::compare_three_way working with const references
|
||||
**/
|
||||
struct DefaultThreeWayCompare {
|
||||
#ifdef NOT_YET // not working with clang 16.0.6
|
||||
template <typename T>
|
||||
auto operator()(const T & a, const T & b) const {
|
||||
return a <=> b;
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
auto operator()(const T& a, const T& b) const -> std::strong_ordering {
|
||||
if (a < b) return std::strong_ordering::less;
|
||||
if (b < a) return std::strong_ordering::greater;
|
||||
return std::strong_ordering::equal;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Red-black tree with order statistics
|
||||
*
|
||||
* require:
|
||||
* Require:
|
||||
* - Key is equality comparable
|
||||
* - Key, Value, Reduce are copyable and null-constructible
|
||||
* - Reduce.value_type = Accumulator
|
||||
* - Reduce.operator() :: (Accumulator x Key) -> Accumulator
|
||||
* - Reduce.operator() :: (Accumulator x Accumulator) -> Accumulator
|
||||
*/
|
||||
**/
|
||||
template <typename Key,
|
||||
typename Value,
|
||||
typename Reduce = NullReduce<Key>,
|
||||
typename Compare = std::less<Key>,
|
||||
typename Compare = DefaultThreeWayCompare, //std::compare_three_way, //std::less<Key>,
|
||||
typename Allocator = std::allocator<std::pair<const Key, Value>>>
|
||||
class RedBlackTree;
|
||||
|
||||
|
|
@ -87,6 +109,16 @@ namespace xo {
|
|||
&& std::default_initializable<Key>
|
||||
&& std::totally_ordered<Key>);
|
||||
|
||||
|
||||
template <typename Compare,
|
||||
typename Key>
|
||||
concept three_way_comparator = requires(const Compare& comp,
|
||||
const Key& a,
|
||||
const Key& b)
|
||||
{
|
||||
{ comp(a, b) } -> std::same_as<std::strong_ordering>;
|
||||
};
|
||||
|
||||
template <typename Value>
|
||||
concept valid_rbtree_node_value = (std::copyable<Value>
|
||||
&& std::default_initializable<Value>);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ namespace xo {
|
|||
using RbTree = RedBlackTree<int,
|
||||
double,
|
||||
SumReduce<double>,
|
||||
std::less<int>,
|
||||
std::compare_three_way,
|
||||
xo::gc::allocator<std::pair<const int, double>>>;
|
||||
|
||||
constexpr bool c_debug_flag = false;
|
||||
|
|
@ -125,7 +125,7 @@ namespace xo {
|
|||
using RbTree = RedBlackTree<int,
|
||||
double,
|
||||
SumReduce<double>,
|
||||
std::less<int>,
|
||||
std::compare_three_way, //std::less<int>,
|
||||
xo::gc::allocator<std::pair<const int, double>>>;
|
||||
|
||||
constexpr bool c_debug_flag = false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue