diff --git a/src/node.tcc b/src/node.tcc index b1ca899..24f51c2 100644 --- a/src/node.tcc +++ b/src/node.tcc @@ -8,28 +8,23 @@ using std::array; -/*! - * Leaf. - */ +/*! Leaf. */ struct Leaf { - size_t count = 0; + size_t count {0}; }; -/*! - * Node. - */ +/*! Node. */ template class Node { public: bool isEmpty() const; - array child = {}; - T* leaf = nullptr; + array child {}; + T* leaf {nullptr}; }; -/*! - * Check whether a node neither has any children, nor a leaf. +/*! Check whether a node neither has any children, nor a leaf. * * \return True is the node is empty, false otherwise. */ diff --git a/src/trie.tcc b/src/trie.tcc index 7bf8afd..24dfbde 100644 --- a/src/trie.tcc +++ b/src/trie.tcc @@ -4,102 +4,121 @@ #include "trieFunctions.tcc" -/*! - * Trie. - */ +/*! Trie. */ template class Trie { public: + /*! Constructor. */ Trie(); + + /*! Destructor. */ ~Trie(); + + /*! Add a word. + * + * \param word Word. + * + * \return Leaf. + */ T* add(vector const&) const; + + /*! Remove a word. + * + * \param word Word. + */ void remove(vector const&) const; + + /*! Find a word. + * + * \param word Word. + * + * \return `node` if found, `nullptr` otherwise. + */ Node* find(vector const&) const; + + /*! Traverse. + * + * \return Traversal results. + */ generator> walk() const; + + /*! Hamming. + * + * \param word Word. + * \param distance Maximum distance. + * + * \return Traversal results. + */ generator> hamming(vector const&, int const) const; + + /*! Asymmetric Hamming. + * + * \param word Word. + * \param distance Maximum distance. + * + * \return Traversal results. + */ generator> asymmetricHamming( vector const&, int const) const; + + /*! Levenshtein. + * + * \param word Word. + * \param distance Maximum distance. + * + * \return Traversal results. + */ generator> levenshtein(vector const&, int const) const; + + /*! Asymmetric Levenshtein. + * + * \param word Word. + * \param distance Maximum distance. + * + * \return Traversal results. + */ generator> asymmetricLevenshtein( vector const&, int const) const; private: - Node* root_ = nullptr; + Node* root_ {nullptr}; }; -/*! - * Constructor. - */ template Trie::Trie() { root_ = new Node; } -/*! - * Destructor. - */ template Trie::~Trie() { delete_(root_); } -/*! - * Add a word. - * - * \param word Word. - * - * \return Leaf. - */ template T* Trie::add(vector const& word) const { return add_(root_, word); } -/*! - * Remove a word. - * - * \param word Word. - */ template void Trie::remove(vector const& word) const { remove_(root_, word, 0); } -/*! - * Find a word. - * - * \param word Word. - * - * \return `node` if found, `nullptr` otherwise. - */ template Node* Trie::find( vector const& word) const { return find_(root_, word); } -/*! - * Traverse. - * - * \return Traversal results. - */ template generator> Trie::walk() const { vector path; co_yield walk_(root_, path); } -/*! - * Hamming. - * - * \param word Word. - * \param distance Maximum distance. - * - * \return Traversal results. - */ template generator> Trie::hamming( vector const& word, int const distance) const { @@ -107,14 +126,6 @@ generator> Trie::hamming( co_yield hamming_(root_, word, 0, distance, path); } -/*! - * Asymmetric Hamming. - * - * \param word Word. - * \param distance Maximum distance. - * - * \return Traversal results. - */ template generator> Trie::asymmetricHamming( vector const& word, int const distance) const { @@ -122,14 +133,6 @@ generator> Trie::asymmetricHamming( co_yield hamming_(root_, word, 0, distance, path); } -/*! - * Levenshtein. - * - * \param word Word. - * \param distance Maximum distance. - * - * \return Traversal results. - */ template generator> Trie::levenshtein( vector const& word, int const distance) const { @@ -137,14 +140,6 @@ generator> Trie::levenshtein( co_yield levenshtein_(root_, word, 0, distance, path); } -/*! - * Asymmetric Levenshtein. - * - * \param word Word. - * \param distance Maximum distance. - * - * \return Traversal results. - */ template generator> Trie::asymmetricLevenshtein( vector const& word, int const distance) const { diff --git a/src/trieFunctions.tcc b/src/trieFunctions.tcc index 6c2d842..7fd02ea 100644 --- a/src/trieFunctions.tcc +++ b/src/trieFunctions.tcc @@ -6,9 +6,7 @@ using std::vector; -/*! - * Result. - */ +/*! Result. */ template struct Result { vector path; @@ -16,8 +14,7 @@ struct Result { }; -/* - * Delete a (sub)trie. +/* Delete a (sub)trie. * * \param node Root. */ @@ -34,8 +31,7 @@ void delete_(Node* const node) { delete node; } -/* - * Add a word to a (sub)trie. +/* Add a word to a (sub)trie. * * \param node Root. * \param word Word. @@ -58,8 +54,7 @@ T* add_(Node* node, vector const& word) { return node->leaf; } -/* - * Remove a word from a (sub)trie. +/* Remove a word from a (sub)trie. * * \param node Root. * \param word Word. @@ -87,7 +82,7 @@ bool remove_( return false; } - bool result = remove_(node->child[word[position]], word, position + 1); + bool result {remove_(node->child[word[position]], word, position + 1)}; if (result) { if (node->child[word[position]]->isEmpty()) { delete node->child[word[position]]; @@ -98,8 +93,7 @@ bool remove_( return result; } -/* - * Find a word in a (sub)trie. +/* Find a word in a (sub)trie. * * \param node Root. * \param word Word. @@ -118,8 +112,7 @@ Node* find_( return node; } -/* - * Traverse a (sub)trie. +/* Traverse a (sub)trie. * * \param node Root. * \param path Path. @@ -130,10 +123,10 @@ template generator> walk_( Node const* const node, vector& path) { if (node->leaf) { - Result result = {path, node->leaf}; + Result result {path, node->leaf}; co_yield result; } - for (size_t i = 0; i < alphabetSize; i++) { + for (size_t i {0}; i < alphabetSize; i++) { if (node->child[i]) { path.push_back(i); co_yield walk_(node->child[i], path); @@ -142,8 +135,7 @@ generator> walk_( } } -/* - * Find all words within Hamming distance `distance` of `word`. +/* Find all words within Hamming distance `distance` of `word`. * * \param node Root. * \param word Word. @@ -159,11 +151,11 @@ generator> hamming_( size_t const position, int const distance, vector& path) { if (distance >= 0) { if (position < word.size()) { - uint8_t start = 0; + uint8_t start {0}; if (!full) { start = word[position]; } - for (uint8_t i = start; i < alphabetSize; i++) { + for (uint8_t i {start}; i < alphabetSize; i++) { if (node->child[i]) { path.push_back(i); co_yield hamming_( @@ -174,14 +166,13 @@ generator> hamming_( } } else { - Result result = {path, node->leaf}; + Result result {path, node->leaf}; co_yield result; } } } -/* - * Find all words within Levenshtein distance `distance` of `word`. +/* Find all words within Levenshtein distance `distance` of `word`. * * \tparam full * @@ -202,11 +193,11 @@ generator> levenshtein_( co_yield levenshtein_( node, word, position + 1, distance - 1, path); - uint8_t start = 0; + uint8_t start {0}; if (!full && position < word.size()) { start = word[position]; } - for (uint8_t i = start; i < alphabetSize; i++) { + for (uint8_t i {start}; i < alphabetSize; i++) { if (node->child[i]) { path.push_back(i); @@ -226,7 +217,7 @@ generator> levenshtein_( } if (position >= word.size() && node->leaf) { - Result result = {path, node->leaf}; + Result result {path, node->leaf}; co_yield result; } } diff --git a/tests/test_functions.cc b/tests/test_functions.cc index 6e12911..dbb9bfb 100644 --- a/tests/test_functions.cc +++ b/tests/test_functions.cc @@ -9,7 +9,7 @@ using std::vector; TEST_CASE("Internal remove function", "[remove]") { Trie<4, Leaf> trie; - vector word = {0x00, 0x01, 0x02}; + vector word {0x00, 0x01, 0x02}; trie.add(word); trie.add(word); diff --git a/tests/test_trie.cc b/tests/test_trie.cc index de67230..2adf868 100644 --- a/tests/test_trie.cc +++ b/tests/test_trie.cc @@ -10,54 +10,54 @@ TEST_CASE("Trie", "[find][add]") { Trie<4, Leaf> trie; SECTION("Find non-existent word") { - vector word = {0x00, 0x01, 0x02}; + vector word {0x00, 0x01, 0x02}; REQUIRE(trie.find(word) == NULL); } SECTION("Add word") { - vector word = {0x00, 0x01, 0x02}; - Leaf* leaf = trie.add(word); + vector word {0x00, 0x01, 0x02}; + Leaf* leaf {trie.add(word)}; REQUIRE(leaf != NULL); REQUIRE(leaf->count == 1); SECTION("Find newly added word") { - vector word = {0x00, 0x01, 0x02}; - Node<4, Leaf>* node = trie.find(word); + vector word {0x00, 0x01, 0x02}; + Node<4, Leaf>* node {trie.find(word)}; REQUIRE(node != NULL); REQUIRE(node->leaf->count == 1); } SECTION("Add word again") { - vector word = {0x00, 0x01, 0x02}; - Leaf* leaf = trie.add(word); + vector word {0x00, 0x01, 0x02}; + Leaf* leaf {trie.add(word)}; REQUIRE(leaf->count == 2); SECTION("Find newly added word again") { - vector word = {0x00, 0x01, 0x02}; - Node<4, Leaf>* node = trie.find(word); + vector word {0x00, 0x01, 0x02}; + Node<4, Leaf>* node {trie.find(word)}; REQUIRE(node != NULL); REQUIRE(node->leaf->count == 2); } SECTION("Remove word") { - vector word = {0x00, 0x01, 0x02}; + vector word {0x00, 0x01, 0x02}; trie.remove(word); - Node<4, Leaf>* node = trie.find(word); + Node<4, Leaf>* node {trie.find(word)}; REQUIRE(node != NULL); REQUIRE(node->leaf->count == 1); SECTION("Remove word again") { - vector word = {0x00, 0x01, 0x02}; + vector word {0x00, 0x01, 0x02}; trie.remove(word); - Node<4, Leaf>* node = trie.find(word); + Node<4, Leaf>* node {trie.find(word)}; REQUIRE(node == NULL); SECTION("No prefixes remaining") { - vector prefix = {0x00, 0x01}; + vector prefix {0x00, 0x01}; - Node<4, Leaf>* node = trie.find(prefix); + Node<4, Leaf>* node {trie.find(prefix)}; REQUIRE(node == NULL); prefix = {0x00}; @@ -66,8 +66,8 @@ TEST_CASE("Trie", "[find][add]") { } SECTION("Add word after emptying trie") { - vector word = {0x00, 0x01, 0x02}; - Leaf* leaf = trie.add(word); + vector word {0x00, 0x01, 0x02}; + Leaf* leaf {trie.add(word)}; REQUIRE(leaf != NULL); REQUIRE(leaf->count == 1); } @@ -77,21 +77,21 @@ TEST_CASE("Trie", "[find][add]") { } SECTION("Add multiple words") { - vector> words = { + vector> words { {0x00, 0x01, 0x02}, {0x00, 0x01, 0x03}, {0x00, 0x02, 0x02}, {0x00, 0x02, 0x03}, {0x01, 0x01, 0x02}}; - for (vector word: words) { + for (vector const& word: words) { trie.add(word); REQUIRE(trie.find(word) != NULL); } SECTION("Traverse") { - size_t i = 0; - for (Result result: trie.walk()) { + size_t i {0}; + for (Result const& result: trie.walk()) { REQUIRE(result.leaf->count == 1); REQUIRE(result.path == words[i++]); } @@ -99,27 +99,27 @@ TEST_CASE("Trie", "[find][add]") { } SECTION("Hamming") { - vector word = {0x00, 0x01, 0x03}; - vector> words = { + vector word {0x00, 0x01, 0x03}; + vector> words { {0x00, 0x01, 0x02}, {0x00, 0x01, 0x03}, {0x00, 0x02, 0x03}}; - size_t i = 0; - for (Result result: trie.hamming(word, 1)) { + size_t i {0}; + for (Result const& result: trie.hamming(word, 1)) { REQUIRE(result.path == words[i++]); } REQUIRE(i == words.size()); } SECTION("Asymmetric Hamming") { - vector word = {0x00, 0x01, 0x03}; - vector> words = { + vector word {0x00, 0x01, 0x03}; + vector> words { {0x00, 0x01, 0x03}, {0x00, 0x02, 0x03}}; - size_t i = 0; - for (Result result: trie.asymmetricHamming(word, 1)) { + size_t i {0}; + for (Result const& result: trie.asymmetricHamming(word, 1)) { REQUIRE(result.path == words[i++]); } REQUIRE(i == words.size()); @@ -127,7 +127,7 @@ TEST_CASE("Trie", "[find][add]") { } SECTION("Add multiple words of different length") { - vector> words = { + vector> words { {0x00, 0x00, 0x01, 0x02}, {0x00, 0x00, 0x02}, {0x00, 0x00, 0x03, 0x02}, @@ -138,14 +138,14 @@ TEST_CASE("Trie", "[find][add]") { {0x00, 0x02, 0x02}, {0x00, 0x03}}; - for (vector word: words) { + for (vector const& word: words) { trie.add(word); REQUIRE(trie.find(word) != NULL); } SECTION("Traverse") { - size_t i = 0; - for (Result result: trie.walk()) { + size_t i {0}; + for (Result const& result: trie.walk()) { REQUIRE(result.leaf->count == 1); REQUIRE(result.path == words[i++]); } @@ -153,8 +153,8 @@ TEST_CASE("Trie", "[find][add]") { } SECTION("Levenshtein") { - vector word = {0x00, 0x01, 0x02}; - vector> words = { + vector word {0x00, 0x01, 0x02}; + vector> words { {0x00, 0x02}, {0x00, 0x00, 0x02}, {0x00, 0x00, 0x01, 0x02}, @@ -165,16 +165,16 @@ TEST_CASE("Trie", "[find][add]") { {0x00, 0x02, 0x02}, {0x00, 0x00, 0x01, 0x02}}; - size_t i = 0; - for (Result result: trie.levenshtein(word, 1)) { + size_t i {0}; + for (Result const& result: trie.levenshtein(word, 1)) { REQUIRE(result.path == words[i++]); } REQUIRE(i == words.size()); } SECTION("Asymmetric Levenshtein") { - vector word = {0x00, 0x01, 0x02}; - vector> words = { + vector word {0x00, 0x01, 0x02}; + vector> words { {0x00, 0x02}, {0x00, 0x01}, {0x00, 0x01, 0x02}, @@ -183,8 +183,8 @@ TEST_CASE("Trie", "[find][add]") { {0x00, 0x02, 0x02}, {0x00, 0x00, 0x01, 0x02}}; - size_t i = 0; - for (Result result: trie.asymmetricLevenshtein(word, 1)) { + size_t i {0}; + for (Result const& result: trie.asymmetricLevenshtein(word, 1)) { REQUIRE(result.path == words[i++]); } REQUIRE(i == words.size());