137 , ptr_(std::bit_cast<uintptr_t>(d)) {}
138 constexpr iterator(D*
const* elems) noexcept
140 , ptr_(std::bit_cast<uintptr_t>(elems)) {}
141 constexpr iterator(Node* node) noexcept
143 , ptr_(std::bit_cast<uintptr_t>(node)) {}
163 constexpr iterator& operator++() noexcept {
166 case Tag::Uniq:
return clear();
167 case Tag::Data:
return ptr_ = std::bit_cast<uintptr_t>(std::bit_cast<D* const*>(ptr_) + 1), *
this;
169 auto node = std::bit_cast<Node*>(ptr_);
174 ptr_ = std::bit_cast<uintptr_t>(node);
177 default: fe::unreachable();
192 constexpr bool operator==(iterator other)
const noexcept {
return this->tag_ == other.tag_ && this->ptr_ == other.ptr_; }
193 constexpr bool operator!=(iterator other)
const noexcept {
return this->tag_ != other.tag_ || this->ptr_ != other.ptr_; }
201 case Tag::Uniq:
return std::bit_cast<D*>(ptr_);
202 case Tag::Data:
return *std::bit_cast<D* const*>(ptr_);
203 case Tag::Node:
return std::bit_cast<Node*>(ptr_)->def;
204 default: fe::unreachable();
232 constexpr Set&
operator=(
const Set&)
noexcept =
default;
237 constexpr size_t size() const noexcept {
238 if (isa_uniq())
return 1;
239 if (
auto d = isa_data())
return d->size;
240 if (
auto n = isa_node())
return n->size;
245 constexpr bool empty() const noexcept {
246 assert(tag() != Tag::Node || !ptr<Node>()->is_root());
250 constexpr explicit operator bool() const noexcept {
return ptr_ != 0; }
258 if (
auto u = isa_uniq())
return d == u;
260 if (
auto data = isa_data()) {
262 if (d == e)
return true;
266 if (
auto n = isa_node())
return n->contains(d);
273 if (*
this == other)
return true;
274 if (this->
empty() || other.empty())
return false;
276 auto u1 = this->isa_uniq();
277 auto u2 = other.isa_uniq();
278 if (
u1)
return other.contains(
u1);
281 auto d1 = this->isa_data();
282 auto d2 = other.isa_data();
284 for (
auto ai = d1->begin(), ae = d1->end(), bi = d2->begin(), be = d2->end(); ai != ae && bi != be;) {
285 if (*ai == *bi)
return true;
287 if ((*ai)->gid() < (*bi)->gid())
296 auto n1 = this->isa_node();
297 auto n2 = other.isa_node();
299 if (n1->min > n2->def->tid() || n1->def->tid() < n2->min)
return false;
300 if (n1->def == n2->def)
return true;
301 if (!n1->lca(n2)->is_root())
return true;
303 while (!n1->is_root() && !n2->is_root()) {
304 if (n1->def->tid() > n2->def->tid()) {
305 if (n1 = n1->find(n2->def); n2->def == n1->def)
return true;
308 if (n2 = n2->find(n1->def); n1->def == n2->def)
return true;
316 auto n = n1 ? n1 : n2;
317 for (
auto e : *(d1 ? d1 : d2))
318 if (n->contains(e))
return true;
327 if (
auto u = isa_uniq())
return {u};
328 if (
auto d = isa_data())
return {d->begin()};
329 if (
auto n = isa_node(); n && !n->is_root())
return {n};
334 if (
auto data = isa_data())
return iterator(data->end());
341 constexpr bool operator==(Set other)
const noexcept {
return this->ptr_ == other.ptr_; }
342 constexpr bool operator!=(Set other)
const noexcept {
return this->ptr_ != other.ptr_; }
347 std::ostream&
stream(std::ostream& os)
const {
350 for (
auto d : *
this) {
351 os << sep << d->sym() <<
": " << d->gid() <<
'/' << d->tid();
361 constexpr Tag tag() const noexcept {
return Tag(ptr_ & uintptr_t(0b11)); }
363 constexpr T* ptr() const noexcept {
364 return std::bit_cast<T*>(ptr_ & (uintptr_t(-2) << uintptr_t(2)));
367 constexpr D* isa_uniq() const noexcept {
return tag() == Tag::Uniq ? ptr<D >() : nullptr; }
368 constexpr Data* isa_data() const noexcept {
return tag() == Tag::Data ? ptr<Data>() : nullptr; }
369 constexpr Node* isa_node() const noexcept {
return tag() == Tag::Node ? ptr<Node>() : nullptr; }
375 friend std::ostream&
operator<<(std::ostream& os, Set set) {
return set.stream(os); }
378 static_assert(std::forward_iterator<typename Set::iterator>);
379 static_assert(std::ranges::range<Set>);
386 : root_(make_node()) {}
402 std::sort(vb, ve, [](D* d1, D* d2) {
return d1->gid() < d2->gid(); });
403 auto vu = std::unique(vb, ve);
404 auto size = std::distance(vb, vu);
406 if (
size == 0)
return {};
407 if (
size == 1)
return {*vb};
409 if (
size_t(
size) <= N) {
410 auto [data, state] = allocate(
size);
411 std::copy(vb, vu, data->begin());
412 return unify(data, state);
416 std::sort(vb, vu, [](D* d1, D* d2) {
return d1->tid() != 0 && (d2->tid() == 0 || d1->tid() < d2->tid()); });
419 for (
auto i = vb; i != vu; ++i)
426 if (
auto u = s.isa_uniq()) {
427 if (d == u)
return {d};
429 auto [data, state] = allocate(2);
430 if (d->gid() < u->gid())
431 data->elems[0] = d, data->elems[1] = u;
433 data->elems[0] = u, data->elems[1] = d;
434 return unify(data, state);
437 if (
auto src = s.isa_data()) {
438 auto size = src->size;
440 auto [dst, state] = allocate(
size + 1);
444 for (
auto si = src->begin(), di = dst->begin(), se = src->end(); si != se || !ins; ++di) {
445 if (si != se && d == *si) {
446 data_arena_.deallocate(state);
450 if (!ins && (si == se || d->gid() < (*si)->gid()))
456 return unify(dst, state);
458 auto [dst, state] = allocate(
size + 1);
461 auto di = dst->begin();
462 for (
auto si = src->begin(), se = src->end(); si != se; ++si, ++di) {
464 data_arena_.deallocate(state);
473 std::sort(dst->begin(), di,
474 [](D* d1, D* d2) { return d1->tid() != 0 && (d2->tid() == 0 || d1->tid() < d2->tid()); });
477 for (
auto i = dst->begin(), e = dst->end(); i != e; ++i)
483 if (
auto n = s.isa_node()) {
484 if (n->contains(d))
return n;
492 [[nodiscard]] Set
merge(Set s1, Set s2) {
493 if (s1.empty() || s1 == s2)
return s2;
494 if (s2.empty())
return s1;
496 if (
auto u = s1.isa_uniq())
return insert(s2, u);
497 if (
auto u = s2.isa_uniq())
return insert(s1, u);
499 auto d1 = s1.isa_data();
500 auto d2 = s2.isa_data();
503 v.reserve(d1->size + d2->size);
510 return create(std::move(v));
513 auto n1 = s1.isa_node();
514 auto n2 = s2.isa_node();
516 if (n1->is_descendant_of(n2))
return n1;
517 if (n2->is_descendant_of(n1))
return n2;
518 return merge(n1, n2);
521 auto n = n1 ? n1 : n2;
522 for (
auto d : *(d1 ? d1 : d2))
523 if (!n->contains(d)) n =
insert(n, d);
528 [[nodiscard]] Set
erase(Set s, D* d) {
529 if (
auto u = s.isa_uniq())
return d == u ? Set() : s;
531 if (
auto data = s.isa_data()) {
532 size_t i = 0,
size = data->size;
533 for (; i !=
size; ++i)
534 if (data->elems[i] == d)
break;
536 if (i ==
size--)
return s;
537 if (
size == 0)
return {};
538 if (
size == 1)
return {i == 0 ? data->elems[1] : data->elems[0]};
541 auto [new_data, state] = allocate(
size);
542 auto db = data->begin();
543 std::copy(db + i + 1, data->end(), std::copy(db, db + i, new_data->elems));
545 return unify(new_data, state);
548 if (
auto n = s.isa_node()) {
549 if (d->tid() == 0 || d->tid() < n->min)
return n;
550 if (!n->contains(d))
return n;
552 auto res =
erase(n, d);
553 if (res->size > N)
return res;
556 v.reserve(res->size);
557 for (
auto i = res; !i->is_root(); i = i->parent)
558 v.emplace_back(i->def);
559 return create(std::move(v));
568 auto of = std::ofstream(
"trie.dot");
572 void dot(std::ostream& os)
const {
573 os <<
"digraph {{" << std::endl;
574 os <<
"ordering=out;" << std::endl;
575 os <<
"node [shape=box,style=filled];" << std::endl;
577 os <<
"}}" << std::endl;
583 swap(s1.data_arena_, s2.data_arena_);
584 swap(s1.node_arena_, s2.node_arena_);
585 swap(s1.pool_, s2.pool_);
586 swap(s1.root_, s2.root_);
587 swap(s1.tid_counter_, s2.tid_counter_);
588 swap(s1.id_counter_ , s2.id_counter_ );
593 D* set_tid(D* def)
noexcept {
594 assert(def->tid() == 0);
595 def->tid_ = tid_counter_++;
601 inline static constexpr size_t SizeOf =
sizeof(std::conditional_t<std::is_pointer_v<T>, uintptr_t, T>);
604 std::pair<Data*, fe::Arena::State> allocate(
size_t size) {
605 auto bytes =
sizeof(Data) + size * SizeOf<D>;
606 auto state = data_arena_.state();
607 auto buff = data_arena_.allocate(bytes,
alignof(Data));
608 auto data =
new (buff) Data(size);
609 return {data, state};
612 Set unify(Data* data, fe::Arena::State state,
size_t excess = 0) {
613 assert(data->size != 0);
614 auto [i, ins] = pool_.emplace(data);
616 data_arena_.deallocate(excess * SizeOf<D>);
620 data_arena_.deallocate(state);
625 constexpr Node* root() const noexcept {
return root_.get(); }
626 fe::Arena::Ptr<Node> make_node() {
return node_arena_.mk<Node>(id_counter_++); }
627 fe::Arena::Ptr<Node> make_node(Node* parent, D* def) {
return node_arena_.mk<Node>(parent, def, id_counter_++); }
629 [[nodiscard]] Node* mount(Node* parent, D* def) {
630 assert(def->tid() != 0);
631 auto [i, ins] = parent->children.emplace(def,
nullptr);
632 if (ins) i->second = make_node(parent, def);
633 return i->second.get();
636 [[nodiscard]]
constexpr Node*
insert(Node* n, D* d)
noexcept {
637 if (
d->tid() == 0)
return mount(n, set_tid(d));
638 if (n->def == d)
return n;
639 if (n->is_root() || n->def->tid() <
d->tid())
return mount(n, d);
640 return mount(
insert(n->parent, d), n->def);
643 [[nodiscard]]
constexpr Node*
merge(Node* n, Node* m) {
644 if (n == m || m->is_root())
return n;
645 if (n->is_root())
return m;
646 auto nn = n->def->tid() < m->def->tid() ? n : n->parent;
647 auto mm = n->def->tid() > m->def->tid() ? m : m->parent;
648 return mount(
merge(nn, mm), n->def->tid() < m->def->tid() ? m->def : n->def);
651 [[nodiscard]] Node*
erase(Node* n, D* d) {
652 if (
d->tid() > n->def->tid())
return n;
653 if (n->def == d)
return n->parent;
654 return mount(
erase(n->parent, d), n->def);
657 fe::Arena node_arena_;
658 fe::Arena data_arena_;
659 absl::flat_hash_set<const Data*, absl::Hash<const Data*>,
typename Data::Equal> pool_;
660 fe::Arena::Ptr<Node> root_;
661 u32 tid_counter_ = 1;