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