Flow123d  DF_patch_fe_mechanics-a6ba684
type_record.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_record.hh
15  * @brief
16  */
17 
18 #ifndef TYPE_RECORD_HH_
19 #define TYPE_RECORD_HH_
20 
21 #include "system/exceptions.hh"
22 //
23 
24 #include <utility> // for pair
25 #include "system/asserts.hh" // for Assert, ASSERT
26 namespace Input { class StorageBase; }
27 
28 
29 #include "type_base.hh"
30 
31 #include <string>
32 #include <memory>
33 #include <vector>
34 #include <map>
35 
36 namespace Input {
37 namespace Type {
38 
39 
40 using namespace std;
41 
42 
43 /** *********************************************************************************************************************************
44  * @brief Class \p Input::Type::Default specifies default value of keys of a \p Input::Type::Record.
45  *
46  * It contains type of default value and possibly the value itself stored as \p std::string. Currently we distinguish four
47  * cases:
48  * - \b Default value given \b at \b declaration time, i.e. the default value is part of the \p Input::Type specification.
49  * This should be preferred way to give the default value since it can by documented as part of
50  * Record type specification.
51  * - \b Default value given \b at \b read time, i.e. when you ask for the value through the Input::Record accessor. It should be used only
52  * if the default value is not constant, i.e. is taken from a global setting. In this case you should provide textual description
53  * where the default value comes from. Of course it could be difficult if the value is read on several places with different default values.
54  * - \b No \b default value is given and input value is \b obligatory. An exception is thrown when the key is missing on the input.
55  * - \b No \b default value is given and input value is \b optional.
56  *
57  *
58  *
59  * @ingroup input_types
60  */
61 class Default {
62  friend class Record;
63  friend class OutputBase;
64 
65 private:
66  /// Possible types of default values.
67  enum DefaultType {
68  default_at_declaration, ///< Default value given at declaration time.
69  default_at_read_time, ///< Some default value will be given when the key is read. The description of this value should be provided.
70  no_default_optional_type, ///< No default value, optional key. This is default type of the Default.
71  no_default_obligatory_type ///< No default value, obligatory key.
72  };
73 public:
74 
75  /// Constructor with given default value (at declaration time)
76  Default(const std::string & value);
77 
78  /// Hash of the Default specification, counted of type_ and value_.
79  TypeBase::TypeHash content_hash() const;
80 
81  /**
82  * @brief The factory function to make an default value that will be specified at the time when a key will be read.
83  *
84  * You have to provide a string with description of the default value used at the read time., e.g.
85  * the key \p time_governer of an equation can specify default value as
86  * @code
87  * Default::read_time("By default the global time governor is used.")
88  * @endcode
89  * To get the value of such key from the input you have to use non-throwing variant of the method
90  * Input::Record::key, which returns the value through reference and allows checking presence of the key on the input.
91  *
92  * Example of usage:
93  * @code
94  * some_record.declare_key("time_governor",TimeGovernor(),Default::optional(),"description");
95  * @endcode
96  */
97  static Default read_time(const std::string & description)
98  { return Default(default_at_read_time, description ); }
99 
100  /**
101  * @brief The factory function to make an empty default value which is obligatory.
102  *
103  * This and following factory functions should be used instead of private constructors.
104  *
105  * Example of usage:
106  * @code
107  * some_record.declare_key("some_key",Integer(),Default::obligatory(),"description");
108  * @endcode
109  */
110  inline static Default obligatory()
111  { return Default(no_default_obligatory_type, "OBLIGATORY"); }
112 
113  /**
114  * @brief The factory function to make an empty default value which is optional.
115  *
116  * To get the value of such key from the input you have to use non-throwing variant of the method
117  * Input::Record::key, which returns the value through reference and allows checking presence of the key on the input.
118  *
119  * Example of usage:
120  * @code
121  * some_record.declare_key("some_key",Integer(),Default::optional(),"description");
122  * @endcode
123  */
124  inline static Default optional()
125  { return Default(no_default_optional_type, "OPTIONAL"); }
126 
127  /// Returns true if the default value is or will be available when someone tries to read the value.
128  inline bool has_value_at_read_time() const
129  { return (type_ == default_at_read_time); }
130 
131  /// Returns true if the default value is or will be available when someone tries to read the value.
132  inline bool has_value_at_declaration() const
133  { return (type_ == default_at_declaration); }
134 
135 
136  /// Returns true if the key is obligatory and thus must be specified on input. No default value is given.
137  inline bool is_obligatory() const
138  { return (type_ == no_default_obligatory_type); }
139 
140  /// Returns true if the key is optional.
141  inline bool is_optional() const
142  { return (type_ == no_default_optional_type); }
143 
144  /// Returns stored value. Possibly empty string.
145  inline const string & value() const
146  { return (value_); }
147 
148  /// Compares values type_ of two Default objects.
149  inline bool has_same_type(const Default &other) const
150  {return type_ == other.type_; }
151 
152  /// Check validity of @p value_ using the JSON reader if default type is default_at_declaration.
153  bool check_validity(std::shared_ptr<TypeBase> type) const;
154 
155  /// Return @p storage_, if storage_ is NULL, call check_validity method
156  Input::StorageBase *get_storage(std::shared_ptr<TypeBase> type) const;
157 
158 private:
159  string value_; ///< Stored value.
160  enum DefaultType type_; ///< Type of the Default.
161  mutable Input::StorageBase *storage_; ///< Storage of default value read by reader
162 
163  /// Forbids default constructor.
164  Default();
165 
166  /// Constructor for other types then 'declaration'.
167  Default(enum DefaultType type, const std::string &value);
168 };
169 
170 
171 class Abstract;
172 
173 
174 /** ******************************************************************************************************************************
175  * @brief Record type proxy class.
176  *
177  * To keep consistency, we have to prevent copies of the actual Record data. Therefore this class is just a proxy that
178  * can be freely (and cheaply) copied.
179  *
180  * @ingroup input_types
181  */
182 class Record : public TypeBase {
183  friend class OutputBase;
184  friend class Abstract;
185 
186 public:
187 
188  /*
189  * Exceptions specific to this class.
190  */
191  TYPEDEF_ERR_INFO( EI_Record, Record );
192  TYPEDEF_ERR_INFO( EI_RecordName, const string);
193  DECLARE_EXCEPTION( ExcRecordKeyNotFound, << "Key " << EI_KeyName::qval <<" not found in Record:\n" << EI_Record::val );
194 
195  /**
196  * @brief Structure for description of one key in record.
197  *
198  * The members dflt_type_ and default have reasonable meaning only for
199  * type_ == Scalar
200  */
201  struct Key {
202  unsigned int key_index; ///< Position inside the record.
203  string key_; ///< Key identifier.
204  string description_; ///< Key description in context of particular Record type.
205  std::shared_ptr<TypeBase> type_; ///< Type of the key.
206  Default default_; ///< Default, type and possibly value itself.
207  /**
208  * Is true if the key was created through copy_keys method, but not explicitly declared.
209  * This is used to check duplicate key declaration while allowing overriding of copied keys.
210  */
211  bool derived;
212  Input::Type::TypeBase::attribute_map attributes; ///< Key specific attributes.
213  };
214 
215  /// Public typedef of constant iterator into array of keys.
217 
218  /// Default constructor. Empty handle.
219  Record();
220 
221  /**
222  * @brief Copy constructor.
223  *
224  * We allow only copies of non-empty records.
225  */
226  Record(const Record & other);
227 
228 
229  /**
230  * @brief Basic constructor.
231  *
232  * You have to provide \p type_name of the new declared Record type and its \p description.
233  */
234  Record(const string & type_name_in, const string & description);
235 
236 
237  /**
238  * @brief Implements @p TypeBase::content_hash.
239  *
240  * Hash is calculated by type name, description, auto conversion key, hash of keys and attributes.
241  */
242  virtual TypeHash content_hash() const override;
243 
244 
245  /**
246  * @brief Method to derive new Record from an AbstractRecord @p parent.
247  *
248  * This register the @p parent to Record. Method checks if TYPE key of Record exists and ensures that Record
249  * has assigned one parent only once.
250  *
251  * Usage of this method:
252  *
253  * - during creating Record before its closing (optional usage but recommended for better clarity)
254  * - in \p Abstract::add_child provides bilateral binding between parent and child
255  *
256  * See also \p close and \p Abstract::add_child methods
257  */
258  virtual Record &derive_from(Abstract &parent);
259 
260  /**
261  * @brief Copy keys from other record.
262  *
263  * Record @p other must be \p closed.
264  */
265  Record &copy_keys(const Record &other);
266 
267  /**
268  * @brief Allows shorter input of the Record providing only value of the \p from_key given as the parameter.
269  *
270  * All other keys of the Record must have default values specified at declaration. This is checked when the
271  * \p finish method is called.
272  *
273  * If the input reader come across the Record in declaration tree, but there is not 'record-like' input, it
274  * save default values into storage tree and tries to match the input with the type of the \p from_key.
275  */
276  virtual Record &allow_auto_conversion(const string &from_key);
277 
278  /**
279  * @brief Declares a new key of the Record.
280  *
281  * Key has name given by parameter @p key, the type given by target of pointer @p type,
282  * default value by parameter @p default_value, and with given @p description.
283  * The parameter @p type points to a descendant of TypeBase.
284  *
285  * If the the function is called with the already existing key name @p key, an assert takes place,
286  * Howeverf, if the the function is called with the same key name @p key in the derived Record,
287  * the key is overwritten.
288  *
289  * The optional attributes map may be provided, e.g.:
290  *
291  * declare_key("old_key", ..., { {Attribute::obsolete(), "Replaced by 'new_key'."} } )
292  */
293  Record &declare_key(const string &key, std::shared_ptr<TypeBase> type,
294  const Default &default_value, const string &description,
296 
297  /**
298  * @brief Declares a new key of the Record.
299  *
300  * Key has name given by parameter @p key, the type given by parameter @p type,
301  * default value by parameter @p default_value, and with given @p description.
302  * The parameter @p type has a descendant of TypeBase.
303  */
304  template <class KeyType>
305  Record &declare_key(const string &key, const KeyType &type,
306  const Default &default_value,
307  const string &description,
309 
310 
311  /**
312  * @brief Declares a new key of the Record.
313  *
314  * Same as previous method but without given default value (same as Default() - optional key )
315  */
316  template <class KeyType>
317  Record &declare_key(const string &key, const KeyType &type,
318  const string &description,
320 
321 
322  /**
323  * @brief Close the Record for further declarations of keys.
324  *
325  * Adds Record to type repository (see @p TypeRepository::add_type) and provides correct bindings
326  * between parent Abstract and child Record if Record is derived from one or more Abstracts.
327  *
328  * Mechanism of set parent to derived Record and child to parent Abstract is provided with
329  * \p Abstract::add_child method.
330  *
331  * See also \p derive_from and \p Abstract::add_child methods
332  */
333  Record &close() const;
334 
335 
336  /// Implements @p TypeBase::finish_status.
337  FinishStatus finish_status() const override;
338 
339  /// Implements @p TypeBase::is_finished.
340  bool is_finished() const override;
341 
342  /// Returns true if @p data_ is closed.
343  bool is_closed() const override;
344 
345  /**
346  * @brief Implements @p Type::TypeBase::type_name.
347  *
348  * Name corresponds to @p data->type_name_.
349  */
350  string type_name() const override;
351  /// Override @p Type::TypeBase::class_name.
352  virtual string class_name() const override;
353 
354  /// Class comparison and Record type name comparision.
355  bool operator==(const TypeBase &other) const override;
356 
357  /**
358  * @brief Interface to mapping key -> index in record.
359  *
360  * Returns index (in continuous array) for given key.
361  *
362  * Works also for unfinished Record.
363  */
364  inline unsigned int key_index(const string& key) const;
365 
366  /// Returns iterator to the key struct for given key string.
367  inline KeyIter key_iterator(const string& key) const;
368 
369  /**
370  * @brief Returns iterator to auto-conversion key.
371  *
372  * See Record::allow_auto_conversion. If the auto conversion is not allowed, returns end().
373  */
374  KeyIter auto_conversion_key_iter() const;
375 
376  /// Returns iterator to the key struct for given key string.
377  inline bool has_key_iterator(const string& key, KeyIter &it) const;
378 
379  /**
380  * @brief Container-like access to the keys of the Record.
381  *
382  * Returns iterator to the first key.
383  */
384  inline KeyIter begin() const;
385 
386  /**
387  * @brief Container-like access to the keys of the Record.
388  *
389  * Returns iterator to the last key.
390  */
391  inline KeyIter end() const;
392 
393  /// Returns true if the Record contains key with given name.
394  inline bool has_key(const string& key) const;
395 
396  /// Returns number of keys in the Record.
397  inline unsigned int size() const;
398 
399  /**
400  * @brief Finish declaration of the Record type.
401  *
402  * Checks if Record is closed and completes Record (check auto convertible key, parameters of generic types etc).
403  */
404  FinishStatus finish(FinishStatus finish_type = FinishStatus::regular_) override;
405 
406  /**
407  * @brief Add TYPE key as obligatory.
408  *
409  * This method can't be used for derived record.
410  */
411  //Record &has_obligatory_type_key();
412 
413  Record &add_attribute(std::string key, TypeBase::json_string value);
414 
415  /// Implements @p TypeBase::make_instance.
417 
418  /// Create deep copy of Record (copy all data stored in shared pointers etc.)
419  Record deep_copy() const;
420 
421  /**
422  * Mark the type to be root of a generic subtree.
423  * Such type can not appear in IST directly but only as the internal type
424  * of the Instance auxiliary object.
425  */
426  virtual Record &root_of_generic_subtree();
427 
428 
429 protected:
430 
431  /// Assertion for finished Type::Record.
432  inline void finished_check() const {
433  ASSERT(is_finished())(this->type_name()).error();
434  }
435 
436  /// Auxiliary method that actually makes the copy of keys.
437  void make_copy_keys(Record &origin);
438 
439  /**
440  * @brief Declares a TYPE key of the Record.
441  *
442  * TYPE key must be declared as first key of Record.
443  */
444  //Record &declare_type_key();
445 
446  /**
447  * @brief Set parent Abstract of Record.
448  *
449  * This method is created for correct functionality of generic types. It must be called
450  * in Abstract::finish() and refill @p parent_vec_ vector of correct parents (for complete
451  * mechanism of set parent and descendant see \p derive_from)
452  */
453  //const Record &add_parent(Abstract &parent) const;
454 
455  /**
456  * @brief Set data of Instance of generic type.
457  *
458  * Called from make_instance method and set data of Record or its descendants.
459  */
460  ParameterMap set_instance_data(Record &rec, std::vector<ParameterPair> vec);
461 
462  /**
463  * @brief Internal data class.
464  *
465  * Stores data of the Record.
466  */
467  class RecordData {
468  public:
469  /// Constructor
470  RecordData(const string & type_name_in, const string & description);
471 
472  /**
473  * @brief Declares a key and stores its type.
474  *
475  * The type parameter has to be finished at the call of declare_key().
476  * If the parameter @p type_temporary is NULL, the parameter @p type provides pointer to
477  * already finished type that will be assigned to the key. On the other hand, if @p type_temporary is not NULL,
478  * only this raw pointer is stored and key is fully completed later through TypeBase::lazy_finish().
479  */
480  void declare_key(const string &key,
481  std::shared_ptr<TypeBase> type,
482  const Default &default_value,
483  const string &description,
484  TypeBase::attribute_map key_attributes);
485 
486  /// Returns iterator to auto-conversion key.
487  Record::KeyIter auto_conversion_key_iter() const;
488 
489  /// Count hash of RecordData.
490  void content_hash(TypeBase::TypeHash &seed) const;
491 
492  /// Database of valid keys
494  /// Container-like access to the database of valid keys
496 
497  /// Keys in order as they where declared.
499 
500  /// Description of the whole record type.
501  const string description_;
502  /// Name of the whole record type.
503  const string type_name_;
504 
505  /// Permanent pointer to parent Abstract, necessary for output.
507 
508  /// Record is finished when it is correctly derived (optional) and have correct shared pointers to types in all keys.
510 
511  /// If record is closed, we do not allow any further declare_key calls.
512  bool closed_;
513 
514  /// True for derived records after make_derived.
515  bool derived_;
516 
517  /**
518  * @brief Index of auto convertible key.
519  *
520  * Initial value is = -1, when allow_auto_conversion is called we set this to 0.
521  * Final value can be assigned just after possible inheritance copy of keys from parent Abstract.
522  */
524 
525  /// Name of key to use for auto conversion.
526  std::string auto_conversion_key;
527 
528  };
529 
530  /// Data handle.
531  std::shared_ptr<RecordData> data_;
532 };
533 
534 
535 /*********************************************************
536  * Implementation
537  */
538 
539 
540 
541 
542 inline unsigned int Record::key_index(const string& key) const
543 {
544  KeyHash key_h = key_hash(key);
545  RecordData::key_to_index_const_iter it = data_->key_to_index.find(key_h);
546  if (it != data_->key_to_index.end()) return it->second;
547  else
548  THROW( ExcRecordKeyNotFound() << EI_KeyName(key) << EI_Record(*this) );
549 
550  return size();
551 }
552 
553 
554 
555 inline Record::KeyIter Record::key_iterator(const string& key) const
556 {
557 
558  finished_check();
559  return begin() + key_index(key);
560 }
561 
562 
563 
564 inline bool Record::has_key_iterator(const string& key, KeyIter &it) const
565 {
566  finished_check();
567  KeyHash key_h = key_hash(key);
568  RecordData::key_to_index_const_iter data_it = data_->key_to_index.find(key_h);
569  if (data_it == data_->key_to_index.end()) {
570  return false;
571  } else {
572  it = begin()+data_it->second;
573  return true;
574  }
575 }
576 
577 
578 
580 {
581  finished_check();
582  return data_->keys.begin();
583 }
584 
585 
586 
588 {
589  finished_check();
590  return data_->keys.end();
591 }
592 
593 
594 
595 inline bool Record::has_key(const string& key) const
596 {
597  return key_iterator(key) != end();
598 }
599 
600 
601 
602 inline unsigned int Record::size() const {
603  ASSERT(is_closed())(this->type_name()).error();
604  ASSERT_EQ(data_->keys.size(), data_->key_to_index.size()).error();
605  return data_->keys.size();
606 }
607 
608 
609 
610 
611 
612 
613 } // closing namespace Type
614 } // closing namespace Input
615 
616 
617 
618 
619 #endif /* TYPE_RECORD_HH_ */
Definitions of ASSERTS.
#define ASSERT(expr)
Definition: asserts.hh:351
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
Definition: asserts.hh:333
Base class for nodes of a data storage tree.
Definition: storage.hh:68
Class for declaration of polymorphic Record.
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:61
DefaultType
Possible types of default values.
Definition: type_record.hh:67
@ no_default_optional_type
No default value, optional key. This is default type of the Default.
Definition: type_record.hh:70
@ default_at_declaration
Default value given at declaration time.
Definition: type_record.hh:68
@ default_at_read_time
Some default value will be given when the key is read. The description of this value should be provid...
Definition: type_record.hh:69
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:110
enum DefaultType type_
Type of the Default.
Definition: type_record.hh:160
bool has_value_at_read_time() const
Returns true if the default value is or will be available when someone tries to read the value.
Definition: type_record.hh:128
bool is_optional() const
Returns true if the key is optional.
Definition: type_record.hh:141
bool has_same_type(const Default &other) const
Compares values type_ of two Default objects.
Definition: type_record.hh:149
static Default read_time(const std::string &description)
The factory function to make an default value that will be specified at the time when a key will be r...
Definition: type_record.hh:97
bool is_obligatory() const
Returns true if the key is obligatory and thus must be specified on input. No default value is given.
Definition: type_record.hh:137
Input::StorageBase * storage_
Storage of default value read by reader.
Definition: type_record.hh:161
const string & value() const
Returns stored value. Possibly empty string.
Definition: type_record.hh:145
bool has_value_at_declaration() const
Returns true if the default value is or will be available when someone tries to read the value.
Definition: type_record.hh:132
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:124
Base abstract class for output description of the Input::Type tree.
Definition: type_output.hh:65
FinishStatus finish_status_
Record is finished when it is correctly derived (optional) and have correct shared pointers to types ...
Definition: type_record.hh:509
const string description_
Description of the whole record type.
Definition: type_record.hh:501
int auto_conversion_key_idx
Index of auto convertible key.
Definition: type_record.hh:523
std::map< KeyHash, unsigned int > key_to_index
Database of valid keys.
Definition: type_record.hh:493
std::map< KeyHash, unsigned int >::const_iterator key_to_index_const_iter
Container-like access to the database of valid keys.
Definition: type_record.hh:495
bool derived_
True for derived records after make_derived.
Definition: type_record.hh:515
const string type_name_
Name of the whole record type.
Definition: type_record.hh:503
std::vector< std::shared_ptr< Abstract > > parent_vec_
Permanent pointer to parent Abstract, necessary for output.
Definition: type_record.hh:506
bool closed_
If record is closed, we do not allow any further declare_key calls.
Definition: type_record.hh:512
std::string auto_conversion_key
Name of key to use for auto conversion.
Definition: type_record.hh:526
std::vector< struct Key > keys
Keys in order as they where declared.
Definition: type_record.hh:498
Record type proxy class.
Definition: type_record.hh:182
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:602
DECLARE_EXCEPTION(ExcRecordKeyNotFound,<< "Key "<< EI_KeyName::qval<<" not found in Record:\n"<< EI_Record::val)
void finished_check() const
Assertion for finished Type::Record.
Definition: type_record.hh:432
KeyIter key_iterator(const string &key) const
Returns iterator to the key struct for given key string.
Definition: type_record.hh:555
std::shared_ptr< RecordData > data_
Data handle.
Definition: type_record.hh:531
TYPEDEF_ERR_INFO(EI_RecordName, const string)
KeyIter begin() const
Container-like access to the keys of the Record.
Definition: type_record.hh:579
std::vector< struct Key >::const_iterator KeyIter
Public typedef of constant iterator into array of keys.
Definition: type_record.hh:216
bool has_key_iterator(const string &key, KeyIter &it) const
Returns iterator to the key struct for given key string.
Definition: type_record.hh:564
KeyIter end() const
Container-like access to the keys of the Record.
Definition: type_record.hh:587
TYPEDEF_ERR_INFO(EI_Record, Record)
bool has_key(const string &key) const
Returns true if the Record contains key with given name.
Definition: type_record.hh:595
unsigned int key_index(const string &key) const
Interface to mapping key -> index in record.
Definition: type_record.hh:542
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
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
std::size_t TypeHash
Type returned by content_hash methods.
Definition: type_base.hh:95
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
static constexpr bool value
Definition: json.hpp:87
ArmaVec< double, N > vec
Definition: armor.hh:933
Abstract linear system class.
Definition: balance.hh:40
bool operator==(const Null &, const Null &)
Structure for description of one key in record.
Definition: type_record.hh:201
Default default_
Default, type and possibly value itself.
Definition: type_record.hh:206
string key_
Key identifier.
Definition: type_record.hh:203
Input::Type::TypeBase::attribute_map attributes
Key specific attributes.
Definition: type_record.hh:212
std::shared_ptr< TypeBase > type_
Type of the key.
Definition: type_record.hh:205
unsigned int key_index
Position inside the record.
Definition: type_record.hh:202
string description_
Key description in context of particular Record type.
Definition: type_record.hh:204