140 template <
typename Node>
142 const char *
prefix)
noexcept
148 for (
const char *ptr =
prefix; *ptr !=
'\0'; ++ptr)
150 auto *
child = node->search_child(*ptr);
151 if (
child ==
nullptr)
152 return std::make_tuple(node, ptr);
156 return std::make_tuple(node,
"");
168 template <
typename Node>
175 const char key =
child->get_key();
194 template <
typename Node>
200 if (
child->get_key() > c)
222 if (
root_ !=
nullptr)
252 for (
size_t i = 0; i <
count_; ++i)
259 for (
size_t i = 0; i <
count_; ++i)
269 void set(
const size_t i,
Cnode *node)
const noexcept
328 explicit Cnode(
const char c)
noexcept
354 r.append(
static_cast<Cnode *
>(p));
368 const auto *node =
static_cast<const Cnode *
>(p);
483 for (
const char *ptr =
word; *ptr !=
'\0'; ++ptr)
485 node = node->search_child(*ptr);
490 return node->is_end_word() ? node :
nullptr;
533 if (*remaining !=
'\0')
585 if (
pp->is_end_word())
592 for (
const char *ptr =
rem; *ptr; ++ptr)
596 for (
size_t i = 0; i < n; ++i)
599 path[n - 1]->mark_end_word();
602 auto *parent =
pp->insert_child(path[0]);
603 for (
size_t i = 1; i < n; ++i)
605 parent->insert_rightmost_child(path[i]);
621 Cnode *to_delete = p;
622 p =
static_cast<Cnode *
>(p->get_left_sibling());
638 const auto *node =
static_cast<const Cnode *
>(
child);
639 word.push_back(node->symbol());
675 std::cout <<
w <<
'\n';
692 const auto *src_node =
static_cast<const Cnode *
>(src);
693 auto *tgt_node =
static_cast<Cnode *
>(tgt);
695 tgt_node->ends_word_ = src_node->ends_word_;
724 return ret.release();
934 if (
root_ ==
nullptr)
1017template <
typename T>
1034 template <
typename Node_Type>
1036 const char c)
noexcept
1043 const char key =
child->get_key();
1045 return static_cast<Node_Type *
>(
child);
1054 template <
typename Node_Type>
1056 const char c)
noexcept
1062 if (
child->get_key() > c)
1063 return static_cast<Node_Type *
>(
child);
1068 template <
typename Node_Type>
1069 [[
nodiscard]]
static std::tuple<Node_Type *, const char *>
1076 for (
const char *ptr =
prefix; *ptr !=
'\0'; ++ptr)
1078 auto *
child = node->search_child(*ptr);
1079 if (
child ==
nullptr)
1080 return std::make_tuple(node, ptr);
1084 return std::make_tuple(node,
"");
1100 if (root_ !=
nullptr)
1131 for (
size_t i = 0; i < count_; ++i)
1132 nodes_[i] =
nullptr;
1138 for (
size_t i = 0; i < count_; ++i)
1148 void set(
const size_t i,
Node *node)
const noexcept
1155 owns_nodes_ =
false;
1164 explicit Node(
const char c)
noexcept
1177 template <
typename U>
1198 return value_.has_value();
1235 template <
typename U>
1288 [[
nodiscard]] std::tuple<Node *, const char *>
1301 [[
nodiscard]] std::tuple<const Node *, const char *>
1337 template <
typename U>
1344 for (
const char *ptr =
suffix; *ptr !=
'\0'; ++ptr)
1348 for (
size_t i = 0; i + 1 < n; ++i)
1354 for (
size_t i = 1; i < n; ++i)
1369 Node *to_delete = p;
1370 p =
static_cast<Node *
>(p->get_left_sibling());
1387 return ret.release();
1398 requires std::is_copy_constructible_v<Value>
1403 if (src->value_.has_value())
1404 tgt->value_.emplace(*src->value_);
1436 const auto *node =
static_cast<const Node *
>(
child);
1437 word.push_back(node->symbol());
1450 if (
root ==
nullptr)
1460 if (
root_ ==
nullptr)
1467 if (
root_ ==
nullptr)
1471 return *remaining ==
'\0' ? node :
nullptr;
1477 return const_cast<Node *
>(
1489 template <
typename U>
1496 if (*remaining ==
'\0')
1498 if (node->has_value())
1501 *node->value() = std::forward<U>(
value);
1504 node->emplace_value(std::forward<U>(
value));
1509 node->insert_suffix(remaining, std::forward<U>(
value));
1531 requires std::is_copy_constructible_v<Value>
1545 other.root_ =
nullptr;
1569 requires std::is_copy_constructible_v<Value>
1594 other.root_ =
nullptr;
1669 return find(key) !=
nullptr;
1683 return node !=
nullptr ? node->
value() :
nullptr;
1697 return node !=
nullptr ? node->
value() :
nullptr;
1760 if (
root_ ==
nullptr)
1784 if (
root_ ==
nullptr)
1788 if (*remaining !=
'\0')
Exception handling system with formatted messages for Aleph-w.
WeightedDigraph::Node Node
size_t size_t int32_t value
size_t size_t int32_t * out
Restore a clone target if appending cloned children fails.
Clone_Target_Rollback(Cnode *target) noexcept
Tree_Node< char > * previous_rightmost_
Own a detached subtree until it is committed elsewhere.
Cnode * get() const noexcept
~Detached_Subtree_Guard()
Detached_Subtree_Guard(Cnode *root) noexcept
Cnode * release() noexcept
Own standalone nodes until an insertion path is committed.
void set(const size_t i, Cnode *node) const noexcept
Pending_Path_Guard(const size_t count)
Cnode * operator[](const size_t i) const noexcept
void release_nodes() noexcept
Low-level prefix tree node for storing character sequences.
Cnode * search_child(const char c) noexcept
Search for a mutable child with the given character.
Cnode(const char c) noexcept
Construct a node with the given character.
size_t count() const noexcept
Count total words stored in this subtree.
static void clone(const Tree_Node< char > *src, Tree_Node< char > *tgt)
Clone helper - copies children from src to tgt.
Cnode * clone() const
Create a deep copy of this subtree.
static std::tuple< Node *, const char * > search_prefix_impl(Node *root, const char *prefix) noexcept
Shared implementation for mutable and const prefix searches.
bool contains(const std::string &word) const noexcept
Check if a word exists in the tree.
void destroy() noexcept
Destroy all children of this node.
const Cnode * greater_child(const char c) const noexcept
Find the first const child with a character greater than c.
Cnode * greater_child(const char c) noexcept
Find the first mutable child with a character greater than c.
std::tuple< Cnode *, const char * > search_prefix(const char *prefix) noexcept
Search for a prefix in the mutable tree.
std::string to_str() const
Convert the subtree to a string representation.
void words_impl(std::string &word, DynArray< std::string > &l, const size_t max_word_length) const
std::tuple< const Cnode *, const char * > search_prefix(const char *prefix) const noexcept
Search for a prefix in the const tree.
const Cnode * search_word(const char *word) const noexcept
Search for a complete word in the tree.
void mark_end_word()
Mark this node as the end of a word.
void print_words(const size_t max_word_length=2048) const
Print all words to stdout.
bool is_end_word() const noexcept
Check if this node marks the end of a word.
Cnode * insert_child(Cnode *child)
Insert a child node in sorted order.
char symbol() const noexcept
Return the character stored in this node.
static Node * search_child_impl(Node *root, const char c) noexcept
Shared implementation for mutable and const child lookup.
bool insert_word(const std::string &word)
Insert a word into the tree.
const Cnode * search_child(const char c) const noexcept
Search for a const child with the given character.
DynArray< std::string > words(size_t max_word_length=2048) const
Get all words stored in this subtree.
DynArray< std::string > words_with_prefix(const std::string &prefix, const size_t max_word_length=2048) const
Get all words starting with a given prefix.
DynList< Cnode * > children() const
Return a list of all child nodes.
static Node * greater_child_impl(Node *root, const char c) noexcept
Shared implementation for mutable and const sorted-child lookup.
void reserve(const size_t l, const size_t r)
Allocate a range of entries.
Doubly-linked list (defined in tpl_dynList.H).
T & append(const T &item)
Own a detached map subtree until it is committed.
~Detached_Subtree_Guard()
Node * release() noexcept
Node * get() const noexcept
Detached_Subtree_Guard(Node *root) noexcept
Own standalone insertion nodes until a new path is committed.
Pending_Path_Guard(const size_t count)
void release_nodes() noexcept
void set(const size_t i, Node *node) const noexcept
Internal trie node storing one character and an optional value.
static void clone_into(const Node *src, Node *tgt)
Copy src contents into an already allocated target node.
void words_impl(std::string &word, DynArray< std::string > &out, const size_t max_word_length) const
Append all terminal keys in this subtree.
Node(const char c) noexcept
Construct a structural node with no mapped value.
const Node * search_child(const char c) const noexcept
Search for a const child with the given character.
void insert_suffix(const char *suffix, U &&value)
Insert a key suffix below this node.
Node * clone() const
Clone this node and all descendants.
void emplace_value(U &&value)
Emplace this node's mapped value.
Node * insert_child(Node *child)
Insert a child node in sorted order.
char symbol() const noexcept
Return the character stored in this node.
std::optional< Value > value_
const Node * greater_child(const char c) const noexcept
Find the first const child with a character greater than c.
std::tuple< const Node *, const char * > search_prefix(const char *prefix) const noexcept
Search for a prefix in the const tree.
void reset_value() noexcept
Remove this node's mapped value.
Node * greater_child(const char c) noexcept
Find the first mutable child with a character greater than c.
bool has_value() const noexcept
Check whether this node terminates a key.
static std::tuple< Node_Type *, const char * > search_prefix_impl(Node_Type *root, const char *prefix) noexcept
Shared mutable and const prefix search.
static Node_Type * greater_child_impl(Node_Type *root, const char c) noexcept
Shared mutable and const sorted-child lookup.
static Node_Type * search_child_impl(Node_Type *root, const char c) noexcept
Shared mutable and const child lookup.
std::tuple< Node *, const char * > search_prefix(const char *prefix) noexcept
Search for a prefix in the mutable tree.
const Value * value() const noexcept
Return the stored mapped value.
Node(const char c, U &&value)
Construct a terminal node with a mapped value.
void destroy() noexcept
Destroy all children of this node.
Value * value() noexcept
Return the stored mapped value.
Node * search_child(const char c) noexcept
Search for a mutable child with the given character.
Owning prefix tree map from strings to values.
DynArray< Key > words(const size_t max_word_length=2048) const
Get all keys stored in the map.
size_t count() const noexcept
Return the number of stored key-value pairs.
T Value
Mapped value type stored in terminal nodes.
bool contains(const Key &key) const noexcept
Check whether key is stored.
void ensure_root()
Ensure the root node exists after a move.
Value * find(const Key &key) noexcept
Mutable lookup overload.
Node * find_node(const std::string &word) noexcept
Find the terminal node for word.
Prefix_Tree_Map & operator=(const Prefix_Tree_Map &other)
Replace this map with a deep copy of another map.
bool insert(const Key &key, Value &&value)
Insert key with a moved value if absent.
const Value * find(const Key &key) const noexcept
Look up key.
bool insert(const Key &key, const Value &value)
Insert key with a copied value if absent.
std::string Key
Key type accepted by the map.
Prefix_Tree_Map(Prefix_Tree_Map &&other) noexcept
Move-construct, taking ownership of another map's root.
Prefix_Tree_Map(const Prefix_Tree_Map &other)
Construct a deep copy of another prefix map.
DynArray< Key > words_with_prefix(const Key &prefix, const size_t max_word_length=2048) const
Get all keys with a given prefix.
void insert_or_assign(const Key &key, Value value)
Insert key or overwrite its mapped value.
const Node * find_node(const std::string &word) const noexcept
Find the terminal node for word.
bool insert_impl(const std::string &word, U &&value, const bool assign_if_present=false)
Shared implementation for insert()'s copy/move overloads and for insert_or_assign(): when assign_if_p...
Prefix_Tree_Map()
Construct an empty prefix map.
bool erase(const Key &key) noexcept
Remove key if present.
void clear()
Remove every key-value pair from the map.
static void destroy_root(Node *root) noexcept
Destroy an owned root and all descendants.
size_t size() const noexcept
Return the number of stored key-value pairs.
~Prefix_Tree_Map() noexcept
Destroy the owned root and all descendants.
bool is_empty() const noexcept
Check whether the map has no keys.
Owning prefix tree wrapper.
bool insert_word(const std::string &word)
Insert a word into the tree.
static void destroy_root(Cnode *root) noexcept
Destroy an owned root and all its descendants.
const Cnode * root() const noexcept
Return the const root node.
Prefix_Tree & operator=(const Prefix_Tree &other)
Replace this tree with a deep copy of another tree.
Prefix_Tree()
Construct an empty prefix tree.
DynArray< std::string > words(const size_t max_word_length=2048) const
Get all words stored in the tree.
DynArray< std::string > words_with_prefix(const std::string &prefix, const size_t max_word_length=2048) const
Get all words with a given prefix.
Prefix_Tree(Prefix_Tree &&other)
Move-construct, taking ownership of another tree's contents.
bool mutable_root_exposed_
Prefix_Tree(const Prefix_Tree &other)
Construct a deep copy of another prefix tree.
Cnode * root() noexcept
Return the mutable root node.
~Prefix_Tree() noexcept
Destroy the owned root and all descendants.
size_t count() const noexcept
Count the words stored in the tree.
void swap_state(Prefix_Tree &other) noexcept
Swap internal ownership and cached count state.
bool contains(const std::string &word) const noexcept
Check whether a word exists in the tree.
size_t size() const noexcept
Return the number of words stored in the tree.
Forward declaration used by CRTP helpers before the full node definition.
Tree_Node * get_left_child() const noexcept
Returns the leftmost child of this.
void insert_rightmost_child(Tree_Node *p) noexcept
Inserts p as the rightmost child of this.
void set_is_leaf(bool value) noexcept
Sets the leaf flag.
void for_each_child(Operation &op) const
Visits each child of this and executes the operation on the child node.
Tree_Node * get_right_child() const noexcept
Returns the rightmost child of this.
char & get_key() noexcept
Returns a modifiable reference to the node contents.
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
__gmp_expr< T, __gmp_binary_expr< __gmp_expr< T, U >, unsigned long int, __gmp_root_function > > root(const __gmp_expr< T, U > &expr, unsigned long int l)
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
void destroy_tree(Node *root)
Destroys (frees memory) the tree whose root is root.
Main namespace for Aleph-w library functions.
static void suffix(Node *root, DynList< Node * > &acc)
and
Check uniqueness with explicit hash + equality functors.
std::decay_t< typename HeadC::Item_Type > T
static void prefix(Node *root, DynList< Node * > &acc)
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Lazy and scalable dynamic array implementation.
Alias for htlist.H (DynList implementation).
General tree (n-ary tree) node.