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