Flow123d  release_2.1.0-87-gfbc1563
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  */
187  ~AddressData();
188  };
189 
190 public:
191  /**
192  * Empty constructor.
193  *
194  * Constructor should be called only by empty accessors.
195  */
196  Address();
197 
198  /**
199  * Basic constructor. We forbids default one since we always need the root input type.
200  */
201  Address(const StorageBase * storage_root, const Type::TypeBase *type_root);
202 
203  /**
204  * Copy constructor.
205  * TODO: For optimization we can
206  * use one vector of storage pointers shared (using shared_ptr) by all accessors along the path.
207  */
208  Address(const Address &other);
209 
210  /**
211  * Dive deeper in the storage tree following index @p idx. Assumes that actual node
212  * is an StorageArray, has to be asserted.
213  */
214  std::shared_ptr<Address> down(unsigned int idx) const;
215 
216  /**
217  * Getter. Returns actual storage node.
218  */
219  inline const StorageBase * storage_head() const {
220  ASSERT_PTR(data_->actual_storage_).error();
221 
222  return data_->actual_storage_;
223  }
224 
225  /**
226  * Produce a full address, i.e. sequence of keys and indices separated by '/',
227  * that leads from the root storage and root Input::Type::TypeBase to the actual node in the storage
228  * that is nodes_[actual_node_].
229  */
230  std::string make_full_address() const;
231 
232 protected:
233 
234  /**
235  * Shared part of address.
236  */
237  std::shared_ptr<AddressData> data_;
238 
239 
240 };
241 
242 
243 
244 /**
245  * Address output operator.
246  */
247 inline std::ostream& operator<<(std::ostream& stream, const Address & address) {
248  return stream << address.make_full_address();
249 }
250 
251 
252 /**
253  * @brief Accessor to the data with type \p Type::Record.
254  *
255  * This class provides access to the data through names -- key of the data fields.
256  * It merge information from a @p Type::Record object, which describes valid keys and their types,
257  * and reference into a StorageBase that provides access to actual values.
258  *
259  * The keys that are obligatory or has specified default value can be read either by the method template \p val<OutputType>
260  * which returns the value of type \p OutputType that should be compatible with declared type (i.e. you can get unsigned int from
261  * an input value of type Type:Integer, but not from an input value of type Type::String).
262  *
263  * The keys which are optional and has no default value you has to use
264  * the method template \p find<OutputType> that returns an iterator to the type OutputType, which is invalid if the value
265  * is missing on the input and no the default string is provided.
266  *
267  * Usage:
268  @code
269  using namespace Input;
270  Record record = some_other_record.val<Record>("output_format");
271  // reading an obligatory key or key with default value
272  int n_digis = record.val<int>("number_of_substances");
273  // reading an optional key
274  Iterator<Array> it = record.find<Array>("substances_names");
275  if ( it ) {
276  it->copy_to( list_of_names );
277  } else {
278  // generic names of substances
279  }
280 
281  @endcode
282  *
283  * @ingroup input_accessors
284  *
285  */
286 class Record {
287 
288 public:
289  typedef ::Input::Type::Record InputType;
290  /**
291  * Default constructor.
292  *
293  * Constructor uses empty Address which causes error in program, Address has to be filled.
294  */
295  Record();
296 
297  /**
298  * Copy constructor.
299  */
300  Record(const Record &rec);
301 
302  /**
303  * Constructs the accessor providing pointer \p store to storage node with list of data of the record and
304  * type specification of the record given by parameter \p type.
305  */
306  Record(const Address &address, const Type::Record type);
307 
308  /**
309  * Returns value of given @p key if the declared key type (descendant of @p Input:Type:TypeBase) is convertible to the C++
310  * class type given as the template parameter. If the key has no defined value
311  * (either from input or a declared default value) it throws an exception. It throws also, if the
312  * declared type do not match desired C++ type.
313  *
314  * This method can be used only for keys which are obligatory or has default value given at declaration.
315  * The optional keys must use method @p find. Keys with default value at read time must use
316  * the overloaded variant of method @p val or the method @p find
317  *
318  */
319  template <class Ret>
320  inline const Ret val(const string &key) const;
321 
322  /**
323  * 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.
324  * This method can be used only for keys declared with Default::reat_time().
325  */
326  template <class Ret>
327  inline const Ret val(const string &key, const Ret default_val) const;
328 
329 
330  /**
331  * Returns iterator to the key if it exists or NULL Iterator if it doesn't.
332  * This method must be used for keys which are optional or has default value provided at read time.
333  */
334  template <class Ret>
335  inline Iterator<Ret> find(const string &key) const;
336 
337  /**
338  * This has similar function as the previous method, but simpler usage in some cases. You has to provide reference to the variable @p value
339  * 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
340  * and the method returns false. If the key has a value the method returns true. Typical usage:
341  * @code
342  * double param;
343  * string other_param;
344  * if (rec.opt_val("optional_param", param) ) {
345  * use_param(param);
346  * } else if (rec.opt_val("other_param", other_param) ) {
347  * use_other_param(other_param);
348  * } else {
349  * ... error, no value for param
350  * }
351  * @endcode
352  */
353  template <class Ret>
354  inline bool opt_val(const string &key, Ret &value) const;
355 
356  /**
357  * Returns true if the accessor is empty (after default constructor).
358  * TODO: have something similar for other accessors.
359  */
360  inline bool is_empty() const
361  { return (address_.storage_head() == Address().storage_head()); }
362 
363  /**
364  * Returns address error info.
365  */
366  EI_Address ei_address() const ;
367 
368  /**
369  * Get address as string.
370  */
371  string address_string() const;
372 
373  /**
374  * Get name of record_type_
375  */
376  virtual string input_type_name();
377 
378 
379 
380 protected:
381  /**
382  * Set address (currently necessary for creating root accessor)
383  */
384  void set_address(const Address &address);
385  friend class ReaderToStorage;
386 
387  /// Return iterator to Type::Record key of given name
388  virtual Type::Record::KeyIter get_type_key_iterator(const string &key) const;
389 
390  /// Contains address and relationships with record ancestor
392 
393 private:
394  /// Corresponding Type::Record object.
396  friend class AbstractRecord;
397 };
398 
399 
400 
401 /**
402  * @brief Accessor to the data with type \p Type::Tuple.
403  *
404  * @ingroup input_accessors
405  */
406 class Tuple : public Record {
407 public:
408  typedef ::Input::Type::Tuple InputType;
409  /**
410  * Default constructor.
411  *
412  * Constructor uses empty Address which causes error in program, Address has to be filled.
413  */
414  Tuple();
415 
416  /**
417  * Copy constructor.
418  */
419  Tuple(const Tuple &tpl);
420 
421  /**
422  * Constructs the accessor providing pointer \p store to storage node with list of data of the tuple and
423  * type specification of the tuple given by parameter \p type.
424  */
425  Tuple(const Address &address, const Type::Tuple type);
426 
427  /**
428  * Get name of tuple_type_
429  */
430  string input_type_name() override;
431 
432 protected:
433  /// Return iterator to Type::Tuple key of given name
434  Type::Record::KeyIter get_type_key_iterator(const string &key) const override;
435 
436 private:
437  /// Corresponding Type::Tuple object.
439 
440 };
441 
442 
443 /**
444  * @brief Accessor to the polymorphic input data of a type given by an AbstracRecord object.
445  *
446  * Provides conversion operator to the Record accessor in ordred to behave in the same way, but
447  * further it provides method \p type() that can be used to call constructor of the class corresponding to the
448  * input data.
449  *
450  * @ingroup input_accessors
451  */
452 
454 public:
455  typedef ::Input::Type::Abstract InputType;
456 
457  /**
458  * Default constructor creates an empty accessor.
459  *
460  * Constructor uses empty Address which causes error in program, Address has to be filled.
461  */
462  AbstractRecord();
463 
464  /**
465  * Copy constructor.
466  */
467  AbstractRecord(const AbstractRecord &rec);
468 
469  /**
470  * Constructs the accessor providing pointer \p store to storage node with list of data of the record and
471  * type specification of the record given by parameter \p type.
472  */
473  AbstractRecord(const Address &address, const Type::Abstract type);
474 
475  /**
476  * Implicit conversion to the \p Input::Record accessor. You can use \p Input::AbstractRecord in the same
477  * way as the \p Input::Record.
478  */
479  operator Record() const;
480 
481  /**
482  * Returns particular type selected from input. You can use it to construct particular type.
483  *
484  * @code
485  * class MyClass {
486  * MyClass( Input::Record );
487  * }
488  *
489  * if (abstract_record.type() == MyClass.get_input_type())
490  * my_class = new MyClass(abstract_record); // here the implicit conversion to Input::Record is used
491  * @endcode
492  */
493  Input::Type::Record type() const;
494 
495  /**
496  * Returns address error info.
497  */
498  EI_Address ei_address() const ;
499 
500  /**
501  * Get address as string.
502  */
503  string address_string() const;
504 
505  /**
506  * Construct classes given by TYPE key of AbstractRecord.
507  *
508  * Method uses Input::Factory class. All constructed classes (representing by descendants
509  * of AbstractRecord) must be registered to factory (see Input::Factory class) and must have
510  * constructors with same parameters (given by Arguments).
511  */
512  template<class Type, class... Arguments>
513  const std::shared_ptr<Type> factory(Arguments... arguments) const;
514 
515 
516 private:
517  /// Corresponding Type::Abstract object.
519 
520  /// Contains address and relationships with abstract record ancestor
522 };
523 
524 
525 
526 /**
527  * @brief Accessor to input data conforming to declared Array.
528  *
529  * There are two possible ways how to retrieve data from Array accessor. First, you can use generic
530  * @p copy_to function to copy the data into a given container. Second, you can get an Iterator<Type>
531  * and iterate through the Array. Unfortunately, you have to provide Type to the begin() method so this
532  * implementation is not fully compliant with standard library. The reason is that in order to speed up compilation of many
533  * classes using input accessors we wouldn't have Input::Array a class template that it can be compiled only once.
534  * By this reason one can not use BOOST_FOREACH to iterate over Input::Array.
535  * TODO: Make Input::Array<Type> wrapper which is compliant with standard library.
536  *
537  * In either case correspondence between resulting type (i.e. type of elements of the container or type of the Iterator)
538  * and the type of the data in the Array is checked only once.
539  *
540  * Example of usage:
541  * @code
542  * Input::Array decay_array = in_rec.val<Input::Array>("decays"); // get accessor to an array stored under key 'decays'
543  * int size = decay_array.size(); // get size of the actual arrya in the input (possibly for allocation)
544  *
545  * for(Input::Iterator<Input::Record> it = decay_array.begin<Input::Record>() // pass through the array, that is array of records
546  * ; it != dacay_array.end(); ++it) {
547  *
548  * Input::Iterator<double> it_hl = it->find<double>("half_life"); // check existence of an optional key
549  * if (it_hl) {
550  * double hl = *it_hl;
551  * } else {
552  * // use some other value, or turn-off the decay
553  * }
554  * Input::Array products = it->val<Input::Array>("products"); // read an obligatory key, theat conatins an array
555  * // ... process the array 'products'
556  * }
557  * @endcode
558  *
559  * @ingroup input_accessors
560  */
561 class Array {
562 public:
563 
564  typedef ::Input::Type::Array InputType;
565 
566  /**
567  * Default constructor, empty accessor.
568  *
569  * Constructor uses empty Address which causes error in program, Address has to be filled.
570  */
571  Array();
572 
573  /**
574  * Copy constructor.
575  */
576  Array(const Array &ar);
577 
578  /**
579  * Constructs the accessor providing pointer \p store to storage node with list of data of the record and
580  * type specification of the record given by parameter \p type.
581  */
582  Array(const Address &address, const Type::Array type);
583 
584  /**
585  * Returns iterator to the first element of input array. The template parameter is C++ type you want to
586  * read from the array. Only types supported by Input::Interface::Iterator can be used.
587  */
588  template <class ValueType>
589  inline Iterator<ValueType> begin() const;
590 
591  /**
592  * Returns end iterator common to all iterators inner types.
593  */
594  inline IteratorBase end() const;
595 
596  /**
597  * Actual size of the input array.
598  */
599  inline unsigned int size() const;
600 
601  /**
602  * Method to fill the given container @p out with data in the input Array.
603  * The container has to have methods @p clear and @p push_back. The C++ type of the
604  * values in the container has to be supported by Iterator<T>.
605  */
606  template <class Container>
607  void copy_to(Container &out) const;
608 
609  /**
610  * Returns true if the accessor is empty (after default constructor).
611  * TODO: have something similar for other accessors.
612  */
613  inline bool is_empty() const
614  { return (address_.storage_head() == Address().storage_head()); }
615 
616  /**
617  * Returns address error info.
618  */
619  EI_Address ei_address() const ;
620 
621  /**
622  * Get address as string.
623  */
624  string address_string() const;
625 
626  /// Need persisting empty instance of StorageArray that can be used to create an empty Address.
628 
629 private:
630  /// Corresponding Type::Array.
632 
633  /// Contains address and relationships with array ancestor
635 
636 
637 };
638 
639 
640 /*TODO:
641  * Fast variant of RecordRead for reading array of records of same type. Has sense only for buffered input
642  * storage and large data.
643  *
644  * usage:
645  *
646  * Array<FastRecordReader> a_of_fr;
647  * FastRecordReader::iterator<double> iter_x = a_of_fr.get_type().iter_of_key<double>("x");
648  * FastRecordReader::iterator<double> iter_y = a_of_fr.get_type().iterof_key<double>("y");
649  * for(Array<FastRecordReader>::iterator it=a_of_fr.begin(); it != a_of_fr.end(); ++it) {
650  * it->fast_get(iter_x);
651  * it->fast_get(iter_y);
652  * }
653  *
654  */
655 
656 
657 namespace internal {
658 
659  /**
660  * Primary type dispatch. For every intermediate C++ type that can be read from input we have to define
661  * read function from a given storage and Input type i.e. descendant of Input::Type::TypeBase.
662  */
663 
664  template<class T, class Enable = void>
665  struct TypeDispatch;
666 } // close namespace internal
667 
668 
669 /**
670  * Base class of input Iterator<Type> template. Main reason is possibility to construct
671  * invalid iterator without template parameter ( used in \p Array::end() )
672  */
674 public:
675 
676  /**
677  * Constructor. Creates iterator effectively pointing to data address_->get_storage()->get_item(index),
678  * that is parameter @p address points to StorageArray and parameter @p index gives index into this array.
679  *
680  */
681  IteratorBase(const Address &address, const unsigned int index);
682 
683  /// Comparison of two Iterators. Do no compare types only position in the storage
684  inline bool operator == (const IteratorBase &that) const;
685 
686  inline bool operator != (const IteratorBase &that) const;
687 
688  /**
689  * Implicit conversion to bool. Returns true if iterator points to non-null storage.
690  */
691  inline operator bool() const;
692 
693  /**
694  * Return index in an array or record.
695  */
696  inline unsigned int idx() const;
697 
698  /**
699  * Returns address
700  */
701  const Address &get_address() const;
702 
703 
704 protected:
706  unsigned int index_;
707 };
708 
709 
710 
711 /**
712  * This class behaves like iterator to type @p T (the template parameter), but in fact it is
713  * iterator into input storage and also into tree of declarations through Input::Type classes.
714  *
715  * This class provides only limited functionality of iterators, namely prefix advance operator ++(),
716  * dereference operator * (), dereference operator -> (), comparison operators == and != and implicit conversion to
717  * bool (false in the case of the 'null' iterator).
718  *
719  *
720  * @ingroup input_accessors
721  */
722 template <class T>
723 class Iterator : public IteratorBase {
724 public:
725  /// Converts C++ type @p T (template parameter) to 'DispatchType' from smaller set of types.
726  typedef T DispatchType;
727  /**
728  * For small set of C++ types and accessor classes Record, AbstractRecord, and Array,
729  * returns type of value given by dereference of the iterator (just add const to C++ types).
730  */
732  /**
733  * A descendant of Input::Type::TypeBase that is appropriate to template parameter @p T.
734  */
736 
737 
738  /**
739  * Iterator is not default constructible.
740  *
741  * Constructor uses empty Address which causes error in program, Address has to be filled.
742  */
744 
745  /**
746  * Constructor. Creates iterator effectively pointing to data address_->get_storage()->get_item(index),
747  * that is parameter @p address points to StorageArray and parameter @p index gives index into this array.
748  * Parameter @p type is Input::Type of object the iterator points to.
749  *
750  *
751  */
752  Iterator(const Input::Type::TypeBase &type, const Address &address, const unsigned int index)
753  : IteratorBase(address, index), type_( type_check_and_convert(type))
754  {}
755 
756  /// Prefix. Advance operator.
757  inline Iterator<T> &operator ++ ();
758 
759  /// Prefix. Back operator.
760  inline Iterator<T> &operator -- ();
761 
762  /**
763  * Dereference operator * ; Shouldn't we return type T, i.e. try to cast from OutputType to T ??
764  */
765  inline OutputType operator *() const;
766 
767  /**
768  * Dereference operator can be used only for iterators to accessors Record, AbstractRecord, and Array.
769  */
770  inline OutputType *operator ->() const;
771 
772 
773 private:
774 
775  /**
776  * Check that Type::TypeBase reference is in fact object of InputType
777  * and returns converted copy (note that Type declaration objects are only handles.
778  */
779  static InputType type_check_and_convert(const Input::Type::TypeBase &type);
780 
781  /// Input type declaration.
782  InputType type_;
783 
784  /**
785  * temporary for -> operator, necessary only for T == DispatchType == OutputType
786  * == any accessor: Record, AbstractRecord, Array
787  *
788  * for other types this is just an int.
789  */
791 };
792 
793 
794 
795 
796 namespace internal {
797 
798 /**
799  * Template specializations for type dispatch.
800  */
801 
802 // Generic implementation can't be accepted.
803 template< class T, class Enable >
804 struct TypeDispatch {
805  class some_nonexisting_type;
806  static_assert( std::is_same<T, some_nonexisting_type>::value, "Wrong TypeDispatch type.");
807 };
808 
809 template<class T>
810 struct TypeDispatch<T, typename boost::enable_if<boost::is_enum<T> >::type> {
811  typedef T TmpType;
812 
814  typedef const TmpType ReadType;
815  static inline ReadType value(const Address &a, const InputType&) { return ReadType( a.storage_head()->get_int() ); }
816 };
817 
818 template<>
820  typedef Enum TmpType;
822  typedef const TmpType ReadType;
823  static inline ReadType value(const Address &a, const InputType&) { return ReadType( a.storage_head()->get_int() ); }
824 };
825 
826 template<>
828  typedef FullEnum TmpType;
830  typedef const TmpType ReadType;
831  static inline ReadType value(const Address &a, const InputType &t) { return ReadType( a.storage_head()->get_int(), t ); }
832 };
833 
834 template<class T>
835 struct TypeDispatch<T, typename boost::enable_if<boost::is_integral<T> >::type> {
837  typedef const int ReadType;
838  typedef int TmpType;
839  static inline ReadType value(const Address &a, const InputType&t) {
840  std::int64_t val = a.storage_head()->get_int();
841  if (val >= std::numeric_limits<T>::min() &&
842  val <= std::numeric_limits<T>::max() ) {
843  return val;
844  } else {
845  THROW( ExcInputMessage()
846  << EI_Message("Error in input file at address " + a.make_full_address() + ".\nValue out of bounds.") );
847  }
848  }
849 };
850 
851 template<>
852 struct TypeDispatch<bool> {
854  typedef const bool ReadType;
855  typedef int TmpType;
856  static inline ReadType value(const Address &a, const InputType&) { return a.storage_head()->get_bool(); }
857 };
858 
859 template<class T>
860 struct TypeDispatch<T, typename boost::enable_if<boost::is_float<T> >::type> {
862  typedef const double ReadType;
863  typedef int TmpType;
864  static inline ReadType value(const Address &a, const InputType&) { return a.storage_head()->get_double(); }
865 };
866 
867 
868 template<>
869 struct TypeDispatch<string> {
871  typedef const string ReadType;
872  typedef int TmpType;
873  static inline ReadType value(const Address &a, const InputType&) { return a.storage_head()->get_string(); }
874 };
875 
876 
877 template<>
882  static inline ReadType value(const Address &a, const InputType& t) { return AbstractRecord(a, t); }
883 };
884 
885 
886 template<>
889  typedef Record ReadType;
890  typedef Record TmpType;
891  static inline ReadType value(const Address &a, const InputType& t) { return Record(a,t); }
892 };
893 
894 
895 template<>
898  typedef Tuple ReadType;
899  typedef Tuple TmpType;
900  static inline ReadType value(const Address &a, const InputType& t) { return Tuple(a,t); }
901 };
902 
903 
904 template<>
907  typedef Array ReadType;
908  typedef Array TmpType;
909  static inline ReadType value(const Address &a, const InputType& t) { return Array(a,t); }
910 
911 };
912 
913 template<>
917  typedef int TmpType;
918  static inline ReadType value(const Address &a, const InputType& t) { return FilePath(a.storage_head()->get_string(), t.get_file_type() ); }
919 
920 };
921 
922 
923 
924 
925 } // closing namespace internal
926 
927 
928 
929 
930 
931 } // closing namespace Input
932 
933 
934 // include implementation of templates and inline methods
935 #include "accessors_impl.hh"
936 
937 
938 
939 #endif
Address address_
Contains address and relationships with abstract record ancestor.
Definition: accessors.hh:521
static ReadType value(const Address &a, const InputType &t)
Definition: accessors.hh:909
bool is_empty() const
Definition: accessors.hh:613
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:900
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:735
::Input::Type::Record InputType
Definition: accessors.hh:289
Accessor to input data conforming to declared Array.
Definition: accessors.hh:561
std::vector< struct Key >::const_iterator KeyIter
Public typedef of constant iterator into array of keys.
Definition: type_record.hh:211
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:247
Class for declaration of the input of type Bool.
Definition: type_base.hh:452
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:438
std::string make_full_address() const
Definition: accessors.cc:105
Input::Type::Selection InputType
Definition: accessors.hh:821
Address address_
Contains address and relationships with record ancestor.
Definition: accessors.hh:391
InputType type_
Input type declaration.
Definition: accessors.hh:782
::Input::Type::Abstract InputType
Definition: accessors.hh:455
Class for declaration of the input data that are file names.
Definition: type_base.hh:611
Input::Type::Array array_type_
Corresponding Type::Array.
Definition: accessors.hh:631
Class for declaration of the integral input data.
Definition: type_base.hh:483
const StorageBase * storage_head() const
Definition: accessors.hh:219
Class for declaration of inputs sequences.
Definition: type_base.hh:339
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:395
Input::Type::Abstract abstract_type_
Corresponding Type::Abstract object.
Definition: accessors.hh:518
static ReadType value(const Address &a, const InputType &t)
Definition: accessors.hh:891
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:534
internal::TypeDispatch< DispatchType >::TmpType temporary_value_
Definition: accessors.hh:790
Accessor to the data with type Type::Record.
Definition: accessors.hh:286
static ReadType value(const Address &a, const InputType &t)
Definition: accessors.hh:918
Iterator(const Input::Type::TypeBase &type, const Address &address, const unsigned int index)
Definition: accessors.hh:752
bool is_empty() const
Definition: accessors.hh:360
Enum(int v)
Definition: accessors.hh:116
::FilePath::FileType get_file_type() const
Returns type of the file input/output.
Definition: type_base.cc:557
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:627
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:453
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:823
::Input::Type::Array InputType
Definition: accessors.hh:564
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:831
static ReadType value(const Address &a, const InputType &)
Definition: accessors.hh:873
T DispatchType
Converts C++ type T (template parameter) to &#39;DispatchType&#39; from smaller set of types.
Definition: accessors.hh:726
#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:408
TYPEDEF_ERR_INFO(EI_InputType, const string)
static ReadType value(const Address &a, const InputType &t)
Definition: accessors.hh:882
unsigned int index_
Definition: accessors.hh:706
const Input::Type::TypeBase * root_type_
Definition: accessors.hh:174
Record type proxy class.
Definition: type_record.hh:177
internal::TypeDispatch< DispatchType >::ReadType OutputType
Definition: accessors.hh:731
Accessor to the data with type Type::Tuple.
Definition: accessors.hh:406
static ReadType value(const Address &a, const InputType &)
Definition: accessors.hh:856
Class for declaration of the input data that are in string format.
Definition: type_base.hh:582
#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:237
Address address_
Contains address and relationships with array ancestor.
Definition: accessors.hh:634