Flow123d  release_2.2.0-914-gf1a3a4f
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 #include <boost/exception/detail/error_info_impl.hpp> // for error_info
23 #include <boost/exception/info.hpp> // for error_info::~e...
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  * The optional attributes map may be provided, e.g.:
286  *
287  * declare_key("old_key", ..., { {Attribute::obsolete(), "Replaced by 'new_key'."} } )
288  */
289  Record &declare_key(const string &key, std::shared_ptr<TypeBase> type,
290  const Default &default_value, const string &description,
292 
293  /**
294  * @brief Declares a new key of the Record.
295  *
296  * Key has name given by parameter @p key, the type given by parameter @p type,
297  * default value by parameter @p default_value, and with given @p description.
298  * The parameter @p type has a descendant of TypeBase.
299  */
300  template <class KeyType>
301  Record &declare_key(const string &key, const KeyType &type,
302  const Default &default_value,
303  const string &description,
305 
306 
307  /**
308  * @brief Declares a new key of the Record.
309  *
310  * Same as previous method but without given default value (same as Default() - optional key )
311  */
312  template <class KeyType>
313  Record &declare_key(const string &key, const KeyType &type,
314  const string &description,
316 
317 
318  /**
319  * @brief Close the Record for further declarations of keys.
320  *
321  * Adds Record to type repository (see @p TypeRepository::add_type) and provides correct bindings
322  * between parent Abstract and child Record if Record is derived from one or more Abstracts.
323  *
324  * Mechanism of set parent to derived Record and child to parent Abstract is provided with
325  * \p Abstract::add_child method.
326  *
327  * See also \p derive_from and \p Abstract::add_child methods
328  */
329  Record &close() const;
330 
331 
332  /// Implements @p TypeBase::finish_status.
333  FinishStatus finish_status() const override;
334 
335  /// Implements @p TypeBase::is_finished.
336  bool is_finished() const override;
337 
338  /// Returns true if @p data_ is closed.
339  bool is_closed() const override;
340 
341  /**
342  * @brief Implements @p Type::TypeBase::type_name.
343  *
344  * Name corresponds to @p data->type_name_.
345  */
346  string type_name() const override;
347  /// Override @p Type::TypeBase::class_name.
348  virtual string class_name() const override;
349 
350  /// Class comparison and Record type name comparision.
351  bool operator==(const TypeBase &other) const override;
352 
353  /**
354  * @brief Interface to mapping key -> index in record.
355  *
356  * Returns index (in continuous array) for given key.
357  *
358  * Works also for unfinished Record.
359  */
360  inline unsigned int key_index(const string& key) const;
361 
362  /// Returns iterator to the key struct for given key string.
363  inline KeyIter key_iterator(const string& key) const;
364 
365  /**
366  * @brief Returns iterator to auto-conversion key.
367  *
368  * See Record::allow_auto_conversion. If the auto conversion is not allowed, returns end().
369  */
370  KeyIter auto_conversion_key_iter() const;
371 
372  /// Returns iterator to the key struct for given key string.
373  inline bool has_key_iterator(const string& key, KeyIter &it) const;
374 
375  /**
376  * @brief Container-like access to the keys of the Record.
377  *
378  * Returns iterator to the first key.
379  */
380  inline KeyIter begin() const;
381 
382  /**
383  * @brief Container-like access to the keys of the Record.
384  *
385  * Returns iterator to the last key.
386  */
387  inline KeyIter end() const;
388 
389  /// Returns true if the Record contains key with given name.
390  inline bool has_key(const string& key) const;
391 
392  /// Returns number of keys in the Record.
393  inline unsigned int size() const;
394 
395  /**
396  * @brief Finish declaration of the Record type.
397  *
398  * Checks if Record is closed and completes Record (check auto convertible key, parameters of generic types etc).
399  */
400  FinishStatus finish(FinishStatus finish_type = FinishStatus::regular_) override;
401 
402  /**
403  * @brief Add TYPE key as obligatory.
404  *
405  * This method can't be used for derived record.
406  */
407  //Record &has_obligatory_type_key();
408 
409  Record &add_attribute(std::string key, TypeBase::json_string value);
410 
411  /// Implements @p TypeBase::make_instance.
412  virtual MakeInstanceReturnType make_instance(std::vector<ParameterPair> vec = std::vector<ParameterPair>()) override;
413 
414  /// Create deep copy of Record (copy all data stored in shared pointers etc.)
415  Record deep_copy() const;
416 
417  /**
418  * Mark the type to be root of a generic subtree.
419  * Such type can not appear in IST directly but only as the internal type
420  * of the Instance auxiliary object.
421  */
422  virtual Record &root_of_generic_subtree();
423 
424 
425 protected:
426 
427  /// Assertion for finished Type::Record.
428  inline void finished_check() const {
429  ASSERT(is_finished())(this->type_name()).error();
430  }
431 
432  /// Auxiliary method that actually makes the copy of keys.
433  void make_copy_keys(Record &origin);
434 
435  /**
436  * @brief Declares a TYPE key of the Record.
437  *
438  * TYPE key must be declared as first key of Record.
439  */
440  //Record &declare_type_key();
441 
442  /**
443  * @brief Set parent Abstract of Record.
444  *
445  * This method is created for correct functionality of generic types. It must be called
446  * in Abstract::finish() and refill @p parent_vec_ vector of correct parents (for complete
447  * mechanism of set parent and descendant see \p derive_from)
448  */
449  //const Record &add_parent(Abstract &parent) const;
450 
451  /**
452  * @brief Set data of Instance of generic type.
453  *
454  * Called from make_instance method and set data of Record or its descendants.
455  */
456  void set_instance_data(Record &rec, ParameterMap &parameter_map, std::vector<ParameterPair> vec);
457 
458  /**
459  * @brief Internal data class.
460  *
461  * Stores data of the Record.
462  */
463  class RecordData {
464  public:
465  /// Constructor
466  RecordData(const string & type_name_in, const string & description);
467 
468  /**
469  * @brief Declares a key and stores its type.
470  *
471  * The type parameter has to be finished at the call of declare_key().
472  * If the parameter @p type_temporary is NULL, the parameter @p type provides pointer to
473  * already finished type that will be assigned to the key. On the other hand, if @p type_temporary is not NULL,
474  * only this raw pointer is stored and key is fully completed later through TypeBase::lazy_finish().
475  */
476  void declare_key(const string &key,
477  std::shared_ptr<TypeBase> type,
478  const Default &default_value,
479  const string &description,
480  TypeBase::attribute_map key_attributes);
481 
482  /// Returns iterator to auto-conversion key.
483  Record::KeyIter auto_conversion_key_iter() const;
484 
485  /// Count hash of RecordData.
486  void content_hash(TypeBase::TypeHash &seed) const;
487 
488  /// Database of valid keys
490  /// Container-like access to the database of valid keys
492 
493  /// Keys in order as they where declared.
495 
496  /// Description of the whole record type.
497  const string description_;
498  /// Name of the whole record type.
499  const string type_name_;
500 
501  /// Permanent pointer to parent Abstract, necessary for output.
503 
504  /// Record is finished when it is correctly derived (optional) and have correct shared pointers to types in all keys.
506 
507  /// If record is closed, we do not allow any further declare_key calls.
508  bool closed_;
509 
510  /// True for derived records after make_derived.
511  bool derived_;
512 
513  /**
514  * @brief Index of auto convertible key.
515  *
516  * Initial value is = -1, when allow_auto_conversion is called we set this to 0.
517  * Final value can be assigned just after possible inheritance copy of keys from parent Abstract.
518  */
520 
521  /// Name of key to use for auto conversion.
522  std::string auto_conversion_key;
523 
524  };
525 
526  /// Data handle.
527  std::shared_ptr<RecordData> data_;
528 };
529 
530 
531 /*********************************************************
532  * Implementation
533  */
534 
535 
536 
537 
538 inline unsigned int Record::key_index(const string& key) const
539 {
540  KeyHash key_h = key_hash(key);
541  RecordData::key_to_index_const_iter it = data_->key_to_index.find(key_h);
542  if (it != data_->key_to_index.end()) return it->second;
543  else
544  THROW( ExcRecordKeyNotFound() << EI_KeyName(key) << EI_Record(*this) );
545 
546  return size();
547 }
548 
549 
550 
551 inline Record::KeyIter Record::key_iterator(const string& key) const
552 {
553 
554  finished_check();
555  return begin() + key_index(key);
556 }
557 
558 
559 
560 inline bool Record::has_key_iterator(const string& key, KeyIter &it) const
561 {
562  finished_check();
563  KeyHash key_h = key_hash(key);
564  RecordData::key_to_index_const_iter data_it = data_->key_to_index.find(key_h);
565  if (data_it == data_->key_to_index.end()) {
566  return false;
567  } else {
568  it = begin()+data_it->second;
569  return true;
570  }
571 }
572 
573 
574 
576 {
577  finished_check();
578  return data_->keys.begin();
579 }
580 
581 
582 
584 {
585  finished_check();
586  return data_->keys.end();
587 }
588 
589 
590 
591 inline bool Record::has_key(const string& key) const
592 {
593  return key_iterator(key) != end();
594 }
595 
596 
597 
598 inline unsigned int Record::size() const {
599  ASSERT(is_closed())(this->type_name()).error();
600  ASSERT_EQ(data_->keys.size(), data_->key_to_index.size()).error();
601  return data_->keys.size();
602 }
603 
604 
605 
606 
607 
608 
609 } // closing namespace Type
610 } // closing namespace Input
611 
612 
613 
614 
615 #endif /* TYPE_RECORD_HH_ */
Base of classes for declaring structure of the input data.
Definition: type_base.hh:99
Base class for nodes of a data storage tree.
Definition: storage.hh:68
No default value, optional key. This is default type of the Default.
Definition: type_record.hh:70
std::vector< struct Key >::const_iterator KeyIter
Public typedef of constant iterator into array of keys.
Definition: type_record.hh:216
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:598
TYPEDEF_ERR_INFO(EI_KeyName, const string)
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:61
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
Abstract linear system class.
Definition: equation.hh:37
DefaultType
Possible types of default values.
Definition: type_record.hh:67
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:491
std::vector< std::shared_ptr< Abstract > > parent_vec_
Permanent pointer to parent Abstract, necessary for output.
Definition: type_record.hh:502
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
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:505
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:110
unsigned int key_index(const string &key) const
Interface to mapping key -> index in record.
Definition: type_record.hh:538
Definitions of ASSERTS.
bool has_key(const string &key) const
Returns true if the Record contains key with given name.
Definition: type_record.hh:591
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
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:346
KeyIter key_iterator(const string &key) const
Returns iterator to the key struct for given key string.
Definition: type_record.hh:551
Input::StorageBase * storage_
Storage of default value read by reader.
Definition: type_record.hh:161
Some default value will be given when the key is read. The description of this value should be provid...
Definition: type_record.hh:69
KeyIter begin() const
Container-like access to the keys of the Record.
Definition: type_record.hh:575
bool is_optional() const
Returns true if the key is optional.
Definition: type_record.hh:141
static constexpr bool value
Definition: json.hpp:87
string description_
Key description in context of particular Record type.
Definition: type_record.hh:204
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
bool operator==(const Null &, const Null &)
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:124
bool derived_
True for derived records after make_derived.
Definition: type_record.hh:511
bool closed_
If record is closed, we do not allow any further declare_key calls.
Definition: type_record.hh:508
enum DefaultType type_
Type of the Default.
Definition: type_record.hh:160
const string description_
Description of the whole record type.
Definition: type_record.hh:497
string key_
Key identifier.
Definition: type_record.hh:203
Class for declaration of polymorphic Record.
Internal data class.
Definition: type_record.hh:463
Structure for description of one key in record.
Definition: type_record.hh:201
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
bool has_same_type(const Default &other) const
Compares values type_ of two Default objects.
Definition: type_record.hh:149
void finished_check() const
Assertion for finished Type::Record.
Definition: type_record.hh:428
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 has_key_iterator(const string &key, KeyIter &it) const
Returns iterator to the key struct for given key string.
Definition: type_record.hh:560
string value_
Stored value.
Definition: type_record.hh:159
Input::Type::TypeBase::attribute_map attributes
Key specific attributes.
Definition: type_record.hh:212
std::string auto_conversion_key
Name of key to use for auto conversion.
Definition: type_record.hh:522
int auto_conversion_key_idx
Index of auto convertible key.
Definition: type_record.hh:519
KeyIter end() const
Container-like access to the keys of the Record.
Definition: type_record.hh:583
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)
std::string json_string
String stored in JSON format.
Definition: type_base.hh:105
Record type proxy class.
Definition: type_record.hh:182
const string & value() const
Returns stored value. Possibly empty string.
Definition: type_record.hh:145
Default default_
Default, type and possibly value itself.
Definition: type_record.hh:206
std::vector< struct Key > keys
Keys in order as they where declared.
Definition: type_record.hh:494
std::shared_ptr< RecordData > data_
Data handle.
Definition: type_record.hh:527
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
Default value given at declaration time.
Definition: type_record.hh:68
std::size_t TypeHash
Type returned by content_hash methods.
Definition: type_base.hh:102
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
std::map< KeyHash, unsigned int > key_to_index
Database of valid keys.
Definition: type_record.hh:489
const string type_name_
Name of the whole record type.
Definition: type_record.hh:499
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual)
Definition: asserts.hh:327