summaryrefslogtreecommitdiff
path: root/include/mercury/kernel/utility.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/mercury/kernel/utility.hpp')
-rw-r--r--include/mercury/kernel/utility.hpp108
1 files changed, 28 insertions, 80 deletions
diff --git a/include/mercury/kernel/utility.hpp b/include/mercury/kernel/utility.hpp
index 1648e67..3edd7d4 100644
--- a/include/mercury/kernel/utility.hpp
+++ b/include/mercury/kernel/utility.hpp
@@ -106,6 +106,18 @@ namespace mercury::kernel::utility {
last = new_last;
}
+ void remove(node *n) {
+ if (n->prev)
+ n->prev->next = n->next;
+ else
+ first = n->next;
+ if (n->next)
+ n->next->prev = n->prev;
+ else
+ last = n->prev;
+ delete n;
+ }
+
};
template <class value_t>
@@ -124,6 +136,14 @@ namespace mercury::kernel::utility {
buffer[i] = copy_from[i];
}
+ vector(const vector<value_t> &other)
+ : buffer(new value_t[other.buffer_len]),
+ buffer_len(other.buffer_len), count(other.count)
+ {
+ for (unsigned i = 0; i < count; ++i)
+ buffer[i] = other.buffer[i];
+ }
+
~vector() {
if (buffer)
delete[] buffer;
@@ -134,6 +154,7 @@ namespace mercury::kernel::utility {
delete[] buffer;
buffer = new value_t[other.buffer_len];
buffer_len = other.buffer_len;
+ count = other.count;
for (unsigned i = 0; i < other.count; ++i)
buffer[i] = other.buffer[i];
return *this;
@@ -185,92 +206,19 @@ namespace mercury::kernel::utility {
++count;
}
- };
-
- typedef vector<char> string;
-
- template <class key_component_t, class value_t>
- struct trie {
-
- typedef vector<key_component_t> key_t;
-
- struct child {
- key_component_t component;
- trie tr;
- };
-
- //really this should be a hashmap or something
- vector<child> children;
-
- trie *try_get_child(const key_component_t &component) const {
- for (unsigned i = 0; i < children.count; ++i)
- if (children.buffer[i].component == component)
- return &children.buffer[i].tr;
- return 0;
- }
-
- std::optional<value_t> value_here;
-
- trie() : children(0) {}
-
- //prefix length is in key components, with the root node having a prefix
- //length of 0. if no prefix of key has a value, then this just returns the
- //root node and sets prefix length to 0.
- const trie &longest_prefix_with_value(
- const key_t &key, unsigned &prefix_length_out
- ) const {
-
- const trie *on = this;
- unsigned with_i = 0;
-
- const trie *longest_found = this;
- prefix_length_out = 0;
-
- while (true) {
- if (with_i == key.count)
- return *longest_found;
- on = on->try_get_child(key.buffer[with_i]);
- if (!on)
- return *longest_found;
- ++with_i;
- if (on->value_here) {
- longest_found = on;
- prefix_length_out = with_i;
- }
- }
-
- }
-
- bool has_key(const key_t &key) {
- const trie *on = this;
- for (unsigned i = 0; i < key.count; ++i) {
- on = on->try_get_child(key.buffer[i]);
- if (!on)
- return false;
- }
- return on->value_here.has_value();
- }
-
- //returns false if this key is already in use.
- bool try_insert(const key_t &key, value_t value) {
- trie *on = this;
- for (unsigned i = 0; i < key.count; ++i) {
- on = on->try_get_child(key.buffer[i]);
- if (!on) {
- child ch;
- ch.component = key.buffer[i];
- on->children.add_end(std::move(ch));
- on = &on->children.buffer[on->children.count - 1].tr;
- }
- }
- if (on->value_here)
+ bool starts_with(const vector<value_t> &other) {
+ if (count < other.count)
return false;
- *on->value_here = value;
+ for (unsigned i = 0; i < other.count; ++i)
+ if (buffer[i] != other.buffer[i])
+ return false;
return true;
}
};
+ typedef vector<char> string;
+
}
#endif