Flow123d  last_with_con_2.0.0-4-g42e6930
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/make_shared.hpp>
20 #include <boost/lexical_cast.hpp>
21 #include "input/accessors.hh"
22 
23 
24 namespace Input {
25 
26 
27 /*************************************************************************************************************************************
28  * Implementation of InputException
29  */
30 
31 
32 std::ostringstream &Exception::form_message(std::ostringstream &converter) const {
33 
34  converter << "--------------------------------------------------------" << std::endl;
35  converter << "User Error: ";
36  print_info(converter);
37 #ifdef FLOW123D_DEBUG_MESSAGES
38  converter << "\n** Diagnosting info **\n" ;
39  converter << boost::diagnostic_information_what( *this );
40  print_stacktrace(converter);
41 #endif
42  converter << std::endl << "--------------------------------------------------------" << std::endl;
43 
44  return converter;
45 }
46 
47 
48 
49 
50 
51 /*****************************************************************************
52  * Implementation of the class Input::Address
53  */
54 
56 : data_(boost::make_shared<AddressData>())
57 {
58  data_->root_type_ = nullptr;
59  data_->root_storage_ = &Array::empty_storage_;
60  data_->descendant_order_ = 0;
61  data_->actual_storage_ = &Array::empty_storage_;
62 }
63 
64 
65 Address::Address(const StorageBase * storage_root, const Type::TypeBase *type_root)
66 : data_( boost::make_shared<AddressData>() )
67 {
68  if (! storage_root)
69  THROW( ExcAddressNullPointer() << EI_AccessorName("storage_root") );
70  if (! type_root )
71  THROW( ExcAddressNullPointer() << EI_AccessorName("type_root") );
72 
73  data_->root_type_ = type_root;
74  data_->root_storage_ = storage_root;
75  data_->descendant_order_ = 0;
76  data_->actual_storage_ = storage_root;
77 }
78 
79 
80 
82 : data_(other.data_)
83 {}
84 
85 
86 std::shared_ptr<Address> Address::down(unsigned int idx) const {
87 
88  auto addr = std::make_shared<Address>(this->data_->root_storage_, this->data_->root_type_);
89  addr->data_->parent_ = this->data_;
90  addr->data_->descendant_order_ = idx;
91  addr->data_->actual_storage_ = data_->actual_storage_->get_item(idx);
92 
93  return addr;
94 }
95 
96 
97 std::string Address::make_full_address() const {
99  boost::shared_ptr<AddressData> address_data = data_;
100  while (address_data->parent_ != NULL) {
101  path.push_back(address_data->descendant_order_);
102  address_data = address_data->parent_;
103  }
104 
105  // for empty path is returned address of root node
106  if (path.size() == 0) {
107  return "/";
108  }
109 
110  const StorageBase * storage = address_data->root_storage_;
111  const Type::TypeBase * input_type = address_data->root_type_;
112  std::string address = "";
113  int i = path.size()-1;
114 
115  while (i >= 0) {
116 
117  // dispatch types
118  if (typeid(*input_type) == typeid(Type::Record)) {
119  storage = storage->get_item(path[i]);
120  const Type::Record * rec = static_cast<const Type::Record *>(input_type);
121  Type::Record::KeyIter it = rec->begin() + path[i];
122  address = address + "/" + it->key_;
123  input_type = it->type_.get();
124  i--;
125  } else
126  if (typeid(*input_type) == typeid(Type::Abstract)) {
127  const Type::Abstract * a_rec = static_cast<const Type::Abstract *>(input_type);
128  const StorageString * storage_type = static_cast<const StorageString *>(storage->get_item(0));
129  input_type = & a_rec->get_descendant(storage_type->get_string());
130  } else
131  if (typeid(*input_type) == typeid(Type::Array)) {
132  storage = storage->get_item(path[i]);
133  const Type::Array * arr = static_cast<const Type::Array *>(input_type);
134  address = address + "/" + boost::lexical_cast<std::string>(path[i]);
135  input_type = & arr->get_sub_type();
136  i--;
137  }
138  }
139 
140  return address;
141 }
142 
143 
144 
145 /*****************************************************************************
146  * Implementation of the class Input::Record
147  */
148 
149 
151 : address_( Address() ), record_type_()
152 {}
153 
154 
155 
158 {}
159 
160 
161 
162 Record::Record(const Address &address, const Type::Record type)
163 : address_(address), record_type_(type)
164 {
165  if (address.storage_head()->is_null())
166  THROW( ExcAccessorForNullStorage() << EI_AccessorName("Record") );
167 }
168 
169 
170 Input::EI_Address Record::ei_address() const
171 {
172  return EI_Address(address_string());
173 }
174 
175 
177 {
178  return address_.make_full_address();
179 }
180 
182 {
183  return record_type_.type_name();
184 }
185 
186 
188  return record_type_.key_iterator(key);
189 }
190 
191 
192 
193 /*****************************************************************************
194  * Implementation of the class Input::Tuple
195  */
196 
197 
199 : tuple_type_()
200 {
201  this->address_ = Address();
202 }
203 
204 
205 
206 Tuple::Tuple(const Tuple &tpl)
208 {
209  this->address_ = tpl.address_;
210 }
211 
212 
213 
214 Tuple::Tuple(const Address &address, const Type::Tuple type)
215 : tuple_type_(type)
216 {
217  this->address_ = address;
218  if (address.storage_head()->is_null())
219  THROW( ExcAccessorForNullStorage() << EI_AccessorName("Tuple") );
220 }
221 
222 
224 {
225  return tuple_type_.type_name();
226 }
227 
228 
230  return tuple_type_.key_iterator(key);
231 }
232 
233 
234 
235 /*****************************************************************************
236  * Implementation of the class Input::AbstractRecord
237  */
238 
240 : abstract_type_(), address_( Address() )
241 {}
242 
243 
244 
247 {}
248 
249 
250 
252 : abstract_type_(type), address_(address)
253 {
254  if (address.storage_head()->is_null())
255  THROW( ExcAccessorForNullStorage() << EI_AccessorName("AbstractRecord") );
256 }
257 
258 
259 
260 AbstractRecord::operator Record() const
261 { return Record(address_,type()); }
262 
263 
264 
266 {
267  string type_name = address_.storage_head()->get_item(0)->get_string();
268  return abstract_type_.get_descendant(type_name);
269 }
270 
271 
272 Input::EI_Address AbstractRecord::ei_address() const
273 {
274  return EI_Address(address_string());
275 }
276 
278 {
279  return address_.make_full_address();
280 }
281 
282 
283 /*****************************************************************************
284  * Implementation of the class Input::Array
285  */
286 
287 
289 : array_type_(Type::Bool()), address_( Address() )
290 {}
291 
292 
293 Array::Array(const Array &ar)
295 {}
296 
297 
298 Array::Array(const Address &address, const Type::Array type)
299 : array_type_(type), address_(address)
300 {
301  if (address.storage_head()->is_null())
302  THROW( ExcAccessorForNullStorage() << EI_AccessorName("Array") );
303 }
304 
305 
306 Input::EI_Address Array::ei_address() const
307 {
308  return EI_Address(address_string());
309 }
310 
311 
312 
313 string Array::address_string() const
314 {
315  return address_.make_full_address();
316 }
317 
318 
320 
321 
322 /*****************************************************************************
323  * Explicit instantiation of accessor's templates
324  *
325  * .. TODO
326  */
327 
328 
329 
330 } // closing namespace Input
Address address_
Contains address and relationships with abstract record ancestor.
Definition: accessors.hh:512
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:79
Base class for nodes of a data storage tree.
Definition: storage.hh:68
std::ostringstream & form_message(std::ostringstream &) const override
Definition: accessors.cc:32
Accessor to input data conforming to declared Array.
Definition: accessors.hh:552
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:306
virtual StorageBase * get_item(const unsigned int index) const
Definition: storage.cc:60
virtual const std::string & get_string() const
Definition: storage.cc:50
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_record.cc:299
virtual const std::string & get_string() const
Definition: storage.cc:265
Input::Type::Tuple tuple_type_
Corresponding Type::Tuple object.
Definition: accessors.hh:429
std::string make_full_address() const
Definition: accessors.cc:97
Address address_
Contains address and relationships with record ancestor.
Definition: accessors.hh:382
Input::Type::Array array_type_
Corresponding Type::Array.
Definition: accessors.hh:622
boost::shared_ptr< AddressData > data_
Definition: accessors.hh:228
KeyIter key_iterator(const string &key) const
Returns iterator to the key struct for given key string.
Definition: type_record.hh:535
KeyIter begin() const
Container-like access to the keys of the Record.
Definition: type_record.hh:559
const StorageBase * storage_head() const
Definition: accessors.hh:210
Class for declaration of inputs sequences.
Definition: type_base.hh:321
std::shared_ptr< Address > down(unsigned int idx) const
Definition: accessors.cc:86
Input::Type::Record record_type_
Corresponding Type::Record object.
Definition: accessors.hh:386
Input::Type::Abstract abstract_type_
Corresponding Type::Abstract object.
Definition: accessors.hh:509
EI_Address ei_address() const
Definition: accessors.cc:170
Input::Type::Record type() const
Definition: accessors.cc:265
Accessor to the data with type Type::Record.
Definition: accessors.hh:277
string address_string() const
Definition: accessors.cc:277
string input_type_name() override
Definition: accessors.cc:223
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:618
virtual bool is_null() const =0
Definition: storage.cc:67
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:444
virtual void print_info(std::ostringstream &out) const =0
Type::Record::KeyIter get_type_key_iterator(const string &key) const override
Return iterator to Type::Tuple key of given name.
Definition: accessors.cc:229
Tuple type proxy class.
Definition: type_tuple.hh:41
EI_Address ei_address() const
Definition: accessors.cc:272
string address_string() const
Definition: accessors.cc:313
virtual string input_type_name()
Definition: accessors.cc:181
const TypeBase & get_sub_type() const
Getter for the type of array items.
Definition: type_base.hh:379
virtual Type::Record::KeyIter get_type_key_iterator(const string &key) const
Return iterator to Type::Record key of given name.
Definition: accessors.cc:187
Record type proxy class.
Definition: type_record.hh:171
Accessor to the data with type Type::Tuple.
Definition: accessors.hh:397
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
Address address_
Contains address and relationships with array ancestor.
Definition: accessors.hh:625
string address_string() const
Definition: accessors.cc:176