Flow123d
accessors_impl.hh
Go to the documentation of this file.
1 /*
2  * accessors_impl.hh
3  *
4  * Created on: Aug 1, 2012
5  * Author: jb
6  */
7 
8 #ifndef ACCESSORS_IMPL_HH_
9 #define ACCESSORS_IMPL_HH_
10 
11 
12 namespace Input {
13 
14 using std::string;
15 
16 /******************************************************************************************
17  * Implementation of Input::Record
18  */
19 template <class Ret>
20 inline const Ret Record::val(const string &key) const {
21  try {
23 
24  ASSERT( key_it->default_.is_obligatory() || key_it->default_.has_value_at_declaration(),
25  "The key '%s' is declared as optional or with default value at read time,"
26  " you have to use Record::find instead.\n", key.c_str());
27 
28  Iterator<Ret> it = Iterator<Ret>( *(key_it->type_), address_, key_it->key_index);
29  return *it;
30  }
31  // we catch all possible exceptions
32  catch (Type::Record::ExcRecordKeyNotFound & e) {
33  throw;
34  }
35  catch (ExcTypeMismatch & e) {
36  e << EI_CPPRequiredType(typeid(Ret).name()) << EI_KeyName(key);
37  throw;
38  }
39  catch (ExcStorageTypeMismatch &e) {
40  throw;
41  }
42  catch (ExcAccessorForNullStorage &e) {
43  throw;
44  }
45 }
46 
47 
48 
49 template <class Ret>
50 inline const Ret Record::val(const string &key, const Ret default_val ) const {
51  try {
53 
54  ASSERT( key_it->default_.has_value_at_read_time(),
55  "The key %s is not declared with default value at read time,"
56  " you have to use Record::val or Record::find instead.\n", key.c_str());
57 
58  Iterator<Ret> it = Iterator<Ret>( *(key_it->type_), address_, key_it->key_index);
59  if (it)
60  return *it;
61  else
62  return default_val;
63  }
64  // we catch all possible exceptions
65  catch (Type::Record::ExcRecordKeyNotFound & e) {
66  throw;
67  }
68  catch (ExcTypeMismatch & e) {
69  e << EI_CPPRequiredType(typeid(Ret).name()) << EI_KeyName(key);
70  throw;
71  }
72  catch (ExcStorageTypeMismatch &e) {
73  throw;
74  }
75  catch (ExcAccessorForNullStorage &e) {
76  throw;
77  }
78 }
79 
80 
81 
82 template <class Ret>
83 inline Iterator<Ret> Record::find(const string &key) const {
84  try {
86  return Iterator<Ret>( *(key_it->type_), address_, key_it->key_index);
87  }
88  // we catch all possible exceptions
89  catch (Type::Record::ExcRecordKeyNotFound & e) {
90  throw;
91  }
92  catch (ExcTypeMismatch & e) {
93  e << EI_CPPRequiredType(typeid(Ret).name()) << EI_KeyName(key);
94  throw;
95  }
96 }
97 
98 template <class Ret>
99 inline bool Record::opt_val(const string &key, Ret &value) const {
100  try {
102  Iterator<Ret> it=Iterator<Ret>( *(key_it->type_), address_, key_it->key_index);
103  if (it) {
104  value = *it;
105  } else {
106  return false;
107  }
108  }
109  // we catch all possible exceptions
110  catch (Type::Record::ExcRecordKeyNotFound & e) {
111  throw;
112  }
113  catch (ExcTypeMismatch & e) {
114  e << EI_CPPRequiredType(typeid(Ret).name()) << EI_KeyName(key);
115  throw;
116  }
117 
118  return true;
119 }
120 
121 
122 /******************************************************************************************
123  * Implementation of Input::Array
124  */
125 
126 template <class ValueType>
128  try {
130  }
131  catch (ExcTypeMismatch & e) {
132  e << EI_CPPRequiredType(typeid(ValueType).name()) << EI_KeyName("begin()");
133  throw e;
134  }
135 }
136 
137 
138 
139 inline IteratorBase Array::end() const {
141 }
142 
143 
144 
145 inline unsigned int Array::size() const {
147 }
148 
149 
150 
151 template <class Container>
152 void Array::copy_to(Container &out) const {
153  out.clear();
154  Iterator<typename Container::value_type> it = begin<typename Container::value_type>();
155 
156  for(;it != end(); ++ it) {
157  out.push_back(*it);
158  }
159 }
160 
161 
162 /******************************************************************************************
163  * Implementation of Input::IteratorBase
164  */
165 
166 inline bool IteratorBase::operator == (const IteratorBase &that) const
167  { return ( address_.storage_head() == that.address_.storage_head() && index_ == that.index_); }
168 
169 
170 
171 inline bool IteratorBase::operator != (const IteratorBase &that) const
172  { return ! ( *this == that ); }
173 
174 
175 
176 inline IteratorBase::operator bool() const {
177  const StorageBase *s = address_.storage_head()->get_item(index_);
178  return ( s && ! s->is_null() );
179 }
180 
181 
182 
183 inline unsigned int IteratorBase::idx() const {
184  return index_;
185 }
186 
187 
188 /******************************************************************************************
189  * Implementation of Input::Iterator<Type>
190  */
191 
192 
193 template<class T>
195  index_++;
196  return *this;
197 }
198 
199 
200 
201 template<class T>
203  index_--;
204  return *this;
205 }
206 
207 
208 
209 template<class T>
211 
212  //Address a( address_ );
213  //a.down( index_, address_ );
214  Address a( * const_cast<Address *> (address_.down(index_)) );
215 
216  ASSERT(a.storage_head(), "NULL pointer to storage in address object!!! \n");
217 
218  return internal::TypeDispatch < DispatchType > ::value(a, type_);
219 }
220 
221 template<class T>
223  BOOST_STATIC_ASSERT(
224  (boost::is_same < Record, OutputType > ::value || boost::is_same < AbstractRecord, OutputType > ::value
225  || boost::is_same < Array, OutputType > ::value));
226 
227  // we have to make save temporary
228  temporary_value_ = this->operator*();
229  return &(temporary_value_);
230 
231 }
232 
233 
234 template<class T>
236  if (typeid(type) == typeid(InputType)) {
237  return static_cast<const InputType &>(type);
238  } else {
239  THROW(ExcTypeMismatch() << EI_InputType(type.type_name()) << EI_RequiredType(typeid(InputType).name()));
240  }
241 }
242 
243 
244 } // namespace Input
245 
246 #endif /* ACCESSORS_IMPL_HH_ */