CASM  1.1.0
A Clusters Approach to Statistical Mechanics
DataFormatterTools.hh
Go to the documentation of this file.
1 #ifndef CASM_DataFormatterTools
2 #define CASM_DataFormatterTools
3 #include <boost/algorithm/string.hpp>
4 #include <boost/regex.hpp>
5 #include <iterator>
6 #include <numeric>
7 
11 #include "casm/misc/CASM_TMP.hh"
12 
13 namespace CASM {
14 
15 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 
29 template <typename ValueType, typename ArgType, typename DataObject>
30 class DataFormatterOperator : public BaseDatumFormatter<DataObject> {
31  public:
33  using Evaluator = std::function<ValueType(const std::vector<ArgType> &)>;
34  // validator probably not necessary?
35  // using Validator = std::function<bool(const DataObject &)>;
36 
37  DataFormatterOperator(const std::string &_init_name, const std::string &_desc,
38  Evaluator evaluator)
39  : BaseDatumFormatter<DataObject>(_init_name, _desc),
40  m_evaluate(evaluator) {}
41 
42  std::unique_ptr<DataFormatterOperator> clone() const {
43  return std::unique_ptr<DataFormatterOperator>(this->_clone());
44  }
45 
46  DatumFormatterClass type() const override {
48  }
49 
50  std::string short_header(const DataObject &_template_obj) const override;
51 
52  bool validate(const DataObject &_data_obj) const override {
53  return m_arg_formatter.validate(_data_obj);
54  }
55 
56  bool parse_args(const std::string &_args) override;
57 
58  void inject(const DataObject &_data_obj, DataStream &_stream,
59  Index pass_index) const override {
60  if (!validate(_data_obj)) {
61  _stream << DataStream::failbit << ValueType();
62  } else {
63  _stream << _evaluate(_data_obj);
64  }
65  }
66 
67  void print(const DataObject &_data_obj, std::ostream &_stream,
68  Index pass_index) const override {
69  _stream.flags(std::ios::showpoint | std::ios::fixed | std::ios::right);
70  _stream.precision(8);
71  if (validate(_data_obj))
72  _stream << _evaluate(_data_obj);
73  else
74  _stream << "unknown";
75  }
76 
77  jsonParser &to_json(const DataObject &_data_obj,
78  jsonParser &json) const override {
79  if (validate(_data_obj)) json = _evaluate(_data_obj);
80  return json;
81  }
82 
83  protected:
84  ValueType _evaluate(const DataObject &_data_obj) const {
85  VectorDataStream<ArgType> vec_stream;
86  vec_stream << m_arg_formatter(_data_obj);
87  return m_evaluate(vec_stream.vector());
88  }
89 
90  private:
91  DataFormatterOperator *_clone() const override {
92  return new DataFormatterOperator(*this);
93  }
94 
97 };
98 
103 template <typename DataObject>
106  "add", "Add two or more numbers",
107  [](const std::vector<double> &vec) -> double {
108  return std::accumulate(vec.cbegin(), vec.cend(), 0.0);
109  });
110 }
111 
116 template <typename DataObject>
119  "sub", "Subtract two numbers",
120  [](const std::vector<double> &vec) -> double {
121  if (vec.size() != 2)
122  throw std::runtime_error(
123  "Subtraction operator must receive exactly two values!");
124  return vec[0] - vec[1];
125  });
126 }
127 
133 template <typename DataObject>
136  "mult", "Multiply two or more numbers",
137  [](const std::vector<double> &vec) -> double {
138  return std::accumulate(
139  vec.cbegin(), vec.cend(), 1.0,
140  [](double a, double b) -> double { return a * b; });
141  });
142 }
143 
148 template <typename DataObject>
151  "div", "Divide two numbers",
152  [](const std::vector<double> &vec) -> double {
153  if (vec.size() != 2)
154  throw std::runtime_error(
155  "Division operator must receive exactly two values!");
156  return vec[0] / vec[1];
157  });
158 }
159 
165 template <typename DataObject>
168  "rms", "Root mean square of 0 or more numerical values",
169  [](const std::vector<double> &vec) -> double {
170  return sqrt(std::accumulate(
171  vec.cbegin(), vec.cend(), 0.0,
172  [](double a, double b) -> double { return a + b * b; }));
173  });
174 }
175 
181 template <typename DataObject>
184  "pnorm",
185  "Vector p-norm of zero or more elements Ex: 'pnorm(p, elem1, elem2)' "
186  "evaluates (elem1^p+elem2^p)^(1/p)",
187  [](const std::vector<double> &vec) -> double {
188  if (vec.empty())
189  throw std::runtime_error(
190  "pnorm query operator must receive at least one value!");
191  double p = vec[0];
192  return pow(std::accumulate(++vec.cbegin(), vec.cend(), 0.0,
193  [p](double a, double b) -> double {
194  return a + pow(b, p);
195  }),
196  (1 / p));
197  });
198 }
199 
205 template <typename DataObject>
208  "max", "Max value of two or more numbers",
209  [](const std::vector<double> &vec) -> double {
210  return (*std::max_element(vec.cbegin(), vec.cend()));
211  });
212 }
213 
219 template <typename DataObject>
222  "min", "Min value of two or more numbers",
223  [](const std::vector<double> &vec) -> double {
224  return (*std::min_element(vec.cbegin(), vec.cend()));
225  });
226 }
227 
233 template <typename DataObject>
236  "imax", "Index (from 0) of max value in array of two or more numbers",
237  [](const std::vector<double> &vec) -> long {
238  auto it = std::max_element(vec.cbegin(), vec.cend());
239  return std::distance(vec.cbegin(), it);
240  });
241 }
242 
248 template <typename DataObject>
251  "imin", "Index (from 0) of min value in array of two or more numbers",
252  [](const std::vector<double> &vec) -> long {
253  auto it = std::min_element(vec.cbegin(), vec.cend());
254  return std::distance(vec.cbegin(), it);
255  });
256 }
257 
263 template <typename DataObject>
266  "exp", "Exponential function",
267  [](const std::vector<double> &vec) -> double {
268  if (vec.size() != 1)
269  throw std::runtime_error(
270  "Exponent operator must receive exactly one value!");
271  return exp(vec[0]);
272  });
273 }
274 
282 template <typename DataObject>
285  "re",
286  "Check if string matches regular expression. Ex: "
287  "re('input_string','regex_pattern')",
288  [](const std::vector<std::string> &vec) -> bool {
289  if (vec.size() != 2)
290  throw std::runtime_error(
291  "Operator re('input_string','regex_pattern') must receive "
292  "exactly 2 values!");
293  boost::regex e(boost::trim_copy_if(vec[1], boost::is_any_of(" '")));
294  return boost::regex_match(vec[0], e);
295  });
296 }
297 
305 template <typename DataObject>
308  "rs",
309  "Check if string contains regular expression. Ex: "
310  "rs('input_string','regex_pattern')",
311  [](const std::vector<std::string> &vec) -> bool {
312  if (vec.size() != 2)
313  throw std::runtime_error(
314  "Operator re('input_string','regex_pattern') must receive "
315  "exactly 2 values!");
316  boost::regex e(boost::trim_copy_if(vec[1], boost::is_any_of(" '")));
317  return boost::regex_search(vec[0], e);
318  });
319 }
320 
325 template <typename DataObject>
328  "sq", "Square of a number", [](const std::vector<double> &vec) -> double {
329  if (vec.size() != 1)
330  throw std::runtime_error(
331  "Square operator must receive exactly one value!");
332  return vec[0] * vec[0];
333  });
334 }
335 
341 template <typename DataObject>
344  "sqrt", "Square root of a number",
345  [](const std::vector<double> &vec) -> double {
346  if (vec.size() != 1)
347  throw std::runtime_error(
348  "Square-root operator must receive exactly one value!");
349  return sqrt(vec[0]);
350  });
351 }
352 
357 template <typename DataObject>
360  "neg", "Negative of a number",
361  [](const std::vector<double> &vec) -> double {
362  if (vec.size() != 1)
363  throw std::runtime_error(
364  "Negation operator must receive exactly one value!");
365  return -vec[0];
366  });
367 }
368 
374 template <typename DataObject>
377  "and", "Boolean AND for sequence of boolean values",
378  [](const std::vector<bool> &vec) -> bool {
379  return std::accumulate(vec.cbegin(), vec.cend(), true,
380  [](bool a, bool b) -> bool { return a && b; });
381  });
382 }
383 
389 template <typename DataObject>
392  "or", "Boolean OR for sequence of boolean values",
393  [](const std::vector<bool> &vec) -> bool {
394  return std::accumulate(vec.cbegin(), vec.cend(), false,
395  [](bool a, bool b) -> bool { return a || b; });
396  });
397 }
398 
404 template <typename DataObject>
407  "xor", "Boolean XOR for for two boolean values",
408  [](const std::vector<bool> &vec) -> bool {
409  if (vec.size() != 2)
410  throw std::runtime_error(
411  "Boolean XOR operator expects exactly two values!");
412  return (vec[0] && !vec[1]) || (!vec[0] && vec[1]);
413  });
414 }
415 
416 template <typename DataObject>
419  "not", "Boolean NOT for a single boolean value",
420  [](const std::vector<bool> &vec) -> bool {
421  if (vec.size() != 1)
422  throw std::runtime_error(
423  "Boolean NOT operator must receive exactly one value!");
424  return !vec[0];
425  });
426 }
427 
432 template <typename DataObject>
435  "eq", "Equality comparison for two values",
436  [](const std::vector<double> &vec) -> bool {
437  if (vec.size() != 2)
438  throw std::runtime_error(
439  "Equality operator must receive exactly two values!");
440  return almost_equal(vec[0], vec[1]);
441  });
442 }
443 
448 template <typename DataObject>
451  "lt", "Less-than comparison for two values",
452  [](const std::vector<double> &vec) -> bool {
453  if (vec.size() != 2)
454  throw std::runtime_error(
455  "Less-than operator must receive exactly two values!");
456  return vec[0] < vec[1];
457  });
458 }
459 
465 template <typename DataObject>
468  "le", "Less-than-or-equal comparison for two values",
469  [](const std::vector<double> &vec) -> bool {
470  if (vec.size() != 2)
471  throw std::runtime_error(
472  "Less-than-or-equal operator must receive exactly two values!");
473  return vec[0] <= vec[1];
474  });
475 }
476 
482 template <typename DataObject>
485  "gt", "Greater-than comparison for two values",
486  [](const std::vector<double> &vec) -> bool {
487  if (vec.size() != 2)
488  throw std::runtime_error(
489  "Greater-than operator must receive exactly two values!");
490  return vec[0] > vec[1];
491  });
492 }
493 
499 template <typename DataObject>
502  "ge", "Greater-than-or-equal comparison for two values",
503  [](const std::vector<double> &vec) -> bool {
504  if (vec.size() != 2)
505  throw std::runtime_error(
506  "Greater-than-or-equal operator must receive exactly two "
507  "values!");
508  return vec[0] >= vec[1];
509  });
510 }
511 
513 template <typename DataObject>
516 
517  dict.insert(
518  format_operator_add<DataObject>(), format_operator_sub<DataObject>(),
519  format_operator_mult<DataObject>(), format_operator_div<DataObject>(),
520  format_operator_exp<DataObject>(), format_operator_sq<DataObject>(),
521  format_operator_sqrt<DataObject>(), format_operator_neg<DataObject>(),
522  format_operator_and<DataObject>(), format_operator_or<DataObject>(),
523  format_operator_not<DataObject>(), format_operator_min<DataObject>(),
524  format_operator_max<DataObject>(), format_operator_imin<DataObject>(),
525  format_operator_imax<DataObject>(), format_operator_eq<DataObject>(),
526  format_operator_lt<DataObject>(), format_operator_le<DataObject>(),
527  format_operator_gt<DataObject>(), format_operator_ge<DataObject>(),
528  format_operator_re<DataObject>(), format_operator_rs<DataObject>());
529 
530  return dict;
531 }
532 
533 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
534 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
535 
541 template <typename DataObject>
542 class DatumFormatterAlias : public BaseDatumFormatter<DataObject> {
543  public:
545 
546  DatumFormatterAlias(const std::string &_name, const std::string &_command,
548  const std::string &_help = "")
550  _name, _help.empty() ? "User-specified alias for '" + _command + "'"
551  : _help) {
553  if (m_format_tags.size() != 1)
554  throw std::runtime_error(
555  "Expression '" + _command +
556  "' is either empty or consists of multiple expressions.\n");
557  m_formatter = _dict.lookup(m_format_tags[0])->clone();
558  }
559 
560  DatumFormatterAlias(const std::string &_name,
561  const BaseDatumFormatter<DataObject> &_rhs,
562  const std::string &_help = "")
564  _name, _help.empty()
565  ? "User-specified alias for '" + _rhs.name() + "'"
566  : _help),
567  m_formatter(_rhs.clone()) {}
568 
569  DatumFormatterClass type() const override {
571  }
572 
573  std::unique_ptr<DatumFormatterAlias> clone() const {
574  return std::unique_ptr<DatumFormatterAlias>(this->_clone());
575  }
576 
577  bool init(const DataObject &_template_obj) const override {
578  return m_formatter->init(_template_obj);
579  }
580 
582  bool validate(const DataObject &_data_obj) const override {
583  return m_formatter->validate(_data_obj);
584  }
585 
589  std::vector<std::string> col_header(
590  const DataObject &_template_obj) const override {
591  std::vector<std::string> _col;
592  CountDataStream tcount;
593  m_formatter->inject(_template_obj, tcount);
594  if (tcount.count() == 1) {
595  _col.push_back(name());
596  return _col;
597  }
598 
599  for (Index i = 0; i < tcount.count(); i++) {
600  std::stringstream t_ss;
601  t_ss << name() << '(' << i << ')';
602  _col.push_back(t_ss.str());
603  }
604 
605  return _col;
606  }
607 
612  std::string short_header(const DataObject &_template_obj) const override {
613  return name();
614  }
615 
619  Index num_passes(const DataObject &_data_obj) const override {
620  return m_formatter->num_passes(_data_obj);
621  }
622 
626  void print(const DataObject &_data_obj, std::ostream &_stream,
627  Index pass_index = 0) const override {
628  m_formatter->print(_data_obj, _stream, pass_index);
629  }
630 
634  void inject(const DataObject &_data_obj, DataStream &_stream,
635  Index pass_index = 0) const override {
636  m_formatter->inject(_data_obj, _stream, pass_index);
637  }
638 
647  jsonParser &to_json(const DataObject &_data_obj,
648  jsonParser &json) const override {
649  return m_formatter->to_json(_data_obj, json);
650  }
658  bool parse_args(const std::string &args) override {
659  if (!m_formatter) {
660  throw std::runtime_error("ERROR: DataFormatterAlias has no formatter");
661  }
662  // Parse the arguments of of the command now. Later, we may want to do
663  // expression substitution
664  // (e.g., "comp_plus = add(comp(a),$1)" where $1 specifies an argument)
665  if (m_subexprs.size() && !m_formatter->parse_args(m_subexprs[0])) {
666  throw std::runtime_error(
667  "Invalid arguments passed to '" + m_format_tags[0] +
668  "'. Cannot accept expression '" + m_subexprs[0] + "'\n");
669  }
670 
671  return args.size() == 0;
672  // return m_formatter->parse_args(args);
673  }
674 
675  private:
679  DatumFormatterAlias *_clone() const override {
680  return new DatumFormatterAlias(*this);
681  }
682 
683  std::vector<std::string> m_format_tags, m_subexprs;
685 };
686 
691 template <typename DataObject>
693  const std::string &_name, const std::string &_command,
695  const std::string &_help = "") {
696  return DatumFormatterAlias<DataObject>(_name, _command, _dict, _help);
697 }
698 
703 template <typename DataObject>
705  const std::string &_name, const BaseDatumFormatter<DataObject> &_inside,
706  const std::string &_help = "") {
707  return DatumFormatterAlias<DataObject>(_name, _inside, _help);
708 }
709 
710 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
711 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
712 
718 template <typename ValueType, typename DataObject>
719 class ConstantValueFormatter : public BaseDatumFormatter<DataObject> {
720  public:
722 
723  ConstantValueFormatter(const std::string &_header, const ValueType &_value,
724  bool _print_json = false)
726  _header, "Constant value that will be printed on each line"),
727  m_value(_value),
728  m_print_json(_print_json) {}
729 
730  std::unique_ptr<ConstantValueFormatter> clone() const {
731  return std::unique_ptr<ConstantValueFormatter>(this->_clone());
732  }
733 
734  void inject(const DataObject &_data_obj, DataStream &_stream,
735  Index pass_index) const override {
736  _stream << m_value;
737  }
738 
739  void print(const DataObject &_data_obj, std::ostream &_stream,
740  Index pass_index) const override {
741  _stream << m_value;
742  }
743 
744  jsonParser &to_json(const DataObject &_data_obj,
745  jsonParser &json) const override {
746  if (m_print_json) json = m_value;
747  return json;
748  }
749 
750  private:
751  ConstantValueFormatter *_clone() const override {
752  return new ConstantValueFormatter(*this);
753  }
754 
755  ValueType m_value;
757 };
758 
759 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
760 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
761 
787 template <typename ValueType, typename DataObject>
788 class BaseValueFormatter : public BaseDatumFormatter<DataObject> {
789  public:
791  BaseValueFormatter(const std::string &_name, const std::string &_desc)
792  : BaseDatumFormatter<DataObject>(_name, _desc) {}
793 
795  virtual ~BaseValueFormatter() {}
796 
797  std::unique_ptr<BaseValueFormatter> clone() const {
798  return std::unique_ptr<BaseValueFormatter>(this->_clone());
799  }
800 
803  virtual ValueType operator()(const DataObject &obj) const {
804  if (!this->validate(obj)) {
805  throw std::runtime_error(std::string("Invalid DataObject in ") +
806  this->name());
807  }
808  return evaluate(obj);
809  }
810 
811  // --- Derived classes require an evaluate member ----
812 
813  virtual ValueType evaluate(const DataObject &obj) const = 0;
814 
815  // --- These methods specialize virtual BaseDatumFormatter<DataObject> methods
816  // ----
817 
821  virtual void inject(const DataObject &_data_obj, DataStream &_stream,
822  Index pass_index = 0) const override {
823  if (!this->validate(_data_obj))
824  _stream << DataStream::failbit << ValueType();
825  else
826  _stream << this->evaluate(_data_obj);
827  }
828 
833  virtual void print(const DataObject &_data_obj, std::ostream &_stream,
834  Index pass_index = 0) const override {
835  _stream.flags(std::ios::showpoint | std::ios::fixed | std::ios::right);
836  _stream.precision(8);
837  if (this->validate(_data_obj))
838  _stream << this->evaluate(_data_obj);
839  else
840  _stream << "unknown";
841  }
842 
847  virtual jsonParser &to_json(const DataObject &_data_obj,
848  jsonParser &json) const override {
849  if (this->validate(_data_obj)) json = this->evaluate(_data_obj);
850  return json;
851  }
852 
853  private:
855  virtual BaseValueFormatter *_clone() const override = 0;
856 };
857 
858 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
859 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
860 
867 template <typename ValueType, typename DataObject>
868 class GenericDatumFormatter : public BaseValueFormatter<ValueType, DataObject> {
869  public:
870  using Evaluator = std::function<ValueType(const DataObject &)>;
871  using Validator = std::function<bool(const DataObject &)>;
872 
881  GenericDatumFormatter(const std::string &_init_name, const std::string &_desc,
882  Evaluator _evaluator,
883  Validator _validator = always_true<DataObject>)
884  : BaseValueFormatter<ValueType, DataObject>(_init_name, _desc),
885  m_evaluate(_evaluator),
886  m_validate(_validator) {}
887 
888  // /// \brief Destructor
889  // virtual ~GenericDatumFormatter() {}
890 
891  // --- Required implementations -----------
892 
895  ValueType evaluate(const DataObject &obj) const override {
896  return m_evaluate(obj);
897  }
898 
900  std::unique_ptr<GenericDatumFormatter> clone() const {
901  return std::unique_ptr<GenericDatumFormatter>(this->_clone());
902  }
903 
904  // --- Specialized implementation -----------
905 
909  bool validate(const DataObject &obj) const override {
910  return m_validate(obj);
911  }
912 
913  private:
915  GenericDatumFormatter *_clone() const override {
916  return new GenericDatumFormatter(*this);
917  }
918 
921 };
922 
923 template <typename DataObject>
926  "name", traits<DataObject>::name + " name",
927  [](const DataObject &obj) -> std::string { return obj.name(); });
928 }
929 
930 template <typename DataObject>
933  "alias", traits<DataObject>::name + " alias (if exists, else \"none\")",
934  [](const DataObject &obj) -> std::string {
935  std::string alias = obj.alias();
936  if (alias.empty()) {
937  return "none";
938  }
939  return alias;
940  });
941 }
942 
943 template <typename DataObject>
946  "alias_or_name",
947  traits<DataObject>::name + " alias (if exists), else name",
948  [](const DataObject &obj) -> std::string {
949  std::string alias = obj.alias();
950  if (alias.empty()) {
951  return obj.name();
952  }
953  return alias;
954  });
955 }
956 
957 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
958 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
959 
1001 template <typename Container, typename DataObject>
1002 class Base1DDatumFormatter : public BaseValueFormatter<Container, DataObject>,
1003  public ContainerTraits<Container> {
1004  public:
1008 
1010  Base1DDatumFormatter(const std::string &_name, const std::string &_desc)
1011  : BaseValueFormatter<Container, DataObject>(_name, _desc) {}
1012 
1015 
1017  std::unique_ptr<Base1DDatumFormatter> clone() const {
1018  return std::unique_ptr<Base1DDatumFormatter>(this->_clone());
1019  }
1020 
1021  // --- These methods specialize virtual BaseValueFormatter<Container,
1022  // DataObject> methods ----
1023 
1025  virtual bool init(const DataObject &_template_obj) const override {
1026  if (_index_rules().size()) return true;
1027 
1028  if (!this->validate(_template_obj)) return false;
1029 
1030  Index size =
1031  ContainerTraits<Container>::size(this->evaluate(_template_obj));
1032  for (Index i = 0; i < size; i++) {
1033  _add_rule(std::vector<Index>({i}));
1034  }
1035  return true;
1036  }
1037 
1041  virtual std::vector<std::string> col_header(
1042  const DataObject &_template_obj) const override {
1043  std::vector<std::string> _col;
1044  auto it(_index_rules().cbegin()), end_it(_index_rules().cend());
1045  Index s = max(8 - int(this->name().size()), 0);
1046  for (; it != end_it; ++it) {
1047  std::stringstream t_ss;
1048  t_ss << std::string(s, ' ') << this->name() << '(' << (*it)[0] << ')';
1049  _col.push_back(t_ss.str());
1050  }
1051  return _col;
1052  }
1053 
1055  virtual bool parse_args(const std::string &args) override {
1057  return true;
1058  }
1059 
1063  virtual void inject(const DataObject &_data_obj, DataStream &_stream,
1064  Index pass_index = 0) const override {
1065  // add_rules to print all elements if not set yet
1066  if (!_index_rules().size()) {
1067  init(_data_obj);
1068  }
1069 
1070  Container val = this->evaluate(_data_obj);
1071  auto it(_index_rules().cbegin()), end_it(_index_rules().cend());
1072  if (!this->validate(_data_obj)) {
1073  _stream << DataStream::failbit;
1074  for (; it != end_it; ++it) {
1075  _stream << ValueType();
1076  }
1077  } else {
1078  for (; it != end_it; ++it) {
1079  _stream << Access::at(val, (*it)[0]);
1080  }
1081  }
1082  }
1083 
1087  virtual void print(const DataObject &_data_obj, std::ostream &_stream,
1088  Index pass_index = 0) const override {
1089  // add_rules to print all elements if not set yet
1090  if (!_index_rules().size()) {
1091  init(_data_obj);
1092  }
1093 
1094  _stream.flags(std::ios::showpoint | std::ios::fixed | std::ios::right);
1095  _stream.precision(8);
1096  bool known = this->validate(_data_obj);
1097  Container val;
1098  if (known) val = this->evaluate(_data_obj);
1099  auto it(_index_rules().cbegin()), end_it(_index_rules().cend());
1100  for (; it != end_it; ++it) {
1101  if (known)
1102  _stream << " " << Access::at(val, (*it)[0]);
1103  else
1104  _stream << " unknown";
1105  }
1106  }
1107 
1108  protected:
1112 
1113  private:
1115  virtual Base1DDatumFormatter *_clone() const override = 0;
1116 };
1117 
1124 template <typename Container, typename DataObject>
1126  : public Base1DDatumFormatter<Container, DataObject> {
1127  public:
1128  typedef std::function<Container(const DataObject &)> Evaluator;
1129  typedef std::function<bool(const DataObject &)> Validator;
1130 
1139  Generic1DDatumFormatter(const std::string &_name, const std::string &_desc,
1140  Evaluator _evaluator,
1141  Validator _validator = always_true<DataObject>)
1142  : Base1DDatumFormatter<Container, DataObject>(_name, _desc),
1143  m_evaluate(_evaluator),
1144  m_validate(_validator) {}
1145 
1146  // --- Required implementations -----------
1147 
1150  Container evaluate(const DataObject &obj) const override {
1151  return m_evaluate(obj);
1152  }
1153 
1155  std::unique_ptr<Generic1DDatumFormatter> clone() const {
1156  return std::unique_ptr<Generic1DDatumFormatter>(this->_clone());
1157  }
1158 
1159  // --- Specialized implementation -----------
1160 
1164  bool validate(const DataObject &obj) const override {
1165  return m_validate(obj);
1166  }
1167 
1168  private:
1170  Generic1DDatumFormatter *_clone() const override {
1171  return new Generic1DDatumFormatter(*this);
1172  }
1173 
1176 };
1177 
1181 template <typename DataObject>
1184 
1185  dict.insert(make_string_dictionary<DataObject>(),
1186  make_boolean_dictionary<DataObject>(),
1187  make_integer_dictionary<DataObject>(),
1188  make_scalar_dictionary<DataObject>(),
1189  make_vectorxi_dictionary<DataObject>(),
1190  make_vectorxd_dictionary<DataObject>(),
1191  make_matrixxd_dictionary<DataObject>(),
1192  make_json_dictionary<DataObject>());
1193 
1194  return dict;
1195 }
1196 
1197 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1198 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1199 
1206 template <typename Container, typename DataObject>
1207 class Base2DDatumFormatter : public BaseValueFormatter<Container, DataObject> {
1208  public:
1213 
1215  Base2DDatumFormatter(const std::string &_name, const std::string &_desc)
1216  : BaseValueFormatter<Container, DataObject>(_name, _desc),
1217  m_current_ptr(nullptr),
1218  m_known(false) {}
1219 
1222 
1224  std::unique_ptr<Base2DDatumFormatter> clone() const {
1225  return std::unique_ptr<Base2DDatumFormatter>(this->_clone());
1226  }
1227 
1228  // --- These methods specialize virtual BaseValueFormatter<Container,
1229  // DataObject> methods ----
1230 
1232  virtual bool init(const DataObject &_template_obj) const override {
1233  _prepare(_template_obj);
1234  return m_known;
1235  }
1236 
1237  virtual Index num_passes(const DataObject &_template_obj) const override {
1238  _prepare(_template_obj);
1239  Index result(0);
1240  if (!m_known)
1241  result = 1;
1242  else if (_index_rules().size() && _index_rules()[0].size()) {
1243  if (valid_index(_index_rules()[0][0].first))
1244  result = _index_rules().size();
1245  else
1247  }
1248 
1249  // std::cout << "Requesting " << result << " passes.\n";
1250  return result;
1251  }
1252 
1256  virtual std::vector<std::string> col_header(
1257  const DataObject &_template_obj) const override {
1258  std::vector<std::string> _col;
1259  init(_template_obj);
1260  if (!_index_rules().size()) return _col;
1261 
1262  Index s = max(8 - int(this->name().size()), 0);
1263 
1264  for (Index j = 0; j < _index_rules()[0].size(); ++j) {
1265  Index a(_index_rules()[0][j].first), b(_index_rules().back()[j].first);
1266  std::stringstream t_ss;
1267  t_ss << std::string(s, ' ') << this->name() << '(';
1268 
1269  if (!valid_index(a)) {
1270  t_ss << ":";
1271  } else if (a == b)
1272  t_ss << a;
1273  else
1274  t_ss << a << ":" << b;
1275  t_ss << ", " << _index_rules()[0][j].second << ')';
1276  _col.push_back(t_ss.str());
1277  }
1278  return _col;
1279  }
1280 
1282  virtual bool parse_args(const std::string &args) override {
1284  return true;
1285  }
1286 
1290  virtual void inject(const DataObject &_data_obj, DataStream &_stream,
1291  Index pass_index = 0) const override {
1292  // add_rules to print all elements if not set yet
1293  _prepare(_data_obj);
1294 
1295  if (!m_known) _stream << DataStream::failbit;
1296 
1297  Index i = pass_index;
1298  Index row = 0;
1299  Index *row_ptr = &row;
1300 
1301  Index rows = _index_rules().size();
1302  Index cols = 0;
1303  if (rows && _index_rules()[0].size()) {
1304  cols = _index_rules()[0].size();
1305  if (m_known) {
1306  if (!valid_index(_index_rules()[0][0].first)) {
1308  row_ptr = &pass_index;
1309  i = 0;
1310  }
1311  }
1312  }
1313  if (i <= _index_rules().size()) {
1314  for (Index j = 0; j < cols; ++j) {
1315  row = _index_rules()[i][j].first;
1316  _stream << (m_known ? Access::at(m_cache, *row_ptr,
1317  _index_rules()[i][j].second)
1318  : ValueType());
1319  }
1320  }
1321  }
1322 
1326  virtual void print(const DataObject &_data_obj, std::ostream &_stream,
1327  Index pass_index = 0) const override {
1328  // add_rules to print all elements if not set yet
1329  _prepare(_data_obj);
1330 
1331  _stream.flags(std::ios::showpoint | std::ios::fixed | std::ios::right);
1332  _stream.precision(8);
1333 
1334  Index i = pass_index;
1335  Index row = 0;
1336  Index *row_ptr = &row;
1337 
1338  Index rows = _index_rules().size();
1339  Index cols = 0;
1340  if (rows && _index_rules()[0].size()) {
1341  cols = _index_rules()[0].size();
1342  if (m_known) {
1343  if (!valid_index(_index_rules()[0][0].first)) {
1345  row_ptr = &pass_index;
1346  i = 0;
1347  }
1348  }
1349  }
1350 
1351  if (i <= _index_rules().size()) {
1352  for (Index j = 0; j < cols; ++j) {
1353  row = _index_rules()[i][j].first;
1354  if (m_known)
1355  _stream << " "
1356  << Access::at(m_cache, *row_ptr, _index_rules()[i][j].second);
1357  else
1358  _stream << " unknown";
1359  }
1360  }
1361  }
1362 
1363  protected:
1365 
1367 
1379  void _parse_index_expression(const std::string &_expr) {
1380  // std::cout << "Parsing index expression: " << _expr << "\n";
1381  auto bounds = index_expression_to_bounds(_expr);
1382  // std::vector<difference_type> ind_begin(bounds.first.rbegin(),
1383  // bounds.first.rend()); std::vector<difference_type>
1384  // ind_end(bounds.second.rbegin(), bounds.second.rend());
1385  if (bounds.first.empty() && bounds.second.empty()) return;
1386 
1387  if (bounds.first.size() != 2 || bounds.second.size() != 2) {
1388  throw std::runtime_error(
1389  "Attempted to initialize 2D DatumFormatter with incompatible index "
1390  "expression: " +
1391  _expr);
1392  }
1393 
1394  Index r = 0;
1395  for (difference_type i = bounds.first[0]; i < bounds.second[0]; ++i, ++r) {
1396  for (difference_type j = bounds.first[1]; j < bounds.second[1]; ++j) {
1397  _add_rule(r, std::make_pair(i, j));
1398  }
1399  }
1400  }
1401 
1402  void _add_rule(Index row, std::pair<Index, Index> const &new_rule) const {
1403  while (m_2D_index_rules.size() < row + 1) m_2D_index_rules.push_back({});
1404 
1405  m_2D_index_rules[row].push_back(new_rule);
1406  }
1407 
1408  const IndexContainer &_index_rules() const { return m_2D_index_rules; }
1409 
1410  void _prepare(DataObject const &_data_obj) const {
1411  if (m_current_ptr != &_data_obj) {
1412  m_current_ptr = &_data_obj;
1413  m_known = this->validate(_data_obj);
1414  if (m_known) {
1415  m_cache = this->evaluate(_data_obj);
1416  }
1417  }
1418 
1419  if (m_known && _index_rules().empty()) {
1420  // std::cout << "creating idices, cache size: " <<
1421  // ContainerTraits<Container>::rows(m_cache) << ", " <<
1422  // ContainerTraits<Container>::cols(m_cache) << "\n"
1423  // << "cache matrix:\n" << m_cache << "\n";
1425  for (Index j = 0; j < cols; j++) {
1426  _add_rule(0, std::make_pair(-1, j));
1427  }
1428  }
1429  }
1430 
1431  private:
1432  mutable DataObject const *m_current_ptr;
1433  mutable bool m_known;
1434  mutable Container m_cache;
1435 
1437  virtual Base2DDatumFormatter *_clone() const override = 0;
1438 };
1439 
1445 template <typename Container, typename DataObject>
1447  : public Base2DDatumFormatter<Container, DataObject> {
1448  public:
1449  typedef std::function<Container(const DataObject &)> Evaluator;
1450  typedef std::function<bool(const DataObject &)> Validator;
1451 
1460  Generic2DDatumFormatter(const std::string &_name, const std::string &_desc,
1461  Evaluator _evaluator,
1462  Validator _validator = always_true<DataObject>)
1463  : Base2DDatumFormatter<Container, DataObject>(_name, _desc),
1464  m_evaluate(_evaluator),
1465  m_validate(_validator) {}
1466 
1467  // --- Required implementations -----------
1468 
1471  Container evaluate(const DataObject &obj) const override {
1472  return m_evaluate(obj);
1473  }
1474 
1476  std::unique_ptr<Generic2DDatumFormatter> clone() const {
1477  return std::unique_ptr<Generic2DDatumFormatter>(this->_clone());
1478  }
1479 
1480  // --- Specialized implementation -----------
1481 
1485  bool validate(const DataObject &obj) const override {
1486  return m_validate(obj);
1487  }
1488 
1489  private:
1491  Generic2DDatumFormatter *_clone() const override {
1492  return new Generic2DDatumFormatter(*this);
1493  }
1494 
1497 };
1498 
1499 template <typename DataObject>
1502 }
1503 
1504 } // namespace CASM
1505 
1506 #endif
std::set< std::string > & s
Abstract base class for creating 1D DatumFormatter.
ContainerTraits< Container >::value_type ValueType
virtual bool init(const DataObject &_template_obj) const override
Default initialization adds rules for each element.
virtual void inject(const DataObject &_data_obj, DataStream &_stream, Index pass_index=0) const override
Default implementation injects each element.
ContainerTraits< Container >::Access Access
Access methods for Container.
virtual ~Base1DDatumFormatter()
Destructor.
std::unique_ptr< Base1DDatumFormatter > clone() const
Clone.
virtual void print(const DataObject &_data_obj, std::ostream &_stream, Index pass_index=0) const override
Default implementation prints each element in a column.
virtual Base1DDatumFormatter * _clone() const override=0
Clone.
virtual std::vector< std::string > col_header(const DataObject &_template_obj) const override
Default col_header uses 'name(index)' for each column.
virtual bool parse_args(const std::string &args) override
Default implementation calls _parse_index_expression.
Base1DDatumFormatter(const std::string &_name, const std::string &_desc)
Constructor.
A DatumFormatter that returns a value of specified 2d container.
const IndexContainer & _index_rules() const
virtual Base2DDatumFormatter * _clone() const override=0
Clone.
Base2DDatumFormatter(const std::string &_name, const std::string &_desc)
Constructor.
virtual bool parse_args(const std::string &args) override
Default implementation calls _parse_index_expression.
virtual bool init(const DataObject &_template_obj) const override
Default initialization adds rules for each element.
virtual void print(const DataObject &_data_obj, std::ostream &_stream, Index pass_index=0) const override
Default implementation prints each element in a column.
multivector< std::pair< Index, Index > >::X< 2 > IndexContainer
std::unique_ptr< Base2DDatumFormatter > clone() const
Clone.
void _prepare(DataObject const &_data_obj) const
virtual void inject(const DataObject &_data_obj, DataStream &_stream, Index pass_index=0) const override
Default implementation injects each element.
virtual std::vector< std::string > col_header(const DataObject &_template_obj) const override
Default col_header uses 'name(index)' for each column.
virtual Index num_passes(const DataObject &_template_obj) const override
virtual ~Base2DDatumFormatter()
Destructor.
void _parse_index_expression(const std::string &_expr)
ContainerTraits< Container >::Access Access
Access methods for Container.
void _add_rule(Index row, std::pair< Index, Index > const &new_rule) const
ContainerTraits< Container >::value_type2D ValueType
Abstract base class from which all other DatumFormatter<DataObject> classes inherit.
void _add_rule(const std::vector< Index > &new_rule) const
void _parse_index_expression(const std::string &_expr)
const IndexContainer & _index_rules() const
const std::string & name() const
Returns a name for the formatter, which becomes the tag used for parsing.
virtual bool validate(const DataObject &_data_obj) const
Returns true if _data_obj has valid values for requested data.
Base class for creating scalar DatumFormatter.
virtual ValueType evaluate(const DataObject &obj) const =0
BaseValueFormatter(const std::string &_name, const std::string &_desc)
Constructor.
virtual void inject(const DataObject &_data_obj, DataStream &_stream, Index pass_index=0) const override
Default implementation injects each element, via operator<<.
std::unique_ptr< BaseValueFormatter > clone() const
virtual ValueType operator()(const DataObject &obj) const
Return requested data from obj, throwing std::runtime_error if not valid.
virtual BaseValueFormatter * _clone() const override=0
Clone.
virtual jsonParser & to_json(const DataObject &_data_obj, jsonParser &json) const override
Default implementation calls jsonParser& to_json(const ValueType&, jsonParser&)
virtual void print(const DataObject &_data_obj, std::ostream &_stream, Index pass_index=0) const override
Default implementation prints each element in a column, via operator<<.
virtual ~BaseValueFormatter()
Destructor.
Prints a string value specified at construction. A header string can also be passed.
ConstantValueFormatter * _clone() const override
Make an exact copy of the formatter (including any initialized members)
void print(const DataObject &_data_obj, std::ostream &_stream, Index pass_index) const override
std::unique_ptr< ConstantValueFormatter > clone() const
void inject(const DataObject &_data_obj, DataStream &_stream, Index pass_index) const override
ConstantValueFormatter(const std::string &_header, const ValueType &_value, bool _print_json=false)
jsonParser & to_json(const DataObject &_data_obj, jsonParser &json) const override
const_iterator lookup(const key_type &_name) const
Equivalent to find, but set 'home' and throws error with suggestion if.
std::pair< iterator, bool > insert(const value_type &value)
Insert single value.
Definition: unique_map.hh:149
bool validate(const DataObject &_obj) const
Returns true if _obj has valid data for all portions of query.
DataFormatters that operate on the results of other DataFormatters.
std::string short_header(const DataObject &_template_obj) const override
Returns a short expression for the formatter parsing the short_header should allow the formatter to b...
void inject(const DataObject &_data_obj, DataStream &_stream, Index pass_index) const override
DatumFormatterClass type() const override
void print(const DataObject &_data_obj, std::ostream &_stream, Index pass_index) const override
bool validate(const DataObject &_data_obj) const override
Returns true if _data_obj has valid values for requested data.
DataFormatterOperator * _clone() const override
Make an exact copy of the formatter (including any initialized members)
bool parse_args(const std::string &_args) override
DataFormatter< DataObject > m_arg_formatter
DataFormatterOperator(const std::string &_init_name, const std::string &_desc, Evaluator evaluator)
std::unique_ptr< DataFormatterOperator > clone() const
std::function< ValueType(const std::vector< ArgType > &)> Evaluator
jsonParser & to_json(const DataObject &_data_obj, jsonParser &json) const override
ValueType _evaluate(const DataObject &_data_obj) const
Implements a DatumFormatter that is an alias for a combination of others.
std::vector< std::string > m_subexprs
std::vector< std::string > m_format_tags
Index num_passes(const DataObject &_data_obj) const override
void inject(const DataObject &_data_obj, DataStream &_stream, Index pass_index=0) const override
DatumFormatterAlias * _clone() const override
Make an exact copy of the formatter (including any initialized members)
notstd::cloneable_ptr< BaseDatumFormatter< DataObject > > m_formatter
std::unique_ptr< DatumFormatterAlias > clone() const
std::vector< std::string > col_header(const DataObject &_template_obj) const override
Returns a std::vector<std::string> with each column header.
DatumFormatterClass type() const override
jsonParser & to_json(const DataObject &_data_obj, jsonParser &json) const override
std::string short_header(const DataObject &_template_obj) const override
Returns a short expression for the formatter parsing the short_header should allow the formatter to b...
bool init(const DataObject &_template_obj) const override
Perform all initialization steps using _template_obj. Returns true if initialization is successful an...
bool parse_args(const std::string &args) override
bool validate(const DataObject &_data_obj) const override
Returns true if _data_obj has valid values for requested data.
void print(const DataObject &_data_obj, std::ostream &_stream, Index pass_index=0) const override
DatumFormatterAlias(const std::string &_name, const BaseDatumFormatter< DataObject > &_rhs, const std::string &_help="")
DatumFormatterAlias(const std::string &_name, const std::string &_command, const DataFormatterDictionary< DataObject > &_dict, const std::string &_help="")
A DatumFormatter that returns a 1D value of specified type, via functions that may be specified at ru...
bool validate(const DataObject &obj) const override
Returns boolean indicating if the _evaluator can be used successfully, the result of the Validator.
std::unique_ptr< Generic1DDatumFormatter > clone() const
Clone using copy constructor.
std::function< bool(const DataObject &)> Validator
std::function< Container(const DataObject &)> Evaluator
Generic1DDatumFormatter * _clone() const override
Clone using copy constructor.
Container evaluate(const DataObject &obj) const override
Returns Container type piece of data about a DataObject, the result of the Evaluator.
Generic1DDatumFormatter(const std::string &_name, const std::string &_desc, Evaluator _evaluator, Validator _validator=always_true< DataObject >)
Constructor.
A DatumFormatter that returns a 2D value of specified type, via functions that may be specified at ru...
std::function< Container(const DataObject &)> Evaluator
Generic2DDatumFormatter(const std::string &_name, const std::string &_desc, Evaluator _evaluator, Validator _validator=always_true< DataObject >)
Constructor.
bool validate(const DataObject &obj) const override
Returns boolean indicating if the _evaluator can be used successfully, the result of the Validator.
std::function< bool(const DataObject &)> Validator
Generic2DDatumFormatter * _clone() const override
Clone using copy constructor.
std::unique_ptr< Generic2DDatumFormatter > clone() const
Clone using copy constructor.
Container evaluate(const DataObject &obj) const override
Returns Container type piece of data about a DataObject, the result of the Evaluator.
A DatumFormatter that returns a value of specified type, via functions that may be specified at runti...
GenericDatumFormatter(const std::string &_init_name, const std::string &_desc, Evaluator _evaluator, Validator _validator=always_true< DataObject >)
Constructor.
bool validate(const DataObject &obj) const override
Returns boolean indicating if the _evaluator can be used successfully, the result of the Validator.
std::unique_ptr< GenericDatumFormatter > clone() const
Clone.
ValueType evaluate(const DataObject &obj) const override
Returns Container type piece of data about a DataObject, the result of the Evaluator.
GenericDatumFormatter * _clone() const override
Clone.
std::function< bool(const DataObject &)> Validator
std::function< ValueType(const DataObject &)> Evaluator
const std::vector< T > & vector() const
Definition: DataStream.hh:293
A 'cloneable_ptr' can be used in place of 'unique_ptr'.
DatumFormatterAlias< DataObject > datum_formatter_alias(const std::string &_name, const std::string &_command, const DataFormatterDictionary< DataObject > &_dict, const std::string &_help="")
Make a DatumFormatterAlias.
MatrixXdAttributeDictionary< DataObject > make_matrixxd_dictionary()
Template to be specialized for constructing dictionaries for particular DataObject.
DataFormatterOperator< bool, bool, DataObject > format_operator_and()
Makes a DataFormatterOperator that returns the boolean AND for a sequence of boolean values.
DataFormatterOperator< double, double, DataObject > format_operator_min()
Makes a DataFormatterOperator that returns the minimum of two or more numbers.
DataFormatterOperator< bool, double, DataObject > format_operator_le()
Makes a DataFormatterOperator for less-than-or-equal comparison of two numbers.
DataFormatterOperator< bool, std::string, DataObject > format_operator_re()
Makes a DataFormatterOperator that checks if a string matches a regular expression.
DataFormatterOperator< double, double, DataObject > format_operator_pnorm()
Makes a DataFormatterOperator that returns the root-mean-square value of 0 or more elements.
DataFormatterOperator< bool, bool, DataObject > format_operator_or()
Makes a DataFormatterOperator that returns the boolean OR for a sequence of boolean values.
DataFormatterOperator< double, double, DataObject > format_operator_mult()
Makes a DataFormatterOperator that returns the product of two or more numbers.
DataFormatterOperator< double, double, DataObject > format_operator_sub()
Makes a DataFormatterOperator that subtracts two numbers.
DataFormatterOperator< double, double, DataObject > format_operator_max()
Makes a DataFormatterOperator that returns the maximum of two or more numbers.
DataFormatterOperator< double, double, DataObject > format_operator_sq()
Makes a DataFormatterOperator that returns the square of a number.
DataFormatterOperator< bool, double, DataObject > format_operator_lt()
Makes a DataFormatterOperator for less-than comparison of two numbers.
DataFormatterOperator< double, double, DataObject > format_operator_div()
Makes a DataFormatterOperator that divides two numbers.
DataFormatterOperator< bool, bool, DataObject > format_operator_xor()
Makes a DataFormatterOperator that returns the boolean NOT for a single boolean value.
DataFormatterOperator< bool, double, DataObject > format_operator_eq()
Makes a DataFormatterOperator for equality comparison of two numbers.
DataFormatterOperator< double, double, DataObject > format_operator_neg()
Makes a DataFormatterOperator that returns the negative of a number.
DataFormatterOperator< bool, double, DataObject > format_operator_ge()
Makes a DataFormatterOperator for greater-than-or-equal comparison of two numbers.
DataFormatterOperator< long, double, DataObject > format_operator_imax()
Makes a DataFormatterOperator that returns the index (from 0) of the maximum of two or more numbers.
DataFormatterOperator< double, double, DataObject > format_operator_sqrt()
Makes a DataFormatterOperator that returns the square root of a number.
DataFormatterOperator< long, double, DataObject > format_operator_imin()
Makes a DataFormatterOperator that returns the index (from 0) of the minimum of two or more numbers.
DataFormatterOperator< bool, double, DataObject > format_operator_gt()
Makes a DataFormatterOperator for greater-than comparison of two numbers.
DataFormatterOperator< double, double, DataObject > format_operator_rms()
Makes a DataFormatterOperator that returns the root-mean-square value of 0 or more elements.
DataFormatterOperator< bool, std::string, DataObject > format_operator_rs()
Makes a DataFormatterOperator that checks if a string contains a regular expression.
DataFormatterOperator< double, double, DataObject > format_operator_exp()
Makes a DataFormatterOperator that returns the exponential of a number.
DataFormatterOperator< double, double, DataObject > format_operator_add()
Makes a DataFormatterOperator that adds two or more numbers.
Main CASM namespace.
Definition: APICommand.hh:8
std::pair< std::vector< long >, std::vector< long > > index_expression_to_bounds(const std::string &_expr)
bool almost_equal(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Check if ClusterInvariants are equal.
GenericDatumFormatter< std::string, DataObject > alias()
GenericDatumFormatter< std::string, DataObject > alias_or_name()
DataFormatterOperator< bool, bool, DataObject > format_operator_not()
DatumFormatterClass
DataFormatterDictionary< DataObject > make_operator_dictionary()
Dictionary of all DatumFormatterOperator.
void split_formatter_expression(const std::string &input_expr, std::vector< std::string > &tag_names, std::vector< std::string > &sub_exprs)
GenericDatumFormatter< std::string, DataObject > name()
bool valid_index(Index i)
Definition: definitions.cc:5
DataFormatterDictionary< DataObject > make_attribute_dictionary()
Dictionary of all AttributeFormatter (i.e. BaseValueFormatter<V, DataObject>)
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39
T max(const T &A, const T &B)
Definition: CASM_math.hh:95
Specialize container traits Expects:
Shortcut for multidimensional vector (std::vector< std::vector< ...)
Definition: multivector.hh:26