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