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