Flow123d  release_3.0.0-968-gc359144
accessors.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 accessors.hh
15  * @brief
16  * @todo
17  * - decide which part of interface has to be optimized ( probably nothing until we
18  * implement reader for HDF5, XML or large Raw data files, and try to use the same input interface for input of large data)
19  * - then make inlined only neccessary functions and carefully move as much as possible into accessors.cc including explicit instantiation of
20  * support classes. This should speedup compilation of the code that use the accessors.
21  * - implement operator -> without allocation (shared_ptr), i.e. put Accesors into Iterators
22  * Create corresponding accessor at construction of the iterator.
23  */
24 
25 #ifndef INPUT_INTERFACE_HH_
26 #define INPUT_INTERFACE_HH_
27 
28 #include <string>
29 #include <memory>
30 #include <cstdint>
31 #include <iosfwd> // for ostream
32 #include <limits> // for numeric_limits
33 #include <type_traits> // for is_same
34 #include "input/type_abstract.hh" // for Abstract
35 #include "input/type_base.hh" // for TypeBase (ptr ...
36 #include "input/type_record.hh" // for Record, Record...
37 #include "input/type_selection.hh" // for Selection
38 #include "input/type_tuple.hh" // for Tuple
39 #include "system/asserts.hh" // for Assert, ASSERT...
40 #include "system/exc_common.hh" // for EI_Message
41 #include "system/file_path.hh" // for FilePath
42 //namespace boost { template <typename T> struct is_enum; }
43 //namespace boost { template <typename T> struct is_float; }
44 //namespace boost { template <typename T> struct is_integral; }
45 
46 
47 #include "system/exceptions.hh"
48 //#include <boost/core/enable_if.hpp> // for enable_if
49 #include "input/storage.hh"
50 #include "input/input_exception.hh"
51 
52 
53 
54 
55 
56 /****************************************************************
57  * Definition of macro that allows catch exception and adds address to given error info tag.
58  *
59  * Parameters:
60  * - ExceptionType: type of exception must be descendant of ExceptionBase
61  * - AddressEITag: error info tag of string type
62  * - input_accessor: accessor must be in non-pointer format and have to declare method address_string()
63  */
64 #define INPUT_CATCH(ExceptionType, AddressEITag, input_accessor) \
65  catch (ExceptionType &e ) { \
66  e << AddressEITag(input_accessor.address_string()); \
67  throw; \
68  }
69 
70 
71 
72 namespace Input {
73 
74 using std::string;
75 
76 
77 
78 
79 
80 
81 
82 // exceptions and error_info types
83 // throwed in Iterator<>
84 TYPEDEF_ERR_INFO( EI_InputType, const string);
85 TYPEDEF_ERR_INFO( EI_RequiredType, const string );
86 TYPEDEF_ERR_INFO( EI_CPPRequiredType, const string );
87 TYPEDEF_ERR_INFO( EI_KeyName, const string);
88 DECLARE_EXCEPTION( ExcTypeMismatch, << "Key:" << EI_KeyName::qval
89  << ". Can not construct Iterator<T> with C++ type T=" << EI_CPPRequiredType::qval << ";\n"
90  << "can not convert Type: " << EI_InputType::qval << " to: " << EI_RequiredType::qval
91  );
92 
93 // throwed in Record, Array, AbstractRecord
94 TYPEDEF_ERR_INFO( EI_AccessorName, const string );
95 DECLARE_EXCEPTION( ExcAccessorForNullStorage, << "Can not create " << EI_AccessorName::val << " from StorageNull.");
96 
97 // throwed in Address
98 TYPEDEF_ERR_INFO( EI_ParamName, const string);
99 DECLARE_EXCEPTION( ExcAddressNullPointer, << "NULL pointer in " << EI_ParamName::val << " parameter.");
100 
101 
102 
103 
104 /**
105  * Class that works as base type of all enum types. We need it to return integer from a Selection input without
106  * knowing exact enum type. This class contains int and is convertible to int.
107  *
108  * Usage example:
109  * @CODE
110  *
111  * // in some general read function that do not know BCTypeEnum
112  * int bc_type_int = record.val<Enum>("bc_type_selection_key");
113  * ...
114  * // outside of general function
115  * enum { dirichlet, neumann, newton } BCTypeEnum;
116  * BCTypeEnum bc_type = bc_typ_int;
117  * @ENDCODE
118  *
119  */
120 class Enum {
121 public:
122  Enum() : val_(0) {}
123  Enum(int v) :val_(v) {}
124  operator int() const {return val_;}
125  operator unsigned int() const {return val_;}
126 private:
127  int val_;
128 };
129 
130 class FullEnum {
131 public:
132  FullEnum() : val_(0) {}
133  FullEnum(int v, Input::Type::Selection sel) :val_(v), sel_(sel) { this->sel_ = sel; }
134  operator int() const {return this->val_;}
135  operator unsigned int() const {return this->val_;}
136  operator string() const {return this->sel_.int_to_name(this->val_); }
137 private:
138  int val_;
140 };
141 
142 // Forward declaration
143 class IteratorBase;
144 template <class T> class Iterator;
145 
146 
147 /**
148  * Class for storing and formating input address of an accessor (necessary for input errors detected after readed).
149  *
150  * To get full path of an accessor we need:
151  * - root Input::Type
152  * - whole path through the storage
153  *
154  * TODO:
155  * - allow Address with NULL pointers, allow default constructor
156  * - How we can get Address with NULL pointer to storage? (currently we need Array::empty_storage_)
157  * - default constructor (should be called only by empty accessors)
158  * see if we can not get empty accessor in json_to_storage
159  * => empty address is error in program
160  * - test NULL pointers in Address::Address(.., ..) constructor
161  * - down ( pokud storage nemuze vracet null , tak zde take nedostaneme null)
162  *
163  * - find all places where we use Address::storage_head(), check NULL pointer there
164  * - where we need StorageArray::new_item() and if we can replace it by add_item()
165  */
166 class Address {
167 protected:
168  struct AddressData {
169  /**
170  * Pointer to data of parent node in the address tree
171  */
172  std::shared_ptr<AddressData> parent_;
173  /**
174  * Index in StorageArray of the parent_ to get actual node.
175  */
176  unsigned int descendant_order_;
177  /**
178  * Root of the Input::Type tree.
179  */
181  /**
182  * Root of the storage tree.
183  */
185  /**
186  * Actual storage - tip of the storage tree
187  */
189 
190  /**
191  * Delete whole storage tree when last root input accessor is destroyed.
192  */
193  ~AddressData();
194  };
195 
196 public:
197  /**
198  * Empty constructor.
199  *
200  * Constructor should be called only by empty accessors.
201  */
202  Address();
203 
204  /**
205  * Basic constructor. We forbids default one since we always need the root input type.
206  */
207  Address(const StorageBase * storage_root, const Type::TypeBase *type_root);
208 
209  /**
210  * Copy constructor.
211  * TODO: For optimization we can
212  * use one vector of storage pointers shared (using shared_ptr) by all accessors along the path.
213  */
214  Address(const Address &other);
215 
216  /**
217  * Dive deeper in the storage tree following index @p idx. Assumes that actual node
218  * is an StorageArray, has to be asserted.
219  */
220  std::shared_ptr<Address> down(unsigned int idx) const;
221 
222  /**
223  * Getter. Returns actual storage node.
224  */
225  inline const StorageBase * storage_head() const {
226  ASSERT_PTR(data_->actual_storage_).error();
227 
228  return data_->actual_storage_;
229  }
230 
231  /**
232  * Produce a full address, i.e. sequence of keys and indices separated by '/',
233  * that leads from the root storage and root Input::Type::TypeBase to the actual node in the storage
234  * that is nodes_[actual_node_].
235  */
236  std::string make_full_address() const;
237 
238 protected:
239 
240  /**
241  * Shared part of address.
242  */
243  std::shared_ptr<AddressData> data_;
244 
245 
246 };
247 
248 
249 
250 /**
251  * Address output operator.
252  */
253 inline std::ostream& operator<<(std::ostream& stream, const Address & address) {
254  return stream << address.make_full_address();
255 }
256 
257 
258 /**
259  * @brief Accessor to the data with type \p Type::Record.
260  *
261  * This class provides access to the data through names -- key of the data fields.
262  * It merge information from a @p Type::Record object, which describes valid keys and their types,
263  * and reference into a StorageBase that provides access to actual values.
264  *
265  * The keys that are obligatory or has specified default value can be read either by the method template \p val<OutputType>
266  * which returns the value of type \p OutputType that should be compatible with declared type (i.e. you can get unsigned int from
267  * an input value of type Type:Integer, but not from an input value of type Type::String).
268  *
269  * The keys which are optional and has no default value you has to use
270  * the method template \p find<OutputType> that returns an iterator to the type OutputType, which is invalid if the value
271  * is missing on the input and no the default string is provided.
272  *
273  * Usage:
274  @code
275  using namespace Input;
276  Record record = some_other_record.val<Record>("output_format");
277  // reading an obligatory key or key with default value
278  int n_digis = record.val<int>("number_of_substances");
279  // reading an optional key
280  Iterator<Array> it = record.find<Array>("substances_names");
281  if ( it ) {
282  it->copy_to( list_of_names );
283  } else {
284  // generic names of substances
285  }
286 
287  @endcode
288  *
289  * @ingroup input_accessors
290  *
291  */
292 class Record {
293 
294 public:
295  typedef ::Input::Type::Record InputType;
296  /**
297  * Default constructor.
298  *
299  * Constructor uses empty Address which causes error in program, Address has to be filled.
300  */
301  Record();
302 
303  /**
304  * Copy constructor.
305  */
306  Record(const Record &rec);
307 
308  /**
309  * Constructs the accessor providing pointer \p store to storage node with list of data of the record and
310  * type specification of the record given by parameter \p type.
311  */
312  Record(const Address &address, const Type::Record type);
313 
314  /**
315  * Returns value of given @p key if the declared key type (descendant of @p Input:Type:TypeBase) is convertible to the C++
316  * class type given as the template parameter. If the key has no defined value
317  * (either from input or a declared default value) it throws an exception. It throws also, if the
318  * declared type do not match desired C++ type.
319  *
320  * This method can be used only for keys which are obligatory or has default value given at declaration.
321  * The optional keys must use method @p find. Keys with default value at read time must use
322  * the overloaded variant of method @p val or the method @p find
323  *
324  */
325  template <class Ret>
326  inline const Ret val(const string &key) const;
327 
328  /**
329  * Same as the previous, but you can specify default value @p default_val that is used if the key is not specified at the input.
330  * This method can be used only for keys declared with Default::reat_time().
331  */
332  template <class Ret>
333  inline const Ret val(const string &key, const Ret default_val) const;
334 
335 
336  /**
337  * Returns iterator to the key if it exists or NULL Iterator if it doesn't.
338  * This method must be used for keys which are optional or has default value provided at read time.
339  */
340  template <class Ret>
341  inline Iterator<Ret> find(const string &key) const;
342 
343  /**
344  * This has similar function as the previous method, but simpler usage in some cases. You has to provide reference to the variable @p value
345  * where the value of an optional @p key should be placed. If the key in not present in the input the value of @p value is not changed
346  * and the method returns false. If the key has a value the method returns true. Typical usage:
347  * @code
348  * double param;
349  * string other_param;
350  * if (rec.opt_val("optional_param", param) ) {
351  * use_param(param);
352  * } else if (rec.opt_val("other_param", other_param) ) {
353  * use_other_param(other_param);
354  * } else {
355  * ... error, no value for param
356  * }
357  * @endcode
358  */
359  template <class Ret>
360  inline bool opt_val(const string &key, Ret &value) const;
361 
362  /**
363  * Returns true if the accessor is empty (after default constructor).
364  * TODO: have something similar for other accessors.
365  */
366  inline bool is_empty() const
367  { return (address_.storage_head() == Address().storage_head()); }
368 
369  /**
370  * Returns address error info.
371  */
372  EI_Address ei_address() const ;
373 
374  /**
375  * Get address as string.
376  */
377  string address_string() const;
378 
379  /**
380  * Get name of record_type_
381  */
382  virtual string input_type_name();
383 
384 
385 
386 protected:
387  /**
388  * Set address (currently necessary for creating root accessor)
389  */
390  void set_address(const Address &address);
391  friend class ReaderToStorage;
392 
393  /// Return iterator to Type::Record key of given name
394  virtual Type::Record::KeyIter get_type_key_iterator(const string &key) const;
395 
396  /// Contains address and relationships with record ancestor
398 
399 private:
400  /// Corresponding Type::Record object.
402  friend class AbstractRecord;
403 };
404 
405 
406 
407 /**
408  * @brief Accessor to the data with type \p Type::Tuple.
409  *
410  * @ingroup input_accessors
411  */
412 class Tuple : public Record {
413 public:
414  typedef ::Input::Type::Tuple InputType;
415  /**
416  * Default constructor.
417  *
418  * Constructor uses empty Address which causes error in program, Address has to be filled.
419  */
420  Tuple();
421 
422  /**
423  * Copy constructor.
424  */
425  Tuple(const Tuple &tpl);
426 
427  /**
428  * Constructs the accessor providing pointer \p store to storage node with list of data of the tuple and
429  * type specification of the tuple given by parameter \p type.
430  */
431  Tuple(const Address &address, const Type::Tuple type);
432 
433  /**
434  * Get name of tuple_type_
435  */
436  string input_type_name() override;
437 
438 protected:
439  /// Return iterator to Type::Tuple key of given name
440  Type::Record::KeyIter get_type_key_iterator(const string &key) const override;
441 
442 private:
443  /// Corresponding Type::Tuple object.
445 
446 };
447 
448 
449 /**
450  * @brief Accessor to the polymorphic input data of a type given by an AbstracRecord object.
451  *
452  * Provides conversion operator to the Record accessor in ordred to behave in the same way, but
453  * further it provides method \p type() that can be used to call constructor of the class corresponding to the
454  * input data.
455  *
456  * @ingroup input_accessors
457  */
458 
460 public:
461  typedef ::Input::Type::Abstract InputType;
462 
463  /**
464  * Default constructor creates an empty accessor.
465  *
466  * Constructor uses empty Address which causes error in program, Address has to be filled.
467  */
468  AbstractRecord();
469 
470  /**
471  * Copy constructor.
472  */
473  AbstractRecord(const AbstractRecord &rec);
474 
475  /**
476  * Constructs the accessor providing pointer \p store to storage node with list of data of the record and
477  * type specification of the record given by parameter \p type.
478  */
479  AbstractRecord(const Address &address, const Type::Abstract type);
480 
481  /**
482  * Implicit conversion to the \p Input::Record accessor. You can use \p Input::AbstractRecord in the same
483  * way as the \p Input::Record.
484  */
485  operator Record() const;
486 
487  /**
488  * Returns particular type selected from input. You can use it to construct particular type.
489  *
490  * @code
491  * class MyClass {
492  * MyClass( Input::Record );
493  * }
494  *
495  * if (abstract_record.type() == MyClass.get_input_type())
496  * my_class = new MyClass(abstract_record); // here the implicit conversion to Input::Record is used
497  * @endcode
498  */
499  Input::Type::Record type() const;
500 
501  /**
502  * Returns address error info.
503  */
504  EI_Address ei_address() const ;
505 
506  /**
507  * Get address as string.
508  */
509  string address_string() const;
510 
511  /**
512  * Construct classes given by TYPE key of AbstractRecord.
513  *
514  * Method uses Input::Factory class. All constructed classes (representing by descendants
515  * of AbstractRecord) must be registered to factory (see Input::Factory class) and must have
516  * constructors with same parameters (given by Arguments).
517  */
518  template<class Type, class... Arguments>
519  const std::shared_ptr<Type> factory(Arguments... arguments) const;
520 
521 
522 private:
523  /// Corresponding Type::Abstract object.
525 
526  /// Contains address and relationships with abstract record ancestor
528 };
529 
530 
531 
532 /**
533  * @brief Accessor to input data conforming to declared Array.
534  *
535  * There are two possible ways how to retrieve data from Array accessor. First, you can use generic
536  * @p copy_to function to copy the data into a given container. Second, you can get an Iterator<Type>
537  * and iterate through the Array. Unfortunately, you have to provide Type to the begin() method so this
538  * implementation is not fully compliant with standard library. The reason is that in order to speed up compilation of many
539  * classes using input accessors we wouldn't have Input::Array a class template that it can be compiled only once.
540  * By this reason one can not use BOOST_FOREACH to iterate over Input::Array.
541  * TODO: Make Input::Array<Type> wrapper which is compliant with standard library.
542  *
543  * In either case correspondence between resulting type (i.e. type of elements of the container or type of the Iterator)
544  * and the type of the data in the Array is checked only once.
545  *
546  * Example of usage:
547  * @code
548  * Input::Array decay_array = in_rec.val<Input::Array>("decays"); // get accessor to an array stored under key 'decays'
549  * int size = decay_array.size(); // get size of the actual arrya in the input (possibly for allocation)
550  *
551  * for(Input::Iterator<Input::Record> it = decay_array.begin<Input::Record>() // pass through the array, that is array of records
552  * ; it != dacay_array.end(); ++it) {
553  *
554  * Input::Iterator<double> it_hl = it->find<double>("half_life"); // check existence of an optional key
555  * if (it_hl) {
556  * double hl = *it_hl;
557  * } else {
558  * // use some other value, or turn-off the decay
559  * }
560  * Input::Array products = it->val<Input::Array>("products"); // read an obligatory key, theat conatins an array
561  * // ... process the array 'products'
562  * }
563  * @endcode
564  *
565  * @ingroup input_accessors
566  */
567 class Array {
568 public:
569 
570  typedef ::Input::Type::Array InputType;
571 
572  /**
573  * Default constructor, empty accessor.
574  *
575  * Constructor uses empty Address which causes error in program, Address has to be filled.
576  */
577  Array();
578 
579  /**
580  * Copy constructor.
581  */
582  Array(const Array &ar);
583 
584  /**
585  * Constructs the accessor providing pointer \p store to storage node with list of data of the record and
586  * type specification of the record given by parameter \p type.
587  */
588  Array(const Address &address, const Type::Array type);
589 
590  /**
591  * Returns iterator to the first element of input array. The template parameter is C++ type you want to
592  * read from the array. Only types supported by Input::Interface::Iterator can be used.
593  */
594  template <class ValueType>
595  inline Iterator<ValueType> begin() const;
596 
597  /**
598  * Returns end iterator common to all iterators inner types.
599  */
600  inline IteratorBase end() const;
601 
602  /**
603  * Actual size of the input array.
604  */
605  inline unsigned int size() const;
606 
607  /**
608  * Method to fill the given container @p out with data in the input Array.
609  * The container has to have methods @p clear and @p push_back. The C++ type of the
610  * values in the container has to be supported by Iterator<T>.
611  */
612  template <class Container>
613  void copy_to(Container &out) const;
614 
615  /**
616  * Returns true if the accessor is empty (after default constructor).
617  * TODO: have something similar for other accessors.
618  */
619  inline bool is_empty() const
620  { return (address_.storage_head() == Address().storage_head()); }
621 
622  /**
623  * Returns address error info.
624  */
625  EI_Address ei_address() const ;
626 
627  /**
628  * Get address as string.
629  */
630  string address_string() const;
631 
632  /// Need persisting empty instance of StorageArray that can be used to create an empty Address.
634 
635 private:
636  /// Corresponding Type::Array.
638 
639  /// Contains address and relationships with array ancestor
641 
642 
643 };
644 
645 
646 /*TODO:
647  * Fast variant of RecordRead for reading array of records of same type. Has sense only for buffered input
648  * storage and large data.
649  *
650  * usage:
651  *
652  * Array<FastRecordReader> a_of_fr;
653  * FastRecordReader::iterator<double> iter_x = a_of_fr.get_type().iter_of_key<double>("x");
654  * FastRecordReader::iterator<double> iter_y = a_of_fr.get_type().iterof_key<double>("y");
655  * for(Array<FastRecordReader>::iterator it=a_of_fr.begin(); it != a_of_fr.end(); ++it) {
656  * it->fast_get(iter_x);
657  * it->fast_get(iter_y);
658  * }
659  *
660  */
661 
662 
663 namespace internal {
664 
665  /**
666  * Primary type dispatch. For every intermediate C++ type that can be read from input we have to define
667  * read function from a given storage and Input type i.e. descendant of Input::Type::TypeBase.
668  */
669 
670  template<class T, class Enable = void>
671  struct TypeDispatch;
672 } // close namespace internal
673 
674 
675 /**
676  * Base class of input Iterator<Type> template. Main reason is possibility to construct
677  * invalid iterator without template parameter ( used in \p Array::end() )
678  */
680 public:
681 
682  /**
683  * Constructor. Creates iterator effectively pointing to data address_->get_storage()->get_item(index),
684  * that is parameter @p address points to StorageArray and parameter @p index gives index into this array.
685  *
686  */
687  IteratorBase(const Address &address, const unsigned int index);
688 
689  /// Comparison of two Iterators. Do no compare types only position in the storage
690  inline bool operator == (const IteratorBase &that) const;
691 
692  inline bool operator != (const IteratorBase &that) const;
693 
694  /**
695  * Implicit conversion to bool. Returns true if iterator points to non-null storage.
696  */
697  inline operator bool() const;
698 
699  /**
700  * Return index in an array or record.
701  */
702  inline unsigned int idx() const;
703 
704  /**
705  * Returns address
706  */
707  const Address &get_address() const;
708 
709 
710 protected:
712  unsigned int index_;
713 };
714 
715 
716 
717 /**
718  * This class behaves like iterator to type @p T (the template parameter), but in fact it is
719  * iterator into input storage and also into tree of declarations through Input::Type classes.
720  *
721  * This class provides only limited functionality of iterators, namely prefix advance operator ++(),
722  * dereference operator * (), dereference operator -> (), comparison operators == and != and implicit conversion to
723  * bool (false in the case of the 'null' iterator).
724  *
725  *
726  * @ingroup input_accessors
727  */
728 template <class T>
729 class Iterator : public IteratorBase {
730 public:
731  /// Converts C++ type @p T (template parameter) to 'DispatchType' from smaller set of types.
732  typedef T DispatchType;
733  /**
734  * For small set of C++ types and accessor classes Record, AbstractRecord, and Array,
735  * returns type of value given by dereference of the iterator (just add const to C++ types).
736  */
738  /**
739  * A descendant of Input::Type::TypeBase that is appropriate to template parameter @p T.
740  */
742 
743 
744  /**
745  * Iterator is not default constructible.
746  *
747  * Constructor uses empty Address which causes error in program, Address has to be filled.
748  */
750 
751  /**
752  * Constructor. Creates iterator effectively pointing to data address_->get_storage()->get_item(index),
753  * that is parameter @p address points to StorageArray and parameter @p index gives index into this array.
754  * Parameter @p type is Input::Type of object the iterator points to.
755  *
756  *
757  */
758  Iterator(const Input::Type::TypeBase &type, const Address &address, const unsigned int index)
759  : IteratorBase(address, index), type_( type_check_and_convert(type))
760  {}
761 
762  /// Prefix. Advance operator.
763  inline Iterator<T> &operator ++ ();
764 
765  /// Prefix. Back operator.
766  inline Iterator<T> &operator -- ();
767 
768  /**
769  * Dereference operator * ; Shouldn't we return type T, i.e. try to cast from OutputType to T ??
770  */
771  inline OutputType operator *() const;
772 
773  /**
774  * Dereference operator can be used only for iterators to accessors Record, AbstractRecord, and Array.
775  */
776  inline OutputType *operator ->() const;
777 
778 
779 private:
780 
781  /**
782  * Check that Type::TypeBase reference is in fact object of InputType
783  * and returns converted copy (note that Type declaration objects are only handles.
784  */
785  static InputType type_check_and_convert(const Input::Type::TypeBase &type);
786 
787  /// Input type declaration.
788  InputType type_;
789 
790  /**
791  * temporary for -> operator, necessary only for T == DispatchType == OutputType
792  * == any accessor: Record, AbstractRecord, Array
793  *
794  * for other types this is just an int.
795  */
797 };
798 
799 
800 
801 
802 namespace internal {
803 
804 /**
805  * Template specializations for type dispatch.
806  */
807 
808 // Generic implementation can't be accepted.
809 template< class T, class Enable >
810 struct TypeDispatch {
811  class some_nonexisting_type;
812  static_assert( std::is_same<T, some_nonexisting_type>::value, "Wrong TypeDispatch type.");
813 };
814 
815 template<class T>
816 struct TypeDispatch<T, typename std::enable_if<std::is_enum<T>::value >::type> {
817  typedef T TmpType;
818 
820  typedef const TmpType ReadType;
821  static inline ReadType value(const Address &a, const InputType&) { return ReadType( a.storage_head()->get_int() ); }
822 };
823 
824 template<>
826  typedef Enum TmpType;
828  typedef const TmpType ReadType;
829  static inline ReadType value(const Address &a, const InputType&) { return ReadType( a.storage_head()->get_int() ); }
830 };
831 
832 template<>
834  typedef FullEnum TmpType;
836  typedef const TmpType ReadType;
837  static inline ReadType value(const Address &a, const InputType &t) { return ReadType( a.storage_head()->get_int(), t ); }
838 };
839 
840 template<class T>
841 struct TypeDispatch<T, typename std::enable_if<std::is_integral<T>::value >::type> {
843  typedef const int ReadType;
844  typedef int TmpType;
845  static inline ReadType value(const Address &a, const InputType&t) {
846  std::int64_t val = a.storage_head()->get_int();
847  if (val >= std::numeric_limits<T>::min() &&
848  val <= std::numeric_limits<T>::max() ) {
849  return val;
850  } else {
851  THROW( ExcInputMessage()
852  << EI_Message("Error in input file at address " + a.make_full_address() + ".\nValue out of bounds.") );
853  }
854  }
855 };
856 
857 template<>
858 struct TypeDispatch<bool> {
860  typedef const bool ReadType;
861  typedef int TmpType;
862  static inline ReadType value(const Address &a, const InputType&) { return a.storage_head()->get_bool(); }
863 };
864 
865 template<class T>
866 struct TypeDispatch<T, typename std::enable_if<std::is_floating_point<T>::value >::type> {
868  typedef const double ReadType;
869  typedef int TmpType;
870  static inline ReadType value(const Address &a, const InputType&) { return a.storage_head()->get_double(); }
871 };
872 
873 
874 template<>
875 struct TypeDispatch<string> {
877  typedef const string ReadType;
878  typedef int TmpType;
879  static inline ReadType value(const Address &a, const InputType&) { return a.storage_head()->get_string(); }
880 };
881 
882 
883 template<>
888  static inline ReadType value(const Address &a, const InputType& t) { return AbstractRecord(a, t); }
889 };
890 
891 
892 template<>
895  typedef Record ReadType;
896  typedef Record TmpType;
897  static inline ReadType value(const Address &a, const InputType& t) { return Record(a,t); }
898 };
899 
900 
901 template<>
904  typedef Tuple ReadType;
905  typedef Tuple TmpType;
906  static inline ReadType value(const Address &a, const InputType& t) { return Tuple(a,t); }
907 };
908 
909 
910 template<>
913  typedef Array ReadType;
914  typedef Array TmpType;
915  static inline ReadType value(const Address &a, const InputType& t) { return Array(a,t); }
916 
917 };
918 
919 template<>
923  typedef int TmpType;
924  static inline ReadType value(const Address &a, const InputType& t) { return FilePath(a.storage_head()->get_string(), t.get_file_type() ); }
925 
926 };
927 
928 
929 
930 
931 } // closing namespace internal
932 
933 
934 
935 
936 
937 } // closing namespace Input
938 
939 
940 // include implementation of templates and inline methods
941 #include "accessors_impl.hh"
942 
943 
944 
945 #endif
Address address_
Contains address and relationships with abstract record ancestor.
Definition: accessors.hh:527
static ReadType value(const Address &a, const InputType &t)
Definition: accessors.hh:915
bool is_empty() const
Definition: accessors.hh:619
Base of classes for declaring structure of the input data.
Definition: type_base.hh:99
static ReadType value(const Address &a, const InputType &t)
Definition: accessors.hh:906
Base class for nodes of a data storage tree.
Definition: storage.hh:68
virtual std::int64_t get_int() const
Definition: storage.cc:29
internal::TypeDispatch< DispatchType >::InputType InputType
Definition: accessors.hh:741
::Input::Type::Record InputType
Definition: accessors.hh:295
Accessor to input data conforming to declared Array.
Definition: accessors.hh:567
std::vector< struct Key >::const_iterator KeyIter
Public typedef of constant iterator into array of keys.
Definition: type_record.hh:216
virtual const std::string & get_string() const
Definition: storage.cc:50
Reader for (slightly) modified input files.
const StorageBase * root_storage_
Definition: accessors.hh:184
std::ostream & operator<<(std::ostream &stream, const Address &address)
Definition: accessors.hh:253
Class for declaration of the input of type Bool.
Definition: type_base.hh:459
DECLARE_EXCEPTION(ExcTypeMismatch,<< "Key:"<< EI_KeyName::qval<< ". Can not construct Iterator<T> with C++ type T="<< EI_CPPRequiredType::qval<< ";\n"<< "can not convert Type: "<< EI_InputType::qval<< " to: "<< EI_RequiredType::qval)
Abstract linear system class.
Definition: balance.hh:35
Input::Type::Tuple tuple_type_
Corresponding Type::Tuple object.
Definition: accessors.hh:444
std::string make_full_address() const
Definition: accessors.cc:105
Input::Type::Selection InputType
Definition: accessors.hh:827
Definitions of ASSERTS.
Address address_
Contains address and relationships with record ancestor.
Definition: accessors.hh:397
InputType type_
Input type declaration.
Definition: accessors.hh:788
::Input::Type::Abstract InputType
Definition: accessors.hh:461
Class for declaration of the input data that are file names.
Definition: type_base.hh:618
Input::Type::Array array_type_
Corresponding Type::Array.
Definition: accessors.hh:637
Class for declaration of the integral input data.
Definition: type_base.hh:490
const StorageBase * storage_head() const
Definition: accessors.hh:225
Class for declaration of inputs sequences.
Definition: type_base.hh:346
static constexpr bool value
Definition: json.hpp:87
unsigned int descendant_order_
Definition: accessors.hh:176
UnitSI operator*(const UnitSI &a, const UnitSI &b)
Product of two units.
Definition: unit_si.cc:235
Input::Type::Record record_type_
Corresponding Type::Record object.
Definition: accessors.hh:401
Input::Type::Abstract abstract_type_
Corresponding Type::Abstract object.
Definition: accessors.hh:524
static ReadType value(const Address &a, const InputType &t)
Definition: accessors.hh:897
bool operator==(const Null &, const Null &)
virtual double get_double() const
Definition: storage.cc:36
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:541
internal::TypeDispatch< DispatchType >::TmpType temporary_value_
Definition: accessors.hh:796
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
static ReadType value(const Address &a, const InputType &t)
Definition: accessors.hh:924
Iterator(const Input::Type::TypeBase &type, const Address &address, const unsigned int index)
Definition: accessors.hh:758
bool is_empty() const
Definition: accessors.hh:366
Enum(int v)
Definition: accessors.hh:123
::FilePath::FileType get_file_type() const
Returns type of the file input/output.
Definition: type_base.cc:582
std::shared_ptr< AddressData > parent_
Definition: accessors.hh:172
Class for declaration of polymorphic Record.
static StorageArray empty_storage_
Need persisting empty instance of StorageArray that can be used to create an empty Address...
Definition: accessors.hh:633
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:459
const StorageBase * actual_storage_
Definition: accessors.hh:188
Dedicated class for storing path to input and output files.
Definition: file_path.hh:54
static ReadType value(const Address &a, const InputType &)
Definition: accessors.hh:829
::Input::Type::Array InputType
Definition: accessors.hh:570
Tuple type proxy class.
Definition: type_tuple.hh:45
virtual bool get_bool() const
Definition: storage.cc:43
static ReadType value(const Address &a, const InputType &t)
Definition: accessors.hh:837
static ReadType value(const Address &a, const InputType &)
Definition: accessors.hh:879
T DispatchType
Converts C++ type T (template parameter) to &#39;DispatchType&#39; from smaller set of types.
Definition: accessors.hh:732
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:335
FullEnum(int v, Input::Type::Selection sel)
Definition: accessors.hh:133
::Input::Type::Tuple InputType
Definition: accessors.hh:414
TYPEDEF_ERR_INFO(EI_InputType, const string)
static ReadType value(const Address &a, const InputType &t)
Definition: accessors.hh:888
unsigned int index_
Definition: accessors.hh:712
const Input::Type::TypeBase * root_type_
Definition: accessors.hh:180
Record type proxy class.
Definition: type_record.hh:182
internal::TypeDispatch< DispatchType >::ReadType OutputType
Definition: accessors.hh:737
Accessor to the data with type Type::Tuple.
Definition: accessors.hh:412
static ReadType value(const Address &a, const InputType &)
Definition: accessors.hh:862
Class for declaration of the input data that are in string format.
Definition: type_base.hh:589
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
Template for classes storing finite set of named values.
Input::Type::Selection sel_
Definition: accessors.hh:139
std::shared_ptr< AddressData > data_
Definition: accessors.hh:243
Address address_
Contains address and relationships with array ancestor.
Definition: accessors.hh:640