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