11namespace pixie::permutations::detail {
15template <std::
size_t Fanout>
16struct DirectChildOrder {
17 static constexpr bool supports_bias =
true;
19 std::size_t count : std::bit_width(Fanout) = 0;
20 std::size_t regular_prefix : std::bit_width(Fanout) = 0;
23 static std::size_t slot(
const Node&, std::size_t i, std::size_t)
noexcept {
27 static void reset(Node&)
noexcept {}
28 template <
class Tree,
class Node>
29 static std::size_t rotate(Node& node,
33 std::size_t)
noexcept {
34 std::rotate(node.children.begin() + begin, node.children.begin() + middle,
35 node.children.begin() + end);
39 static bool valid(
const Node&, std::size_t)
noexcept {
47 NoNodeReserve* for_rotation(std::size_t, std::size_t)
noexcept {
50 void trim(std::size_t, std::size_t)
noexcept {}
51 void clear() noexcept {}
52 std::size_t node_count() const noexcept {
return 0; }
58template <
class Node,
class Owner,
class Allocator>
59struct SequenceNodePool {
60 Node* nodes =
nullptr;
61 std::array<Owner, 3> leaves;
62 std::size_t leaf_count = 0;
64 explicit SequenceNodePool(NoNodeReserve<Node>* =
nullptr) noexcept {}
65 SequenceNodePool(
const SequenceNodePool&) =
delete;
66 SequenceNodePool& operator=(
const SequenceNodePool&) =
delete;
69 auto* next =
static_cast<Node*
>(nodes->children[0]);
70 Allocator::dispose(nodes);
74 void commit() noexcept {}
75 void reserve(std::size_t node_count, std::size_t leaf_spares) {
76 for (std::size_t i = 0; i < node_count; ++i) {
77 recycle(Allocator::node());
79 for (; leaf_count < leaf_spares; ++leaf_count) {
80 leaves[leaf_count] = Allocator::leaf();
83 void recycle(Node* node)
noexcept {
84 Allocator::reset(node);
85 node->children[0] = nodes;
88 Node* node() noexcept {
89 assert(nodes && nodes->count == 0);
91 nodes =
static_cast<Node*
>(nodes->children[0]);
92 result->children[0] =
nullptr;
95 Owner leaf() noexcept {
97 return std::move(leaves[--leaf_count]);
104struct SequenceTreePolicy {
105 template <std::
size_t Fanout>
106 using Order = DirectChildOrder<Fanout>;
107 template <
class Node,
class Allocator>
108 using Reserve = NoNodeReserve<Node>;
109 template <
class Node,
class Owner,
class Allocator>
110 using Pool = SequenceNodePool<Node, Owner, Allocator>;
111 struct TestCounters {};