19 #ifndef LEMON_BITS_VARIANT_H |
19 #ifndef LEMON_BITS_VARIANT_H |
20 #define LEMON_BITS_VARIANT_H |
20 #define LEMON_BITS_VARIANT_H |
21 |
21 |
22 #include <lemon/error.h> |
22 #include <lemon/error.h> |
23 |
23 |
|
24 /// \file |
|
25 /// \brief Variant types |
|
26 |
24 namespace lemon { |
27 namespace lemon { |
25 |
28 |
26 template <bool left, bool right> |
29 namespace _variant_bits { |
27 struct CTOr { |
|
28 static const bool value = true; |
|
29 }; |
|
30 |
|
31 template <> |
|
32 struct CTOr<false, false> { |
|
33 static const bool value = false; |
|
34 }; |
|
35 |
|
36 template <bool left, bool right> |
|
37 struct CTAnd { |
|
38 static const bool value = false; |
|
39 }; |
|
40 |
|
41 template <> |
|
42 struct CTAnd<true, true> { |
|
43 static const bool value = true; |
|
44 }; |
|
45 |
|
46 template <int left, int right> |
|
47 struct CTEqual { |
|
48 static const bool value = false; |
|
49 }; |
|
50 |
|
51 template <int val> |
|
52 struct CTEqual<val, val> { |
|
53 static const bool value = true; |
|
54 }; |
|
55 |
|
56 |
|
57 template <int left, int right> |
|
58 struct CTLess { |
|
59 static const bool value = left < right; |
|
60 }; |
|
61 |
|
62 template <int left> |
|
63 struct CTLess<left, 0> { |
|
64 static const bool value = false; |
|
65 }; |
|
66 |
|
67 template <int right> |
|
68 struct CTLess<0, right> { |
|
69 static const bool value = true; |
|
70 }; |
|
71 |
|
72 template <> |
|
73 struct CTLess<0, 0> { |
|
74 static const bool value = false; |
|
75 }; |
|
76 |
|
77 template <> |
|
78 struct CTLess<1, 1> { |
|
79 static const bool value = false; |
|
80 }; |
|
81 |
|
82 template <bool less, int left, int right> |
|
83 struct CTMaxImpl { |
|
84 static const int value = left; |
|
85 }; |
|
86 |
|
87 template <int left, int right> |
|
88 struct CTMaxImpl<true, left, right> { |
|
89 static const int value = right; |
|
90 }; |
|
91 |
30 |
92 template <int left, int right> |
31 template <int left, int right> |
93 struct CTMax { |
32 struct CTMax { |
94 static const int value = |
33 static const int value = left < right ? right : left; |
95 CTMaxImpl<CTLess<left, right>::value, left, right>::value; |
34 }; |
96 }; |
35 |
97 |
36 } |
98 |
37 |
99 /// \brief Simple Variant type with two type |
38 |
|
39 /// \brief Simple Variant type for two types |
100 /// |
40 /// |
101 /// Simple Variant type with two type |
41 /// Simple Variant type for two types. The Variant type is a type |
|
42 /// safe union. The C++ has strong limitations for using unions, by |
|
43 /// example we can not store type with non default constructor or |
|
44 /// destructor in an union. This class always knowns the current |
|
45 /// state of the variant and it cares for the proper construction |
|
46 /// and destruction. |
102 template <typename _First, typename _Second> |
47 template <typename _First, typename _Second> |
103 class BiVariant { |
48 class BiVariant { |
104 public: |
49 public: |
105 |
50 |
|
51 /// \brief The \c First type. |
106 typedef _First First; |
52 typedef _First First; |
|
53 /// \brief The \c Second type. |
107 typedef _Second Second; |
54 typedef _Second Second; |
108 |
55 |
109 struct WrongStateError : public lemon::LogicError { |
56 struct WrongStateError : public lemon::LogicError { |
110 public: |
57 public: |
111 virtual const char* what() const throw() { |
58 virtual const char* what() const throw() { |
112 return "lemon::BiVariant::WrongStateError"; |
59 return "lemon::BiVariant::WrongStateError"; |
113 } |
60 } |
114 }; |
61 }; |
115 |
62 |
|
63 /// \brief Constructor |
|
64 /// |
|
65 /// This constructor initalizes to the default value of the \c First |
|
66 /// type. |
116 BiVariant() { |
67 BiVariant() { |
117 flag = true; |
68 flag = true; |
118 new(reinterpret_cast<First*>(data)) First(); |
69 new(reinterpret_cast<First*>(data)) First(); |
119 } |
70 } |
120 |
71 |
|
72 /// \brief Constructor |
|
73 /// |
|
74 /// This constructor initalizes to the given value of the \c First |
|
75 /// type. |
121 BiVariant(const First& first) { |
76 BiVariant(const First& first) { |
122 flag = true; |
77 flag = true; |
123 new(reinterpret_cast<First*>(data)) First(first); |
78 new(reinterpret_cast<First*>(data)) First(first); |
124 } |
79 } |
125 |
80 |
|
81 /// \brief Constructor |
|
82 /// |
|
83 /// This constructor initalizes to the given value of the \c |
|
84 /// Second type. |
126 BiVariant(const Second& second) { |
85 BiVariant(const Second& second) { |
127 flag = false; |
86 flag = false; |
128 new(reinterpret_cast<Second*>(data)) Second(second); |
87 new(reinterpret_cast<Second*>(data)) Second(second); |
129 } |
88 } |
130 |
89 |
|
90 /// \brief Copy constructor |
|
91 /// |
|
92 /// Copy constructor |
131 BiVariant(const BiVariant& bivariant) { |
93 BiVariant(const BiVariant& bivariant) { |
132 flag = bivariant.flag; |
94 flag = bivariant.flag; |
133 if (flag) { |
95 if (flag) { |
134 new(reinterpret_cast<First*>(data)) First(bivariant.first()); |
96 new(reinterpret_cast<First*>(data)) First(bivariant.first()); |
135 } else { |
97 } else { |
136 new(reinterpret_cast<Second*>(data)) Second(bivariant.second()); |
98 new(reinterpret_cast<Second*>(data)) Second(bivariant.second()); |
137 } |
99 } |
138 } |
100 } |
139 |
101 |
|
102 /// \brief Destrcutor |
|
103 /// |
|
104 /// Destructor |
140 ~BiVariant() { |
105 ~BiVariant() { |
141 destroy(); |
106 destroy(); |
142 } |
107 } |
143 |
108 |
|
109 /// \brief Set to the default value of the \c First type. |
|
110 /// |
|
111 /// This function sets the variant to the default value of the \c |
|
112 /// First type. |
144 BiVariant& setFirst() { |
113 BiVariant& setFirst() { |
145 destroy(); |
114 destroy(); |
146 flag = true; |
115 flag = true; |
147 new(reinterpret_cast<First*>(data)) First(); |
116 new(reinterpret_cast<First*>(data)) First(); |
148 return *this; |
117 return *this; |
149 } |
118 } |
150 |
119 |
|
120 /// \brief Set to the given value of the \c First type. |
|
121 /// |
|
122 /// This function sets the variant to the given value of the \c |
|
123 /// First type. |
151 BiVariant& setFirst(const First& first) { |
124 BiVariant& setFirst(const First& first) { |
152 destroy(); |
125 destroy(); |
153 flag = true; |
126 flag = true; |
154 new(reinterpret_cast<First*>(data)) First(first); |
127 new(reinterpret_cast<First*>(data)) First(first); |
155 return *this; |
128 return *this; |
156 } |
129 } |
157 |
130 |
|
131 /// \brief Set to the default value of the \c Second type. |
|
132 /// |
|
133 /// This function sets the variant to the default value of the \c |
|
134 /// Second type. |
158 BiVariant& setSecond() { |
135 BiVariant& setSecond() { |
159 destroy(); |
136 destroy(); |
160 flag = false; |
137 flag = false; |
161 new(reinterpret_cast<Second*>(data)) Second(); |
138 new(reinterpret_cast<Second*>(data)) Second(); |
162 return *this; |
139 return *this; |
163 } |
140 } |
164 |
141 |
|
142 /// \brief Set to the given value of the \c Second type. |
|
143 /// |
|
144 /// This function sets the variant to the given value of the \c |
|
145 /// Second type. |
165 BiVariant& setSecond(const Second& second) { |
146 BiVariant& setSecond(const Second& second) { |
166 destroy(); |
147 destroy(); |
167 flag = false; |
148 flag = false; |
168 new(reinterpret_cast<Second*>(data)) Second(second); |
149 new(reinterpret_cast<Second*>(data)) Second(second); |
169 return *this; |
150 return *this; |
170 } |
151 } |
171 |
152 |
|
153 /// \brief Operator form of the \c setFirst() |
172 BiVariant& operator=(const First& first) { |
154 BiVariant& operator=(const First& first) { |
173 return setFirst(first); |
155 return setFirst(first); |
174 } |
156 } |
175 |
157 |
|
158 /// \brief Operator form of the \c setSecond() |
176 BiVariant& operator=(const Second& second) { |
159 BiVariant& operator=(const Second& second) { |
177 return setSecond(second); |
160 return setSecond(second); |
178 } |
161 } |
179 |
162 |
180 |
163 /// \brief Assign operator |
181 BiVariant& operator=(const BiVariant& bivariant) { |
164 BiVariant& operator=(const BiVariant& bivariant) { |
182 if (this == &bivariant) return *this; |
165 if (this == &bivariant) return *this; |
183 destroy(); |
166 destroy(); |
184 flag = bivariant.flag; |
167 flag = bivariant.flag; |
185 if (flag) { |
168 if (flag) { |
188 new(reinterpret_cast<Second*>(data)) Second(bivariant.second()); |
171 new(reinterpret_cast<Second*>(data)) Second(bivariant.second()); |
189 } |
172 } |
190 return *this; |
173 return *this; |
191 } |
174 } |
192 |
175 |
|
176 /// \brief Reference to the value |
|
177 /// |
|
178 /// Reference to the value of the \c First type. |
|
179 /// \pre The BiVariant should store value of \c First type. |
193 First& first() { |
180 First& first() { |
194 LEMON_ASSERT(flag, WrongStateError()); |
181 LEMON_ASSERT(flag, WrongStateError()); |
195 return *reinterpret_cast<First*>(data); |
182 return *reinterpret_cast<First*>(data); |
196 } |
183 } |
197 |
184 |
|
185 /// \brief Const reference to the value |
|
186 /// |
|
187 /// Const reference to the value of the \c First type. |
|
188 /// \pre The BiVariant should store value of \c First type. |
198 const First& first() const { |
189 const First& first() const { |
199 LEMON_ASSERT(flag, WrongStateError()); |
190 LEMON_ASSERT(flag, WrongStateError()); |
200 return *reinterpret_cast<const First*>(data); |
191 return *reinterpret_cast<const First*>(data); |
201 } |
192 } |
202 |
193 |
|
194 /// \brief Operator form of the \c first() |
203 operator First&() { return first(); } |
195 operator First&() { return first(); } |
|
196 /// \brief Operator form of the const \c first() |
204 operator const First&() const { return first(); } |
197 operator const First&() const { return first(); } |
205 |
198 |
|
199 /// \brief Reference to the value |
|
200 /// |
|
201 /// Reference to the value of the \c Second type. |
|
202 /// \pre The BiVariant should store value of \c Second type. |
206 Second& second() { |
203 Second& second() { |
207 LEMON_ASSERT(!flag, WrongStateError()); |
204 LEMON_ASSERT(!flag, WrongStateError()); |
208 return *reinterpret_cast<Second*>(data); |
205 return *reinterpret_cast<Second*>(data); |
209 } |
206 } |
210 |
207 |
|
208 /// \brief Const reference to the value |
|
209 /// |
|
210 /// Const reference to the value of the \c Second type. |
|
211 /// \pre The BiVariant should store value of \c Second type. |
211 const Second& second() const { |
212 const Second& second() const { |
212 LEMON_ASSERT(!flag, WrongStateError()); |
213 LEMON_ASSERT(!flag, WrongStateError()); |
213 return *reinterpret_cast<const Second*>(data); |
214 return *reinterpret_cast<const Second*>(data); |
214 } |
215 } |
215 |
216 |
|
217 /// \brief Operator form of the \c second() |
216 operator Second&() { return second(); } |
218 operator Second&() { return second(); } |
|
219 /// \brief Operator form of the const \c second() |
217 operator const Second&() const { return second(); } |
220 operator const Second&() const { return second(); } |
218 |
221 |
|
222 /// \brief %True when the variant is in the first state |
|
223 /// |
|
224 /// %True when the variant stores value of the \c First type. |
219 bool firstState() const { return flag; } |
225 bool firstState() const { return flag; } |
|
226 |
|
227 /// \brief %True when the variant is in the second state |
|
228 /// |
|
229 /// %True when the variant stores value of the \c Second type. |
220 bool secondState() const { return !flag; } |
230 bool secondState() const { return !flag; } |
221 |
231 |
222 private: |
232 private: |
223 |
233 |
224 void destroy() { |
234 void destroy() { |
227 } else { |
237 } else { |
228 reinterpret_cast<Second*>(data)->~Second(); |
238 reinterpret_cast<Second*>(data)->~Second(); |
229 } |
239 } |
230 } |
240 } |
231 |
241 |
232 char data[CTMax<sizeof(First), sizeof(Second)>::value]; |
242 char data[_variant_bits::CTMax<sizeof(First), sizeof(Second)>::value]; |
233 bool flag; |
243 bool flag; |
234 }; |
244 }; |
235 |
245 |
|
246 namespace _variant_bits { |
|
247 |
|
248 template <int _idx, typename _TypeMap> |
|
249 struct Memory { |
|
250 |
|
251 typedef typename _TypeMap::template Map<_idx>::Type Current; |
|
252 |
|
253 static void destroy(int index, char* place) { |
|
254 if (index == _idx) { |
|
255 reinterpret_cast<Current*>(place)->~Current(); |
|
256 } else { |
|
257 Memory<_idx - 1, _TypeMap>::destroy(index, place); |
|
258 } |
|
259 } |
|
260 |
|
261 static void copy(int index, char* to, const char* from) { |
|
262 if (index == _idx) { |
|
263 new (reinterpret_cast<Current*>(to)) |
|
264 Current(reinterpret_cast<const Current*>(from)); |
|
265 } else { |
|
266 Memory<_idx - 1, _TypeMap>::copy(index, to, from); |
|
267 } |
|
268 } |
|
269 |
|
270 }; |
|
271 |
|
272 template <typename _TypeMap> |
|
273 struct Memory<-1, _TypeMap> { |
|
274 |
|
275 static void destroy(int, char*) { |
|
276 LEMON_ASSERT(false, "Wrong Variant Index."); |
|
277 } |
|
278 |
|
279 static void copy(int, char*, const char*) { |
|
280 LEMON_ASSERT(false, "Wrong Variant Index."); |
|
281 } |
|
282 }; |
|
283 |
|
284 template <int _idx, typename _TypeMap> |
|
285 struct Size { |
|
286 static const int value = |
|
287 CTMax<sizeof(typename _TypeMap::template Map<_idx>::Type), |
|
288 Size<_idx - 1, _TypeMap>::value>::value; |
|
289 }; |
|
290 |
|
291 template <typename _TypeMap> |
|
292 struct Size<0, _TypeMap> { |
|
293 static const int value = |
|
294 sizeof(typename _TypeMap::template Map<0>::Type); |
|
295 }; |
|
296 |
|
297 } |
|
298 |
|
299 /// \brief Variant type |
|
300 /// |
|
301 /// Simple Variant type. The Variant type is a type safe union. The |
|
302 /// C++ has strong limitations for using unions, by example we |
|
303 /// cannot store type with non default constructor or destructor in |
|
304 /// a union. This class always knowns the current state of the |
|
305 /// variant and it cares for the proper construction and |
|
306 /// destruction. |
|
307 /// |
|
308 /// \param _num The number of the types which can be stored in the |
|
309 /// variant type. |
|
310 /// \param _TypeMap This class describes the types of the Variant. The |
|
311 /// _TypeMap::Map<index>::Type should be a valid type for each index |
|
312 /// in the range {0, 1, ..., _num - 1}. The \c VariantTypeMap is helper |
|
313 /// class to define such type mappings up to 10 types. |
|
314 /// |
|
315 /// And the usage of the class: |
|
316 ///\code |
|
317 /// typedef Variant<3, VariantTypeMap<int, std::string, double> > MyVariant; |
|
318 /// MyVariant var; |
|
319 /// var.set<0>(12); |
|
320 /// std::cout << var.get<0>() << std::endl; |
|
321 /// var.set<1>("alpha"); |
|
322 /// std::cout << var.get<1>() << std::endl; |
|
323 /// var.set<2>(0.75); |
|
324 /// std::cout << var.get<2>() << std::endl; |
|
325 ///\endcode |
|
326 /// |
|
327 /// The result of course: |
|
328 ///\code |
|
329 /// 12 |
|
330 /// alpha |
|
331 /// 0.75 |
|
332 ///\endcode |
|
333 template <int _num, typename _TypeMap> |
|
334 class Variant { |
|
335 public: |
|
336 |
|
337 static const int num = _num; |
|
338 |
|
339 typedef _TypeMap TypeMap; |
|
340 |
|
341 struct WrongStateError : public lemon::LogicError { |
|
342 public: |
|
343 virtual const char* what() const throw() { |
|
344 return "lemon::Variant::WrongStateError"; |
|
345 } |
|
346 }; |
|
347 |
|
348 /// \brief Constructor |
|
349 /// |
|
350 /// This constructor initalizes to the default value of the \c type |
|
351 /// with 0 index. |
|
352 Variant() { |
|
353 flag = 0; |
|
354 new(reinterpret_cast<typename TypeMap::template Map<0>::Type*>(data)) |
|
355 typename TypeMap::template Map<0>::Type(); |
|
356 } |
|
357 |
|
358 |
|
359 /// \brief Copy constructor |
|
360 /// |
|
361 /// Copy constructor |
|
362 Variant(const Variant& variant) { |
|
363 flag = variant.flag; |
|
364 _variant_bits::Memory<num - 1, TypeMap>::copy(flag, data, variant.data); |
|
365 } |
|
366 |
|
367 /// \brief Assign operator |
|
368 /// |
|
369 /// Assign operator |
|
370 Variant& operator=(const Variant& variant) { |
|
371 if (this == &variant) return *this; |
|
372 _variant_bits::Memory<num - 1, TypeMap>:: |
|
373 destroy(flag, data); |
|
374 flag = variant.flag; |
|
375 _variant_bits::Memory<num - 1, TypeMap>:: |
|
376 copy(flag, data, variant.data); |
|
377 return *this; |
|
378 } |
|
379 |
|
380 /// \brief Destrcutor |
|
381 /// |
|
382 /// Destructor |
|
383 ~Variant() { |
|
384 _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data); |
|
385 } |
|
386 |
|
387 /// \brief Set to the default value of the type with \c _idx index. |
|
388 /// |
|
389 /// This function sets the variant to the default value of the |
|
390 /// type with \c _idx index. |
|
391 template <int _idx> |
|
392 Variant& set() { |
|
393 _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data); |
|
394 flag = _idx; |
|
395 new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data)) |
|
396 typename TypeMap::template Map<_idx>::Type(); |
|
397 return *this; |
|
398 } |
|
399 |
|
400 /// \brief Set to the given value of the type with \c _idx index. |
|
401 /// |
|
402 /// This function sets the variant to the given value of the type |
|
403 /// with \c _idx index. |
|
404 template <int _idx> |
|
405 Variant& set(const typename _TypeMap::template Map<_idx>::Type& init) { |
|
406 _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data); |
|
407 flag = _idx; |
|
408 new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data)) |
|
409 typename TypeMap::template Map<_idx>::Type(init); |
|
410 return *this; |
|
411 } |
|
412 |
|
413 /// \brief Gets the current value of the type with \c _idx index. |
|
414 /// |
|
415 /// Gets the current value of the type with \c _idx index. |
|
416 template <int _idx> |
|
417 const typename TypeMap::template Map<_idx>::Type& get() const { |
|
418 LEMON_ASSERT(_idx == flag, "Wrong Variant Index."); |
|
419 return *reinterpret_cast<const typename TypeMap:: |
|
420 template Map<_idx>::Type*>(data); |
|
421 } |
|
422 |
|
423 /// \brief Gets the current value of the type with \c _idx index. |
|
424 /// |
|
425 /// Gets the current value of the type with \c _idx index. |
|
426 template <int _idx> |
|
427 typename _TypeMap::template Map<_idx>::Type& get() { |
|
428 LEMON_ASSERT(_idx == flag, "Wrong Variant Index."); |
|
429 return *reinterpret_cast<typename TypeMap::template Map<_idx>::Type*> |
|
430 (data); |
|
431 } |
|
432 |
|
433 /// \brief Returns the current state of the variant. |
|
434 /// |
|
435 /// Returns the current state of the variant. |
|
436 int state() const { |
|
437 return flag; |
|
438 } |
|
439 |
|
440 private: |
|
441 |
|
442 char data[_variant_bits::Size<num - 1, TypeMap>::value]; |
|
443 int flag; |
|
444 }; |
|
445 |
|
446 namespace _variant_bits { |
|
447 |
|
448 template <int _index, typename _List> |
|
449 struct Get { |
|
450 typedef typename Get<_index - 1, typename _List::Next>::Type Type; |
|
451 }; |
|
452 |
|
453 template <typename _List> |
|
454 struct Get<0, _List> { |
|
455 typedef typename _List::Type Type; |
|
456 }; |
|
457 |
|
458 struct List {}; |
|
459 |
|
460 template <typename _Type, typename _List> |
|
461 struct Insert { |
|
462 typedef _List Next; |
|
463 typedef _Type Type; |
|
464 }; |
|
465 |
|
466 template <int _idx, typename _T0, typename _T1, typename _T2, |
|
467 typename _T3, typename _T5, typename _T4, typename _T6, |
|
468 typename _T7, typename _T8, typename _T9> |
|
469 struct Mapper { |
|
470 typedef List L10; |
|
471 typedef Insert<_T9, L10> L9; |
|
472 typedef Insert<_T8, L9> L8; |
|
473 typedef Insert<_T7, L8> L7; |
|
474 typedef Insert<_T6, L7> L6; |
|
475 typedef Insert<_T5, L6> L5; |
|
476 typedef Insert<_T4, L5> L4; |
|
477 typedef Insert<_T3, L4> L3; |
|
478 typedef Insert<_T2, L3> L2; |
|
479 typedef Insert<_T1, L2> L1; |
|
480 typedef Insert<_T0, L1> L0; |
|
481 typedef typename Get<_idx, L0>::Type Type; |
|
482 }; |
|
483 |
|
484 } |
|
485 |
|
486 /// \brief Helper class for Variant |
|
487 /// |
|
488 /// Helper class to define type mappings for Variant. This class |
|
489 /// converts the template parameters to be mappable by integer. |
|
490 /// \see Variant |
|
491 template < |
|
492 typename _T0, |
|
493 typename _T1 = void, typename _T2 = void, typename _T3 = void, |
|
494 typename _T5 = void, typename _T4 = void, typename _T6 = void, |
|
495 typename _T7 = void, typename _T8 = void, typename _T9 = void> |
|
496 struct VariantTypeMap { |
|
497 template <int _idx> |
|
498 struct Map { |
|
499 typedef typename _variant_bits:: |
|
500 Mapper<_idx, _T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>::Type |
|
501 Type; |
|
502 }; |
|
503 }; |
|
504 |
236 } |
505 } |
237 |
506 |
238 |
507 |
239 #endif |
508 #endif |