Flow123d  build_with_4.0.3-24aa4ef
reader_internal_transpose.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 reader_internal_transpose.cc
15  * @brief
16  */
17 
18 
20 #include "input/input_type.hh"
21 //#include "input/accessors.hh"
22 
23 namespace Input {
24 
25 using namespace std;
26 
27 /*******************************************************************
28  * implementation of ReaderInternalTranspose
29  */
30 
32 : transpose_index_(0)
33 {}
34 
36 {
37  const Type::TypeBase &sub_type = array->get_sub_type();
38  StorageBase *first_item_storage;
39  try {
40  first_item_storage = make_storage(p, &sub_type);
41  } catch (ExcInputError &e) {
42  if ( !array->match_size(1) ) {
43  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::array_type) + "', but we found: ");
44  }
45  e << EI_TransposeIndex(transpose_index_);
46  e << EI_TransposeAddress(p.as_string());
47  throw;
48  }
49 
50  // automatic conversion to array with one element
51  if (transpose_array_sizes_.size() == 0) {
52  return make_autoconversion_array_storage(p, array, first_item_storage);
53  } else {
54 
55  // check that transposed arrays are of the same size
57  transpose_array_sizes_.end() );
58  if (transpose_array_sizes_.size() == 1) {
59  unsigned int sizes = transpose_array_sizes_[0]; // sizes of transposed
60 
61  // array size out of bounds
62  if ( !array->match_size( sizes ) ) {
63  stringstream ss;
64  ss << "Result of transpose auto-conversion do not fit the size " << sizes << " of the Array.";
65  this->generate_input_error(p, array, ss.str(), false);
66  }
67 
68  // create storage of array
69  StorageArray *storage_array = new StorageArray(sizes);
70  storage_array->new_item(0, first_item_storage);
71  if (sizes>1) {
73  while (transpose_index_ < sizes) {
74  try {
75  storage_array->new_item(transpose_index_, make_storage(p, &sub_type));
76  } catch (ExcInputError &e) {
77  e << EI_TransposeIndex(transpose_index_);
78  e << EI_TransposeAddress(p.as_string());
79  throw;
80  }
82  }
83  }
84 
85  return storage_array;
86  } else {
87  this->generate_input_error(p, array, "Unequal sizes of sub-arrays during transpose auto-conversion of '" + p.get_node_type(ValueTypes::array_type) + "'", false);
88  }
89  }
90 
91  return NULL;
92 }
93 
95 {
96  int arr_size;
97  if ( (arr_size = p.get_array_size()) != -1 ) {
98  return this->make_array_storage(p, array, arr_size);
99  } else {
100  // if transposition is carried, only conversion to array with one element is allowed
101  // try automatic conversion to array with one element
102  const Type::TypeBase &sub_type = array->get_sub_type();
103  StorageBase *one_element_storage = this->make_storage(p, &sub_type);
104  return make_autoconversion_array_storage(p, array, one_element_storage);
105  }
106 }
107 
109 {
110  if ( p.is_array_type() ) {
111  // transpose auto-conversion for array type
112  return this->make_transposed_storage(p, selection);
113  } else {
114  string item_name = read_string_value(p, selection);
115  try {
116  int value = selection->name_to_int( item_name );
117  return new StorageInt( value );
118  } catch (Type::Selection::ExcSelectionKeyNotFound &exc) {
119  this->generate_input_error(p, selection, "Wrong value '" + item_name + "' of the Selection.", false);
120  }
121  }
122 
123  return NULL;
124 }
125 
127 {
128  if ( p.is_array_type() ) {
129  // transpose auto-conversion for array type
130  return this->make_transposed_storage(p, bool_type);
131  } else {
132  return new StorageBool( read_bool_value(p, bool_type) );
133  }
134 }
135 
137 {
138  if ( p.is_array_type() ) {
139  // transpose auto-conversion for array type
140  return this->make_transposed_storage(p, int_type);
141  }
142  std::int64_t value = read_int_value(p, int_type);
143 
144  if ( int_type->match(value) )
145  {
146  return new StorageInt( value );
147  } else {
148  this->generate_input_error(p, int_type, "Value out of bounds.", false);
149  }
150  return NULL;
151 }
152 
154 {
155  if ( p.is_array_type() ) {
156  // transpose auto-conversion for array type
157  return this->make_transposed_storage(p, double_type);
158  } else {
159  double value = read_double_value(p, double_type);
160 
161  if (double_type->match(value)) {
162  return new StorageDouble( value );
163  } else {
164  this->generate_input_error(p, double_type, "Value out of bounds.", false);
165  }
166  }
167 
168  return NULL;
169 }
170 
172 {
173  if ( p.is_array_type() ) {
174  // transpose auto-conversion for array type
175  return this->make_transposed_storage(p, string_type);
176  } else {
177  return new StorageString( read_string_value(p, string_type) );
178  }
179 }
180 
182  ASSERT(p.is_array_type()).error();
183 
184  int arr_size = p.get_array_size();
185  if ( arr_size == 0 ) {
186  this->generate_input_error(p, type, "Empty array during transpose auto-conversion.", false);
187  } else {
188  if (transpose_index_ == 0) transpose_array_sizes_.push_back( arr_size );
190  StorageBase *storage = make_storage(p, type);
191  p.up();
192  return storage;
193  }
194 
195  return NULL;
196 }
197 
199 {
200  if ( array->match_size( 1 ) ) {
201  StorageArray *storage_array = new StorageArray(1);
202  storage_array->new_item(0, item);
203 
204  return storage_array;
205  } else {
206  this->generate_input_error(p, array, "During transpose auto-conversion, the conversion to the single element array not allowed. Require type: '" + p.get_node_type(ValueTypes::array_type) + "'\nFound on input: ", true);
207  }
208 
209  return NULL;
210 }
211 
212 
213 } // namespace Input
#define ASSERT(expr)
Definition: asserts.hh:351
Base abstract class used by ReaderToStorage class to iterate over the input tree.
Definition: path_base.hh:41
virtual bool is_array_type() const =0
Check if type of head node is array.
std::string get_node_type(unsigned int type_idx) const
Get short string description of node type, method is used for printout of messages.
Definition: path_base.cc:64
virtual void up()=0
Return one level up in the hierarchy.
virtual int get_array_size() const =0
Get size of array (sequence type), if object is not array return -1.
virtual bool down(unsigned int index)=0
Dive one level down into path hierarchy.
std::string as_string() const
Returns string address of current position.
Definition: path_base.cc:48
StorageBase * make_array_storage(PathBase &p, const Type::Array *array, int arr_size)
Create storage of Type::Array with given size.
double read_double_value(PathBase &p, const Type::TypeBase *type)
Read double value from path.
std::int64_t read_int_value(PathBase &p, const Type::TypeBase *type)
Read integer value from path.
bool read_bool_value(PathBase &p, const Type::TypeBase *type)
Read boolean value from path.
std::string read_string_value(PathBase &p, const Type::TypeBase *type)
Read string value from path.
void generate_input_error(PathBase &p, const Type::TypeBase *type, std::string spec, bool add_type)
Generate ExcInputError.
StorageBase * make_storage(PathBase &p, const Type::TypeBase *type)
Create storage of given type.
unsigned int transpose_index_
Index of processed item in transposed part of input tree.
vector< unsigned int > transpose_array_sizes_
Helper vector what allows check sizes of all transposed Arrays.
StorageBase * make_sub_storage(PathBase &p, const Type::Array *array) override
Create storage of Type::Array type.
StorageBase * make_autoconversion_array_storage(PathBase &p, const Type::Array *array, StorageBase *item)
Apply conversion to one element storage of Type::Array type.
StorageBase * read_storage(PathBase &p, const Type::Array *array)
Create storage of transposed subtree of given Array.
StorageBase * make_transposed_storage(PathBase &p, const Type::TypeBase *type)
Apply transposition and create storage of Type::Array type.
void new_item(unsigned int index, StorageBase *item)
Definition: storage.cc:107
Base class for nodes of a data storage tree.
Definition: storage.hh:68
Class for declaration of inputs sequences.
Definition: type_base.hh:339
Class for declaration of the input of type Bool.
Definition: type_base.hh:452
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:534
bool match(double value) const
Returns true if the given integer value conforms to the Type::Double bounds.
Definition: type_base.cc:489
Class for declaration of the integral input data.
Definition: type_base.hh:483
Template for classes storing finite set of named values.
int name_to_int(const string &key) const
Converts given value name key to the value.
Class for declaration of the input data that are in string format.
Definition: type_base.hh:582
Base of classes for declaring structure of the input data.
Definition: type_base.hh:92
static constexpr bool value
Definition: json.hpp:87
Array< double > array
Definition: armor.hh:890
Abstract linear system class.
Definition: balance.hh:40