Wordsearch Solver
node.hpp
1 #ifndef TRIE_NODE_HPP
2 #define TRIE_NODE_HPP
3 
4 #include <boost/container/small_vector.hpp>
5 #include <fmt/core.h>
6 #include <fmt/format.h>
7 #include <fmt/ostream.h>
8 // #include "llvm/ADT/SmallVector.h"
9 
10 #include <bitset>
11 #include <cstddef>
12 #include <memory>
13 #include <ostream>
14 #include <string_view>
15 #include <type_traits>
16 #include <vector>
17 
18 namespace trie {
19 
23 class Node {
24 private:
25  // I dislike this. We store a char here but really we're storing a [0, 26)
26  // index. But why store an 8 byte size_t or 4 byte int when a 1 byte char will
27  // do (although due to alignment we save nothing really). Intent? Really need
28  // strong typedefs or equivalent. So much boilerplate to make own simple Index
29  // type though.
30  struct Edge {
31  std::unique_ptr<Node> child;
32  char c;
33  };
34 
35 public:
36  // TODO: try changing this to boost/llvm small_vector and see what difference
37  // using Edges = std::vector<Edge>;
38  using Edges = boost::container::small_vector<Edge, 4>;
39  // using Edges = llvm::SmallVector<Edge, 4>;
40  using EdgesIterator = Edges::const_iterator;
41 
42  Node() = default;
43  Node(bool is_end_of_word);
44 
48  Node* add_char(char c);
49  void set_is_end_of_word(bool is_end_of_word);
50 
51  const Node* test(const char c) const;
52  bool any() const;
53  bool is_end_of_word() const;
54  // PrecedingType preceding() const;
55  friend std::ostream& operator<<(std::ostream& os, const Node& node);
56 
57  // This is here so the owning trie can print nodes and get their children.
58  // Not delighted about it.
59  // Don't want to make the Trie a friend as introduces circular dependency.
60  // Could use Passkey idiom I believe?
61  // Since this is const, leave it for now.
62  const Edges& edges() const;
63 
64 private:
65  Edges edges_;
66  bool is_end_of_word_;
67 };
68 
69 // https://stackoverflow.com/a/18405291/8594193
70 // Assuming the currently used boost::container::small_vector follows
71 // std::vector, this type satisfies the type trait,
72 // std::is_copy_constructible_v even though it's a container of
73 // std::unique_ptr s and therefore clearly should not be copy constructible,
74 // at least now with a defaulted copy constructor
75 // static_assert(std::is_copy_constructible_v<Edges>);
76 // static_assert(std::is_copy_constructible_v<Node>);
77 
78 const Node* search(const Node& node, std::string_view word);
79 
80 } // namespace trie
81 
82 #endif // TRIE_NODE_HPP
A vector of edges to child nodes, sorted by edge child node character value, and a bool indicating wh...
Definition: node.hpp:23
const Node * test(const char c) const
Test if a node has an edge containing the character c.
Definition: node.cpp:68
Node * add_char(char c)
Inserts a child node corresponding to the character c if it doesn't exist, and returns a pointer to t...
Definition: node.cpp:43
namespace trie
Definition: node.hpp:18
Definition: node.hpp:30