Flow123d  master-1d42d53
type_base.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file type_base.hh
15  * @brief
16  */
17 
18 #ifndef TYPE_BASE_HH_
19 #define TYPE_BASE_HH_
20 
21 #include <limits>
22 #include <ios>
23 //#include <set>
24 #include <map>
25 #include <vector>
26 #include <string>
27 //#include <iomanip>
28 
29 #include <stdint.h> // for int64_t
30 
31 #include <memory> // for shared_ptr, __shared_ptr
32 #include <utility> // for pair
33 
34 #include "system/exceptions.hh"
35 #include "system/file_path.hh"
36 
37 
38 
39 
40 namespace Input {
41 
42 namespace Type {
43 
44 
45 
46 using namespace std;
47 
48 /**
49  * Declaration of common exceptions and error info types.
50  */
51 TYPEDEF_ERR_INFO( EI_KeyName, const string );
52 
53 TYPEDEF_ERR_INFO( EI_DefaultStr, const string);
54 TYPEDEF_ERR_INFO( EI_TypeName, const string);
55 TYPEDEF_ERR_INFO( EI_Desc, const string);
56 DECLARE_EXCEPTION( ExcWrongDefaultJSON, << "Consistency Error: Not valid JSON of Default value "
57  << EI_DefaultStr::qval << " of type " << EI_TypeName::qval << ";\n"
58  << "During declaration of the key: " << EI_KeyName::qval );
59 DECLARE_EXCEPTION( ExcWrongDefault, << "Consistency Error: " << EI_Desc::val << "Default value "
60  << EI_DefaultStr::qval << " do not match type: " << EI_TypeName::qval << ";\n"
61  << "During declaration of the key: " << EI_KeyName::qval );
62 DECLARE_EXCEPTION( ExcUnknownDescendant, << "Unknown descendant of TypeBase class, name: " << EI_TypeName::qval );
63 
64 
65 
66 
67 /**
68  * FinishStatus manages finish of elements in IST.
69  *
70  * Specifies:
71  * - finish status of IST elements
72  * - type of executing finish
73  */
75  none_, //< unfinished element / this type can't be used as type of finish
76  in_perform_, //< finish of element performs (used in recursion check) / this type can't be used as type of finish
77  regular_, //< finished element of IST / finish of IST executed recursively from root element
78  generic_, //< finished element in generic subtree / finish of generic subtree (executed from Instance object)
79  delete_ //< finished element marked as deleted (that doesn't appear in IST) / finish of unused elements (that can be removed)
80 };
81 
82 
83 /**
84  * @brief Base of classes for declaring structure of the input data.
85  *
86  * Provides methods and class members common to all types. Namely, the type name, finished status (nontrivial only
87  * for types with complex initialization - Record, AbstractRecosd, Selection), attributes, data of generic types
88  * and output of the documentation.
89  *
90  * @ingroup input_types
91  */
92 class TypeBase {
93 public:
94  /// Type returned by content_hash methods.
95  typedef std::size_t TypeHash;
96  const static TypeHash none_hash = std::numeric_limits<TypeHash>::max();
97 
98  /// String stored in JSON format.
99  typedef std::string json_string;
100  /// Defines map of Input::Type attributes.
102 
103  /// Defines pairs of (name, Input::Type), that are used for replace of parameters in generic types.
104  typedef std::pair< std::string, std::shared_ptr<TypeBase> > ParameterPair;
105  /// Define vector of parameters passed to the overloaded make_instance method.
107 
108  /// Defines map of used parameters
110  /// Return type of make_instance methods, contains instance of generic type and map of used parameters
111  typedef std::pair< std::shared_ptr<TypeBase>, ParameterMap > MakeInstanceReturnType;
112 
113 
114  /**
115  * @brief Returns true if the type is fully specified and ready for read access.
116  *
117  * For Record and Array types this say nothing about child types referenced in particular type object.
118  * In particular for Record and Selection, it returns true after @p finish() method is called.
119  */
120  virtual FinishStatus finish_status() const;
121 
122  virtual bool is_finished() const;
123 
124  /**
125  * @brief Returns true if the type is closed.
126  */
127  virtual bool is_closed() const;
128 
129  /// Returns an identification of the type. Useful for error messages.
130  virtual string type_name() const;
131  /// Returns an identification of the class. Useful for output of the documentation.
132  virtual string class_name() const;
133 
134  /**
135  * @brief Returns string with Type extensive documentation.
136  *
137  * We need this to pass Type description at throw points since the Type object can be deallocated during stack
138  * unrolling so it is not good idea to pass pointer. Maybe we can pass smart pointers. Actually this method is
139  * used in various exceptions in json_to_storage.
140  *
141  * TODO: Some old note on this topic:
142  * !!! how to pass instance of descendant of TypeBase through EI -
143  * - can not pass it directly since TypeBase is not copyconstructable
144  * - can not use shared_ptr for same reason
145  * - can not use C pointers since the referred object can be temporary
146  * solutions:
147  * - consistently move TypeBase to Pimpl design
148  * - provide virtual function make_copy, that returns valid shared_ptr
149  *
150  */
151  string desc() const;
152 
153 
154 
155  /**
156  * @brief Comparison of types.
157  *
158  * It compares kind of type (Integer, Double, String, Record, ..), for complex types it also compares names.
159  * For arrays compare subtypes.
160  */
161  virtual bool operator==(const TypeBase &other) const;
162 
163  /// Comparison of types.
164  bool operator!=(const TypeBase & other) const;
165 
166  /// Destructor
167  virtual ~TypeBase();
168 
169 
170 
171  /**
172  * @brief Finishes and marks all types registered in type repositories and unused in IST.
173  *
174  * Steps of this method:
175  * 1) finishes all types unused in IST, marks them as deleted (FinishStatus::deleted_)
176  * 2) iterates these deleted types once more, checks shared pointers link to Record keys, descendants of Abstract etc.
177  * - if count == 1, it's OK, method resets shared pointer
178  * - in other cases throws error
179  */
180  static void delete_unfinished_types();
181 
182 
183  /**
184  * @brief Finish method. Finalize construction of "Lazy types": Record, Selection, Abstract and generic type.
185  *
186  * These input types are typically defined by means of static generating methods, whose allows initialization
187  * any of other input types. Since e.g. a Record can link to other input types through its keys at the
188  * initialization phase. But some setting (e.g. add descendants to Abstract) can't be done in initialization
189  * phase. Therefore, the remaining part of initialization can be done later, in finalization phase, typically
190  * from main(), by calling the method finish().
191  *
192  * Method allows finish in different cases that is managed by @p finish_type:
193  *
194  * - base finish of IST requires FinishStatus::regular_ and typically finish of root type is called in this case
195  * - finish of generic types can be different of other Input::Types (e. g. for Record) and needs set @p finish_type
196  * to FinishStatus::generic_
197  * - input types unused in IST can be finished with parameter FinishStatus::delete_. These types can be then safely
198  * deleted from \p Input::TypeRepository (see also \p delete_unfinished_types)
199  *
200  */
201  virtual FinishStatus finish(FinishStatus finish_type = FinishStatus::regular_);
202 
203  /**
204  * @brief Hash of the type specification.
205  *
206  * Provides unique id computed from its content (definition) so that same types have same hash.
207  *
208  * Hash is counted using type, name and other class members specific for descendants.
209  */
210  virtual TypeHash content_hash() const =0;
211 
212  /**
213  * @brief Format given hash for output.
214  *
215  * Use hex format and double quotas.
216  */
217  static std::string hash_str(TypeHash hash);
218 
219  /// Format the hash of this type.
220  inline std::string hash_str() const {
221  return hash_str(content_hash());
222  }
223 
224  /**
225  * Create instance of generic type.
226  *
227  * Replace parameters in input tree by type stored in @p vec.
228  */
230 
231  /// Indicates if type is marked with flag @p root_of_generic_subtree_
232  inline bool is_root_of_generic_subtree() const {
233  return root_of_generic_subtree_;
234  }
235 
236 protected:
237 
238  /// The default constructor.
239  TypeBase();
240 
241  /// Copy constructor.
242  TypeBase(const TypeBase& other);
243 
244  /**
245  * @brief Add attribute of given @p name to attribute map.
246  *
247  * Parameter @p val must contain valid JSON string.
248  */
249  void add_attribute_(std::string name, json_string val);
250 
251 
252 
253  /**
254  * @brief The type of hash values used in associative array that translates key names to indices in Record and Selection.
255  *
256  * For simplicity, we currently use whole strings as "hash".
257  */
258  typedef string KeyHash;
259 
260  /// Hash function.
261  inline static KeyHash key_hash(const string &str) {
262  return (str);
263  }
264 
265  /**
266  * @brief Check that a @p key is valid identifier.
267  *
268  * I.e. consists only of valid characters, that are lower-case letters, digits and underscore,
269  * we allow identifiers starting with a digit, but it is discouraged since it slows down parsing of the input file.
270  */
271  static bool is_valid_identifier(const string& key);
272 
273  /// Check if @p str is valid JSON string
274  bool validate_json(json_string str) const;
275 
276  /// Create JSON output from @p parameter_map formatted as value of attribute.
277  json_string print_parameter_map_to_json(ParameterMap parameter_map) const;
278 
279  /**
280  * JSON format of the vector of parameter names. Used for generic composed types.
281  * TODO: use ParameterVector instead of ParameterMap and merge this method with the previous one.
282  */
283  json_string print_parameter_map_keys_to_json(ParameterMap param_map) const;
284 
285  /**
286  * Extract and set attributes from the ParameterMap containing parameters of the subtree.
287  * Used in implementations of the make_instance method.
288  */
289  void set_generic_attributes(ParameterMap param_map);
290 
291  /**
292  * Copy attributes to the instance of the generic type. Remove all internal attributes starting with '_'.
293  */
294  void copy_attributes(attribute_map other_attributes);
295 
296 
297  /// map of type attributes (e. g. input_type, name etc.)
298  std::shared_ptr<attribute_map> attributes_;
299 
300  /// flag is true if type should be root of generic subtree
302 
303  /// hash string of generic type if type is derived, or empty string
305 
306  /// map of parameters if type is part of generic subtree
308 
309  friend class Array;
310  friend class Record;
311  friend class OutputBase;
312 };
313 
314 /**
315  * @brief For convenience we provide also redirection operator for output documentation of Input:Type classes.
316  */
317 std::ostream& operator<<(std::ostream& stream, const TypeBase& type);
318 
319 
320 //class Record;
321 //class Selection;
322 
323 
324 /**
325  * @brief Class for declaration of inputs sequences.
326  *
327  * The type is fully specified after its constructor is called. All elements of the Array has same type, however you
328  * can use elements of Abstract.
329  *
330  * If you not disallow Array size 1, the input reader will try to convert any other type
331  * on input into array with one element, e.g.
332  @code
333  int_array=1 # is equivalent to
334  int_array=[ 1 ]
335  @endcode
336  *
337  * @ingroup input_types
338  */
339 class Array : public TypeBase {
340  friend class OutputBase;
341 
342 protected:
343 
344  /**
345  * @brief Actual data of the Array.
346  */
347  class ArrayData {
348  public:
349 
350  /// Constructor
351  ArrayData(unsigned int min_size, unsigned int max_size);
352  /// Finishes initialization of the ArrayData.
353  FinishStatus finish(FinishStatus finish_type = FinishStatus::regular_);
354  /// Type of Array
355  std::shared_ptr<TypeBase> type_of_values_;
356  /// Minimal size of Array
357  unsigned int lower_bound_;
358  /// Maximal size of Array
359  unsigned int upper_bound_;
360  /// Flag specified if Array is finished
362 
363  };
364 
365 public:
366  /**
367  * @brief Constructor with a @p type of array items given as pure reference.
368  *
369  * In this case \p type has to by descendant of \p TypeBase different from 'complex' types
370  * @p Record and @p Selection. You can also specify minimum and maximum size of the array.
371  */
372  template <class ValueType>
373  Array(const ValueType &type, unsigned int min_size=0, unsigned int max_size=std::numeric_limits<unsigned int>::max() );
374 
375  /**
376  * @brief Constructor with a shared pointer @p type of array.
377  */
378  Array(std::shared_ptr<TypeBase> type, unsigned int min_size=0, unsigned int max_size=std::numeric_limits<unsigned int>::max() );
379 
380  /**
381  * @brief Implements @p TypeBase::content_hash.
382  *
383  * Hash is calculated by type name, bounds, hash of stored type and hash of attributes.
384  */
385  TypeHash content_hash() const override;
386 
387  /// Finishes initialization of the Array type because of lazy evaluation of type_of_values.
388  FinishStatus finish(FinishStatus finish_type = FinishStatus::regular_) override;
389 
390  /// Override @p Type::TypeBase::finish_status.
391  FinishStatus finish_status() const override;
392 
393  /// Override @p Type::TypeBase::is_finished.
394  bool is_finished() const override;
395 
396  /// Getter for the type of array items.
397  inline const TypeBase &get_sub_type() const {
398  return *data_->type_of_values_; }
399 
400  /// Checks size of particular array.
401  inline bool match_size(unsigned int size) const {
402  return size >=data_->lower_bound_ && size<=data_->upper_bound_; }
403 
404  /**
405  * @brief Implements @p Type::TypeBase::type_name.
406  *
407  * Name has form \p array_of_'subtype_name'.
408  */
409  string type_name() const override;
410  /// Override @p Type::TypeBase::class_name.
411  string class_name() const override;
412 
413  /// @brief Implements @p Type::TypeBase::operator== Compares also subtypes.
414  bool operator==(const TypeBase &other) const override;
415 
416  /// Implements @p TypeBase::make_instance.
417  MakeInstanceReturnType make_instance(std::vector<ParameterPair> vec = std::vector<ParameterPair>()) override;
418 
419  /**
420  * @brief Create deep copy of Array.
421  *
422  * Copy all data stored in shared pointers etc.
423  */
424  Array deep_copy() const;
425 
426 protected:
427 
428  /// Handle to the actual array data.
429  std::shared_ptr<ArrayData> data_;
430 private:
431  /// Forbids default constructor in order to prevent empty data_.
432  Array();
433 };
434 
435 
436 
437 /**
438  * @brief Base of all scalar types.
439  *
440  * @ingroup input_types
441  */
442 class Scalar : public TypeBase {};
443 
444 
445 /**
446  * @brief Class for declaration of the input of type Bool.
447  *
448  * String names of boolean values are \p 'true' and \p 'false'.
449  *
450  * @ingroup input_types
451  */
452 class Bool : public Scalar {
453 public:
454  /// Constructor.
456  {}
457 
458  /// Implements @p TypeBase::content_hash.
459  TypeHash content_hash() const override;
460 
461 
462  /**
463  * @brief Implements @p Type::TypeBase::type_name.
464  *
465  * Name has form \p Bool.
466  */
467  string type_name() const override;
468  /// Override @p Type::TypeBase::class_name.
469  string class_name() const override;
470 
471  /// Implements @p TypeBase::make_instance.
472  MakeInstanceReturnType make_instance(std::vector<ParameterPair> vec = std::vector<ParameterPair>()) override;
473 };
474 
475 
476 /**
477  * @brief Class for declaration of the integral input data.
478  *
479  * The data are stored in an \p signed \p int variable. You can specify bounds for the valid input data.
480  *
481  * @ingroup input_types
482  */
483 class Integer : public Scalar {
484  friend class OutputBase;
485 
486 public:
487  /**
488  * @brief Constructor.
489  *
490  * You can also specify minimum and maximum value.
491  */
492  Integer(int lower_bound=std::numeric_limits<int>::min(), int upper_bound=std::numeric_limits<int>::max());
493 
494  /**
495  * @brief Implements @p TypeBase::content_hash.
496  *
497  * Hash is calculated by type name and bounds.
498  */
499  TypeHash content_hash() const override;
500 
501  /**
502  * @brief Check valid value of Integer.
503  *
504  * Returns true if the given integer value conforms to the Type::Integer bounds.
505  */
506  bool match(std::int64_t value) const;
507 
508  /**
509  * @brief Implements @p Type::TypeBase::type_name.
510  *
511  * Name has form \p Integer.
512  */
513  string type_name() const override;
514  /// Override @p Type::TypeBase::class_name.
515  string class_name() const override;
516 
517  /// Implements @p TypeBase::make_instance.
519 private:
520 
521  std::int64_t lower_bound_; ///< Minimal value of Integer.
522  std::int64_t upper_bound_; ///< Maximal value of Integer.
523 
524 };
525 
526 
527 /**
528  * @brief Class for declaration of the input data that are floating point numbers.
529  *
530  * The data are stored in an \p double variable. You can specify bounds for the valid input data.
531  *
532  * @ingroup input_types
533  */
534 class Double : public Scalar {
535  friend class OutputBase;
536 
537 public:
538  /**
539  * @brief Constructor.
540  *
541  * You can also specify minimum and maximum value.
542  */
543  Double(double lower_bound= -std::numeric_limits<double>::max(), double upper_bound=std::numeric_limits<double>::max());
544 
545  /**
546  * @brief Implements @p TypeBase::content_hash.
547  *
548  * Hash is calculated by type name and bounds.
549  */
550  TypeHash content_hash() const override;
551 
552  /// Returns true if the given integer value conforms to the Type::Double bounds.
553  bool match(double value) const;
554 
555  /**
556  * @brief Implements @p Type::TypeBase::type_name.
557  *
558  * Name has form \p Double.
559  */
560  string type_name() const override;
561  /// Override @p Type::TypeBase::class_name.
562  string class_name() const override;
563 
564  /// Implements @p TypeBase::make_instance.
566 private:
567 
568  double lower_bound_; ///< Minimal value of Integer.
569  double upper_bound_; ///< Maximal value of Integer.
570 
571 };
572 
573 
574 
575 /**
576  * @brief Class for declaration of the input data that are in string format.
577  *
578  * Just for consistency, but is essentially same as Scalar.
579  *
580  * @ingroup input_types
581  */
582 class String : public Scalar {
583 public:
584  /**
585  * @brief Implements @p Type::TypeBase::type_name.
586  *
587  * Name has form \p String.
588  */
589  virtual string type_name() const override;
590  /// Override @p Type::TypeBase::class_name.
591  string class_name() const override;
592 
593  /// Implements @p TypeBase::content_hash.
594  TypeHash content_hash() const override;
595 
596  /// Particular descendants can check validity of the string.
597  /// This returns always true.
598  virtual bool match(const string &value) const;
599 
600  /// Implements @p TypeBase::make_instance.
602 };
603 
604 
605 /**
606  * @brief Class for declaration of the input data that are file names.
607  *
608  * We strictly distinguish filenames for input and output files.
609  *
610  * @ingroup input_types
611  */
612 class FileName : public String {
613 public:
614 
615  /// Implements @p TypeBase::content_hash.
616  TypeHash content_hash() const override;
617 
618  /**
619  * @brief The factory function for declaring type FileName for input files.
620  */
621  static FileName input();
622 
623  /**
624  * @brief The factory function for declaring type FileName for input files.
625  */
626  static FileName output();
627 
628  /**
629  * @brief Implements @p Type::TypeBase::type_name.
630  *
631  * Name has form \p FileName_input or \p FileName_output
632  */
633  string type_name() const override;
634  /// Override @p Type::TypeBase::class_name.
635  string class_name() const override;
636 
637  /// Comparison of types.
638  bool operator==(const TypeBase &other) const override;
639 
640  /// Checks relative output paths.
641  bool match(const string &str) const override;
642 
643 
644  /**
645  * @brief Returns type of the file input/output.
646  */
647  ::FilePath::FileType get_file_type() const;
648 
649  /// Implements @p TypeBase::make_instance.
651 
652 
653 
654 private:
655  /// The type of file (input or output).
657 
658  /// Forbids default constructor.
659  FileName();
660 
661  /// Forbids direct construction.
662  FileName(enum ::FilePath::FileType type);
663 
664 };
665 
666 } // closing namespace Type
667 } // closing namespace Input
668 
669 
670 
671 
672 
673 #endif /* TYPE_BASE_HH_ */
FileType
Possible types of file.
Definition: file_path.hh:67
Actual data of the Array.
Definition: type_base.hh:347
unsigned int upper_bound_
Maximal size of Array.
Definition: type_base.hh:359
std::shared_ptr< TypeBase > type_of_values_
Type of Array.
Definition: type_base.hh:355
unsigned int lower_bound_
Minimal size of Array.
Definition: type_base.hh:357
FinishStatus finish_status
Flag specified if Array is finished.
Definition: type_base.hh:361
Class for declaration of inputs sequences.
Definition: type_base.hh:339
Array()
Forbids default constructor in order to prevent empty data_.
bool match_size(unsigned int size) const
Checks size of particular array.
Definition: type_base.hh:401
const TypeBase & get_sub_type() const
Getter for the type of array items.
Definition: type_base.hh:397
std::shared_ptr< ArrayData > data_
Handle to the actual array data.
Definition: type_base.hh:429
Class for declaration of the input of type Bool.
Definition: type_base.hh:452
Bool()
Constructor.
Definition: type_base.hh:455
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:534
double upper_bound_
Maximal value of Integer.
Definition: type_base.hh:569
double lower_bound_
Minimal value of Integer.
Definition: type_base.hh:568
Class for declaration of the input data that are file names.
Definition: type_base.hh:612
::FilePath::FileType type_
The type of file (input or output).
Definition: type_base.hh:656
Class for declaration of the integral input data.
Definition: type_base.hh:483
std::int64_t upper_bound_
Maximal value of Integer.
Definition: type_base.hh:522
std::int64_t lower_bound_
Minimal value of Integer.
Definition: type_base.hh:521
Base abstract class for output description of the Input::Type tree.
Definition: type_output.hh:65
Record type proxy class.
Definition: type_record.hh:182
Base of all scalar types.
Definition: type_base.hh:442
Class for declaration of the input data that are in string format.
Definition: type_base.hh:582
Base of classes for declaring structure of the input data.
Definition: type_base.hh:92
std::pair< std::shared_ptr< TypeBase >, ParameterMap > MakeInstanceReturnType
Return type of make_instance methods, contains instance of generic type and map of used parameters.
Definition: type_base.hh:111
std::string json_string
String stored in JSON format.
Definition: type_base.hh:99
static KeyHash key_hash(const string &str)
Hash function.
Definition: type_base.hh:261
TypeHash generic_type_hash_
hash string of generic type if type is derived, or empty string
Definition: type_base.hh:304
string KeyHash
The type of hash values used in associative array that translates key names to indices in Record and ...
Definition: type_base.hh:258
bool is_root_of_generic_subtree() const
Indicates if type is marked with flag root_of_generic_subtree_.
Definition: type_base.hh:232
std::size_t TypeHash
Type returned by content_hash methods.
Definition: type_base.hh:95
virtual MakeInstanceReturnType make_instance(ParameterVector vec=ParameterVector())=0
std::pair< std::string, std::shared_ptr< TypeBase > > ParameterPair
Defines pairs of (name, Input::Type), that are used for replace of parameters in generic types.
Definition: type_base.hh:104
std::vector< ParameterPair > ParameterVector
Define vector of parameters passed to the overloaded make_instance method.
Definition: type_base.hh:106
std::shared_ptr< attribute_map > attributes_
map of type attributes (e. g. input_type, name etc.)
Definition: type_base.hh:298
virtual TypeHash content_hash() const =0
Hash of the type specification.
ParameterMap parameter_map_
map of parameters if type is part of generic subtree
Definition: type_base.hh:307
bool root_of_generic_subtree_
flag is true if type should be root of generic subtree
Definition: type_base.hh:301
std::string hash_str() const
Format the hash of this type.
Definition: type_base.hh:220
std::map< std::string, TypeHash > ParameterMap
Defines map of used parameters.
Definition: type_base.hh:109
std::map< std::string, json_string > attribute_map
Defines map of Input::Type attributes.
Definition: type_base.hh:101
static constexpr bool value
Definition: json.hpp:87
ArmaVec< double, N > vec
Definition: armor.hh:933
std::ostream & operator<<(std::ostream &stream, const TypeBase &type)
For convenience we provide also redirection operator for output documentation of Input:Type classes.
Definition: type_base.cc:239
DECLARE_EXCEPTION(ExcWrongDefaultJSON,<< "Consistency Error: Not valid JSON of Default value "<< EI_DefaultStr::qval<< " of type "<< EI_TypeName::qval<< ";\n"<< "During declaration of the key: "<< EI_KeyName::qval)
TYPEDEF_ERR_INFO(EI_KeyName, const string)
Abstract linear system class.
Definition: balance.hh:40
bool operator==(const Null &, const Null &)