1 /* -*- C++ -*- |
1 /* -*- mode: C++; indent-tabs-mode: nil; -*- |
2 * |
2 * |
3 * This file is a part of LEMON, a generic C++ optimization library |
3 * This file is a part of LEMON, a generic C++ optimization library. |
4 * |
4 * |
5 * Copyright (C) 2003-2008 |
5 * Copyright (C) 2003-2008 |
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
7 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 * |
8 * |
104 /// This function sets the variant to the default value of the \c |
104 /// This function sets the variant to the default value of the \c |
105 /// First type. |
105 /// First type. |
106 BiVariant& setFirst() { |
106 BiVariant& setFirst() { |
107 destroy(); |
107 destroy(); |
108 flag = true; |
108 flag = true; |
109 new(reinterpret_cast<First*>(data)) First(); |
109 new(reinterpret_cast<First*>(data)) First(); |
110 return *this; |
110 return *this; |
111 } |
111 } |
112 |
112 |
113 /// \brief Set to the given value of the \c First type. |
113 /// \brief Set to the given value of the \c First type. |
114 /// |
114 /// |
115 /// This function sets the variant to the given value of the \c |
115 /// This function sets the variant to the given value of the \c |
116 /// First type. |
116 /// First type. |
117 BiVariant& setFirst(const First& f) { |
117 BiVariant& setFirst(const First& f) { |
118 destroy(); |
118 destroy(); |
119 flag = true; |
119 flag = true; |
120 new(reinterpret_cast<First*>(data)) First(f); |
120 new(reinterpret_cast<First*>(data)) First(f); |
121 return *this; |
121 return *this; |
122 } |
122 } |
123 |
123 |
124 /// \brief Set to the default value of the \c Second type. |
124 /// \brief Set to the default value of the \c Second type. |
125 /// |
125 /// |
126 /// This function sets the variant to the default value of the \c |
126 /// This function sets the variant to the default value of the \c |
127 /// Second type. |
127 /// Second type. |
128 BiVariant& setSecond() { |
128 BiVariant& setSecond() { |
129 destroy(); |
129 destroy(); |
130 flag = false; |
130 flag = false; |
131 new(reinterpret_cast<Second*>(data)) Second(); |
131 new(reinterpret_cast<Second*>(data)) Second(); |
132 return *this; |
132 return *this; |
133 } |
133 } |
134 |
134 |
135 /// \brief Set to the given value of the \c Second type. |
135 /// \brief Set to the given value of the \c Second type. |
136 /// |
136 /// |
137 /// This function sets the variant to the given value of the \c |
137 /// This function sets the variant to the given value of the \c |
138 /// Second type. |
138 /// Second type. |
139 BiVariant& setSecond(const Second& s) { |
139 BiVariant& setSecond(const Second& s) { |
140 destroy(); |
140 destroy(); |
141 flag = false; |
141 flag = false; |
142 new(reinterpret_cast<Second*>(data)) Second(s); |
142 new(reinterpret_cast<Second*>(data)) Second(s); |
143 return *this; |
143 return *this; |
144 } |
144 } |
145 |
145 |
146 /// \brief Operator form of the \c setFirst() |
146 /// \brief Operator form of the \c setFirst() |
147 BiVariant& operator=(const First& f) { |
147 BiVariant& operator=(const First& f) { |
157 BiVariant& operator=(const BiVariant& bivariant) { |
157 BiVariant& operator=(const BiVariant& bivariant) { |
158 if (this == &bivariant) return *this; |
158 if (this == &bivariant) return *this; |
159 destroy(); |
159 destroy(); |
160 flag = bivariant.flag; |
160 flag = bivariant.flag; |
161 if (flag) { |
161 if (flag) { |
162 new(reinterpret_cast<First*>(data)) First(bivariant.first()); |
162 new(reinterpret_cast<First*>(data)) First(bivariant.first()); |
163 } else { |
163 } else { |
164 new(reinterpret_cast<Second*>(data)) Second(bivariant.second()); |
164 new(reinterpret_cast<Second*>(data)) Second(bivariant.second()); |
165 } |
165 } |
166 return *this; |
166 return *this; |
167 } |
167 } |
168 |
168 |
169 /// \brief Reference to the value |
169 /// \brief Reference to the value |
229 reinterpret_cast<First*>(data)->~First(); |
229 reinterpret_cast<First*>(data)->~First(); |
230 } else { |
230 } else { |
231 reinterpret_cast<Second*>(data)->~Second(); |
231 reinterpret_cast<Second*>(data)->~Second(); |
232 } |
232 } |
233 } |
233 } |
234 |
234 |
235 char data[_variant_bits::CTMax<sizeof(First), sizeof(Second)>::value]; |
235 char data[_variant_bits::CTMax<sizeof(First), sizeof(Second)>::value]; |
236 bool flag; |
236 bool flag; |
237 }; |
237 }; |
238 |
238 |
239 namespace _variant_bits { |
239 namespace _variant_bits { |
240 |
240 |
241 template <int _idx, typename _TypeMap> |
241 template <int _idx, typename _TypeMap> |
242 struct Memory { |
242 struct Memory { |
243 |
243 |
244 typedef typename _TypeMap::template Map<_idx>::Type Current; |
244 typedef typename _TypeMap::template Map<_idx>::Type Current; |
245 |
245 |
274 } |
274 } |
275 }; |
275 }; |
276 |
276 |
277 template <int _idx, typename _TypeMap> |
277 template <int _idx, typename _TypeMap> |
278 struct Size { |
278 struct Size { |
279 static const int value = |
279 static const int value = |
280 CTMax<sizeof(typename _TypeMap::template Map<_idx>::Type), |
280 CTMax<sizeof(typename _TypeMap::template Map<_idx>::Type), |
281 Size<_idx - 1, _TypeMap>::value>::value; |
281 Size<_idx - 1, _TypeMap>::value>::value; |
282 }; |
282 }; |
283 |
283 |
284 template <typename _TypeMap> |
284 template <typename _TypeMap> |
285 struct Size<0, _TypeMap> { |
285 struct Size<0, _TypeMap> { |
286 static const int value = |
286 static const int value = |
287 sizeof(typename _TypeMap::template Map<0>::Type); |
287 sizeof(typename _TypeMap::template Map<0>::Type); |
288 }; |
288 }; |
289 |
289 |
290 } |
290 } |
291 |
291 |
299 /// destruction. |
299 /// destruction. |
300 /// |
300 /// |
301 /// \param _num The number of the types which can be stored in the |
301 /// \param _num The number of the types which can be stored in the |
302 /// variant type. |
302 /// variant type. |
303 /// \param _TypeMap This class describes the types of the Variant. The |
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 |
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 |
305 /// in the range {0, 1, ..., _num - 1}. The \c VariantTypeMap is helper |
306 /// class to define such type mappings up to 10 types. |
306 /// class to define such type mappings up to 10 types. |
307 /// |
307 /// |
308 /// And the usage of the class: |
308 /// And the usage of the class: |
309 ///\code |
309 ///\code |
376 /// type with \c _idx index. |
376 /// type with \c _idx index. |
377 template <int _idx> |
377 template <int _idx> |
378 Variant& set() { |
378 Variant& set() { |
379 _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data); |
379 _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data); |
380 flag = _idx; |
380 flag = _idx; |
381 new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data)) |
381 new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data)) |
382 typename TypeMap::template Map<_idx>::Type(); |
382 typename TypeMap::template Map<_idx>::Type(); |
383 return *this; |
383 return *this; |
384 } |
384 } |
385 |
385 |
386 /// \brief Set to the given value of the type with \c _idx index. |
386 /// \brief Set to the given value of the type with \c _idx index. |
389 /// with \c _idx index. |
389 /// with \c _idx index. |
390 template <int _idx> |
390 template <int _idx> |
391 Variant& set(const typename _TypeMap::template Map<_idx>::Type& init) { |
391 Variant& set(const typename _TypeMap::template Map<_idx>::Type& init) { |
392 _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data); |
392 _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data); |
393 flag = _idx; |
393 flag = _idx; |
394 new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data)) |
394 new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data)) |
395 typename TypeMap::template Map<_idx>::Type(init); |
395 typename TypeMap::template Map<_idx>::Type(init); |
396 return *this; |
396 return *this; |
397 } |
397 } |
398 |
398 |
399 /// \brief Gets the current value of the type with \c _idx index. |
399 /// \brief Gets the current value of the type with \c _idx index. |
401 /// Gets the current value of the type with \c _idx index. |
401 /// Gets the current value of the type with \c _idx index. |
402 template <int _idx> |
402 template <int _idx> |
403 const typename TypeMap::template Map<_idx>::Type& get() const { |
403 const typename TypeMap::template Map<_idx>::Type& get() const { |
404 LEMON_DEBUG(_idx == flag, "Variant wrong index"); |
404 LEMON_DEBUG(_idx == flag, "Variant wrong index"); |
405 return *reinterpret_cast<const typename TypeMap:: |
405 return *reinterpret_cast<const typename TypeMap:: |
406 template Map<_idx>::Type*>(data); |
406 template Map<_idx>::Type*>(data); |
407 } |
407 } |
408 |
408 |
409 /// \brief Gets the current value of the type with \c _idx index. |
409 /// \brief Gets the current value of the type with \c _idx index. |
410 /// |
410 /// |
411 /// Gets the current value of the type with \c _idx index. |
411 /// Gets the current value of the type with \c _idx index. |
412 template <int _idx> |
412 template <int _idx> |
413 typename _TypeMap::template Map<_idx>::Type& get() { |
413 typename _TypeMap::template Map<_idx>::Type& get() { |
414 LEMON_DEBUG(_idx == flag, "Variant wrong index"); |
414 LEMON_DEBUG(_idx == flag, "Variant wrong index"); |
415 return *reinterpret_cast<typename TypeMap::template Map<_idx>::Type*> |
415 return *reinterpret_cast<typename TypeMap::template Map<_idx>::Type*> |
416 (data); |
416 (data); |
417 } |
417 } |
418 |
418 |
419 /// \brief Returns the current state of the variant. |
419 /// \brief Returns the current state of the variant. |
420 /// |
420 /// |
421 /// Returns the current state of the variant. |
421 /// Returns the current state of the variant. |
422 int state() const { |
422 int state() const { |
423 return flag; |
423 return flag; |
424 } |
424 } |
425 |
425 |
426 private: |
426 private: |
427 |
427 |
428 char data[_variant_bits::Size<num - 1, TypeMap>::value]; |
428 char data[_variant_bits::Size<num - 1, TypeMap>::value]; |
429 int flag; |
429 int flag; |
430 }; |
430 }; |
431 |
431 |
432 namespace _variant_bits { |
432 namespace _variant_bits { |
440 struct Get<0, _List> { |
440 struct Get<0, _List> { |
441 typedef typename _List::Type Type; |
441 typedef typename _List::Type Type; |
442 }; |
442 }; |
443 |
443 |
444 struct List {}; |
444 struct List {}; |
445 |
445 |
446 template <typename _Type, typename _List> |
446 template <typename _Type, typename _List> |
447 struct Insert { |
447 struct Insert { |
448 typedef _List Next; |
448 typedef _List Next; |
449 typedef _Type Type; |
449 typedef _Type Type; |
450 }; |
450 }; |
451 |
451 |
452 template <int _idx, typename _T0, typename _T1, typename _T2, |
452 template <int _idx, typename _T0, typename _T1, typename _T2, |
453 typename _T3, typename _T5, typename _T4, typename _T6, |
453 typename _T3, typename _T5, typename _T4, typename _T6, |
454 typename _T7, typename _T8, typename _T9> |
454 typename _T7, typename _T8, typename _T9> |
455 struct Mapper { |
455 struct Mapper { |
456 typedef List L10; |
456 typedef List L10; |
457 typedef Insert<_T9, L10> L9; |
457 typedef Insert<_T9, L10> L9; |
464 typedef Insert<_T2, L3> L2; |
464 typedef Insert<_T2, L3> L2; |
465 typedef Insert<_T1, L2> L1; |
465 typedef Insert<_T1, L2> L1; |
466 typedef Insert<_T0, L1> L0; |
466 typedef Insert<_T0, L1> L0; |
467 typedef typename Get<_idx, L0>::Type Type; |
467 typedef typename Get<_idx, L0>::Type Type; |
468 }; |
468 }; |
469 |
469 |
470 } |
470 } |
471 |
471 |
472 /// \brief Helper class for Variant |
472 /// \brief Helper class for Variant |
473 /// |
473 /// |
474 /// Helper class to define type mappings for Variant. This class |
474 /// Helper class to define type mappings for Variant. This class |
475 /// converts the template parameters to be mappable by integer. |
475 /// converts the template parameters to be mappable by integer. |
476 /// \see Variant |
476 /// \see Variant |
477 template < |
477 template < |
478 typename _T0, |
478 typename _T0, |
479 typename _T1 = void, typename _T2 = void, typename _T3 = void, |
479 typename _T1 = void, typename _T2 = void, typename _T3 = void, |
480 typename _T5 = void, typename _T4 = void, typename _T6 = void, |
480 typename _T5 = void, typename _T4 = void, typename _T6 = void, |
481 typename _T7 = void, typename _T8 = void, typename _T9 = void> |
481 typename _T7 = void, typename _T8 = void, typename _T9 = void> |
482 struct VariantTypeMap { |
482 struct VariantTypeMap { |
483 template <int _idx> |
483 template <int _idx> |
485 typedef typename _variant_bits:: |
485 typedef typename _variant_bits:: |
486 Mapper<_idx, _T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>::Type |
486 Mapper<_idx, _T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>::Type |
487 Type; |
487 Type; |
488 }; |
488 }; |
489 }; |
489 }; |
490 |
490 |
491 } |
491 } |
492 |
492 |
493 |
493 |
494 #endif |
494 #endif |