tudocomp
– The TU Dortmund Compression Framework
Meta.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <functional>
4 #include <memory>
5 
8 #include <tudocomp/io.hpp>
9 #include <tudocomp/util.hpp>
10 
11 namespace tdc {
12 
13 class Meta;
14 
16 inline void gather_types(eval::AlgorithmTypes& target, std::vector<Meta>&& metas);
18 
34 class Meta {
35  std::string m_type;
36  std::string m_name;
37  std::string m_docs;
39 
40  std::vector<decl::Arg> m_options;
41 
42  ast::Value m_static_args;
43 
44  std::vector<Meta> m_sub_metas;
45 
46  inline void check_arg(const std::string& argument_name) {
47  for (auto& e : m_options) {
48  if (e.name() == argument_name) {
49  throw std::runtime_error("argument already defined");
50  }
51  }
52  }
53 
54  friend inline void gather_types(eval::AlgorithmTypes& target,
55  Meta&& meta);
56 public:
57 
66  inline Meta(const std::string& type,
67  const std::string& name,
68  const std::string& doc = ""):
69  m_type(type),
70  m_name(name),
71  m_docs(doc),
72  m_ds_flags(),
73  m_static_args(ast::Value(std::string(name), {}))
74  {
75  }
76 
79  class OptionBuilder {
80  Meta& m_meta;
81  std::string m_argument_name;
82  public:
83 
85  OptionBuilder(Meta& meta, const std::string& argument_name):
86  m_meta(meta), m_argument_name(argument_name) {}
87 
92  template<class T>
93  inline void templated(const std::string& accepted_type) {
94  (void) accepted_type; // TODO: Actual use this parameter
95 
96  m_meta.check_arg(m_argument_name);
97  Meta sub_meta = T::meta();
98  m_meta.m_sub_metas.push_back(sub_meta);
99 
100  auto type = std::move(sub_meta.m_type);
101 
102  m_meta.m_static_args.invokation_arguments().push_back(ast::Arg(
103  std::string(m_argument_name),
104  std::move(sub_meta).build_static_args_ast_value()
105  ));
106 
107  m_meta.m_options.push_back(decl::Arg(
108  std::string(m_argument_name),
109  true,
110  std::move(type)
111  ));
112  }
113 
125  template<class T, class D>
126  inline void templated(const std::string& accepted_type) {
127  templated<T>(accepted_type);
128 
129  std::string t_type = m_meta.m_options.back().type();
130  m_meta.m_options.pop_back();
131 
132  Meta sub_meta = D::meta();
133  std::string d_type = sub_meta.m_type;
134  m_meta.m_sub_metas.push_back(sub_meta);
135 
136  DCHECK_EQ(t_type, d_type);
137 
138  m_meta.m_options.push_back(decl::Arg(
139  std::string(m_argument_name),
140  true,
141  std::move(sub_meta.m_type),
142  std::move(sub_meta).build_ast_value_for_default()
143  ));
144  }
145 
150  inline void dynamic() {
151  m_meta.check_arg(m_argument_name);
152  m_meta.m_options.push_back(decl::Arg(
153  std::string(m_argument_name),
154  false,
155  "string"
156  ));
157  }
158 
162  inline void dynamic(const std::string& default_value) {
163  m_meta.check_arg(m_argument_name);
164  m_meta.m_options.push_back(decl::Arg(
165  std::string(m_argument_name),
166  false,
167  "string",
168  ast::Value(std::string(default_value))
169  ));
170  }
171 
173  //yes, this is necessary
174  inline void dynamic(const char* default_value) {
175  dynamic(std::string(default_value));
176  }
178 
182  inline void dynamic(bool default_value) {
183  dynamic(default_value ? "true" : "false");
184  }
185 
189  inline void dynamic(int default_value) { dynamic(to_str(default_value)); }
190 
194  inline void dynamic(float default_value) { dynamic(to_str(default_value)); }
195 
199  inline void dynamic(double default_value) { dynamic(to_str(default_value)); }
200 
203  inline void dynamic_compressor() {
204  m_meta.check_arg(m_argument_name);
205  m_meta.m_options.push_back(decl::Arg(
206  std::string(m_argument_name),
207  false,
208  "compressor"
209  ));
210  }
211  };
212 
216  inline OptionBuilder option(const std::string& name) {
217  return OptionBuilder(*this, name);
218  }
219 
221 
222  inline decl::Algorithm build_def() && {
223  return decl::Algorithm(
224  std::move(m_name),
225  std::move(m_options),
226  std::move(m_docs),
227  m_ds_flags
228  );
229  }
230 
231  inline ast::Value build_ast_value_for_default() && {
232  std::vector<ast::Arg> options;
233  for (auto& arg : m_options) {
234  options.push_back(ast::Arg(
235  arg.name(),
236  std::move(arg.default_value())
237  ));
238  }
239 
240  return ast::Value(std::move(m_name), std::move(options));
241  }
242 
243  inline ast::Value build_static_args_ast_value() && {
244  return std::move(m_static_args);
245  }
246 
248 
251  inline const std::string& name() const {
252  return m_name;
253  }
254 
257  inline const std::string& type() const {
258  return m_type;
259  }
260 
262  inline void input_restrictions(const io::InputRestrictions& restr) {
263  m_ds_flags |= restr;
264  }
265 
272  m_ds_flags |= io::InputRestrictions({ 0 }, true);
273  }
274 
276  template<typename text_t>
277  inline void uses_textds(ds::dsflags_t flags) {
278  io::InputRestrictions existing = m_ds_flags;
279  ds::InputRestrictionsAndFlags r(text_t::common_restrictions(flags) | existing,
280  flags);
281  m_ds_flags = r;
282  }
283 
285  inline ds::InputRestrictionsAndFlags textds_flags() {
286  return m_ds_flags;
287  }
289 };
290 
292 inline void gather_types(eval::AlgorithmTypes& target,
293  Meta&& meta)
294 {
295  // get vector for the current type
296  auto& target_type_algos = target[meta.type()];
297 
298  // Create decl::Algorithm value here
299 
300  auto decl_value = std::move(meta).build_def();
301 
302  bool found = false;
303  for (auto& already_seen_algo : target_type_algos) {
304  if (already_seen_algo.name() == decl_value.name()) {
305  if (already_seen_algo != decl_value) {
306  std::stringstream ss;
307  ss << "Attempting to register the same algorithm twice";
308  ss << " with differing details:";
309  ss << " new: " << decl_value;
310  ss << " existing: " << already_seen_algo;
311  throw std::runtime_error(ss.str());
312  }
313 
314  found = true;
315  break;
316  }
317  }
318 
319  if (!found) {
320  target_type_algos.push_back(std::move(decl_value));
321  }
322 
323  gather_types(target, std::move(meta.m_sub_metas));
324 }
325 
326 inline void gather_types(eval::AlgorithmTypes& target,
327  std::vector<Meta>&& metas)
328 {
329  for (auto& meta : metas) {
330  gather_types(target, std::move(meta));
331  }
332 }
334 
335 }
336 
Contains the text compression and encoding framework.
Definition: namespaces.hpp:11
Provides meta information about an Algorithm.
Definition: Meta.hpp:34
std::string to_str(const T &v)
Represent a value as a string.
const std::string & type() const
Returns the algorithm&#39;s type.
Definition: Meta.hpp:257
OptionBuilder(Meta &meta, const std::string &argument_name)
Constructor. Do not use, construct via Meta::option instead.
Definition: Meta.hpp:85
Meta(const std::string &type, const std::string &name, const std::string &doc="")
Constructs an algorithm meta object with the given information.
Definition: Meta.hpp:66
unsigned int dsflags_t
Definition: TextDSFlags.hpp:8
const std::string & name() const
Returns the algorithm&#39;s name.
Definition: Meta.hpp:251
Describes a set of restrictions placed on input data.
void dynamic(float default_value)
Declares that this option accepts values of a simple type that can be parsed from a string (e...
Definition: Meta.hpp:194
void input_restrictions(const io::InputRestrictions &restr)
Places byte restrictions on the Input.
Definition: Meta.hpp:262
void uses_textds(ds::dsflags_t flags)
Indicates that this Algorithm uses the TextDS class, and how it does.
Definition: Meta.hpp:277
void needs_sentinel_terminator()
Indicates that this Algorithm requires a null terminator symbol in Input.
Definition: Meta.hpp:271
void dynamic(double default_value)
Declares that this option accepts values of a simple type that can be parsed from a string (e...
Definition: Meta.hpp:199
void dynamic_compressor()
Declares that this option accepts values of a arbitrary Compressor type, dispatched at runtime...
Definition: Meta.hpp:203
void templated(const std::string &accepted_type)
Declares that this option accepts values of the specified Algorithm type T.
Definition: Meta.hpp:126
void dynamic(int default_value)
Declares that this option accepts values of a simple type that can be parsed from a string (e...
Definition: Meta.hpp:189
friend void gather_types(eval::AlgorithmTypes &target, Meta &&meta)
void templated(const std::string &accepted_type)
Declares that this option accepts values of the specified Algorithm type T.
Definition: Meta.hpp:93
void dynamic(const std::string &default_value)
Declares that this option accepts values of a simple type that can be parsed from a string (e...
Definition: Meta.hpp:162
void dynamic(bool default_value)
Declares that this option accepts values of a simple type that can be parsed from a string (e...
Definition: Meta.hpp:182
OptionBuilder option(const std::string &name)
Declares an accepted option for this algorithm.
Definition: Meta.hpp:216
Helper for declaring accepted options in algorithm meta information.
Definition: Meta.hpp:79
void dynamic()
Declares that this option accepts values of a simple type that can be parsed from a string (e...
Definition: Meta.hpp:150