#ifndef TRIE_TRIE_HPP #define TRIE_TRIE_HPP #include #include #include template class Trie { public: Trie() : node{nullptr}, size{0} { } Trie(const Trie &rhs) : node(rhs.node ? new Node(*rhs.node) : nullptr), size{rhs.size} { } Trie(Trie &&trie) : Trie() { swap(*this, trie); } friend void swap(Trie &lhs, Trie &rhs) { using std::swap; swap(lhs.node, rhs.node); swap(lhs.size, rhs.size); } ~Trie() { delete node; } Trie & operator=(Trie rhs) { swap(*this, rhs); return *this; } Trie & insert(const std::string &key, const Object &obj) { recursive_insert(node, key.c_str(), obj); return *this; } std::size_t get_size() const { return size; } template const Trie & visit(const std::string &key, const Visitor &visitor) const { recursive_visit(node, key.c_str(), visitor); return *this; } private: struct Node { Node(const Object *value= nullptr) : node{}, object{nullptr} { if (value) { object = new Object(*value); } } Node(const Node &rhs) : object{nullptr} { if (rhs.object) { object = new Object(*rhs.object); } for (std::size_t i=0; inode[key], c+1, value); } else { if (root->object) { delete root->object; } else { ++size; } root->object = new Object(value); } } template void recursive_visit(Node *root, const char *c, const Visitor &visitor) const { if (!root) { return; } if (c && *c) { std::size_t key = Key::map(*c); recursive_visit(root->node[key], c+1, visitor); } else { if (root->object) { visitor(*root->object); } for (std::size_t i=0; inode[i], nullptr, visitor); } } } Node *node; std::size_t size; }; #endif // TRIE_TRIE_HPP