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