CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
DataFormatter.hh
Go to the documentation of this file.
1 #ifndef DATAFORMATTER_HH
2 #define DATAFORMATTER_HH
3 
4 #include <iostream>
5 #include <string>
6 #include <sstream>
7 #include <vector>
8 #include <functional>
9 #include "casm/external/boost.hh"
12 #include "casm/misc/CASM_math.hh"
17 
18 
19 namespace CASM {
20 
52 
53 
59 
60 
61  class DataStream;
62 
63  template<typename DataObject>
65 
66  template<typename DataObject, typename DatumFormatterType>
68 
69  // Given expression string
70  // "subexpr1 subexpr2(subsub1) subexpr3(subsub2(subsubsub1))"
71  // splits expresion so that
72  // tag_names = {"subexpr1", "subexpr2", "subexpr3"}
73  // sub_exprs = {"","subsub1", "subsub2(subsubsub1)"}
74  // whitespace and commas are ignored
75  void split_formatter_expression(const std::string &input_expr,
76  std::vector<std::string> &tag_names,
77  std::vector<std::string> &sub_exprs);
78 
79 
153  template<typename _DataObject>
155  // These are private classes that sweeten the I/O syntax
156  // they have to be forward declared ahead of DataFormatter::operator()
157  template<typename IteratorType>
159 
160  class FormattedObject;
161  public:
162 
163  typedef _DataObject DataObject;
164 
165  DataFormatter(int _sep = 4, int _precision = 12, std::string _comment = "#") :
166  m_initialized(false), m_prec(_precision), m_sep(_sep), m_indent(0), m_comment(_comment) {
167  m_data_formatters.reserve(100);
168  }
169 
170  template<typename ...Args>
171  DataFormatter(const Args &... formatters)
172  : DataFormatter() {
173  push_back(formatters...);
174  }
175 
176  bool empty() const {
177  return m_data_formatters.size() == 0;
178  }
179 
180  void clear() {
181  m_data_formatters.clear();
182  }
183 
184  template<typename IteratorType>
185  FormattedIteratorPair<IteratorType> operator()(IteratorType begin, IteratorType end) const {
186  return FormattedIteratorPair<IteratorType>(this, begin, end);
187  }
188 
189  void set_indent(int _indent) {
190  if(m_col_width.size() == 0)
191  return;
192  m_col_width[0] += _indent;
193  m_col_sep[0] += _indent;
194  //m_indent=_indent;
195  }
196 
197  FormattedObject operator()(const DataObject &data_obj) const {
198  return FormattedObject(this, data_obj);
199  }
200 
202  bool validate(const DataObject &_obj) const;
203 
205  void inject(const DataObject &_obj, DataStream &_stream) const;
206 
208  template<typename ValueType>
209  ValueType evaluate_as_scalar(const DataObject &_obj) const;
210 
212  template<typename ValueType>
213  std::vector<ValueType> evaluate_as_vector(const DataObject &_obj) const;
214 
216  Eigen::MatrixXd evaluate_as_matrix(const DataObject &_obj) const;
217 
219  template<typename ValueType, typename IteratorType>
220  std::vector<ValueType> evaluate_as_vector(IteratorType begin, IteratorType end) const;
221 
223  template<typename IteratorType>
224  Eigen::MatrixXd evaluate_as_matrix(IteratorType begin, IteratorType end) const;
225 
227  void print(const DataObject &_obj, std::ostream &_stream) const;
228 
230  jsonParser &to_json(const DataObject &_obj, jsonParser &json) const;
231 
233  jsonParser &to_json_arrays(const DataObject &_obj, jsonParser &json) const;
234 
236  void print_header(const DataObject &_tmplt_obj, std::ostream &_stream) const;
237 
239  std::vector<std::string> col_header(const DataObject &_template_obj) const;
240 
243  void push_back(const BaseDatumFormatter<DataObject> &new_formatter, const std::string &args) {
244 
245  //If the last formatter matches new_formatter, try to parse the new arguments into it
246  if(m_data_formatters.size() > 0 && m_data_formatters.back()->name() == new_formatter.name()) {
247  if(m_data_formatters.back()->parse_args(args)) {
248  return;
249  }
250  }
251 
252  m_data_formatters.emplace_back(new_formatter);
253  m_col_sep.push_back(0);
254  m_col_width.push_back(0);
255  m_data_formatters.back()->parse_args(args);
256  }
257 
258  void push_back(const BaseDatumFormatter<DataObject> &new_formatter) {
259  m_data_formatters.emplace_back(new_formatter);
260  m_col_sep.push_back(0);
261  m_col_width.push_back(0);
262  }
263 
264  template<typename ...Args>
265  void push_back(const BaseDatumFormatter<DataObject> &new_formatter, const Args &... formatters) {
266  push_back(new_formatter);
267  push_back(formatters...);
268  }
269 
270  void append(const DataFormatter<DataObject> &_tail) {
271  for(const auto &frmtr : _tail.m_data_formatters)
272  push_back(*frmtr);
273  }
274 
275 
276  DataFormatter<DataObject> &operator<<(const BaseDatumFormatter<DataObject> &new_formatter) {
277  push_back(new_formatter);
278  return *this;
279  }
280 
281  void set_header_prefix(const std::string &_prefix) {
282  m_comment += _prefix;
283  }
284  private:
285  mutable bool m_initialized;
286  //List of all the ConfigFormatter objects you want outputted
287  std::vector<notstd::cloneable_ptr<BaseDatumFormatter<DataObject> > > m_data_formatters;
288  mutable std::vector<Index> m_col_sep;
289  mutable std::vector<Index> m_col_width;
290  //Decimal precision
291  int m_prec;
292  //number of spaces between columns
293  int m_sep;
294 
295  int m_indent;
296  //comment prefix -- default to "#"
297  std::string m_comment;
298 
299  void _initialize(const DataObject &_tmplt) const;
300  };
301 
309  template<typename _DataObject>
310  class BaseDatumFormatter {
311  public:
312 
313  typedef _DataObject DataObject;
315  typedef long difference_type;
317 
318 
319  BaseDatumFormatter(const std::string &_init_name, const std::string &_desc) :
320  m_name(_init_name), m_description(_desc) {}
321 
323  virtual ~BaseDatumFormatter() {};
324 
326  const std::string &name() const {
327  return m_name;
328  }
329 
332  const std::string &description() const {
333  return m_description;
334  }
335 
336  virtual FormatterType type() const {
337  return Property;
338  }
339 
341  const DictType &home() const {
342  return *m_home;
343  }
344 
346  void set_home(const DictType &home) const {
347  m_home = &home;
348  }
349 
352  std::unique_ptr<BaseDatumFormatter<DataObject> > clone() const {
353  return std::unique_ptr<BaseDatumFormatter<DataObject> >(this->_clone());
354  }
355 
356  virtual void init(const DataObject &_template_obj) const {
357 
358  };
359 
363  virtual bool validate(const DataObject &_data_obj) const {
364  return true;
365  }
366 
373  virtual std::vector<std::string> col_header(const DataObject &_template_obj) const {
374  return std::vector<std::string> {this->short_header(_template_obj)};
375  }
376 
382  virtual std::string long_header(const DataObject &_template_obj) const {
383  auto _col = col_header(_template_obj);
384  if(_col.size() == 1) {
385  return _col[0];
386  }
387 
388  std::stringstream t_ss;
389  for(Index i = 0; i < _col.size(); i++) {
390  t_ss << " " << _col[i];
391  }
392 
393  return t_ss.str();
394  }
395 
400  virtual std::string short_header(const DataObject &_template_obj) const {
401  return name();
402  };
403 
406  virtual Index num_passes(const DataObject &_data_obj) const {
407  return 1;
408  }
409 
412  virtual void print(const DataObject &_data_obj, std::ostream &_stream, Index pass_index = 0) const = 0;
413 
416  virtual void inject(const DataObject &_data_obj, DataStream &_stream, Index pass_index = 0) const = 0;
417 
424  virtual jsonParser &to_json(const DataObject &_data_obj, jsonParser &json)const = 0;
425 
431  virtual bool parse_args(const std::string &args) {
432  return args.size() == 0;
433  }
434  protected:
436 
445  void _parse_index_expression(const std::string &_expr);
446 
447  void _add_rule(const std::vector<Index> &new_rule) const {
448  m_index_rules.push_back(new_rule);
449  }
450 
451  const IndexContainer &_index_rules() const {
452  return m_index_rules;
453  }
454 
455  private:
456 
459  virtual BaseDatumFormatter *_clone() const = 0;
462  std::string m_name;
463  std::string m_description;
464  mutable IndexContainer m_index_rules;
465  mutable const DictType *m_home;
466  };
467 
468  template<typename T>
469  bool always_true(const T &) {
470  return true;
471  };
472 
473 
474  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
475  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
481 
482  // Couldn't figure out how to get compiler to correctly substitute names
483  // virtual "FormattedPrintable" class is a workaround
484 
485  public:
486  virtual ~FormattedPrintable() {}
487  virtual void inject(DataStream &stream)const = 0;
488  virtual void print(std::ostream &stream)const = 0;
489  virtual jsonParser &to_json(jsonParser &json)const = 0;
490  };
491 
492 
493  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
494  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
495 
500  template<typename DataObject> template<typename IteratorType>
501  class DataFormatter<DataObject>::FormattedIteratorPair : public FormattedPrintable {
503  IteratorType m_begin_it, m_end_it;
504  public:
505  FormattedIteratorPair(const DataFormatter<DataObject> *_formatter_ptr, IteratorType _begin, IteratorType _end):
506  m_formatter_ptr(_formatter_ptr), m_begin_it(_begin), m_end_it(_end) {}
507 
508  void inject(DataStream &_stream) const {
509  if(m_begin_it == m_end_it)
510  return;
511  // hack: always print header to initialize things, like Clexulator, but in this case throw it away
512  std::stringstream _ss;
513  m_formatter_ptr->print_header(*m_begin_it, _ss);
514  for(IteratorType it(m_begin_it); it != m_end_it; ++it)
515  m_formatter_ptr->inject(*it, _stream);
516  }
517 
518  void print(std::ostream &_stream) const {
519  if(m_begin_it == m_end_it)
520  return;
521 
522  FormatFlag format(_stream);
523  if(format.print_header()) {
524  m_formatter_ptr->print_header(*m_begin_it, _stream);
525  }
526  else { // hack: always print header to initialize things, like Clexulator, but in this case throw it away
527  std::stringstream _ss;
528  m_formatter_ptr->print_header(*m_begin_it, _ss);
529  }
530  format.print_header(false);
531  _stream << format;
532  for(IteratorType it(m_begin_it); it != m_end_it; ++it)
533  m_formatter_ptr->print(*it, _stream);
534  }
535 
536  jsonParser &to_json(jsonParser &json) const {
537  json.put_array();
538  for(IteratorType it(m_begin_it); it != m_end_it; ++it)
539  json.push_back((*m_formatter_ptr)(*it));
540  return json;
541  }
542 
545  json = jsonParser::object();
546  for(IteratorType it(m_begin_it); it != m_end_it; ++it)
547  m_formatter_ptr->to_json_arrays(*it, json);
548  return json;
549  }
550 
551 
552  };
553 
554  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
555  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
556 
561  template<typename DataObject>
565  public:
566  FormattedObject(const DataFormatter<DataObject> *_formatter_ptr, const DataObject &_obj):
567  m_formatter_ptr(_formatter_ptr), m_obj_ptr(&_obj) {}
568 
569  void inject(DataStream &_stream) const {
570  m_formatter_ptr->inject(*m_obj_ptr, _stream);
571  }
572 
573  void print(std::ostream &_stream) const {
574  FormatFlag format(_stream);
575  if(format.print_header())
576  m_formatter_ptr->print_header(*m_obj_ptr, _stream);
577  format.print_header(false);
578  _stream << format;
579 
580  m_formatter_ptr->print(*m_obj_ptr, _stream);
581  }
582 
583  jsonParser &to_json(jsonParser &json) const {
584  m_formatter_ptr->to_json(*m_obj_ptr, json);
585  return json;
586  }
587 
588  };
589 
590  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
591  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
592 
593  template<typename DataObject, typename DatumFormatterType>
595 
596  typedef DatumFormatterType formatter;
597 
598 
599  // performs a static_cast of value.clone().unique().release()
600  // (i.e. a BaseDatumFormatter*) to formatter*
601 
603  return notstd::cloneable_ptr<formatter>(static_cast<formatter *>(value.clone().release()));
604  }
605 
606  };
607 
608  template<typename DataObject>
609  struct DictionaryConverter<DataObject, BaseDatumFormatter<DataObject> > {
610 
612 
614  return notstd::cloneable_ptr<formatter>(value);
615  }
616 
617  };
618 
619 
624  template<typename _DataObject, typename _DatumFormatterType = BaseDatumFormatter<_DataObject> >
625  class DataFormatterDictionary :
626  public notstd::unique_cloneable_map<std::string, _DatumFormatterType> {
627 
628  public:
629 
630  typedef _DataObject DataObject;
631  typedef _DatumFormatterType DatumFormatterType;
638 
640  UniqueMapType([](const value_type &value)->std::string {
641  return value.name();
642  },
644 
645  /*
647  explicit DataFormatterDictionary(const value_type& formatter) :
648  DataFormatterDictionary() {
649  insert(formatter);
650  }
651 
653  template<typename... Formatters>
654  explicit DataFormatterDictionary(const Formatters&... more) :
655  DataFormatterDictionary() {
656  insert(more...);
657  }
658 
660  DataFormatterDictionary(const DataFormatterDictionary& dict) :
661  UniqueMapType(dict) {
662  }
663 
665  template<typename... Formatters>
666  DataFormatterDictionary(const Formatters&... more) :
667  DataFormatterDictionary() {
668  insert(more...);
669  }
670  */
671 
672  using UniqueMapType::insert;
673 
676  const_iterator lookup(const key_type &_name) const;
677 
679  bool contains(const key_type &_name) const {
680  return this->find(_name) != this->end();
681  }
682 
683  void print_help(std::ostream &_stream,
685  int width = 60,
686  int separation = 8) const;
687 
689  DataFormatter<DataObject> parse(const std::string &input) const;
690 
692  DataFormatter<DataObject> parse(const std::vector<std::string> &input) const;
693 
694  };
695 
696 
697  // ******************************************************************************
698 
700  template<typename DataObject>
701  DataFormatterDictionary<DataObject> make_attribute_dictionary();
702 
704  template<typename DataObject>
705  DataFormatterDictionary<DataObject> make_operator_dictionary();
706 
710  template<typename DataObject>
713  dict.insert(
714  make_attribute_dictionary<DataObject>(),
715  make_operator_dictionary<DataObject>()
716  );
717 
718  return dict;
719  }
720 
721  // ******************************************************************************
722 
723  inline jsonParser &to_json(const FormattedPrintable &_obj, jsonParser &json) {
724  return _obj.to_json(json);
725  }
726 
727  // ******************************************************************************
728  inline std::ostream &operator<<(std::ostream &_stream, const FormattedPrintable &_formatted) {
729  _formatted.print(_stream);
730  return _stream;
731  }
732 
733  // ******************************************************************************
734  inline DataStream &operator<<(DataStream &_stream, const FormattedPrintable &_formatted) {
735  _formatted.inject(_stream);
736  return _stream;
737  }
738 
739 
740 }
741 
743 
744 #endif
Eigen::MatrixXd MatrixXd
std::unique_ptr< BaseDatumFormatter< DataObject > > clone() const
Make an exact copy of the formatter (including any initialized members)
std::vector< std::string > col_header(const DataObject &_template_obj) const
Returns all column header strings as std::vector
void print(std::ostream &_stream) const
virtual bool parse_args(const std::string &args)
DataFormatterDictionary< DataObject > make_attribute_dictionary()
Dictionary of all AttributeFormatter (i.e. BaseValueFormatter)
std::vector< Index > m_col_width
const std::string & name() const
Returns a name for the formatter, which becomes the tag used for parsing.
multivector< Index >::X< 2 > IndexContainer
BaseDatumFormatter(const std::string &_init_name, const std::string &_desc)
jsonParser & to_json(jsonParser &json) const
virtual std::vector< std::string > col_header(const DataObject &_template_obj) const
Returns a header string for each scalar produced by the formatter parsing the entries in the col_head...
virtual void print(std::ostream &stream) const =0
notstd::unique_cloneable_map< std::string, DatumFormatterType > UniqueMapType
bool contains(const key_type &_name) const
True if dictionary contains entry for.
bool print_header() const
Definition: FormatFlag.hh:33
virtual std::string short_header(const DataObject &_template_obj) const
Returns a short expression for the formatter parsing the short_header should allow the formatter to b...
DataFormatterDictionary< DataObject > make_dictionary()
Template to can be specialized for constructing dictionaries for particular DataObject.
void inject(const DataObject &_obj, DataStream &_stream) const
Output selected data from DataObject to DataStream.
void _initialize(const DataObject &_tmplt) const
jsonParser & to_json_arrays(const DataObject &_obj, jsonParser &json) const
Output data as specified by *this of the given DataObject to json with format {"name1":[..., x], "name2":[..., x], ...}.
DataFormatter(const Args &...formatters)
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
An iterator over a UniqueMap.
Definition: unique_map.hh:18
virtual void inject(DataStream &stream) const =0
void split_formatter_expression(const std::string &input_expr, std::vector< std::string > &tag_names, std::vector< std::string > &sub_exprs)
void print_header(const DataObject &_tmplt_obj, std::ostream &_stream) const
print the header, using _tmplt_obj to inspect array sizes, etc.
void set_home(const DictType &home) const
Set the dictionary containing this formatter, set during DictType::lookup.
virtual jsonParser & to_json(jsonParser &json) const =0
void _add_rule(const std::vector< Index > &new_rule) const
notstd::cloneable_ptr< formatter > operator()(const formatter &value)
virtual std::string long_header(const DataObject &_template_obj) const
Returns a long expression for each scalar produced by the formatter parsing the long_header should re...
void inject(DataStream &_stream) const
virtual void inject(const DataObject &_data_obj, DataStream &_stream, Index pass_index=0) const =0
Main CASM namespace.
Definition: complete.cpp:8
DataFormatter(int _sep=4, int _precision=12, std::string _comment="#")
virtual ~BaseDatumFormatter()
Allow polymorphic deletion.
void push_back(const BaseDatumFormatter< DataObject > &new_formatter)
const DictType * m_home
void print(const DataObject &_obj, std::ostream &_stream) const
Output data as specified by *this of the given DataObject.
void _parse_index_expression(const std::string &_expr)
std::pair< iterator, bool > insert(const value_type &value)
Insert single value.
Definition: unique_map.hh:169
notstd::cloneable_ptr< formatter > operator()(const formatter &value)
virtual jsonParser & to_json(const DataObject &_data_obj, jsonParser &json) const =0
UniqueMapType::size_type size_type
UniqueMapType::const_iterator const_iterator
const std::string & description() const
Returns a short description of the formatter and its allowed arguments (if any). This description is ...
void print_help(std::ostream &_stream, typename BaseDatumFormatter< DataObject >::FormatterType ftype, int width=60, int separation=8) const
Generates formatted help using the 'name' and 'description' of all contained BaseDatumFormatter.
UniqueMapType::key_type key_type
virtual FormatterType type() const
void push_back(const BaseDatumFormatter< DataObject > &new_formatter, const std::string &args)
std::ostream & operator<<(std::ostream &_stream, const FormattedPrintable &_formatted)
virtual BaseDatumFormatter * _clone() const =0
Make an exact copy of the formatter (including any initialized members)
DataFormatterDictionary< DataObject, BaseDatumFormatter< DataObject > > DictType
jsonParser & to_json(const DataObject &_obj, jsonParser &json) const
Output data as specified by *this of the given DataObject to json with format {"name1":x, "name2":x, ...}.
void set_indent(int _indent)
Abstract base class to enable generic formatting.
EigenIndex Index
For long integer indexing:
_DataObject DataObject
FormattedIteratorPair< IteratorType > operator()(IteratorType begin, IteratorType end) const
void push_back(const BaseDatumFormatter< DataObject > &new_formatter, const Args &...formatters)
virtual void print(const DataObject &_data_obj, std::ostream &_stream, Index pass_index=0) const =0
Eigen::MatrixXd evaluate_as_matrix(const DataObject &_obj) const
Useful when formatted output can be represented as Eigen::MatrixXd.
FormattedIteratorPair(const DataFormatter< DataObject > *_formatter_ptr, IteratorType _begin, IteratorType _end)
std::vector< notstd::cloneable_ptr< BaseDatumFormatter< DataObject > > > m_data_formatters
ValueType value_type
Definition: unique_map.hh:145
DataFormatter< DataObject > const * m_formatter_ptr
UniqueMapType::value_type value_type
iterator find(const key_type &key)
Definition: unique_map.hh:215
Implements generic formatting member functions for ranges of data objects.
FormattedObject operator()(const DataObject &data_obj) const
Abstract base class from which all other DatumFormatter classes inherit.
virtual bool validate(const DataObject &_data_obj) const
Returns true if _data_obj has valid values for requested data.
bool always_true(const T &)
_DatumFormatterType DatumFormatterType
jsonParser & to_json(jsonParser &json) const
Extract data from objects of 'DataObject' class.
bool validate(const DataObject &_obj) const
Returns true if _obj has valid data for all portions of query.
virtual Index num_passes(const DataObject &_data_obj) const
jsonParser & push_back(const T &value)
Puts new valued element at end of array of any type T for which 'jsonParser& to_json( const T &value...
Definition: jsonParser.hh:696
const IndexContainer & _index_rules() const
void append(const DataFormatter< DataObject > &_tail)
std::map wrapper to enforce a 1-1 ValueType->KeyType relationship
Definition: unique_map.hh:141
std::vector< Index > m_col_sep
jsonParser & to_json_arrays(jsonParser &json) const
Output data with format {"name1":[..., x], "name2":[..., x], ...}.
void set_header_prefix(const std::string &_prefix)
DatumFormatterType formatter
ValueType evaluate_as_scalar(const DataObject &_obj) const
Useful when formatted output can be represented as single value.
const_iterator lookup(const key_type &_name) const
Equivalent to find, but set 'home' and throws error with suggestion if.
A 'cloneable_ptr' can be used in place of 'unique_ptr'.
virtual void init(const DataObject &_template_obj) const
const DictType & home() const
const Access the dictionary containing this formatter, set during DictType::lookup ...
bool empty() const
MapType::size_type size_type
Definition: unique_map.hh:158
std::vector< ValueType > evaluate_as_vector(const DataObject &_obj) const
Useful when formatted output can be represented as std::vector.
IndexContainer m_index_rules
void print(std::ostream &_stream) const
FormattedObject(const DataFormatter< DataObject > *_formatter_ptr, const DataObject &_obj)
static jsonParser object()
Returns an empty json object.
Definition: jsonParser.hh:329
Implements generic formatting member functions for individual data objects.
jsonParser & put_array()
Puts new empty JSON array.
Definition: jsonParser.hh:285
DataFormatter< DataObject > const * m_formatter_ptr
void inject(DataStream &_stream) const
DataFormatter< DataObject > parse(const std::string &input) const
Use the vector of strings to build a DataFormatter
Parsing dictionary for constructing a DataFormatter object.
Shortcut for multidimensional vector (std::vector< std::vector< ...)
Definition: multivector.hh:26
UniqueMapType::iterator iterator
DataFormatterDictionary< DataObject > make_operator_dictionary()
Dictionary of all DatumFormatterOperator.