Flow123d  jenkins-Flow123d-linux-release-multijob-198
type_selection.hh
Go to the documentation of this file.
1 /*
2  * type_selection.hh
3  *
4  * Created on: May 1, 2012
5  * Author: jb
6  */
7 
8 #ifndef TYPE_SELECTION_HH_
9 #define TYPE_SELECTION_HH_
10 
11 #include "system/exceptions.hh"
12 
13 #include "system/system.hh"
14 #include "type_base.hh"
15 
16 namespace Input {
17 namespace Type {
18 
19 using std::string;
20 
21 
22 
23 /**
24  * @brief Template for classes storing finite set of named values.
25  *
26  * The primary purpose of this class is initialization of enum variables. Since C++ provides no reflection,
27  * in particular no access to enum identifiers as strings, you has to construct the Selection object consistent with an enum you want to initialize.
28  *
29  * Similarly to Type::Record and Type::AbstractRecord the Selection class is only proxy to the actual data.
30  *
31  * Usage:
32  @code
33  enum Colors { blue, white };
34 
35  Selection colors("Colors");
36  colors.add_value(blue, "blue");
37  colors.add_value(white,"white","White color"); // with optional item description
38  colors.finish();
39  @endcode
40  *
41  *
42  * TODO: We can not guarantee full compatibility of the Selection with corresponding Enum type
43  * the Selection can have fewer values since we can not get number of values in the Enum.
44  * Therefore we either have to move under C++11, where enum classes may provide elementary
45  * reflection or have Selection of simple ints.
46  *
47  * @ingroup input_types
48  */
49 
50 class Selection : public Scalar {
51  friend class OutputBase;
52 
53 public:
54  /*
55  * Exceptions specific to this class.
56  */
57  TYPEDEF_ERR_INFO( EI_Selection, const Selection );
58  TYPEDEF_ERR_INFO( EI_Value, const int);
59  DECLARE_EXCEPTION( ExcSelectionKeyNotFound,
60  << "Key " << EI_KeyName::qval <<" not found in Selection:\n" << EI_Selection::val );
61  DECLARE_EXCEPTION( ExcSelectionValueNotFound,
62  << "Value " << EI_Value::val <<" not found in Selection:\n" << EI_Selection::val );
63 
64  /**
65  * Structure for description of one key in selection
66  */
67  struct Key {
68  unsigned int key_index;
69  string key_;
70  string description_;
71  int value;
72  };
73 
74  /**
75  * Public typedef of constant iterator into array of keys
76  */
78 
79  /**
80  * Default constructor. Empty selection.
81  */
82  Selection();
83 
84 
85  /**
86  * Copy constructor.
87  */
88  Selection(const Selection& other);
89 
90  /**
91  * Creates a handle pointing to the new SelectionData.
92  */
93  Selection(const string &name, const std::string &description = "");
94 
95  /**
96  * Adds one new @p value with name given by @p key to the Selection. The @p description of meaning of the value could be provided.
97  */
98  Selection &add_value(const int value, const std::string &key, const std::string &description = "");
99 
100 
101  /**
102  * Close the Selection, no more values can be added.
103  */
104  const Selection &close() const;
105 
106 
107  std::size_t content_hash() const override;
108 
109 
110  /// Implements \p TypeBase::is_finished
111  virtual bool is_finished() const;
112 
113  /// Implements \p TypeBase::type_name
114  virtual string type_name() const;
115 
116  /// Implements \p TypeBase::full_type_name
117  virtual string full_type_name() const;
118 
119  /// Implements \p TypeBase::operator== compare also Selection names.
120  virtual bool operator==(const TypeBase &other) const;
121 
122  /**
123  * Container-like access to the keys of the Record. Returns iterator to the first key.
124  */
125  inline keys_const_iterator begin() const;
126 
127  /**
128  * Container-like access to the keys of the Record. Returns iterator to the last key.
129  */
130  inline keys_const_iterator end() const;
131 
132  /**
133  * Returns iterator to the key struct for given key string.
134  */
135  inline keys_const_iterator key_iterator(const string& key) const;
136 
137  /**
138  * Converts given value name \p key to the value. Throws exception if the value name does not exist.
139  */
140  int name_to_int(const string &key) const;
141 
142  /**
143  * Returns value name for the given \p value. Throws exception if the value does not exist.
144  */
145  string int_to_name(const int &value) const;
146 
147  Selection &copy_values(const Selection &sel);
148 
149  /**
150  * Same as \p Selection::name_to_int, but throws different exception, when string comes from default value.
151  */
152  int from_default(const string &str) const;
153 
154  /// Implements @p Type::TypeBase::valid_defaults.
155  virtual bool valid_default(const string &str) const;
156 
157  /**
158  * Just check if there is a particular name in the Selection.
159  */
160  inline bool has_name(const string &key) const;
161 
162  /**
163  * Check if there is a particular value in the Selection.
164  */
165  inline bool has_value(const int &val) const;
166 
167  /**
168  * Returns number of values in the Selection.
169  */
170  inline unsigned int size() const;
171 
172 
173  bool finish()
174  { close(); return true; }
175 private:
176 
177  /**
178  * Assertion for finished Selection (methods are called in correct order).
179  */
180  void finished_check() const;
181 
182  /**
183  * Used in error messaged, where we can not use desc(), which can lead to infinite loop due to TYPE selection of AbstractRecord.
184  */
185  string key_list() const;
186 
187  /**
188  * Actual Selection data.
189  */
191  public:
192 
193  SelectionData(const string &name)
194  : type_name_(name), /*made_extensive_doc(false),*/ finished(false)
195  {}
196 
197  void add_value(const int value, const std::string &key, const std::string &description);
198 
199 
200  /// Name of the Selection.
201  string type_name_;
202 
203  /// Map : valid value name to index.
206 
207  /// Map : valid value to index.
210 
211  /// Vector of values of the Selection
213 
214  /// Text description of the whole Selection object.
215  std::string description_;
216 
217  /// Indicator of finished Selection.
218  mutable bool finished;
219  };
220 
221  /// Handle to actual Selection data.
222  boost::shared_ptr<SelectionData> data_;
223 
224 };
225 
226 
227 
228 
229 
230 /******************************************************************************
231  * Implementation of inline methods.
232  */
233 
234 inline bool Selection::has_name(const string &key) const {
235  finished_check();
236  KeyHash key_h = key_hash(key);
237  return (data_->key_to_index_.find(key_h) != data_->key_to_index_.end());
238 }
239 
240 
241 
242 inline bool Selection::has_value(const int &val) const {
243  finished_check();
244  return (data_->value_to_index_.find(val) != data_->value_to_index_.end());
245 }
246 
247 
248 
249 inline unsigned int Selection::size() const {
250  finished_check();
251  ASSERT( data_->keys_.size() == data_->key_to_index_.size(),
252  "Sizes of Type:Selection doesn't match. (map: %ld vec: %ld)\n", data_->key_to_index_.size(), data_->keys_.size());
253  ASSERT_EQUAL( data_->keys_.size(), data_->key_to_index_.size());
254  return data_->keys_.size();
255 }
256 
257 
258 
259 
260 inline void Selection::finished_check() const {
261  ASSERT(data_->finished, "Accessing unfinished Selection '%s'\n", type_name().c_str() );
262 }
263 
264 
265 
267 {
268  finished_check();
269  return data_->keys_.begin();
270 }
271 
272 
273 
275 {
276  finished_check();
277  return data_->keys_.end();
278 }
279 
280 
282 {
283  finished_check();
284  return begin() + name_to_int(key);
285 }
286 
287 
288 } // closing namespace Type
289 } // closing namespace Input
290 
291 #endif /* TYPE_SELECTION_HH_ */
std::map< int, unsigned int >::const_iterator value_to_index_const_iter
Base of classes for declaring structure of the input data.
Definition: type_base.hh:63
unsigned int size() const
std::vector< Key > keys_
Vector of values of the Selection.
int from_default(const string &str) const
string int_to_name(const int &value) const
int name_to_int(const string &key) const
virtual string full_type_name() const
Implements TypeBase::full_type_name.
Base abstract class for output description of the Input::Type tree.
Definition: type_output.hh:37
Selection & copy_values(const Selection &sel)
Base of all scalar types.
Definition: type_base.hh:317
static KeyHash key_hash(const string &str)
Hash function.
Definition: type_base.hh:171
void add_value(const int value, const std::string &key, const std::string &description)
virtual string type_name() const
Implements TypeBase::type_name.
bool has_name(const string &key) const
virtual bool operator==(const TypeBase &other) const
Implements TypeBase::operator== compare also Selection names.
keys_const_iterator key_iterator(const string &key) const
virtual bool valid_default(const string &str) const
Implements Type::TypeBase::valid_defaults.
#define ASSERT(...)
Definition: global_defs.h:121
#define ASSERT_EQUAL(a, b)
Definition: global_defs.h:136
Selection & add_value(const int value, const std::string &key, const std::string &description="")
bool finished
Indicator of finished Selection.
TYPEDEF_ERR_INFO(EI_Selection, const Selection)
keys_const_iterator end() const
std::string description_
Text description of the whole Selection object.
std::map< int, unsigned int > value_to_index_
Map : valid value to index.
boost::shared_ptr< SelectionData > data_
Handle to actual Selection data.
const Selection & close() const
std::map< KeyHash, unsigned int >::const_iterator key_to_index_const_iter
DECLARE_EXCEPTION(ExcSelectionKeyNotFound,<< "Key "<< EI_KeyName::qval<<" not found in Selection:\n"<< EI_Selection::val)
std::size_t content_hash() const override
virtual bool is_finished() const
Implements TypeBase::is_finished.
void finished_check() const
std::map< KeyHash, unsigned int > key_to_index_
Map : valid value name to index.
std::vector< struct Key >::const_iterator keys_const_iterator
string type_name_
Name of the Selection.
keys_const_iterator begin() const
string key_list() const
bool has_value(const int &val) const
Template for classes storing finite set of named values.