Wordsearch Solver
flat_char_value_map.hpp
1 #ifndef UTILITY_FLAT_CHAR_VALUE_MAP_HPP
2 #define UTILITY_FLAT_CHAR_VALUE_MAP_HPP
3 
4 #include <algorithm>
5 #include <cstddef>
6 #include <iostream>
7 #include <optional>
8 #include <string>
9 #include <string_view>
10 #include <utility>
11 #include <vector>
12 
13 namespace utility {
14 
30 template <class Value> class FlatCharValueMap {
31 public:
32  FlatCharValueMap() = default;
33 
34  // Makes little sense to copy a cache from object to another, so just leave
35  // the cache empty
37  FlatCharValueMap& operator=(const FlatCharValueMap&) { this->clear(); }
38 
39  // Move construction and move assignment both leave the cache in a default
40  // constructed state, ie. as if clear() had been called. This is to prevent
41  // potential bugs (if the cached values are pointers or iterators), is simple
42  // to implement and unless the cache is frequently moved (it's not, or not
43  // intended to be at least) will not be a performance issue.
44  // FlatCharValueMap(FlatCharValueMap&&) : FlatCharValueMap() {}
45  // FlatCharValueMap& operator=(FlatCharValueMap&&)
46  // {
47  // this->clear();
48  // }
49 
50  ~FlatCharValueMap() {
51  // std::cout << "FlatCharValueMap hits: " << hits << " vs misses: " <<
52  // misses << " -- hits per miss: " << static_cast<double>(hits) /
53  // static_cast<double>(misses) << "" << std::endl;
54  }
55 
56  using NumbElementsConsumed = std::size_t;
70  inline const Value* lookup(const std::string_view& word,
71  std::size_t& consumed) {
72  const auto numb_elements_consumed = this->lookup_impl(word);
73  // hits += numb_elements_consumed;
74  // misses += word.size() - numb_elements_consumed;
75  keys_.resize(numb_elements_consumed);
76  values_.resize(numb_elements_consumed);
77  if (numb_elements_consumed == 0) {
78  return nullptr;
79  }
80  consumed += numb_elements_consumed;
81  return &values_[numb_elements_consumed - 1];
82  // return {{numb_elements_consumed, values_[numb_elements_consumed - 1]}};
83  }
84 
89  inline void append(const char key, const Value& value) {
90  keys_.push_back(key);
91  values_.push_back(value);
92  }
93 
95  inline void append(const char key, Value&& value) {
96  keys_.push_back(key);
97  values_.push_back(std::move(value));
98  }
99 
101  void clear() {
102  keys_.clear();
103  values_.clear();
104  }
105 
106 private:
115  template <class Str>
116  inline NumbElementsConsumed lookup_impl(const Str& word) const {
117  // No elems consumed if no cached keys or searching for nothing
118  if (keys_.empty() || word.empty())
119  return 0;
120 
121  std::size_t i = 0;
122  // Amazingly, changing from std::min to ternary in gcc takes 30% less time
123  // on google bench
124  const auto shorter =
125  keys_.size() < word.size() ? keys_.size() : word.size();
126  // const auto shorter = std::min(keys_.size(), word.size());
127 
128  // #define CHECK_AND_RETURN(index)
129  // if (keys_[i + index] != word[i + index]) i += index; break;
130 
131  // for (; i + 6 <= shorter; i += 6)
132  // {
133  // CHECK_AND_RETURN(0);
134  // CHECK_AND_RETURN(1);
135  // CHECK_AND_RETURN(2);
136  // CHECK_AND_RETURN(3);
137  // CHECK_AND_RETURN(4);
138  // CHECK_AND_RETURN(5);
139  // }
140  // #undef CHECK_AND_RETURN
141 
142  for (; i < shorter; ++i) {
143  if (keys_[i] != word[i])
144  break;
145  }
146 
147  return i;
148  }
149 
150  std::string keys_;
151  std::vector<Value> values_;
152 
153  mutable std::size_t hits = 0;
154  mutable std::size_t misses = 0;
155 };
156 
157 } // namespace utility
158 
159 #endif // UTILITY_FLAT_CHAR_VALUE_MAP_HPP
A small cache for each character of a word and an associated value, such as iterator into a trie for ...
Definition: flat_char_value_map.hpp:30
void append(const char key, Value &&value)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: flat_char_value_map.hpp:95
const Value * lookup(const std::string_view &word, std::size_t &consumed)
Retrieve the cached value for a word.
Definition: flat_char_value_map.hpp:70
void clear()
Clears the cache.
Definition: flat_char_value_map.hpp:101
void append(const char key, const Value &value)
Add a mapping from a char key to value.
Definition: flat_char_value_map.hpp:89
NumbElementsConsumed lookup_impl(const Str &word) const
Lookup word and return how many letters are found in the cache.
Definition: flat_char_value_map.hpp:116
Utility functions.
Definition: flat_char_value_map.hpp:13