Flow123d  last_with_con_2.0.0-663-gd0e2296
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 <vector>
29 #include <string>
30 #include <memory>
31 #include <cstdint>
32 #include <boost/type_traits.hpp>
33 #include <boost/mpl/if.hpp>
34 #include <boost/static_assert.hpp>
35 
36 #include "system/system.hh"
37 #include "system/exceptions.hh"
38 
39 #include "input/input_type.hh"
40 #include "input/factory.hh"
41 #include "input/storage.hh"
42 
43 #include "input/input_exception.hh"
44 
45 
46 
47 
48 
49 /****************************************************************
50  * Definition of macro that allows catch exception and adds address to given error info tag.
51  *
52  * Parameters:
53  * - ExceptionType: type of exception must be descendant of ExceptionBase
54  * - AddressEITag: error info tag of string type
55  * - input_accessor: accessor must be in non-pointer format and have to declare method address_string()
56  */
57 #define INPUT_CATCH(ExceptionType, AddressEITag, input_accessor) \
58  catch (ExceptionType &e ) { \
59  e << AddressEITag(input_accessor.address_string()); \
60  throw; \
61  }
62 
63 
64 
65 namespace Input {
66 
67 using std::string;
68 
69 
70 
71 
72 
73 
74 
75 // exceptions and error_info types
76 // throwed in Iterator<>
77 TYPEDEF_ERR_INFO( EI_InputType, const string);
78 TYPEDEF_ERR_INFO( EI_RequiredType, const string );
79 TYPEDEF_ERR_INFO( EI_CPPRequiredType, const string );
80 TYPEDEF_ERR_INFO( EI_KeyName, const string);
81 DECLARE_EXCEPTION( ExcTypeMismatch, << "Key:" << EI_KeyName::qval
82  << ". Can not construct Iterator<T> with C++ type T=" << EI_CPPRequiredType::qval << ";\n"
83  << "can not convert Type: " << EI_InputType::qval << " to: " << EI_RequiredType::qval
84  );
85 
86 // throwed in Record, Array, AbstractRecord
87 TYPEDEF_ERR_INFO( EI_AccessorName, const string );
88 DECLARE_EXCEPTION( ExcAccessorForNullStorage, << "Can not create " << EI_AccessorName::val << " from StorageNull.");
89 
90 // throwed in Address
91 TYPEDEF_ERR_INFO( EI_ParamName, const string);
92 DECLARE_EXCEPTION( ExcAddressNullPointer, << "NULL pointer in " << EI_ParamName::val << " parameter.");
93 
94 
95 
96 
97 /**
98  * Class that works as base type of all enum types. We need it to return integer from a Selection input without
99  * knowing exact enum type. This class contains int and is convertible to int.
100  *
101  * Usage example:
102  * @CODE
103  *
104  * // in some general read function that do not know BCTypeEnum
105  * int bc_type_int = record.val<Enum>("bc_type_selection_key");
106  * ...
107  * // outside of general function
108  * enum { dirichlet, neumann, newton } BCTypeEnum;
109  * BCTypeEnum bc_type = bc_typ_int;
110  * @ENDCODE
111  *
112  */
113 class Enum {
114 public:
115  Enum() : val_(0) {}
116  Enum(int v) :val_(v) {}
117  operator int() const {return val_;}
118  operator unsigned int() const {return val_;}
119 private:
120  int val_;
121 };
122 
123 class FullEnum {
124 public:
125  FullEnum() : val_(0) {}
126  FullEnum(int v, Input::Type::Selection sel) :val_(v), sel_(sel) { this->sel_ = sel; }
127  operator int() const {return this->val_;}
128  operator unsigned int() const {return this->val_;}
129  operator string() const {return this->sel_.int_to_name(this->val_); }
130 private:
131  int val_;
133 };
134 
135 // Forward declaration
136 class IteratorBase;
137 template <class T> class Iterator;
138 
139 class ReaderToStorage;
140 
141 /**
142  * Class for storing and formating input address of an accessor (necessary for input errors detected after readed).
143  *
144  * To get full path of an accessor we need:
145  * - root Input::Type
146  * - whole path through the storage
147  *
148  * TODO:
149  * - allow Address with NULL pointers, allow default constructor
150  * - How we can get Address with NULL pointer to storage? (currently we need Array::empty_storage_)
151  * - default constructor (should be called only by empty accessors)
152  * see if we can not get empty accessor in json_to_storage
153  * => empty address is error in program
154  * - test NULL pointers in Address::Address(.., ..) constructor
155  * - down ( pokud storage nemuze vracet null , tak zde take nedostaneme null)
156  *
157  * - find all places where we use Address::storage_head(), check NULL pointer there
158  * - where we need StorageArray::new_item() and if we can replace it by add_item()
159  */
160 class Address {
161 protected:
162  struct AddressData {
163  /**
164  * Pointer to data of parent node in the address tree
165  */
166  std::shared_ptr<AddressData> parent_;
167  /**
168  * Index in StorageArray of the parent_ to get actual node.
169  */
170  unsigned int descendant_order_;
171  /**
172  * Root of the Input::Type tree.
173  */
175  /**
176  * Root of the storage tree.
177  */
179  /**
180  * Actual storage - tip of the storage tree
181  */
183 
184  /**
185  * Delete whole storage tree when last root input accessor is destroyed.
186  */
188  if ( !parent_
189  && root_storage_ == actual_storage_
190  && root_type_ ) {
191  delete root_storage_;
192  }
193  }
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  : address_(address), index_(index)
689  {}
690 
691  /// Comparison of two Iterators. Do no compare types only position in the storage
692  inline bool operator == (const IteratorBase &that) const;
693 
694  inline bool operator != (const IteratorBase &that) const;
695 
696  /**
697  * Implicit conversion to bool. Returns true if iterator points to non-null storage.
698  */
699  inline operator bool() const;
700 
701  /**
702  * Return index in an array or record.
703  */
704  inline unsigned int idx() const;
705 
706  /**
707  * Returns address
708  */
709  const Address &get_address() const
710  { return address_; }
711 
712 
713 protected:
715  unsigned int index_;
716 };
717 
718 
719 
720 /**
721  * This class behaves like iterator to type @p T (the template parameter), but in fact it is
722  * iterator into input storage and also into tree of declarations through Input::Type classes.
723  *
724  * This class provides only limited functionality of iterators, namely prefix advance operator ++(),
725  * dereference operator * (), dereference operator -> (), comparison operators == and != and implicit conversion to
726  * bool (false in the case of the 'null' iterator).
727  *
728  *
729  * @ingroup input_accessors
730  */
731 template <class T>
732 class Iterator : public IteratorBase {
733 public:
734  /// Converts C++ type @p T (template parameter) to 'DispatchType' from smaller set of types.
735  typedef T DispatchType;
736  /**
737  * For small set of C++ types and accessor classes Record, AbstractRecord, and Array,
738  * returns type of value given by dereference of the iterator (just add const to C++ types).
739  */
741  /**
742  * A descendant of Input::Type::TypeBase that is appropriate to template parameter @p T.
743  */
745 
746 
747  /**
748  * Iterator is not default constructible.
749  *
750  * Constructor uses empty Address which causes error in program, Address has to be filled.
751  */
753 
754  /**
755  * Constructor. Creates iterator effectively pointing to data address_->get_storage()->get_item(index),
756  * that is parameter @p address points to StorageArray and parameter @p index gives index into this array.
757  * Parameter @p type is Input::Type of object the iterator points to.
758  *
759  *
760  */
761  Iterator(const Input::Type::TypeBase &type, const Address &address, const unsigned int index)
762  : IteratorBase(address, index), type_( type_check_and_convert(type))
763  {}
764 
765  /// Prefix. Advance operator.
766  inline Iterator<T> &operator ++ ();
767 
768  /// Prefix. Back operator.
769  inline Iterator<T> &operator -- ();
770 
771  /**
772  * Dereference operator * ; Shouldn't we return type T, i.e. try to cast from OutputType to T ??
773  */
774  inline OutputType operator *() const;
775 
776  /**
777  * Dereference operator can be used only for iterators to accessors Record, AbstractRecord, and Array.
778  */
779  inline OutputType *operator ->() const;
780 
781 
782 private:
783 
784  /**
785  * Check that Type::TypeBase reference is in fact object of InputType
786  * and returns converted copy (note that Type declaration objects are only handles.
787  */
788  static InputType type_check_and_convert(const Input::Type::TypeBase &type);
789 
790  /// Input type declaration.
791  InputType type_;
792 
793  /**
794  * temporary for -> operator, necessary only for T == DispatchType == OutputType
795  * == any accessor: Record, AbstractRecord, Array
796  *
797  * for other types this is just an int.
798  */
800 };
801 
802 
803 
804 
805 namespace internal {
806 
807 /**
808  * Template specializations for type dispatch.
809  */
810 
811 // Generic implementation can't be accepted.
812 template< class T, class Enable >
813 struct TypeDispatch {
814  class some_nonexisting_type;
815  static_assert( std::is_same<T, some_nonexisting_type>::value, "Wrong TypeDispatch type.");
816 };
817 
818 template<class T>
819 struct TypeDispatch<T, typename boost::enable_if<boost::is_enum<T> >::type> {
820  typedef T TmpType;
821 
823  typedef const TmpType ReadType;
824  static inline ReadType value(const Address &a, const InputType&) { return ReadType( a.storage_head()->get_int() ); }
825 };
826 
827 template<>
829  typedef Enum TmpType;
831  typedef const TmpType ReadType;
832  static inline ReadType value(const Address &a, const InputType&) { return ReadType( a.storage_head()->get_int() ); }
833 };
834 
835 template<>
837  typedef FullEnum TmpType;
839  typedef const TmpType ReadType;
840  static inline ReadType value(const Address &a, const InputType &t) { return ReadType( a.storage_head()->get_int(), t ); }
841 };
842 
843 template<class T>
844 struct TypeDispatch<T, typename boost::enable_if<boost::is_integral<T> >::type> {
846  typedef const int ReadType;
847  typedef int TmpType;
848  static inline ReadType value(const Address &a, const InputType&t) {
849  std::int64_t val = a.storage_head()->get_int();
850  if (val >= std::numeric_limits<T>::min() &&
851  val <= std::numeric_limits<T>::max() ) {
852  return val;
853  } else {
854  THROW( ExcInputMessage()
855  << EI_Message("Error in input file at address " + a.make_full_address() + ".\nValue out of bounds.") );
856  }
857  }
858 };
859 
860 template<>
861 struct TypeDispatch<bool> {
863  typedef const bool ReadType;
864  typedef int TmpType;
865  static inline ReadType value(const Address &a, const InputType&) { return a.storage_head()->get_bool(); }
866 };
867 
868 template<class T>
869 struct TypeDispatch<T, typename boost::enable_if<boost::is_float<T> >::type> {
871  typedef const double ReadType;
872  typedef int TmpType;
873  static inline ReadType value(const Address &a, const InputType&) { return a.storage_head()->get_double(); }
874 };
875 
876 
877 template<>
878 struct TypeDispatch<string> {
880  typedef const string ReadType;
881  typedef int TmpType;
882  static inline ReadType value(const Address &a, const InputType&) { return a.storage_head()->get_string(); }
883 };
884 
885 
886 template<>
891  static inline ReadType value(const Address &a, const InputType& t) { return AbstractRecord(a, t); }
892 };
893 
894 
895 template<>
898  typedef Record ReadType;
899  typedef Record TmpType;
900  static inline ReadType value(const Address &a, const InputType& t) { return Record(a,t); }
901 };
902 
903 
904 template<>
907  typedef Tuple ReadType;
908  typedef Tuple TmpType;
909  static inline ReadType value(const Address &a, const InputType& t) { return Tuple(a,t); }
910 };
911 
912 
913 template<>
916  typedef Array ReadType;
917  typedef Array TmpType;
918  static inline ReadType value(const Address &a, const InputType& t) { return Array(a,t); }
919 
920 };
921 
922 template<>
926  typedef int TmpType;
927  static inline ReadType value(const Address &a, const InputType& t) { return FilePath(a.storage_head()->get_string(), t.get_file_type() ); }
928 
929 };
930 
931 
932 
933 
934 } // closing namespace internal
935 
936 
937 
938 
939 
940 } // closing namespace Input
941 
942 
943 // include implementation of templates and inline methods
944 #include "accessors_impl.hh"
945 
946 
947 
948 #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:918
bool is_empty() const
Definition: accessors.hh:619
Base of classes for declaring structure of the input data.
Definition: type_base.hh:93
static ReadType value(const Address &a, const InputType &t)
Definition: accessors.hh:909
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:744
::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:206
virtual const std::string & get_string() const
Definition: storage.cc:50
Reader for (slightly) modified input files.
const StorageBase * root_storage_
Definition: accessors.hh:178
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:465
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)
Input::Type::Tuple tuple_type_
Corresponding Type::Tuple object.
Definition: accessors.hh:444
std::string make_full_address() const
Definition: accessors.cc:96
Input::Type::Selection InputType
Definition: accessors.hh:830
Address address_
Contains address and relationships with record ancestor.
Definition: accessors.hh:397
InputType type_
Input type declaration.
Definition: accessors.hh:791
::Input::Type::Abstract InputType
Definition: accessors.hh:461
Class for declaration of the input data that are file names.
Definition: type_base.hh:628
Input::Type::Array array_type_
Corresponding Type::Array.
Definition: accessors.hh:637
Class for declaration of the integral input data.
Definition: type_base.hh:496
const StorageBase * storage_head() const
Definition: accessors.hh:225
Class for declaration of inputs sequences.
Definition: type_base.hh:348
static constexpr bool value
Definition: json.hpp:87
unsigned int descendant_order_
Definition: accessors.hh:170
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:900
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:549
const Address & get_address() const
Definition: accessors.hh:709
internal::TypeDispatch< DispatchType >::TmpType temporary_value_
Definition: accessors.hh:799
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
static ReadType value(const Address &a, const InputType &t)
Definition: accessors.hh:927
Iterator(const Input::Type::TypeBase &type, const Address &address, const unsigned int index)
Definition: accessors.hh:761
bool is_empty() const
Definition: accessors.hh:366
Enum(int v)
Definition: accessors.hh:116
std::shared_ptr< AddressData > parent_
Definition: accessors.hh:166
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:182
Dedicated class for storing path to input and output files.
Definition: file_path.hh:48
static ReadType value(const Address &a, const InputType &)
Definition: accessors.hh:832
::Input::Type::Array InputType
Definition: accessors.hh:570
Tuple type proxy class.
Definition: type_tuple.hh:41
virtual bool get_bool() const
Definition: storage.cc:43
static ReadType value(const Address &a, const InputType &t)
Definition: accessors.hh:840
static ReadType value(const Address &a, const InputType &)
Definition: accessors.hh:882
T DispatchType
Converts C++ type T (template parameter) to &#39;DispatchType&#39; from smaller set of types.
Definition: accessors.hh:735
::FilePath::FileType get_file_type() const
Returns type of the file input/output.
Definition: type_base.hh:665
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:336
FullEnum(int v, Input::Type::Selection sel)
Definition: accessors.hh:126
::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:891
unsigned int index_
Definition: accessors.hh:715
const Input::Type::TypeBase * root_type_
Definition: accessors.hh:174
Record type proxy class.
Definition: type_record.hh:171
internal::TypeDispatch< DispatchType >::ReadType OutputType
Definition: accessors.hh:740
Accessor to the data with type Type::Tuple.
Definition: accessors.hh:412
IteratorBase(const Address &address, const unsigned int index)
Definition: accessors.hh:687
static ReadType value(const Address &a, const InputType &)
Definition: accessors.hh:865
Class for declaration of the input data that are in string format.
Definition: type_base.hh:599
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:45
Template for classes storing finite set of named values.
Input::Type::Selection sel_
Definition: accessors.hh:132
std::shared_ptr< AddressData > data_
Definition: accessors.hh:243
Address address_
Contains address and relationships with array ancestor.
Definition: accessors.hh:640