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