Skip to content

Commit

Permalink
Some sanitisation.
Browse files Browse the repository at this point in the history
  • Loading branch information
jfjlaros committed Sep 18, 2022
1 parent 359d7d1 commit 8ffbd44
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 76 deletions.
20 changes: 20 additions & 0 deletions LICENSE
@@ -0,0 +1,20 @@
Copyright (c) 2022 Jeroen F.J. Laros

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 change: 0 additions & 1 deletion docs/index.rst
Expand Up @@ -4,7 +4,6 @@
:maxdepth: 2
:caption: Contents:

introduction
install
usage
api
Expand Down
3 changes: 0 additions & 3 deletions docs/introduction.rst

This file was deleted.

2 changes: 1 addition & 1 deletion examples/demo/Makefile
Expand Up @@ -3,7 +3,7 @@ MAIN := test.cc
LIBS :=

CC := g++
CC_ARGS := -O2 -fcoroutines -std=c++20
CC_ARGS := -std=c++20 -Wall -Wextra -pedantic -fcoroutines -O2


OBJS := $(addsuffix .o, $(LIBS))
Expand Down
6 changes: 3 additions & 3 deletions src/node.tcc
Expand Up @@ -22,9 +22,9 @@ template <uint8_t alphabetSize, class T>
class Node {
public:
array<Node*, alphabetSize> child = {};
T* leaf = NULL;
T* leaf = nullptr;

bool isEmpty();
bool isEmpty() const;
};


Expand All @@ -34,7 +34,7 @@ class Node {
* \return True is the node is empty, false otherwise.
*/
template <uint8_t alphabetSize, class T>
bool Node<alphabetSize, T>::isEmpty() {
bool Node<alphabetSize, T>::isEmpty() const {
if (leaf) {
return false;
}
Expand Down
70 changes: 37 additions & 33 deletions src/trie.tcc
Expand Up @@ -9,20 +9,22 @@
*/
template <uint8_t alphabetSize, class T>
class Trie {
public:
Trie();
~Trie();
T* add(vector<uint8_t>&);
void remove(vector<uint8_t>&);
Node<alphabetSize, T>* find(vector<uint8_t>&);
generator<Result<T>> walk();
generator<Result<T>> hamming(vector<uint8_t>&, int);
generator<Result<T>> asymmetricHamming(vector<uint8_t>&, int);
generator<Result<T>> levenshtein(vector<uint8_t>&, int);
generator<Result<T>> asymmetricLevenshtein(vector<uint8_t>&, int);

private:
Node<alphabetSize, T>* _root = NULL;
Node<alphabetSize, T>* root_ = nullptr;

public:
Trie();
~Trie();

T* add(vector<uint8_t> const&) const;
void remove(vector<uint8_t> const&) const;
Node<alphabetSize, T>* find(vector<uint8_t> const&) const;
generator<Result<T>> walk() const;
generator<Result<T>> hamming(vector<uint8_t> const&, int const) const;
generator<Result<T>> asymmetricHamming(
vector<uint8_t> const&, int const) const;
generator<Result<T>> levenshtein(vector<uint8_t> const&, int const) const;
generator<Result<T>> asymmetricLevenshtein(
vector<uint8_t> const&, int const) const;
};


Expand All @@ -31,17 +33,18 @@ class Trie {
*/
template <uint8_t alphabetSize, class T>
Trie<alphabetSize, T>::Trie() {
_root = new Node<alphabetSize, T>;
root_ = new Node<alphabetSize, T>;
}

/*!
* Destructor.
*/
template <uint8_t alphabetSize, class T>
Trie<alphabetSize, T>::~Trie() {
_delete(_root);
delete_(root_);
}


/*!
* Add a word.
*
Expand All @@ -50,8 +53,8 @@ Trie<alphabetSize, T>::~Trie() {
* \return Leaf.
*/
template <uint8_t alphabetSize, class T>
T* Trie<alphabetSize, T>::add(vector<uint8_t>& word) {
return _add(_root, word);
T* Trie<alphabetSize, T>::add(vector<uint8_t> const& word) const {
return add_(root_, word);
}

/*!
Expand All @@ -60,20 +63,21 @@ T* Trie<alphabetSize, T>::add(vector<uint8_t>& word) {
* \param word Word.
*/
template <uint8_t alphabetSize, class T>
void Trie<alphabetSize, T>::remove(vector<uint8_t>& word) {
_remove(_root, word, 0);
void Trie<alphabetSize, T>::remove(vector<uint8_t> const& word) const {
remove_(root_, word, 0);
}

/*!
* Find a word.
*
* \param word Word.
*
* \return `node` if found, `NULL` otherwise.
* \return `node` if found, `nullptr` otherwise.
*/
template <uint8_t alphabetSize, class T>
Node<alphabetSize, T>* Trie<alphabetSize, T>::find(vector<uint8_t>& word) {
return _find(_root, word);
Node<alphabetSize, T>* Trie<alphabetSize, T>::find(
vector<uint8_t> const& word) const {
return find_(root_, word);
}

/*!
Expand All @@ -82,9 +86,9 @@ Node<alphabetSize, T>* Trie<alphabetSize, T>::find(vector<uint8_t>& word) {
* \return Traversal results.
*/
template <uint8_t alphabetSize, class T>
generator<Result<T>> Trie<alphabetSize, T>::walk() {
generator<Result<T>> Trie<alphabetSize, T>::walk() const {
vector<uint8_t> path;
co_yield _walk(_root, path);
co_yield walk_(root_, path);
}

/*!
Expand All @@ -97,9 +101,9 @@ generator<Result<T>> Trie<alphabetSize, T>::walk() {
*/
template <uint8_t alphabetSize, class T>
generator<Result<T>> Trie<alphabetSize, T>::hamming(
vector<uint8_t>& word, int distance) {
vector<uint8_t> const& word, int const distance) const {
vector<uint8_t> path;
co_yield _hamming<alphabetSize, T, true>(_root, word, 0, distance, path);
co_yield hamming_<alphabetSize, T, true>(root_, word, 0, distance, path);
}

/*!
Expand All @@ -112,9 +116,9 @@ generator<Result<T>> Trie<alphabetSize, T>::hamming(
*/
template <uint8_t alphabetSize, class T>
generator<Result<T>> Trie<alphabetSize, T>::asymmetricHamming(
vector<uint8_t>& word, int distance) {
vector<uint8_t> const& word, int const distance) const {
vector<uint8_t> path;
co_yield _hamming<alphabetSize, T, false>(_root, word, 0, distance, path);
co_yield hamming_<alphabetSize, T, false>(root_, word, 0, distance, path);
}

/*!
Expand All @@ -127,9 +131,9 @@ generator<Result<T>> Trie<alphabetSize, T>::asymmetricHamming(
*/
template <uint8_t alphabetSize, class T>
generator<Result<T>> Trie<alphabetSize, T>::levenshtein(
vector<uint8_t>& word, int distance) {
vector<uint8_t> const& word, int const distance) const {
vector<uint8_t> path;
co_yield _levenshtein<alphabetSize, T, true>(_root, word, 0, distance, path);
co_yield levenshtein_<alphabetSize, T, true>(root_, word, 0, distance, path);
}

/*!
Expand All @@ -142,7 +146,7 @@ generator<Result<T>> Trie<alphabetSize, T>::levenshtein(
*/
template <uint8_t alphabetSize, class T>
generator<Result<T>> Trie<alphabetSize, T>::asymmetricLevenshtein(
vector<uint8_t>& word, int distance) {
vector<uint8_t> const& word, int const distance) const {
vector<uint8_t> path;
co_yield _levenshtein<alphabetSize, T, false>(_root, word, 0, distance, path);
co_yield levenshtein_<alphabetSize, T, false>(root_, word, 0, distance, path);
}
57 changes: 29 additions & 28 deletions src/trieFunctions.tcc
Expand Up @@ -22,10 +22,10 @@ struct Result {
* \param node Root.
*/
template <uint8_t alphabetSize, class T>
void _delete(Node<alphabetSize, T>* node) {
for (Node<alphabetSize, T>* child: node->child) {
void delete_(Node<alphabetSize, T>* const node) {
for (Node<alphabetSize, T>* const child: node->child) {
if (child) {
_delete(child);
delete_(child);
}
}
if (node->leaf) {
Expand All @@ -43,8 +43,8 @@ void _delete(Node<alphabetSize, T>* node) {
* \return Leaf.
*/
template <uint8_t alphabetSize, class T>
T* _add(Node<alphabetSize, T>* node, vector<uint8_t>& word) {
for (uint8_t letter: word) {
T* add_(Node<alphabetSize, T>* node, vector<uint8_t> const& word) {
for (uint8_t const& letter: word) {
if (!node->child[letter]) {
node->child[letter] = new Node<alphabetSize, T>;
}
Expand All @@ -68,14 +68,15 @@ T* _add(Node<alphabetSize, T>* node, vector<uint8_t>& word) {
* \return `true` if the last occurrence of `word` is removed.
*/
template <uint8_t alphabetSize, class T>
bool _remove(
Node<alphabetSize, T>* node, vector<uint8_t>& word, size_t position) {
bool remove_(
Node<alphabetSize, T>* const node, vector<uint8_t> const& word,
size_t const position) {
if (position == word.size()) {
if (node->leaf) {
node->leaf->count--;
if (!node->leaf->count) {
delete node->leaf;
node->leaf = NULL;
node->leaf = nullptr;
return true;
}
}
Expand All @@ -86,11 +87,11 @@ 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]];
node->child[word[position]] = NULL;
node->child[word[position]] = nullptr;
}
}

Expand All @@ -103,14 +104,14 @@ bool _remove(
* \param node Root.
* \param word Word.
*
* \return `node` if found, `NULL` otherwise.
* \return `node` if found, `nullptr` otherwise.
*/
template <uint8_t alphabetSize, class T>
Node<alphabetSize, T>* _find(
Node<alphabetSize, T>* node, vector<uint8_t>& word) {
for (uint8_t letter: word) {
Node<alphabetSize, T>* find_(
Node<alphabetSize, T>* node, vector<uint8_t> const& word) {
for (uint8_t const& letter: word) {
if (!node->child[letter]) {
return NULL;
return nullptr;
}
node = node->child[letter];
}
Expand All @@ -126,16 +127,16 @@ Node<alphabetSize, T>* _find(
* \return Traversal results.
*/
template <uint8_t alphabetSize, class T>
generator<Result<T>> _walk(
Node<alphabetSize, T>* node, vector<uint8_t>& path) {
generator<Result<T>> walk_(
Node<alphabetSize, T> const* const node, vector<uint8_t>& path) {
if (node->leaf) {
Result<T> result = {path, node->leaf};
co_yield result;
}
for (size_t i = 0; i < alphabetSize; i++) {
if (node->child[i]) {
path.push_back(i);
co_yield _walk(node->child[i], path);
co_yield walk_(node->child[i], path);
path.pop_back();
}
}
Expand All @@ -153,9 +154,9 @@ generator<Result<T>> _walk(
* \return Traversal results.
*/
template <uint8_t alphabetSize, class T, bool full>
generator<Result<T>> _hamming(
Node<alphabetSize, T>* node, vector<uint8_t>& word, size_t position,
int distance, vector<uint8_t>& path) {
generator<Result<T>> hamming_(
Node<alphabetSize, T> const* const node, vector<uint8_t> const& word,
size_t const position, int const distance, vector<uint8_t>& path) {
if (distance >= 0) {
if (position < word.size()) {
uint8_t start = 0;
Expand All @@ -165,7 +166,7 @@ generator<Result<T>> _hamming(
for (uint8_t i = start; i < alphabetSize; i++) {
if (node->child[i]) {
path.push_back(i);
co_yield _hamming<alphabetSize, T, full>(
co_yield hamming_<alphabetSize, T, full>(
node->child[i], word, position + 1,
distance - (uint8_t)(i != word[position]), path);
path.pop_back();
Expand Down Expand Up @@ -193,12 +194,12 @@ generator<Result<T>> _hamming(
* \return Traversal results.
*/
template <uint8_t alphabetSize, class T, bool full=true>
generator<Result<T>> _levenshtein(
Node<alphabetSize, T>* node, vector<uint8_t>& word, size_t position,
int distance, vector<uint8_t>& path) {
generator<Result<T>> levenshtein_(
Node<alphabetSize, T> const* const node, vector<uint8_t> const& word,
size_t const position, int const distance, vector<uint8_t>& path) {
if (distance >= 0) {
// Deletion.
co_yield _levenshtein<alphabetSize, T, full>(
co_yield levenshtein_<alphabetSize, T, full>(
node, word, position + 1, distance - 1, path);

uint8_t start = 0;
Expand All @@ -211,13 +212,13 @@ generator<Result<T>> _levenshtein(

// Substitution.
if (position < word.size()) {
co_yield _levenshtein<alphabetSize, T, full>(
co_yield levenshtein_<alphabetSize, T, full>(
node->child[i], word, position + 1,
distance - (uint8_t)(i != word[position]), path);
}

// Insertion.
co_yield _levenshtein<alphabetSize, T, full>(
co_yield levenshtein_<alphabetSize, T, full>(
node->child[i], word, position, distance - 1, path);

path.pop_back();
Expand Down
2 changes: 1 addition & 1 deletion tests/Makefile
Expand Up @@ -5,7 +5,7 @@ FIXTURES :=


CC := g++
CC_ARGS := -std=c++20 -fcoroutines -Wno-pmf-conversions
CC_ARGS := -std=c++20 -Wall -Wextra -pedantic -fcoroutines -fno-access-control


OBJS := $(addsuffix .o, $(TESTS) $(FIXTURES))
Expand Down

0 comments on commit 8ffbd44

Please sign in to comment.