Wordsearch Solver
compact_trie.hpp
1 #ifndef COMPACT_TRIE_HPP
2 #define COMPACT_TRIE_HPP
3 
4 #include "wordsearch_solver/compact_trie/node.hpp"
5 
6 #include <fmt/core.h>
7 #include <fmt/format.h>
8 #include <fmt/ostream.h>
9 #include <fmt/ranges.h>
10 
11 #include <range/v3/view/subrange.hpp>
12 
13 #include <algorithm>
14 #include <cstdint>
15 #include <initializer_list>
16 #include <iterator>
17 #include <ostream>
18 #include <string>
19 #include <string_view>
20 #include <tuple>
21 #include <type_traits>
22 #include <utility>
23 #include <vector>
24 
25 // This might ACTUALLY be a case for inheritance what with the CompactTrie being
26 // a Trie?
27 // TODO: test this with const_iterator not a std::tuple, and try a simple user
28 // defined struct/pointer to make trivial type to help the optimiser? Not even
29 // sure if "trivial" means what I think it does anyway, remove this likely..
30 // TODO: maybe look into units library for the ascii/index conversion stuff, as
31 // that has already wasted a significant amount of time with offset stuff
32 // TODO: std::bitset size on this system is 8 bytes, even though it need only be
33 // 4 bytes (26 bits) for lowercase ascii. Could see if writing own node without
34 // std::bitset that is 4 bytes big changes performance due to whole thing being
35 // approx half size (better for cache).
36 
38 namespace compact_trie {
39 
71 class CompactTrie {
72 public:
73  using Nodes = std::vector<Node>;
74  using NodesIterator = std::vector<Node>::const_iterator;
75  using Rows = std::vector<NodesIterator>;
76  using RowsIterator = Rows::const_iterator;
77  using const_iterator = std::tuple<NodesIterator, RowsIterator>;
78  // static_assert(std::is_trivially_copyable_v<const_iterator>);
79 
80  CompactTrie() = default;
81 
82  CompactTrie(CompactTrie&&) = default;
83  CompactTrie& operator=(CompactTrie&&) = default;
84 
85  CompactTrie(const CompactTrie&) = delete;
86  CompactTrie& operator=(const CompactTrie&) = delete;
87 
88  CompactTrie(const std::initializer_list<std::string_view>& words);
89  CompactTrie(const std::initializer_list<std::string>& words);
90  CompactTrie(const std::initializer_list<const char*>& words);
91 
92  template <class Iterator1, class Iterator2>
93  CompactTrie(Iterator1 first, const Iterator2 last);
94 
96  template <class Strings> explicit CompactTrie(Strings&& strings_in);
97 
99  bool contains(std::string_view word) const;
101  bool further(std::string_view word) const;
102 
104  template <class OutputIterator>
105  void contains_further(std::string_view stem, std::string_view suffixes,
106  OutputIterator contains_further_it) const;
107 
108  std::size_t size() const;
109  bool empty() const;
110 
111  friend std::ostream& operator<<(std::ostream& os, const CompactTrie& ct);
112 
113 private:
114  bool contains(std::string_view word, ranges::subrange<NodesIterator> nodes,
115  ranges::subrange<RowsIterator> rows) const;
116 
117  bool further(std::string_view word, ranges::subrange<NodesIterator> nodes,
118  ranges::subrange<RowsIterator> rows) const;
119 
132  CompactTrie::const_iterator
133  search(std::string_view word,
134  ranges::subrange<CompactTrie::NodesIterator> nodes,
135  ranges::subrange<CompactTrie::RowsIterator> rows) const;
136 
137  Nodes nodes_;
138  Rows rows_;
139  std::size_t size_;
140 };
141 
142 } // namespace compact_trie
143 
144 #include "wordsearch_solver/compact_trie/compact_trie.tpp"
145 
146 #endif // COMPACT_TRIE_HPP
Inline contiguous immutable trie.
Definition: compact_trie.hpp:71
bool contains(std::string_view word) const
Check if this dictionary contains word.
Definition: compact_trie.cpp:56
CompactTrie::const_iterator search(std::string_view word, ranges::subrange< CompactTrie::NodesIterator > nodes, ranges::subrange< CompactTrie::RowsIterator > rows) const
Search as far as possible for word.
Definition: compact_trie.cpp:133
void contains_further(std::string_view stem, std::string_view suffixes, OutputIterator contains_further_it) const
For each char in suffix appended to stem, check whether this dictionary contains this word and if it ...
Definition: compact_trie.tpp:70
bool further(std::string_view word) const
Check if this dictionary might contain words with word as a prefix.
Definition: compact_trie.cpp:72
namespace compact_trie
Definition: compact_trie.hpp:38