Flow123d  jenkins-Flow123d-linux-release-multijob-282
accessors.cc
Go to the documentation of this file.
1 /*
2  * accessors.cc
3  *
4  * Created on: Apr 26, 2012
5  * Author: jb
6  */
7 
8 
9 #include <memory>
10 #include <boost/make_shared.hpp>
11 #include <boost/lexical_cast.hpp>
12 #include "input/accessors.hh"
14 
15 
16 namespace Input {
17 
18 
19 /*************************************************************************************************************************************
20  * Implementation of InputException
21  */
22 
23 
24 const char * Exception::what() const throw () {
25  // have preallocated some space for error message we want to return
26  // Is there any difference, if we move this into ExceptionBase ??
27  static std::string message(1024,' ');
28 
29 
30  // Be sure that this function do not throw.
31  try {
32  std::ostringstream converter;
33 
34  converter << std::endl << std::endl;
35  converter << "--------------------------------------------------------" << std::endl;
36  converter << "User Error: ";
37  print_info(converter);
38 #ifdef DEBUG_MESSAGES
39  converter << "\n** Diagnosting info **\n" ;
40  converter << boost::diagnostic_information_what( *this );
41  print_stacktrace(converter);
42 #endif
43  converter << "--------------------------------------------------------" << std::endl;
44 
45  message = converter.str();
46  return message.c_str();
47 
48  } catch (std::exception &exc) {
49  std::cerr << "*** Exception encountered in exception handling routines ***" << std::endl << "*** Message is " << std::endl
50  << exc.what() << std::endl << "*** Aborting! ***" << std::endl;
51 
52  std::abort();
53  } catch (...) {
54  std::cerr << "*** Exception encountered in exception handling routines ***" << std::endl << "*** Aborting! ***"
55  << std::endl;
56 
57  std::abort();
58  }
59  return 0;
60 }
61 
62 
63 
64 
65 
66 /*****************************************************************************
67  * Implementation of the class Input::Address
68  */
69 
71 : data_(boost::make_shared<AddressData>())
72 {
73  data_->root_type_ = nullptr;
74  data_->root_storage_ = &Array::empty_storage_;
75  data_->parent_ = nullptr;
76  data_->descendant_order_ = 0;
77  data_->actual_storage_ = &Array::empty_storage_;
78 }
79 
80 
81 Address::Address(const StorageBase * storage_root, const Type::TypeBase *type_root)
82 : data_( boost::make_shared<AddressData>() )
83 {
84  if (! storage_root)
85  THROW( ExcAddressNullPointer() << EI_AccessorName("storage_root") );
86  if (! type_root )
87  THROW( ExcAddressNullPointer() << EI_AccessorName("type_root") );
88 
89  data_->root_type_ = type_root;
90  data_->root_storage_ = storage_root;
91  data_->parent_ = nullptr;
92  data_->descendant_order_ = 0;
93  data_->actual_storage_ = storage_root;
94 }
95 
96 
97 
99 : data_(other.data_)
100 {}
101 
102 
103 std::shared_ptr<Address> Address::down(unsigned int idx) const {
104 
105  auto addr = std::make_shared<Address>(this->data_->root_storage_, this->data_->root_type_);
106  addr->data_->parent_ = this->data_.get();
107  addr->data_->descendant_order_ = idx;
108  addr->data_->actual_storage_ = data_->actual_storage_->get_item(idx);
109 
110  return addr;
111 }
112 
113 
114 std::string Address::make_full_address() const {
116  AddressData * address_data = data_.get();
117  while (address_data->parent_ != NULL) {
118  path.push_back(address_data->descendant_order_);
119  address_data = address_data->parent_;
120  }
121 
122  // for empty path is returned address of root node
123  if (path.size() == 0) {
124  return "/";
125  }
126 
127  const StorageBase * storage = address_data->root_storage_;
128  const Type::TypeBase * input_type = address_data->root_type_;
129  std::string address = "";
130  int i = path.size()-1;
131 
132  while (i >= 0) {
133 
134  // dispatch types
135  if (typeid(*input_type) == typeid(Type::Record)) {
136  storage = storage->get_item(path[i]);
137  const Type::Record * rec = static_cast<const Type::Record *>(input_type);
138  Type::Record::KeyIter it = rec->begin() + path[i];
139  address = address + "/" + it->key_;
140  input_type = it->type_.get();
141  i--;
142  } else
143  if (typeid(*input_type) == typeid(Type::AbstractRecord)) {
144  const Type::AbstractRecord * a_rec = static_cast<const Type::AbstractRecord *>(input_type);
145  const StorageInt * storage_type = static_cast<const StorageInt *>(storage->get_item(0));
146  input_type = & a_rec->get_descendant(storage_type->get_int());
147  } else
148  if (typeid(*input_type) == typeid(Type::Array)) {
149  storage = storage->get_item(path[i]);
150  const Type::Array * arr = static_cast<const Type::Array *>(input_type);
151  address = address + "/" + boost::lexical_cast<std::string>(path[i]);
152  input_type = & arr->get_sub_type();
153  i--;
154  }
155  }
156 
157  return address;
158 }
159 
160 
161 
162 /*****************************************************************************
163  * Implementation of the class Input::Record
164  */
165 
166 
168 : record_type_(), address_( Address() )
169 {}
170 
171 
172 
174 : record_type_(rec.record_type_), address_(rec.address_)
175 {}
176 
177 
178 
179 Record::Record(const Address &address, const Type::Record type)
180 : record_type_(type), address_(address)
181 {
182  if (address.storage_head()->is_null())
183  THROW( ExcAccessorForNullStorage() << EI_AccessorName("Record") );
184 }
185 
186 
187 Input::EI_Address Record::ei_address() const
188 {
189  return EI_Address(address_string());
190 }
191 
192 
194 {
195  return address_.make_full_address();
196 }
197 
199 {
200  return record_type_.type_name();
201 }
202 
203 
204 
205 /*****************************************************************************
206  * Implementation of the class Input::AbstractRecord
207  */
208 
210 : record_type_(), address_( Address() )
211 {}
212 
213 
214 
216 : record_type_(rec.record_type_), address_(rec.address_)
217 {}
218 
219 
220 
222 : record_type_(type), address_(address)
223 {
224  if (address.storage_head()->is_null())
225  THROW( ExcAccessorForNullStorage() << EI_AccessorName("AbstractRecord") );
226 }
227 
228 
229 
230 AbstractRecord::operator Record() const
231 { return Record(address_,type()); }
232 
233 
234 
236 {
237  unsigned int type_id = address_.storage_head()->get_item(0)->get_int();
238  return record_type_.get_descendant(type_id);
239 }
240 
241 
242 Input::EI_Address AbstractRecord::ei_address() const
243 {
244  return EI_Address(address_string());
245 }
246 
248 {
249  return address_.make_full_address();
250 }
251 
252 void AbstractRecord::transpose_to(Input::Record &target_rec, string target_key, unsigned int vec_size) {
253  Input::Iterator<Array> it = target_rec.find<Array>(target_key);
254  if (it) { // target_key is set by user
255  return;
256  }
257 
258  Type::Record::KeyIter key_it = target_rec.record_type_.key_iterator(target_key);
259  const Type::Array *in_arr = static_cast<const Type::Array *>(key_it->type_.get());
260  const Type::TypeBase *target_type = &(in_arr->get_sub_type());
261 
262  StorageTranspose trans(target_type, &(this->record_type_), this->address_.storage_head(), vec_size);
263  StorageArray* result_storage = new StorageArray(vec_size);
264  for(unsigned int i=0; i<vec_size; i++) {
265  result_storage->new_item(i, trans.get_item(i));
266  }
267  StorageArray* storage_arr =
268  const_cast<StorageArray *>(
269  static_cast<const StorageArray *>(target_rec.address_.storage_head()));
270  storage_arr->set_item(target_rec.record_type_.key_index(target_key), result_storage);
271 }
272 
273 
274 /*****************************************************************************
275  * Implementation of the class Input::Array
276  */
277 
278 
280 : array_type_(Type::Bool()), address_( Address() )
281 {}
282 
283 
284 Array::Array(const Array &ar)
285 : array_type_(ar.array_type_), address_(ar.address_)
286 {}
287 
288 
289 Array::Array(const Address &address, const Type::Array type)
290 : array_type_(type), address_(address)
291 {
292  if (address.storage_head()->is_null())
293  THROW( ExcAccessorForNullStorage() << EI_AccessorName("Array") );
294 }
295 
296 
297 Input::EI_Address Array::ei_address() const
298 {
299  return EI_Address(address_string());
300 }
301 
302 
303 
304 string Array::address_string() const
305 {
306  return address_.make_full_address();
307 }
308 
309 
311 
312 
313 /*****************************************************************************
314  * Explicit instantiation of accessor's templates
315  *
316  * .. TODO
317  */
318 
319 
320 
321 } // closing namespace Input
Address address_
Contains address and relationships with abstract record ancestor.
Definition: accessors.hh:518
Base of classes for declaring structure of the input data.
Definition: type_base.hh:63
Base class for nodes of a data storage tree.
Definition: storage.hh:57
Accessor to input data conforming to declared Array.
Definition: accessors.hh:558
std::vector< struct Key >::const_iterator KeyIter
Definition: type_record.hh:200
EI_Address ei_address() const
Definition: accessors.cc:297
const StorageBase * root_storage_
Definition: accessors.hh:213
virtual bool is_null() const =0
Definition: storage.cc:57
std::string make_full_address() const
Definition: accessors.cc:114
const char * what() const
Definition: accessors.cc:24
void set_item(unsigned int index, StorageBase *item)
Definition: storage.cc:98
virtual int get_int() const
Definition: storage.cc:187
unsigned int key_index(const string &key) const
Definition: type_record.hh:694
Input::Type::AbstractRecord record_type_
Corresponding Type::AbstractRecord object.
Definition: accessors.hh:515
Address address_
Contains address and relationships with record ancestor.
Definition: accessors.hh:433
Iterator< Ret > find(const string &key) const
string record_type_name()
Definition: accessors.cc:198
virtual string type_name() const
Record type name getter.
Definition: type_record.cc:321
boost::shared_ptr< AddressData > data_
Definition: accessors.hh:278
KeyIter key_iterator(const string &key) const
Definition: type_record.hh:707
KeyIter begin() const
Definition: type_record.hh:731
const StorageBase * storage_head() const
Definition: accessors.hh:260
void transpose_to(Input::Record &target_rec, string target_key, unsigned int vec_size)
Definition: accessors.cc:252
Class for declaration of inputs sequences.
Definition: type_base.hh:239
std::shared_ptr< Address > down(unsigned int idx) const
Definition: accessors.cc:103
unsigned int descendant_order_
Definition: accessors.hh:205
Input::Type::Record record_type_
Corresponding Type::Record object.
Definition: accessors.hh:429
virtual const StorageBase * get_item(const unsigned int index) const
Definition: storage.cc:50
EI_Address ei_address() const
Definition: accessors.cc:187
virtual int get_int() const
Definition: storage.cc:19
Input::Type::Record type() const
Definition: accessors.cc:235
Accessor to the data with type Type::Record.
Definition: accessors.hh:327
Class for declaration of polymorphic Record.
Definition: type_record.hh:487
string address_string() const
Definition: accessors.cc:247
static StorageArray empty_storage_
Need persisting empty instance of StorageArray that can be used to create an empty Address...
Definition: accessors.hh:624
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:448
EI_Address ei_address() const
Definition: accessors.cc:242
string address_string() const
Definition: accessors.cc:304
const Input::Type::TypeBase * root_type_
Definition: accessors.hh:209
const TypeBase & get_sub_type() const
Getter for the type of array items.
Definition: type_base.hh:277
Record type proxy class.
Definition: type_record.hh:169
const Record & get_descendant(const string &name) const
Definition: type_record.cc:597
void print_stacktrace(std::ostream &out) const
Prints formated stacktrace into given stream out.
Definition: exceptions.cc:75
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:34
virtual void print_info(std::ostringstream &out) const =0
Address address_
Contains address and relationships with array ancestor.
Definition: accessors.hh:631
string address_string() const
Definition: accessors.cc:193