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