Flow123d  master-f44eb46
accessors.cc
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.cc
15  * @brief
16  */
17 
18 #include <memory>
19 #include <boost/lexical_cast.hpp>
20 #include "input/accessors.hh"
21 
22 
23 namespace Input {
24 
25 
26 /*************************************************************************************************************************************
27  * Implementation of InputException
28  */
29 
30 
31 std::ostringstream &Exception::form_message(std::ostringstream &converter) const {
32 
33  converter << "--------------------------------------------------------" << std::endl;
34  converter << "User Error: ";
35  print_info(converter);
36 #ifdef FLOW123D_DEBUG_MESSAGES
37  converter << "\n** Diagnosting info **\n" ;
38  converter << boost::diagnostic_information_what( *this );
39  print_stacktrace(converter);
40 #endif
41  converter << std::endl << "--------------------------------------------------------" << std::endl;
42 
43  return converter;
44 }
45 
46 
47 
48 
49 
50 /*****************************************************************************
51  * Implementation of the class Input::Address
52  */
53 
55 : data_(std::make_shared<AddressData>())
56 {
57  data_->root_type_ = nullptr;
58  data_->root_storage_ = &Array::empty_storage_;
59  data_->descendant_order_ = 0;
60  data_->actual_storage_ = &Array::empty_storage_;
61 }
62 
63 
64 Address::Address(const StorageBase * storage_root, const Type::TypeBase *type_root)
65 : data_( std::make_shared<AddressData>() )
66 {
67  if (! storage_root)
68  THROW( ExcAddressNullPointer() << EI_AccessorName("storage_root") );
69  if (! type_root )
70  THROW( ExcAddressNullPointer() << EI_AccessorName("type_root") );
71 
72  data_->root_type_ = type_root;
73  data_->root_storage_ = storage_root;
74  data_->descendant_order_ = 0;
75  data_->actual_storage_ = storage_root;
76 }
77 
78 
79 
81 : data_(other.data_)
82 {}
83 
84 
86  if ( !parent_
88  && root_type_ ) {
89  delete root_storage_;
90  }
91 }
92 
93 
94 std::shared_ptr<Address> Address::down(unsigned int idx) const {
95 
96  auto addr = std::make_shared<Address>(this->data_->root_storage_, this->data_->root_type_);
97  addr->data_->parent_ = this->data_;
98  addr->data_->descendant_order_ = idx;
99  addr->data_->actual_storage_ = data_->actual_storage_->get_item(idx);
100 
101  return addr;
102 }
103 
104 
105 std::string Address::make_full_address() const {
107  std::shared_ptr<AddressData> address_data = data_;
108  while (address_data->parent_ != NULL) {
109  path.push_back(address_data->descendant_order_);
110  address_data = address_data->parent_;
111  }
112 
113  // for empty path is returned address of root node
114  if (path.size() == 0) {
115  return "/";
116  }
117 
118  const StorageBase * storage = address_data->root_storage_;
119  const Type::TypeBase * input_type = address_data->root_type_;
120  std::string address = "";
121  int i = path.size()-1;
122 
123  while (i >= 0) {
124 
125  // dispatch types
126  if (typeid(*input_type) == typeid(Type::Record)) {
127  storage = storage->get_item(path[i]);
128  const Type::Record * rec = static_cast<const Type::Record *>(input_type);
129  Type::Record::KeyIter it = rec->begin() + path[i];
130  address = address + "/" + it->key_;
131  input_type = it->type_.get();
132  i--;
133  } else
134  if (typeid(*input_type) == typeid(Type::Abstract)) {
135  const Type::Abstract * a_rec = static_cast<const Type::Abstract *>(input_type);
136  const StorageString * storage_type = static_cast<const StorageString *>(storage->get_item(0));
137  input_type = & a_rec->get_descendant(storage_type->get_string());
138  } else
139  if (typeid(*input_type) == typeid(Type::Array)) {
140  storage = storage->get_item(path[i]);
141  const Type::Array * arr = static_cast<const Type::Array *>(input_type);
142  address = address + "/" + boost::lexical_cast<std::string>(path[i]);
143  input_type = & arr->get_sub_type();
144  i--;
145  }
146  }
147 
148  return address;
149 }
150 
151 
152 
153 /*****************************************************************************
154  * Implementation of the class Input::Record
155  */
156 
157 
159 : address_( Address() ), record_type_()
160 {}
161 
162 
163 
165 : address_(rec.address_), record_type_(rec.record_type_)
166 {}
167 
168 
169 
170 Record::Record(const Address &address, const Type::Record type)
171 : address_(address), record_type_(type)
172 {
173  if (address.storage_head()->is_null())
174  THROW( ExcAccessorForNullStorage() << EI_AccessorName("Record") );
175 }
176 
177 
178 Input::EI_Address Record::ei_address() const
179 {
180  return EI_Address(address_string());
181 }
182 
183 
185 {
186  return address_.make_full_address();
187 }
188 
190 {
191  return record_type_.type_name();
192 }
193 
194 
196  return record_type_.key_iterator(key);
197 }
198 
199 
200 
201 /*****************************************************************************
202  * Implementation of the class Input::Tuple
203  */
204 
205 
207 : tuple_type_()
208 {
209  this->address_ = Address();
210 }
211 
212 
213 
214 Tuple::Tuple(const Tuple &tpl)
215 : Record(tpl), tuple_type_(tpl.tuple_type_)
216 {
217  this->address_ = tpl.address_;
218 }
219 
220 
221 
222 Tuple::Tuple(const Address &address, const Type::Tuple type)
223 : tuple_type_(type)
224 {
225  this->address_ = address;
226  if (address.storage_head()->is_null())
227  THROW( ExcAccessorForNullStorage() << EI_AccessorName("Tuple") );
228 }
229 
230 
232 {
233  return tuple_type_.type_name();
234 }
235 
236 
238  return tuple_type_.key_iterator(key);
239 }
240 
241 
242 
243 /*****************************************************************************
244  * Implementation of the class Input::AbstractRecord
245  */
246 
248 : abstract_type_(), address_( Address() )
249 {}
250 
251 
252 
254 : abstract_type_(rec.abstract_type_), address_(rec.address_)
255 {}
256 
257 
258 
260 : abstract_type_(type), address_(address)
261 {
262  if (address.storage_head()->is_null())
263  THROW( ExcAccessorForNullStorage() << EI_AccessorName("AbstractRecord") );
264 }
265 
266 
267 
268 AbstractRecord::operator Record() const
269 { return Record(address_,type()); }
270 
271 
272 
274 {
275  string type_name = address_.storage_head()->get_item(0)->get_string();
276  return abstract_type_.get_descendant(type_name);
277 }
278 
279 
280 Input::EI_Address AbstractRecord::ei_address() const
281 {
282  return EI_Address(address_string());
283 }
284 
286 {
287  return address_.make_full_address();
288 }
289 
290 
291 /*****************************************************************************
292  * Implementation of the class Input::Array
293  */
294 
295 
297 : array_type_(Type::Bool()), address_( Address() )
298 {}
299 
300 
301 Array::Array(const Array &ar)
302 : array_type_(ar.array_type_), address_(ar.address_)
303 {}
304 
305 
306 Array::Array(const Address &address, const Type::Array type)
307 : array_type_(type), address_(address)
308 {
309  if (address.storage_head()->is_null())
310  THROW( ExcAccessorForNullStorage() << EI_AccessorName("Array") );
311 }
312 
313 
314 Input::EI_Address Array::ei_address() const
315 {
316  return EI_Address(address_string());
317 }
318 
319 
320 
321 string Array::address_string() const
322 {
323  return address_.make_full_address();
324 }
325 
326 
328 
329 
330 
331 /*****************************************************************************
332  * Implementation of the class Input::IteratorBase
333  */
334 
335 
336 IteratorBase::IteratorBase(const Address &address, const unsigned int index)
337 : address_(address), index_(index)
338 {}
339 
340 
342  return address_;
343 }
344 
345 
346 
347 /*****************************************************************************
348  * Explicit instantiation of accessor's templates
349  *
350  * .. TODO
351  */
352 
353 
354 
355 } // closing namespace Input
void print_stacktrace(std::ostream &out) const
Prints formated stacktrace into given stream out.
Definition: exceptions.cc:42
virtual void print_info(std::ostringstream &out) const =0
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:458
string address_string() const
Definition: accessors.cc:285
Address address_
Contains address and relationships with abstract record ancestor.
Definition: accessors.hh:526
Input::Type::Abstract abstract_type_
Corresponding Type::Abstract object.
Definition: accessors.hh:523
Input::Type::Record type() const
Definition: accessors.cc:273
EI_Address ei_address() const
Definition: accessors.cc:280
std::shared_ptr< AddressData > data_
Definition: accessors.hh:242
std::shared_ptr< Address > down(unsigned int idx) const
Definition: accessors.cc:94
const StorageBase * storage_head() const
Definition: accessors.hh:224
std::string make_full_address() const
Definition: accessors.cc:105
Accessor to input data conforming to declared Array.
Definition: accessors.hh:566
EI_Address ei_address() const
Definition: accessors.cc:314
static StorageArray empty_storage_
Need persisting empty instance of StorageArray that can be used to create an empty Address.
Definition: accessors.hh:632
string address_string() const
Definition: accessors.cc:321
Address address_
Contains address and relationships with array ancestor.
Definition: accessors.hh:639
std::ostringstream & form_message(std::ostringstream &) const override
Definition: accessors.cc:31
IteratorBase(const Address &address, const unsigned int index)
Definition: accessors.cc:336
const Address & get_address() const
Definition: accessors.cc:341
Accessor to the data with type Type::Record.
Definition: accessors.hh:291
string address_string() const
Definition: accessors.cc:184
EI_Address ei_address() const
Definition: accessors.cc:178
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
virtual string input_type_name()
Definition: accessors.cc:189
Input::Type::Record record_type_
Corresponding Type::Record object.
Definition: accessors.hh:400
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 const std::string & get_string() const
Definition: storage.cc:50
virtual bool is_null() const =0
Definition: storage.cc:73
virtual const std::string & get_string() const
Definition: storage.cc:269
Accessor to the data with type Type::Tuple.
Definition: accessors.hh:411
string input_type_name() override
Definition: accessors.cc:231
Type::Record::KeyIter get_type_key_iterator(const string &key) const override
Return iterator to Type::Tuple key of given name.
Definition: accessors.cc:237
Input::Type::Tuple tuple_type_
Corresponding Type::Tuple object.
Definition: accessors.hh:443
Class for declaration of polymorphic Record.
const Record & get_descendant(const string &name) const
Returns reference to the inherited Record with given name.
Class for declaration of inputs sequences.
Definition: type_base.hh:339
const TypeBase & get_sub_type() const
Getter for the type of array items.
Definition: type_base.hh:397
Record type proxy class.
Definition: type_record.hh:182
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_record.cc:317
KeyIter key_iterator(const string &key) const
Returns iterator to the key struct for given key string.
Definition: type_record.hh:555
KeyIter begin() const
Container-like access to the keys of the Record.
Definition: type_record.hh:579
std::vector< struct Key >::const_iterator KeyIter
Public typedef of constant iterator into array of keys.
Definition: type_record.hh:216
Tuple type proxy class.
Definition: type_tuple.hh:45
Base of classes for declaring structure of the input data.
Definition: type_base.hh:92
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
Abstract linear system class.
Definition: balance.hh:40
const StorageBase * actual_storage_
Definition: accessors.hh:187
std::shared_ptr< AddressData > parent_
Definition: accessors.hh:171
const StorageBase * root_storage_
Definition: accessors.hh:183
const Input::Type::TypeBase * root_type_
Definition: accessors.hh:179