36#include <gtest/gtest.h>
54 std::vector<std::string>
sorted(std::vector<std::string> v)
56 std::sort(v.begin(), v.end());
62 std::vector<std::string> v;
63 for (
const auto &s : a)
70 std::vector<std::string> v;
71 a.
for_each([&v](
const std::string &s) { v.push_back(s); });
77 static bool should_throw;
80 explicit Throwing_Copy(
int v) :
value(v) {}
84 throw std::runtime_error(
"Throwing_Copy: copy failed");
86 Throwing_Copy(Throwing_Copy &&) =
default;
87 Throwing_Copy &operator=(
const Throwing_Copy &) =
default;
88 Throwing_Copy &operator=(Throwing_Copy &&) =
default;
91 bool Throwing_Copy::should_throw =
false;
210 std::vector<std::pair<std::string, int>>{
211 {
"romane", 1}, {
"romanus", 2}, {
"romulus", 3}, {
"rubens", 4},
212 {
"ruber", 5}, {
"rubicon", 6}, {
"rubicundus", 7}})
339 {
"romane",
"romanus",
"romulus",
"rubens",
"ruber",
"rubicon"})
343 sorted({
"romane",
"romanus",
"romulus"}));
345 sorted({
"rubens",
"ruber",
"rubicon"}));
347 sorted({
"romane",
"romanus",
"romulus",
"rubens",
"ruber",
370 sorted({
"roman",
"romane"}));
400 target = std::move(source);
468 t.
insert(
"a", Throwing_Copy(1));
471 Throwing_Copy::should_throw =
true;
472 const Throwing_Copy
value(2);
474 Throwing_Copy::should_throw =
false;
496 Throwing_Copy::should_throw =
true;
497 const Throwing_Copy
value(2);
499 Throwing_Copy::should_throw =
false;
520 Throwing_Copy::should_throw =
true;
521 const Throwing_Copy
value(2);
523 Throwing_Copy::should_throw =
false;
536 std::mt19937
rng(0xC0FFEEu);
537 std::uniform_int_distribution<int>
op_dist(0, 2);
539 std::uniform_int_distribution<int>
char_dist(
'a',
'd');
543 std::uniform_int_distribution<int>
value_dist(0, 1'000'000);
546 std::map<std::string, int> reference;
552 for (
int i = 0; i < len; ++i)
567 reference.emplace(key,
value).second;
569 <<
"insert(\"" << key <<
"\") disagreement at iter " <<
iter;
576 <<
"erase(\"" << key <<
"\") disagreement at iter " <<
iter;
583 <<
"find(\"" << key <<
"\") presence disagreement at iter "
587 <<
"find(\"" << key <<
"\") value disagreement at iter "
592 <<
"size disagreement at iter " <<
iter;
594 <<
"structural invariant violation at iter " <<
iter;
599 for (
const auto & [key,
value] : reference)
601 const int * found =
subject.find(key);
602 ASSERT_NE(found,
nullptr) <<
"missing key in final check: " << key;
603 EXPECT_EQ(*found,
value) <<
"value mismatch in final check: " << key;
609 std::mt19937
rng(0xBADC0FFEu);
611 std::uniform_int_distribution<int>
char_dist(
'a',
'c');
616 std::set<std::string> reference;
621 for (
int i = 0; i < len; ++i)
626 for (
int i = 0; i < 500; ++i)
630 reference.insert(key);
632 <<
"structural invariant violation after inserting: " << key;
635 for (
int i = 0; i < 200; ++i)
640 for (
const auto & key : reference)
646 <<
"prefix query disagreement for prefix: \"" <<
prefix <<
"\"";
663 std::mt19937
rng(0xFACEFEEDu);
665 std::uniform_int_distribution<int>
char_dist(
'a',
'e');
684 for (
int i = 0; i < len; ++i)
695 <<
"insert(\"" <<
word <<
"\") disagreement at iter " <<
iter;
697 <<
"count disagreement at iter " <<
iter;
699 <<
"structural invariant violation at iter " <<
iter;
703 for (
int i = 0; i < 1000; ++i)
707 <<
"contains(\"" <<
word <<
"\") disagreement for: " <<
word;
716 for (
int i = 0; i < 300; ++i)
723 <<
"prefix query disagreement for prefix: \"" <<
prefix <<
"\"";
static string random_string(std::mt19937 &rng, size_t len)
size_t size_t int32_t value
Simple dynamic array with automatic resizing and functional operations.
Owning prefix tree wrapper.
bool insert_word(const std::string &word)
Insert a word into the 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.
size_t count() const noexcept
Count the words stored in the tree.
bool contains(const std::string &word) const noexcept
Check whether a word exists in the tree.
Compressed prefix tree mapping std::basic_string<Char> keys to values of type T.
bool is_empty() const noexcept
Check whether the tree holds no keys.
const T * find(const Key &key) const noexcept
Look up key.
bool insert(const Key &key, const T &value)
Insert key with a copy of value, only if key is absent.
size_t size() const noexcept
Return the number of keys currently stored.
bool verify() const
Recursively verify the tree's structural invariants.
std::optional< Key > longest_prefix(const Key &key) const
Find the longest stored key that is a prefix of key.
void insert_or_assign(const Key &key, T value)
Insert key with value, or overwrite the existing value if key is already present.
bool contains(const Key &key) const noexcept
Check whether key is present.
Array< Key > keys_with_prefix(const Key &prefix) const
Return every stored key that starts with prefix.
bool erase(const Key &key)
Remove key if present, merging any resulting single-child, valueless node back into a compressed edge...
Minimal std::expected-style result type for C++20.
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Main namespace for Aleph-w library functions.
static void prefix(Node *root, DynList< Node * > &acc)
std::vector< typename C::Item_Type > to_vector(const C &c)
Convert a container to a std::vector.
Trie (prefix tree) implementation.
Compressed prefix tree (Aleph::RadixTree) mapping string keys to values.