Flow123d  release_2.1.0-87-gfbc1563
accessors_impl.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_impl.hh
15  * @brief
16  */
17 
18 #ifndef ACCESSORS_IMPL_HH_
19 #define ACCESSORS_IMPL_HH_
20 
21 
22 namespace Input {
23 
24 using std::string;
25 
26 /******************************************************************************************
27  * Implementation of Input::Record
28  */
29 template <class Ret>
30 inline const Ret Record::val(const string &key) const {
31  try {
33 
34  ASSERT_DBG(key_it->default_.is_obligatory() || key_it->default_.has_value_at_declaration())(key)
35  .error("You have to use Record::find instead.");
36 
37  Iterator<Ret> it = Iterator<Ret>( *(key_it->type_), address_, key_it->key_index);
38  return *it;
39  }
40  // we catch all possible exceptions
41  catch (Type::Record::ExcRecordKeyNotFound & e) {
42  throw;
43  }
44  catch (ExcTypeMismatch & e) {
45  e << EI_CPPRequiredType(typeid(Ret).name()) << EI_KeyName(key);
46  throw;
47  }
48  catch (ExcStorageTypeMismatch &e) {
49  throw;
50  }
51  catch (ExcAccessorForNullStorage &e) {
52  throw;
53  }
54 }
55 
56 
57 
58 template <class Ret>
59 inline const Ret Record::val(const string &key, const Ret default_val ) const {
60  try {
62 
63  ASSERT_DBG(key_it->default_.has_value_at_read_time())(key).error("You have to use Record::val or Record::find instead.");
64 
65  Iterator<Ret> it = Iterator<Ret>( *(key_it->type_), address_, key_it->key_index);
66  if (it)
67  return *it;
68  else
69  return default_val;
70  }
71  // we catch all possible exceptions
72  catch (Type::Record::ExcRecordKeyNotFound & e) {
73  throw;
74  }
75  catch (ExcTypeMismatch & e) {
76  e << EI_CPPRequiredType(typeid(Ret).name()) << EI_KeyName(key);
77  throw;
78  }
79  catch (ExcStorageTypeMismatch &e) {
80  throw;
81  }
82  catch (ExcAccessorForNullStorage &e) {
83  throw;
84  }
85 }
86 
87 
88 
89 template <class Ret>
90 inline Iterator<Ret> Record::find(const string &key) const {
91  try {
93  return Iterator<Ret>( *(key_it->type_), address_, key_it->key_index);
94  }
95  // we catch all possible exceptions
96  catch (Type::Record::ExcRecordKeyNotFound & e) {
97  throw;
98  }
99  catch (ExcTypeMismatch & e) {
100  e << EI_CPPRequiredType(typeid(Ret).name()) << EI_KeyName(key);
101  throw;
102  }
103 }
104 
105 template <class Ret>
106 inline bool Record::opt_val(const string &key, Ret &value) const {
107  try {
109  Iterator<Ret> it=Iterator<Ret>( *(key_it->type_), address_, key_it->key_index);
110  if (it) {
111  value = *it;
112  } else {
113  return false;
114  }
115  }
116  // we catch all possible exceptions
117  catch (Type::Record::ExcRecordKeyNotFound & e) {
118  throw;
119  }
120  catch (ExcTypeMismatch & e) {
121  e << EI_CPPRequiredType(typeid(Ret).name()) << EI_KeyName(key);
122  throw;
123  }
124 
125  return true;
126 }
127 
128 
129 /******************************************************************************************
130  * Implementation of Input::AbstractRecord
131  */
132 
133 template<class Type, class... Arguments>
134 const std::shared_ptr<Type> AbstractRecord::factory(Arguments... arguments) const {
135  return Input::Factory<Type, Arguments...>::instance()->create(this->type().type_name(), arguments...);
136 }
137 
138 
139 /******************************************************************************************
140  * Implementation of Input::Array
141  */
142 
143 template <class ValueType>
145  try {
146  return Iterator<ValueType>(array_type_.get_sub_type(), address_, 0);
147  }
148  catch (ExcTypeMismatch & e) {
149  e << EI_CPPRequiredType(typeid(ValueType).name()) << EI_KeyName("begin()");
150  throw e;
151  }
152 }
153 
154 
155 
156 inline IteratorBase Array::end() const {
158 }
159 
160 
161 
162 inline unsigned int Array::size() const {
164 }
165 
166 
167 
168 template <class Container>
169 void Array::copy_to(Container &out) const {
170  out.clear();
171  Iterator<typename Container::value_type> it = begin<typename Container::value_type>();
172 
173  for(;it != end(); ++ it) {
174  out.push_back(*it);
175  }
176 }
177 
178 
179 /******************************************************************************************
180  * Implementation of Input::IteratorBase
181  */
182 
183 inline bool IteratorBase::operator == (const IteratorBase &that) const
184  { return ( address_.storage_head() == that.address_.storage_head() && index_ == that.index_); }
185 
186 
187 
188 inline bool IteratorBase::operator != (const IteratorBase &that) const
189  { return ! ( *this == that ); }
190 
191 
192 
193 inline IteratorBase::operator bool() const {
194  StorageBase *s = address_.storage_head()->get_item(index_);
195  return ( s && ! s->is_null() );
196 }
197 
198 
199 
200 inline unsigned int IteratorBase::idx() const {
201  return index_;
202 }
203 
204 
205 /******************************************************************************************
206  * Implementation of Input::Iterator<Type>
207  */
208 
209 
210 template<class T>
212  index_++;
213  return *this;
214 }
215 
216 
217 
218 template<class T>
220  index_--;
221  return *this;
222 }
223 
224 
225 
226 template<class T>
228 
229  auto new_address =address_.down(index_);
230 
231  ASSERT_PTR(new_address->storage_head()).error();
232 
233  return internal::TypeDispatch < DispatchType > ::value(*new_address, type_);
234 }
235 
236 template<class T>
238  // OutputType has to be an accessor to call its method, e.g. iter->val("xyz"). Variable iter has to be e.g. Iterator.
239  BOOST_STATIC_ASSERT(
242 
243  // we have to make save temporary
244  temporary_value_ = this->operator*();
245  return &(temporary_value_);
246 
247 }
248 
249 
250 template<class T>
252  if (typeid(type) == typeid(InputType)) {
253  return static_cast<const InputType &>(type);
254  } else {
255  THROW(ExcTypeMismatch() << EI_InputType(type.type_name()) << EI_RequiredType(typeid(InputType).name()));
256  }
257 }
258 
259 
260 } // namespace Input
261 
262 #endif /* ACCESSORS_IMPL_HH_ */
Iterator< ValueType > begin() const
Base of classes for declaring structure of the input data.
Definition: type_base.hh:93
Base class for nodes of a data storage tree.
Definition: storage.hh:68
internal::TypeDispatch< DispatchType >::InputType InputType
Definition: accessors.hh:735
std::vector< struct Key >::const_iterator KeyIter
Public typedef of constant iterator into array of keys.
Definition: type_record.hh:211
virtual StorageBase * get_item(const unsigned int index) const
Definition: storage.cc:60
virtual bool is_null() const =0
Definition: storage.cc:67
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.
Address address_
Contains address and relationships with record ancestor.
Definition: accessors.hh:391
Iterator< Ret > find(const string &key) const
shared_ptr< Type > const create(string name, Arguments...arguments) const
create an instance of a registered class
Definition: factory_impl.hh:49
const StorageBase * storage_head() const
Definition: accessors.hh:219
std::shared_ptr< Address > down(unsigned int idx) const
Definition: accessors.cc:94
static constexpr bool value
Definition: json.hpp:87
UnitSI operator*(const UnitSI &a, const UnitSI &b)
Product of two units.
Definition: unit_si.cc:235
IteratorBase end() const
static Factory * instance()
Get the single instance of the factory.
Definition: factory_impl.hh:27
bool opt_val(const string &key, Ret &value) const
const Ret val(const string &key) const
static InputType type_check_and_convert(const Input::Type::TypeBase &type)
virtual unsigned int get_array_size() const
Definition: storage.cc:73
Iterator< T > & operator++()
Prefix. Advance operator.
OutputType operator*() const
void copy_to(Container &out) const
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:336
unsigned int index_
Definition: accessors.hh:706
#define ASSERT_DBG(expr)
Definition: asserts.hh:350
virtual string type_name() const
Returns an identification of the type. Useful for error messages.
Definition: type_base.cc:182
unsigned int idx() const
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
unsigned int size() const
internal::TypeDispatch< DispatchType >::ReadType OutputType
Definition: accessors.hh:731
OutputType * operator->() const
const std::shared_ptr< Type > factory(Arguments...arguments) const
Iterator< T > & operator--()
Prefix. Back operator.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:45