Flow123d  last_with_con_2.0.0-663-gd0e2296
type_base.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 type_base.cc
15  * @brief
16  */
17 
18 #include <limits>
19 #include <ios>
20 #include <map>
21 #include <vector>
22 #include <string>
23 #include <iomanip>
24 
25 #include "system/system.hh"
26 
27 #include <boost/type_traits.hpp>
28 #include <boost/tokenizer.hpp>
29 #include <boost/algorithm/string.hpp>
30 #include <boost/functional/hash.hpp>
31 #include <boost/pointer_cast.hpp>
32 
33 
34 #include "input_type.hh"
35 #include "type_output.hh"
36 #include "type_repository.hh"
37 #include "attribute_lib.hh"
39 
40 
41 namespace Input {
42 namespace Type {
43 
44 using namespace std;
45 
46 
47 
48 /*******************************************************************
49  * implementation of TypeBase
50  */
51 
52 
53 
55 : attributes_( std::make_shared<attribute_map>() ), root_of_generic_subtree_(false),
56  generic_type_hash_(0) {}
57 
58 
59 
63 
64 
65 
67 
68 
69 bool TypeBase::is_valid_identifier(const string& key) {
70  namespace ba = boost::algorithm;
71  return ba::all( key, ba::is_lower() || ba::is_digit() || ba::is_any_of("_") );
72 }
73 
74 
75 string TypeBase::desc() const {
76  stringstream ss;
77  ss << OutputText(this);
78  return ss.str();
79 }
80 
81 
82 
84  // mark unfinished types as deleted
90 
91  // check and remove deleted types
97 }
98 
99 
100 
101  std::string TypeBase::hash_str(TypeHash hash) {
102  stringstream ss;
103  ss << "\"" << std::hex << hash << "\"";
104  return ss.str();
105 }
106 
107 
108 
109 
110 void TypeBase::add_attribute_(std::string name, json_string val) {
111  ASSERT(validate_json(val))(name)(val).error("Invalid JSON format of attribute");
112  (*attributes_)[name] = val;
113 }
114 
115 
117  try {
118  json_spirit::mValue node;
119  json_spirit::read_or_throw( str, node);
120  return true;
121  } catch (json_spirit::Error_position &e ) {
122  return false;
123  }
124 }
125 
126 
128  std::stringstream ss;
129  ss << "{";
130  for (ParameterMap::iterator it=parameter_map.begin(); it!=parameter_map.end(); it++) {
131  if (it != parameter_map.begin()) ss << "," << endl;
132  ss << "\"" << (*it).first << "\" : " << TypeBase::hash_str( (*it).second );
133  }
134  ss << "}";
135  return ss.str();
136 }
137 
139  stringstream ss;
140  ss << "[ ";
141  for (ParameterMap::iterator it=parameter_map.begin(); it!=parameter_map.end(); it++) {
142  if (it != parameter_map.begin()) ss << ", ";
143  ss << "\"" << it->first << "\"";
144  }
145  ss << " ]";
146  return ss.str();
147 }
148 
150  // check if the type is really generic (it may be non-generic even if part of a generic subtree)
151  if (parameter_map.size() > 0)
155 }
156 
157 
158 void TypeBase::copy_attributes(attribute_map other_attributes) {
159  attributes_->clear();
160  for(auto &item : other_attributes) {
161  if (item.first[0] != '_') // not internal attribute
162  attributes_->insert(item);
163  }
164 }
165 
166 
167 
168 
169 
170 
171 
172 
173 std::ostream& operator<<(std::ostream& stream, const TypeBase& type) {
174  return ( stream << OutputText(&type) );
175 }
176 
177 
178 
179 /**********************************************************************************
180  * implementation of Type::Array
181  */
182 
184 {
185  TypeHash seed=0;
186  boost::hash_combine(seed, type_name());
187  boost::hash_combine(seed, data_->lower_bound_);
188  boost::hash_combine(seed, data_->upper_bound_);
189  boost::hash_combine(seed, data_->type_of_values_->content_hash() );
190  return seed;
191 }
192 
193 
195  return data_->finish(finish_type);
196 }
197 
198 
199 
201 {
202  ASSERT(finish_type != FinishStatus::none_).error();
203  ASSERT(finish_type != FinishStatus::in_perform_).error();
204  ASSERT(finish_status != FinishStatus::in_perform_).error("Recursion in the IST element: array_of_" + type_of_values_->type_name());
205 
207 
208 
210 
211  if (typeid( *(type_of_values_.get()) ) == typeid(Instance)) {
212  type_of_values_->finish(FinishStatus::generic_); // finish Instance object
213  type_of_values_ = type_of_values_->make_instance().first;
214  }
215  if ((finish_type != FinishStatus::generic_) && type_of_values_->is_root_of_generic_subtree())
216  THROW( ExcGenericWithoutInstance() << EI_Object(type_of_values_->type_name()) );
217 
218  type_of_values_->finish(finish_type);
219  ASSERT(type_of_values_->is_finished()).error();
220  if (finish_type == FinishStatus::delete_) type_of_values_.reset();
221  finish_status = finish_type;
222  return (finish_status);
223 }
224 
225 
226 
227 string Array::type_name() const {
228  return "array_of_" + data_->type_of_values_->type_name();
229 }
230 
231 
232 
233 bool Array::operator==(const TypeBase &other) const {
234  return typeid(*this) == typeid(other) &&
235  (*data_->type_of_values_ == static_cast<const Array *>(&other)->get_sub_type() );
236 }
237 
238 
239 
241  // Create copy of array, we can't set type from parameter vector directly (it's TypeBase that is not allowed)
242  Array arr = this->deep_copy();
243  // Replace parameter stored in type_of_values_
244  MakeInstanceReturnType inst = arr.data_->type_of_values_->make_instance(vec);
245  arr.data_->type_of_values_ = inst.first;
246  ParameterMap parameter_map = inst.second;
247  // Copy attributes
249 
250  // Set parameters as attribute
251  json_string val = this->print_parameter_map_to_json(parameter_map);
252  ASSERT(this->validate_json(val))(val).error("Invalid JSON format of attribute 'parameters'.");
253  arr.parameter_map_ = parameter_map;
254  arr.generic_type_hash_ = this->content_hash();
255 
256  return std::make_pair( std::make_shared<Array>(arr), parameter_map );
257 }
258 
259 
261  Array arr = Array(Integer()); // Type integer will be overwritten
262  arr.data_ = std::make_shared<Array::ArrayData>(*this->data_);
263  arr.data_->finish_status = FinishStatus::none_;
264  return arr;
265 }
266 
267 
268 Array::Array(std::shared_ptr<TypeBase> type, unsigned int min_size, unsigned int max_size)
269 : data_(std::make_shared<ArrayData>(min_size, max_size))
270 {
271  ASSERT_LE(min_size, max_size).error("Wrong limits for size of Input::Type::Array");
272  ASSERT(type->is_closed()).error();
273 
274  data_->type_of_values_ = type;
275 }
276 
277 
278 /**********************************************************************************
279  * implementation and explicit instantiation of Array constructor template
280  */
281 
282 template <class ValueType>
283 Array::Array(const ValueType &type, unsigned int min_size, unsigned int max_size)
284 : Array(std::static_pointer_cast<TypeBase>( std::make_shared<ValueType>(type) ), min_size, max_size)
285 {
286  // ASSERT MESSAGE: The type of declared keys has to be a class derived from TypeBase.
287  BOOST_STATIC_ASSERT( (boost::is_base_of<TypeBase, ValueType >::value) );
288 }
289 
290 // explicit instantiation
291 
292 #define ARRAY_CONSTRUCT(TYPE) \
293 template Array::Array(const TYPE &type, unsigned int min_size, unsigned int max_size)
294 
295 ARRAY_CONSTRUCT(String);
296 ARRAY_CONSTRUCT(Integer);
297 ARRAY_CONSTRUCT(Double);
298 ARRAY_CONSTRUCT(Bool);
299 ARRAY_CONSTRUCT(FileName);
300 ARRAY_CONSTRUCT(Selection);
303 ARRAY_CONSTRUCT(Tuple);
304 ARRAY_CONSTRUCT(Abstract);
305 ARRAY_CONSTRUCT(Parameter);
306 ARRAY_CONSTRUCT(Instance);
307 
308 
309 /**********************************************************************************
310  * implementation of Type::Scalar ... and descendants.
311  */
312 
313 /**********************************************************************************
314  * implementation of Type::Bool
315  */
316 
317 
319 {
320  TypeHash seed=0;
321  boost::hash_combine(seed, type_name());
322  return seed;
323 }
324 
325 
326 string Bool::type_name() const {
327  return "Bool";
328 }
329 
330 
332  return std::make_pair( std::make_shared<Bool>(*this), ParameterMap() );
333 }
334 
335 /**********************************************************************************
336  * implementation of Type::Integer
337  */
338 
340 {
341  TypeHash seed=0;
342  boost::hash_combine(seed, type_name());
343  boost::hash_combine(seed, lower_bound_);
344  boost::hash_combine(seed, upper_bound_);
345  return seed;
346 }
347 
348 
349 
350 bool Integer::match(std::int64_t value) const {
351  return ( value >=lower_bound_ && value <= upper_bound_);
352 }
353 
354 
355 
356 string Integer::type_name() const {
357  return "Integer";
358 }
359 
360 
362  return std::make_pair( std::make_shared<Integer>(*this), ParameterMap() );
363 }
364 
365 
366 /**********************************************************************************
367  * implementation of Type::Double
368  */
369 
370 
372 {
373  TypeHash seed=0;
374  boost::hash_combine(seed, type_name());
375  boost::hash_combine(seed, lower_bound_);
376  boost::hash_combine(seed, upper_bound_);
377  return seed;
378 }
379 
380 
381 
382 bool Double::match(double value) const {
383  return ( value >=lower_bound_ && value <= upper_bound_);
384 }
385 
386 
387 
388 string Double::type_name() const {
389  return "Double";
390 }
391 
392 
394  return std::make_pair( std::make_shared<Double>(*this), ParameterMap() );
395 }
396 
397 
398 /**********************************************************************************
399  * implementation of Type::FileName
400  */
401 
403 {
404  TypeHash seed=0;
405  boost::hash_combine(seed, type_name());
406  boost::hash_combine(seed, type_);
407  return seed;
408 }
409 
410 
411 
412 
413 
414 string FileName::type_name() const {
415  switch (type_) {
416  case ::FilePath::input_file:
417  return "FileName_input";
418  case ::FilePath::output_file:
419  return "FileName_output";
420  default:
421  return "FileName";
422  }
423 }
424 
425 bool FileName::operator==(const TypeBase &other) const
426 { return typeid(*this) == typeid(other) &&
427  (type_== static_cast<const FileName *>(&other)->get_file_type() );
428 }
429 
430 
431 bool FileName::match(const string &str) const {
432  return (type_ == ::FilePath::input_file) || (str[0] != DIR_DELIMITER); // output files can not be absolute
433 }
434 
435 
436 
438  return std::make_pair( std::make_shared<FileName>(*this), ParameterMap() );
439 }
440 
441 
442 /**********************************************************************************
443  * implementation of Type::String
444  */
445 
446 
448 {
449  TypeHash seed=0;
450  boost::hash_combine(seed, type_name());
451  return seed;
452 }
453 
454 
455 
456 string String::type_name() const {
457  return "String";
458 }
459 
460 
461 
462 
463 bool String::match(const string &str) const {
464  return true;
465 }
466 
467 
468 
470  return std::make_pair( std::make_shared<String>(*this), ParameterMap() );
471 }
472 
473 
474 
475 } // closing namespace Type
476 } // closing namespace Input
477 
478 
479 
bool operator==(const TypeBase &other) const override
Implements Type::TypeBase::operator== Compares also subtypes.
Definition: type_base.cc:233
bool validate_json(json_string str) const
Check if str is valid JSON string.
Definition: type_base.cc:116
MakeInstanceReturnType make_instance(std::vector< ParameterPair > vec=std::vector< ParameterPair >()) override
Implements TypeBase::make_instance.
Definition: type_base.cc:437
static bool is_valid_identifier(const string &key)
Check that a key is valid identifier.
Definition: type_base.cc:69
Base of classes for declaring structure of the input data.
Definition: type_base.hh:93
void set_generic_attributes(ParameterMap param_map)
Definition: type_base.cc:149
MakeInstanceReturnType make_instance(std::vector< ParameterPair > vec=std::vector< ParameterPair >()) override
Implements TypeBase::make_instance.
Definition: type_base.cc:361
bool is_root_of_generic_subtree()
Indicates if type is marked with flag root_of_generic_subtree_.
Definition: type_base.hh:241
virtual string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_base.cc:456
void copy_attributes(attribute_map other_attributes)
Definition: type_base.cc:158
static string generic_parameters()
std::string hash_str() const
Format the hash of this type.
Definition: type_base.hh:229
bool root_of_generic_subtree_
flag is true if type should be root of generic subtree
Definition: type_base.hh:310
string desc() const
Returns string with Type extensive documentation.
Definition: type_base.cc:75
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:318
IntFormatSpec< int, TypeSpec<'x'> > hex(int value)
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_base.cc:388
FinishStatus finish(FinishStatus finish_type=FinishStatus::regular_)
Finishes initialization of the ArrayData.
Definition: type_base.cc:200
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:447
std::pair< std::shared_ptr< TypeBase >, ParameterMap > MakeInstanceReturnType
Return type of make_instance methods, contains instance of generic type and map of used parameters...
Definition: type_base.hh:111
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_base.cc:414
Helper class that stores data of generic types.
Definition: type_generic.hh:88
#define ASSERT_LE(a, b)
Definition of comparative assert macro (Less or Equal)
Definition: asserts.hh:304
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:183
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_base.cc:326
virtual string type_name() const
Returns an identification of the type. Useful for error messages.
Definition: type_base.hh:133
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:347
std::shared_ptr< attribute_map > attributes_
map of type attributes (e. g. input_type, name etc.)
Definition: type_base.hh:307
Class for declaration of the integral input data.
Definition: type_base.hh:496
void add_attribute_(std::string name, json_string val)
Add attribute of given name to attribute map.
Definition: type_base.cc:110
Class for declaration of inputs sequences.
Definition: type_base.hh:348
void read_or_throw(const std::string &s, mValue &value)
static constexpr bool value
Definition: json.hpp:87
static TypeRepository & get_instance()
Return singleton instance of class.
ParameterMap parameter_map_
map of parameters if type is part of generic subtree
Definition: type_base.hh:316
virtual TypeHash content_hash() const =0
Hash of the type specification.
std::shared_ptr< ArrayData > data_
Handle to the actual array data.
Definition: type_base.hh:442
bool match(std::int64_t value) const
Check valid value of Integer.
Definition: type_base.cc:350
std::map< std::string, TypeHash > ParameterMap
Defines map of used parameters.
Definition: type_base.hh:109
void reset_deleted_types()
Reset and remove types marked as deleted during finish.
TypeBase()
The default constructor.
Definition: type_base.cc:54
bool match(double value) const
Returns true if the given integer value conforms to the Type::Double bounds.
Definition: type_base.cc:382
static string root_of_generic_subtree()
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:339
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_base.cc:356
MakeInstanceReturnType make_instance(std::vector< ParameterPair > vec=std::vector< ParameterPair >()) override
Implements TypeBase::make_instance.
Definition: type_base.cc:240
FinishStatus finish(FinishStatus finish_type=FinishStatus::regular_) override
Finishes initialization of the Array type because of lazy evaluation of type_of_values.
Definition: type_base.cc:194
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:402
virtual MakeInstanceReturnType make_instance(std::vector< ParameterPair > vec=std::vector< ParameterPair >()) override
Implements TypeBase::make_instance.
Definition: type_base.cc:469
bool match(const string &str) const override
Checks relative output paths.
Definition: type_base.cc:431
virtual FinishStatus finish_status() const
Returns true if the type is fully specified and ready for read access.
Definition: type_base.hh:120
virtual bool match(const string &value) const
Particular descendants can check validity of the string.
Definition: type_base.cc:463
TypeHash generic_type_hash_
hash string of generic type if type is derived, or empty string
Definition: type_base.hh:313
json_string print_parameter_map_to_json(ParameterMap parameter_map) const
Create JSON output from parameter_map formatted as value of attribute.
Definition: type_base.cc:127
friend class Array
Definition: type_base.hh:318
Actual data of the Array.
Definition: type_base.hh:356
#define DIR_DELIMITER
Definition: system.hh:44
std::string json_string
String stored in JSON format.
Definition: type_base.hh:99
MakeInstanceReturnType make_instance(std::vector< ParameterPair > vec=std::vector< ParameterPair >()) override
Implements TypeBase::make_instance.
Definition: type_base.cc:331
std::ostream & operator<<(std::ostream &stream, const TypeBase &type)
For convenience we provide also redirection operator for output documentation of Input:Type classes...
Definition: type_base.cc:173
bool operator==(const TypeBase &other) const override
Comparison of types.
Definition: type_base.cc:425
static void delete_unfinished_types()
Finishes and marks all types registered in type repositories and unused in IST.
Definition: type_base.cc:83
TypeHash content_hash() const override
Implements TypeBase::content_hash.
Definition: type_base.cc:371
Class for create text documentation.
Definition: type_output.hh:201
ARRAY_CONSTRUCT(String)
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_base.cc:227
virtual ~TypeBase()
Destructor.
Definition: type_base.cc:66
Array deep_copy() const
Create deep copy of Array.
Definition: type_base.cc:260
json_string print_parameter_map_keys_to_json(ParameterMap param_map) const
Definition: type_base.cc:138
std::size_t TypeHash
Type returned by content_hash methods.
Definition: type_base.hh:96
Array()
Forbids default constructor in order to prevent empty data_.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:45
friend class Record
Definition: type_base.hh:319
MakeInstanceReturnType make_instance(std::vector< ParameterPair > vec=std::vector< ParameterPair >()) override
Implements TypeBase::make_instance.
Definition: type_base.cc:393
void finish(Type::FinishStatus finish_type)
Finish all stored types.