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