Flow123d  last_with_con_2.0.0-663-gd0e2296
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 
85 std::shared_ptr<Address> Address::down(unsigned int idx) const {
86 
87  auto addr = std::make_shared<Address>(this->data_->root_storage_, this->data_->root_type_);
88  addr->data_->parent_ = this->data_;
89  addr->data_->descendant_order_ = idx;
90  addr->data_->actual_storage_ = data_->actual_storage_->get_item(idx);
91 
92  return addr;
93 }
94 
95 
96 std::string Address::make_full_address() const {
98  std::shared_ptr<AddressData> address_data = data_;
99  while (address_data->parent_ != NULL) {
100  path.push_back(address_data->descendant_order_);
101  address_data = address_data->parent_;
102  }
103 
104  // for empty path is returned address of root node
105  if (path.size() == 0) {
106  return "/";
107  }
108 
109  const StorageBase * storage = address_data->root_storage_;
110  const Type::TypeBase * input_type = address_data->root_type_;
111  std::string address = "";
112  int i = path.size()-1;
113 
114  while (i >= 0) {
115 
116  // dispatch types
117  if (typeid(*input_type) == typeid(Type::Record)) {
118  storage = storage->get_item(path[i]);
119  const Type::Record * rec = static_cast<const Type::Record *>(input_type);
120  Type::Record::KeyIter it = rec->begin() + path[i];
121  address = address + "/" + it->key_;
122  input_type = it->type_.get();
123  i--;
124  } else
125  if (typeid(*input_type) == typeid(Type::Abstract)) {
126  const Type::Abstract * a_rec = static_cast<const Type::Abstract *>(input_type);
127  const StorageString * storage_type = static_cast<const StorageString *>(storage->get_item(0));
128  input_type = & a_rec->get_descendant(storage_type->get_string());
129  } else
130  if (typeid(*input_type) == typeid(Type::Array)) {
131  storage = storage->get_item(path[i]);
132  const Type::Array * arr = static_cast<const Type::Array *>(input_type);
133  address = address + "/" + boost::lexical_cast<std::string>(path[i]);
134  input_type = & arr->get_sub_type();
135  i--;
136  }
137  }
138 
139  return address;
140 }
141 
142 
143 
144 /*****************************************************************************
145  * Implementation of the class Input::Record
146  */
147 
148 
150 : address_( Address() ), record_type_()
151 {}
152 
153 
154 
157 {}
158 
159 
160 
161 Record::Record(const Address &address, const Type::Record type)
162 : address_(address), record_type_(type)
163 {
164  if (address.storage_head()->is_null())
165  THROW( ExcAccessorForNullStorage() << EI_AccessorName("Record") );
166 }
167 
168 
169 Input::EI_Address Record::ei_address() const
170 {
171  return EI_Address(address_string());
172 }
173 
174 
176 {
177  return address_.make_full_address();
178 }
179 
181 {
182  return record_type_.type_name();
183 }
184 
185 
187  return record_type_.key_iterator(key);
188 }
189 
190 
191 
192 /*****************************************************************************
193  * Implementation of the class Input::Tuple
194  */
195 
196 
198 : tuple_type_()
199 {
200  this->address_ = Address();
201 }
202 
203 
204 
205 Tuple::Tuple(const Tuple &tpl)
207 {
208  this->address_ = tpl.address_;
209 }
210 
211 
212 
213 Tuple::Tuple(const Address &address, const Type::Tuple type)
214 : tuple_type_(type)
215 {
216  this->address_ = address;
217  if (address.storage_head()->is_null())
218  THROW( ExcAccessorForNullStorage() << EI_AccessorName("Tuple") );
219 }
220 
221 
223 {
224  return tuple_type_.type_name();
225 }
226 
227 
229  return tuple_type_.key_iterator(key);
230 }
231 
232 
233 
234 /*****************************************************************************
235  * Implementation of the class Input::AbstractRecord
236  */
237 
239 : abstract_type_(), address_( Address() )
240 {}
241 
242 
243 
246 {}
247 
248 
249 
251 : abstract_type_(type), address_(address)
252 {
253  if (address.storage_head()->is_null())
254  THROW( ExcAccessorForNullStorage() << EI_AccessorName("AbstractRecord") );
255 }
256 
257 
258 
259 AbstractRecord::operator Record() const
260 { return Record(address_,type()); }
261 
262 
263 
265 {
266  string type_name = address_.storage_head()->get_item(0)->get_string();
267  return abstract_type_.get_descendant(type_name);
268 }
269 
270 
271 Input::EI_Address AbstractRecord::ei_address() const
272 {
273  return EI_Address(address_string());
274 }
275 
277 {
278  return address_.make_full_address();
279 }
280 
281 
282 /*****************************************************************************
283  * Implementation of the class Input::Array
284  */
285 
286 
288 : array_type_(Type::Bool()), address_( Address() )
289 {}
290 
291 
292 Array::Array(const Array &ar)
294 {}
295 
296 
297 Array::Array(const Address &address, const Type::Array type)
298 : array_type_(type), address_(address)
299 {
300  if (address.storage_head()->is_null())
301  THROW( ExcAccessorForNullStorage() << EI_AccessorName("Array") );
302 }
303 
304 
305 Input::EI_Address Array::ei_address() const
306 {
307  return EI_Address(address_string());
308 }
309 
310 
311 
312 string Array::address_string() const
313 {
314  return address_.make_full_address();
315 }
316 
317 
319 
320 
321 /*****************************************************************************
322  * Explicit instantiation of accessor's templates
323  *
324  * .. TODO
325  */
326 
327 
328 
329 } // closing namespace Input
Address address_
Contains address and relationships with abstract record ancestor.
Definition: accessors.hh:527
const Record & get_descendant(const string &name) const
Returns reference to the inherited Record with given name.
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
Accessor to input data conforming to declared Array.
Definition: accessors.hh:567
std::vector< struct Key >::const_iterator KeyIter
Public typedef of constant iterator into array of keys.
Definition: type_record.hh:206
EI_Address ei_address() const
Definition: accessors.cc:305
virtual StorageBase * get_item(const unsigned int index) const
Definition: storage.cc:60
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_record.cc:315
virtual const std::string & get_string() const
Definition: storage.cc:50
virtual bool is_null() const =0
Definition: storage.cc:67
virtual const std::string & get_string() const
Definition: storage.cc:265
Input::Type::Tuple tuple_type_
Corresponding Type::Tuple object.
Definition: accessors.hh:444
std::string make_full_address() const
Definition: accessors.cc:96
Address address_
Contains address and relationships with record ancestor.
Definition: accessors.hh:397
Input::Type::Array array_type_
Corresponding Type::Array.
Definition: accessors.hh:637
KeyIter key_iterator(const string &key) const
Returns iterator to the key struct for given key string.
Definition: type_record.hh:541
KeyIter begin() const
Container-like access to the keys of the Record.
Definition: type_record.hh:565
const StorageBase * storage_head() const
Definition: accessors.hh:225
Class for declaration of inputs sequences.
Definition: type_base.hh:348
std::shared_ptr< Address > down(unsigned int idx) const
Definition: accessors.cc:85
Input::Type::Record record_type_
Corresponding Type::Record object.
Definition: accessors.hh:401
Input::Type::Abstract abstract_type_
Corresponding Type::Abstract object.
Definition: accessors.hh:524
EI_Address ei_address() const
Definition: accessors.cc:169
Input::Type::Record type() const
Definition: accessors.cc:264
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
string address_string() const
Definition: accessors.cc:276
string input_type_name() override
Definition: accessors.cc:222
Class for declaration of polymorphic Record.
static StorageArray empty_storage_
Need persisting empty instance of StorageArray that can be used to create an empty Address...
Definition: accessors.hh:633
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:459
Tuple type proxy class.
Definition: type_tuple.hh:41
EI_Address ei_address() const
Definition: accessors.cc:271
string address_string() const
Definition: accessors.cc:312
Type::Record::KeyIter get_type_key_iterator(const string &key) const override
Return iterator to Type::Tuple key of given name.
Definition: accessors.cc:228
virtual string input_type_name()
Definition: accessors.cc:180
const TypeBase & get_sub_type() const
Getter for the type of array items.
Definition: type_base.hh:410
std::ostringstream & form_message(std::ostringstream &) const override
Definition: accessors.cc:31
virtual Type::Record::KeyIter get_type_key_iterator(const string &key) const
Return iterator to Type::Record key of given name.
Definition: accessors.cc:186
Record type proxy class.
Definition: type_record.hh:171
Accessor to the data with type Type::Tuple.
Definition: accessors.hh:412
void print_stacktrace(std::ostream &out) const
Prints formated stacktrace into given stream out.
Definition: exceptions.cc:42
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:45
virtual void print_info(std::ostringstream &out) const =0
std::shared_ptr< AddressData > data_
Definition: accessors.hh:243
Address address_
Contains address and relationships with array ancestor.
Definition: accessors.hh:640
string address_string() const
Definition: accessors.cc:175