tudocomp
– The TU Dortmund Compression Framework
Registry.hpp
Go to the documentation of this file.
1 #pragma once
2 
5 
7 namespace tdc {
8 
9 template<typename algorithm_t>
10 template<typename T>
12  auto meta = T::meta();
13 
14  ast::Value s = std::move(meta).build_static_args_ast_value();
15 
16  gather_types(m_data->m_algorithms, std::move(meta));
17 
18  auto static_s
19  = eval::pattern_eval(std::move(s), m_root_type, m_data->m_algorithms);
20 
21  CHECK(m_data->m_registered.count(static_s) == 0) << "registered twice"; // Don't register twice...
22  m_data->m_registered[std::move(static_s)] = [](Env&& env) {
23  return std::make_unique<T>(std::move(env));
24  };
25 }
26 
27 template<typename algorithm_t>
28 inline eval::AlgorithmTypes& Registry<algorithm_t>::algorithm_map() {
29  return m_data->m_algorithms;
30 }
31 
32 template<typename algorithm_t>
33 inline const eval::AlgorithmTypes& Registry<algorithm_t>::algorithm_map() const {
34  return m_data->m_algorithms;
35 }
36 
37 template<typename algorithm_t>
38 inline std::vector<pattern::Algorithm> Registry<algorithm_t>::all_algorithms_with_static_internal(
39  std::vector<AlreadySeenPair>& already_seen,
40  View type
41 ) const {
42  std::vector<pattern::Algorithm> r;
43 
44  using AlgorithmArgs = std::vector<pattern::Arg>;
45 
46  for (auto& c : m_data->m_algorithms.at(type)) {
47  std::vector<std::vector<AlgorithmArgs>> args_variations;
48 
49  auto seen = AlreadySeenPair {
50  type, c.name()
51  };
52  //std::cout << "Checking if " << type << ", " << c.name() << "\n";
53  int found = 0;
54  for (auto& x: already_seen) {
55  //std::cout << " " << x.pair[0] << "\n";
56  if (x.pair[0] == type) {
57  found++;
58  }
59  }
60  if (found > 2) {
61  //std::cout << "break\n";
62  continue;
63  }
64 
65  already_seen.push_back(seen);
66 
67  for (auto& arg : c.arguments()) {
68  const std::string& arg_name = arg.name();
69  CHECK(arg_name.size() > 0);
70 
71  auto arg_type = arg.type();
72  bool is_static = arg.is_static();
73  if (is_static) {
74  std::vector<AlgorithmArgs> arg_variations;
75 
76  for(auto arg : all_algorithms_with_static_internal(already_seen, arg_type)) {
77  arg_variations.push_back(AlgorithmArgs {
78  pattern::Arg {
79  std::string(arg_name),
80  std::move(arg)
81  }
82  });
83  }
84  args_variations.push_back(arg_variations);
85  }
86  }
87 
88  already_seen.pop_back();
89 
90  std::string x_name;
91  std::vector<pattern::Arg> x_args;
92 
93  x_name = c.name();
94  std::vector<AlgorithmArgs> r_;
95  if (args_variations.size() == 0) {
96  pattern::Algorithm x {
97  std::move(x_name),
98  std::move(x_args)
99  };
100 
101  r.push_back(x);
102  } else {
103  r_ = cross<AlgorithmArgs>(
104  std::move(args_variations), [](AlgorithmArgs s,
105  AlgorithmArgs& t) {
106  for (auto& e : t) {
107  s.push_back(e);
108  }
109  return s;
110  });
111  }
112 
113  for (auto& elem : r_) {
114  r.push_back(pattern::Algorithm {
115  std::string(c.name()),
116  std::move(elem)
117  });
118  }
119  }
120 
121  return r;
122 }
123 
124 template<typename algorithm_t>
125 inline std::vector<pattern::Algorithm> Registry<algorithm_t>::all_algorithms_with_static(View type) const {
126  std::vector<pattern::Algorithm> filtered_r;
127 
128  std::vector<AlreadySeenPair> already_seen;
129  for (auto x : all_algorithms_with_static_internal(already_seen, type)) {
130  if (m_data->m_registered.count(x) > 0) {
131  filtered_r.push_back(std::move(x));
132  }
133  }
134 
135  return filtered_r;
136 }
137 
138 template<typename algorithm_t>
139 inline std::vector<pattern::Algorithm> Registry<algorithm_t>::check_for_undefined_algorithms() {
140  std::vector<pattern::Algorithm> r;
141  for (auto& s : all_algorithms_with_static(m_root_type)) {
142  if (m_data->m_registered.count(s) == 0) {
143  r.push_back(s);
144  }
145  }
146  return r;
147 }
148 
149 template<typename algorithm_t>
150 inline Registry<algorithm_t> Registry<algorithm_t>::with_all_from(std::function<void(Registry&)> f, const std::string& root_type) {
151  Registry r(root_type);
152  f(r);
153  return r;
154 }
155 
156 template<typename algorithm_t>
157 inline std::string Registry<algorithm_t>::generate_doc_string(const std::string& title) const {
158  auto print = [](std::vector<decl::Algorithm>& x, size_t iden) {
159  std::vector<std::string> cells;
160 
161  for (auto& y : x) {
162  auto spec = y.to_string(true);
163 
164  std::stringstream where;
165  bool first = true;
166  for (auto& z : y.arguments()) {
167  if (first) {
168  where << "\n where ";
169  } else {
170  where << "\n ";
171  }
172  first = false;
173  where << "`" << z.name() << "` is one of [" << z.type() << "],";
174  }
175  auto s = spec + where.str();
176  if (y.arguments().size() > 0) {
177  s = s.substr(0, s.size() - 1);
178  }
179  cells.push_back(s);
180  cells.push_back(y.doc());
181  }
182 
183  return indent_lines(make_table(cells, 2), iden);
184  };
185 
186  std::stringstream ss;
187 
188  ss << " [" << title << "]\n";
189  ss << print(m_data->m_algorithms[m_root_type], 2) << "\n\n";
190 
191  ss << " [Argument types]\n";
192  for (auto& x : m_data->m_algorithms) {
193  if (x.first == m_root_type) {
194  continue;
195  }
196  ss << " [" << x.first << "]\n";
197  ss << print(x.second, 4) << "\n\n";
198  }
199 
200  return ss.str();
201 }
202 
203 template<typename algorithm_t>
204 inline std::unique_ptr<algorithm_t> Registry<algorithm_t>::select_algorithm(const AlgorithmValue& algo) const {
205  auto& static_only_evald_algo = algo.static_selection();
206 
207  if (m_data->m_registered.count(static_only_evald_algo) > 0) {
208  auto env = std::make_shared<EnvRoot>(AlgorithmValue(algo));
209 
210  auto& constructor = m_data->m_registered[static_only_evald_algo];
211 
212  return constructor(Env(env, env->algo_value()));
213  } else {
214  throw std::runtime_error("No implementation found for " + m_root_type + " "
215  + static_only_evald_algo.to_string()
216  );
217  }
218 }
219 
220 template<typename algorithm_t>
221 inline AlgorithmValue Registry<algorithm_t>::parse_algorithm_id(
222  string_ref text) const {
223 
224  ast::Parser p { text };
225  auto parsed_algo = p.parse_value();
226  auto options = eval::cl_eval(std::move(parsed_algo),
227  m_root_type,
228  m_data->m_algorithms);
229 
230  return std::move(options).to_algorithm();
231 }
232 
233 template<typename algorithm_t>
234 inline std::unique_ptr<algorithm_t> Registry<algorithm_t>::select(
235  const std::string& options) const {
236 
237  return select_algorithm(parse_algorithm_id(options));
238 }
239 
240 }
242 
Contains the text compression and encoding framework.
Definition: namespaces.hpp:11
View string_ref
Definition: View.hpp:26
std::string make_table(const std::vector< std::string > &data, size_t cols, bool draw_grid=true)
Renders the given dataset into an ASCII table.
void register_algorithm()
Registers an tdc::Algorithm.
uint64_t m_data
Definition: uint_t.hpp:30
std::string indent_lines(const std::string &s, size_t indent)
Indents each line of a string (separated by \n) by the specified amount of spaces.
eval::AlgorithmTypes & algorithm_map()
ByteView View
Definition: View.hpp:25
Automatically select compress mode, internal use in TextDS only.