Flow123d  release_2.1.0-84-g6a13a75
type_selection.hh
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_selection.hh
15  * @brief
16  */
17 
18 #ifndef TYPE_SELECTION_HH_
19 #define TYPE_SELECTION_HH_
20 
21 #include "system/exceptions.hh"
22 #include "system/system.hh"
23 
24 #include "type_base.hh"
25 
26 #include <string>
27 #include <vector>
28 
29 namespace Input {
30 namespace Type {
31 
32 using namespace std;
33 
34 
35 
36 /**
37  * @brief Template for classes storing finite set of named values.
38  *
39  * The primary purpose of this class is initialization of enum variables. Since C++ provides no reflection,
40  * in particular no access to enum identifiers as strings, you has to construct the Selection object consistent
41  * with an enum you want to initialize.
42  *
43  * Similarly to Type::Record and Type::Abstract the Selection class is only proxy to the actual data.
44  *
45  * Usage:
46  @code
47  enum Colors { blue, white };
48 
49  const Selection & SomeClass::get_selection_input_type() {
50  return Selection("Colors", "Set of color.")
51  .add_value(blue, "blue")
52  .add_value(white,"white","White color") // with optional item description
53  .close();
54  }
55  @endcode
56  *
57  *
58  * TODO: We can not guarantee full compatibility of the Selection with corresponding Enum type
59  * the Selection can have fewer values since we can not get number of values in the Enum.
60  * Therefore we either have to move under C++11, where enum classes may provide elementary
61  * reflection or have Selection of simple ints.
62  *
63  * @ingroup input_types
64  */
65 
66 class Selection : public Scalar {
67  friend class OutputBase;
68 
69 public:
70  /*
71  * Exceptions specific to this class.
72  */
73  TYPEDEF_ERR_INFO( EI_Selection, const Selection );
74  TYPEDEF_ERR_INFO( EI_Value, const int);
75  DECLARE_EXCEPTION( ExcSelectionKeyNotFound,
76  << "Key " << EI_KeyName::qval <<" not found in Selection:\n" << EI_Selection::val );
77  DECLARE_EXCEPTION( ExcSelectionValueNotFound,
78  << "Value " << EI_Value::val <<" not found in Selection:\n" << EI_Selection::val );
79 
80  /// Structure for description of one key in selection
81  struct Key {
82  unsigned int key_index;
83  string key_;
84  string description_;
85  int value;
87  };
88 
89  /// Public typedef of constant iterator into array of keys
91 
92  /// Default constructor. Empty selection.
93  Selection();
94 
95 
96  /// Copy constructor.
97  Selection(const Selection& other);
98 
99  /// Creates a handle pointing to the new SelectionData.
100  Selection(const string &name, const std::string &description = "");
101 
102  /**
103  * @brief Adds one new @p value with name given by @p key to the Selection.
104  *
105  * The @p description of meaning of the value could be provided.
106  */
107  Selection &add_value(const int value, const std::string &key,
108  const std::string &description = "", TypeBase::attribute_map attributes = TypeBase::attribute_map() );
109 
110  Selection &add_attribute(std::string key, TypeBase::json_string value);
111 
112  /// Close the Selection, no more values can be added.
113  const Selection &close() const;
114 
115 
116  /**
117  * @brief Implements @p TypeBase::content_hash.
118  *
119  * Hash is calculated by type name, description, hash of keys and attributes.
120  */
121  TypeHash content_hash() const override;
122 
123 
124  /// Implements @p TypeBase::finish_status.
125  FinishStatus finish_status() const override;
126 
127  /// Implements \p TypeBase::is_finished
128  bool is_finished() const override;
129 
130  /**
131  * @brief Implements @p Type::TypeBase::type_name.
132  *
133  * Name corresponds to @p data->type_name_.
134  */
135  string type_name() const override;
136  /// Override @p Type::TypeBase::class_name.
137  string class_name() const override;
138 
139  /// Implements \p TypeBase::operator== compare also Selection names.
140  bool operator==(const TypeBase &other) const override;
141 
142  /**
143  * @brief Container-like access to the keys of the Selection.
144  *
145  * Returns iterator to the first key.
146  */
147  inline keys_const_iterator begin() const;
148 
149  /**
150  * @brief Container-like access to the keys of the Selection.
151  *
152  * Returns iterator to the last key.
153  */
154  inline keys_const_iterator end() const;
155 
156  /// Returns iterator to the key struct for given key string.
157  inline keys_const_iterator key_iterator(const string& key) const;
158 
159  /**
160  * @brief Converts given value name \p key to the value.
161  *
162  * Throws exception if the value name does not exist.
163  */
164  int name_to_int(const string &key) const;
165 
166  /**
167  * @brief Returns value name for the given \p value.
168  *
169  * Throws exception if the value does not exist.
170  */
171  string int_to_name(const int &value) const;
172 
173  /// Copy all keys and values from @p sel
174  Selection &copy_values(const Selection &sel);
175 
176  /// Just check if there is a particular name in the Selection.
177  inline bool has_name(const string &key) const;
178 
179  /// Check if there is a particular value in the Selection.
180  inline bool has_value(const int &val) const;
181 
182  /// Returns number of values in the Selection.
183  inline unsigned int size() const;
184 
185  /// Finish declaration of the Selection type.
186  FinishStatus finish(FinishStatus finish_type = FinishStatus::regular_) override;
187 
188 
189  /// Implements \p TypeBase::is_closed
190  bool is_closed() const override;
191 
192 
193  // Implements @p TypeBase::make_instance.
195 private:
196 
197  /// Assertion for finished Selection (methods are called in correct order).
198  void finished_check() const;
199 
200  /**
201  * @brief Create string from values of keys.
202  *
203  * Used in error messaged, where we can not use desc(), which can lead to infinite loop due to TYPE selection of Abstract.
204  */
205  string key_list() const;
206 
207  /**
208  * @brief Internal data class.
209  *
210  * Stores data of the Selection.
211  */
213  public:
214 
215  /// Constructor.
216  SelectionData(const string &name);
217 
218  /// Inster new value to the Selection
219  void add_value(const int value, const std::string &key,
220  const std::string &description, TypeBase::attribute_map attributes);
221 
222 
223  /// Name of the Selection.
224  string type_name_;
225 
226  /// Map : valid value name to index.
228  /// Container-like access to the map of valid value name to index
230 
231  /// Map : valid value to index.
233  /// Container-like access to the map of valid value to index
235 
236  /// Vector of values of the Selection
238 
239  /// Text description of the whole Selection object.
240  std::string description_;
241 
242  /// Indicator of closed Selection.
243  mutable bool closed_;
244 
245  /// Indicator of finished Selection.
247  };
248 
249  /// Handle to actual Selection data.
250  std::shared_ptr<SelectionData> data_;
251 
252 };
253 
254 
255 
256 
257 
258 /******************************************************************************
259  * Implementation of inline methods.
260  */
261 
262 inline bool Selection::has_name(const string &key) const {
263  finished_check();
264  KeyHash key_h = key_hash(key);
265  return (data_->key_to_index_.find(key_h) != data_->key_to_index_.end());
266 }
267 
268 
269 
270 inline bool Selection::has_value(const int &val) const {
271  finished_check();
272  return (data_->value_to_index_.find(val) != data_->value_to_index_.end());
273 }
274 
275 
276 
277 inline unsigned int Selection::size() const {
278  finished_check();
279  ASSERT_EQ(data_->keys_.size(), data_->key_to_index_.size()).error();
280  return data_->keys_.size();
281 }
282 
283 
284 
285 
286 inline void Selection::finished_check() const {
287  ASSERT(data_->closed_)(this->type_name()).error();
288 }
289 
290 
291 
293 {
294  finished_check();
295  return data_->keys_.begin();
296 }
297 
298 
299 
301 {
302  finished_check();
303  return data_->keys_.end();
304 }
305 
306 
308 {
309  finished_check();
310  return begin() + name_to_int(key);
311 }
312 
313 
314 } // closing namespace Type
315 } // closing namespace Input
316 
317 #endif /* TYPE_SELECTION_HH_ */
std::map< int, unsigned int >::const_iterator value_to_index_const_iter
Container-like access to the map of valid value to index.
Base of classes for declaring structure of the input data.
Definition: type_base.hh:93
unsigned int size() const
Returns number of values in the Selection.
std::vector< Key > keys_
Vector of values of the Selection.
bool closed_
Indicator of closed Selection.
TYPEDEF_ERR_INFO(EI_KeyName, const string)
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
Base abstract class for output description of the Input::Type tree.
Definition: type_output.hh:61
std::shared_ptr< SelectionData > data_
Handle to actual Selection data.
Base of all scalar types.
Definition: type_base.hh:442
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:347
bool has_name(const string &key) const
Just check if there is a particular name in the Selection.
static constexpr bool value
Definition: json.hpp:87
string KeyHash
The type of hash values used in associative array that translates key names to indices in Record and ...
Definition: type_base.hh:258
bool operator==(const Null &, const Null &)
Structure for description of one key in selection.
keys_const_iterator key_iterator(const string &key) const
Returns iterator to the key struct for given key string.
TypeBase::attribute_map attributes_
keys_const_iterator end() const
Container-like access to the keys of the Selection.
std::string description_
Text description of the whole Selection object.
std::map< int, unsigned int > value_to_index_
Map : valid value to index.
std::map< KeyHash, unsigned int >::const_iterator key_to_index_const_iter
Container-like access to the map of valid value name to index.
DECLARE_EXCEPTION(ExcWrongDefaultJSON,<< "Consistency Error: Not valid JSON of Default value "<< EI_DefaultStr::qval<< " of type "<< EI_TypeName::qval<< ";\n"<< "During declaration of the key: "<< EI_KeyName::qval)
std::string json_string
String stored in JSON format.
Definition: type_base.hh:99
void finished_check() const
Assertion for finished Selection (methods are called in correct order).
std::map< KeyHash, unsigned int > key_to_index_
Map : valid value name to index.
std::vector< struct Key >::const_iterator keys_const_iterator
Public typedef of constant iterator into array of keys.
string type_name_
Name of the Selection.
keys_const_iterator begin() const
Container-like access to the keys of the Selection.
FinishStatus finish_status_
Indicator of finished Selection.
std::size_t TypeHash
Type returned by content_hash methods.
Definition: type_base.hh:96
bool has_value(const int &val) const
Check if there is a particular value in the Selection.
Template for classes storing finite set of named values.
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual)
Definition: asserts.hh:328