1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/lemon/bits/variant.h Thu Nov 05 15:50:01 2009 +0100
1.3 @@ -0,0 +1,494 @@
1.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
1.5 + *
1.6 + * This file is a part of LEMON, a generic C++ optimization library.
1.7 + *
1.8 + * Copyright (C) 2003-2009
1.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
1.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
1.11 + *
1.12 + * Permission to use, modify and distribute this software is granted
1.13 + * provided that this copyright notice appears in all copies. For
1.14 + * precise terms see the accompanying LICENSE file.
1.15 + *
1.16 + * This software is provided "AS IS" with no warranty of any kind,
1.17 + * express or implied, and with no claim as to its suitability for any
1.18 + * purpose.
1.19 + *
1.20 + */
1.21 +
1.22 +#ifndef LEMON_BITS_VARIANT_H
1.23 +#define LEMON_BITS_VARIANT_H
1.24 +
1.25 +#include <lemon/assert.h>
1.26 +
1.27 +// \file
1.28 +// \brief Variant types
1.29 +
1.30 +namespace lemon {
1.31 +
1.32 + namespace _variant_bits {
1.33 +
1.34 + template <int left, int right>
1.35 + struct CTMax {
1.36 + static const int value = left < right ? right : left;
1.37 + };
1.38 +
1.39 + }
1.40 +
1.41 +
1.42 + // \brief Simple Variant type for two types
1.43 + //
1.44 + // Simple Variant type for two types. The Variant type is a type-safe
1.45 + // union. C++ has strong limitations for using unions, for
1.46 + // example you cannot store a type with non-default constructor or
1.47 + // destructor in a union. This class always knowns the current
1.48 + // state of the variant and it cares for the proper construction
1.49 + // and destruction.
1.50 + template <typename _First, typename _Second>
1.51 + class BiVariant {
1.52 + public:
1.53 +
1.54 + // \brief The \c First type.
1.55 + typedef _First First;
1.56 + // \brief The \c Second type.
1.57 + typedef _Second Second;
1.58 +
1.59 + // \brief Constructor
1.60 + //
1.61 + // This constructor initalizes to the default value of the \c First
1.62 + // type.
1.63 + BiVariant() {
1.64 + flag = true;
1.65 + new(reinterpret_cast<First*>(data)) First();
1.66 + }
1.67 +
1.68 + // \brief Constructor
1.69 + //
1.70 + // This constructor initalizes to the given value of the \c First
1.71 + // type.
1.72 + BiVariant(const First& f) {
1.73 + flag = true;
1.74 + new(reinterpret_cast<First*>(data)) First(f);
1.75 + }
1.76 +
1.77 + // \brief Constructor
1.78 + //
1.79 + // This constructor initalizes to the given value of the \c
1.80 + // Second type.
1.81 + BiVariant(const Second& s) {
1.82 + flag = false;
1.83 + new(reinterpret_cast<Second*>(data)) Second(s);
1.84 + }
1.85 +
1.86 + // \brief Copy constructor
1.87 + //
1.88 + // Copy constructor
1.89 + BiVariant(const BiVariant& bivariant) {
1.90 + flag = bivariant.flag;
1.91 + if (flag) {
1.92 + new(reinterpret_cast<First*>(data)) First(bivariant.first());
1.93 + } else {
1.94 + new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
1.95 + }
1.96 + }
1.97 +
1.98 + // \brief Destrcutor
1.99 + //
1.100 + // Destructor
1.101 + ~BiVariant() {
1.102 + destroy();
1.103 + }
1.104 +
1.105 + // \brief Set to the default value of the \c First type.
1.106 + //
1.107 + // This function sets the variant to the default value of the \c
1.108 + // First type.
1.109 + BiVariant& setFirst() {
1.110 + destroy();
1.111 + flag = true;
1.112 + new(reinterpret_cast<First*>(data)) First();
1.113 + return *this;
1.114 + }
1.115 +
1.116 + // \brief Set to the given value of the \c First type.
1.117 + //
1.118 + // This function sets the variant to the given value of the \c
1.119 + // First type.
1.120 + BiVariant& setFirst(const First& f) {
1.121 + destroy();
1.122 + flag = true;
1.123 + new(reinterpret_cast<First*>(data)) First(f);
1.124 + return *this;
1.125 + }
1.126 +
1.127 + // \brief Set to the default value of the \c Second type.
1.128 + //
1.129 + // This function sets the variant to the default value of the \c
1.130 + // Second type.
1.131 + BiVariant& setSecond() {
1.132 + destroy();
1.133 + flag = false;
1.134 + new(reinterpret_cast<Second*>(data)) Second();
1.135 + return *this;
1.136 + }
1.137 +
1.138 + // \brief Set to the given value of the \c Second type.
1.139 + //
1.140 + // This function sets the variant to the given value of the \c
1.141 + // Second type.
1.142 + BiVariant& setSecond(const Second& s) {
1.143 + destroy();
1.144 + flag = false;
1.145 + new(reinterpret_cast<Second*>(data)) Second(s);
1.146 + return *this;
1.147 + }
1.148 +
1.149 + // \brief Operator form of the \c setFirst()
1.150 + BiVariant& operator=(const First& f) {
1.151 + return setFirst(f);
1.152 + }
1.153 +
1.154 + // \brief Operator form of the \c setSecond()
1.155 + BiVariant& operator=(const Second& s) {
1.156 + return setSecond(s);
1.157 + }
1.158 +
1.159 + // \brief Assign operator
1.160 + BiVariant& operator=(const BiVariant& bivariant) {
1.161 + if (this == &bivariant) return *this;
1.162 + destroy();
1.163 + flag = bivariant.flag;
1.164 + if (flag) {
1.165 + new(reinterpret_cast<First*>(data)) First(bivariant.first());
1.166 + } else {
1.167 + new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
1.168 + }
1.169 + return *this;
1.170 + }
1.171 +
1.172 + // \brief Reference to the value
1.173 + //
1.174 + // Reference to the value of the \c First type.
1.175 + // \pre The BiVariant should store value of \c First type.
1.176 + First& first() {
1.177 + LEMON_DEBUG(flag, "Variant wrong state");
1.178 + return *reinterpret_cast<First*>(data);
1.179 + }
1.180 +
1.181 + // \brief Const reference to the value
1.182 + //
1.183 + // Const reference to the value of the \c First type.
1.184 + // \pre The BiVariant should store value of \c First type.
1.185 + const First& first() const {
1.186 + LEMON_DEBUG(flag, "Variant wrong state");
1.187 + return *reinterpret_cast<const First*>(data);
1.188 + }
1.189 +
1.190 + // \brief Operator form of the \c first()
1.191 + operator First&() { return first(); }
1.192 + // \brief Operator form of the const \c first()
1.193 + operator const First&() const { return first(); }
1.194 +
1.195 + // \brief Reference to the value
1.196 + //
1.197 + // Reference to the value of the \c Second type.
1.198 + // \pre The BiVariant should store value of \c Second type.
1.199 + Second& second() {
1.200 + LEMON_DEBUG(!flag, "Variant wrong state");
1.201 + return *reinterpret_cast<Second*>(data);
1.202 + }
1.203 +
1.204 + // \brief Const reference to the value
1.205 + //
1.206 + // Const reference to the value of the \c Second type.
1.207 + // \pre The BiVariant should store value of \c Second type.
1.208 + const Second& second() const {
1.209 + LEMON_DEBUG(!flag, "Variant wrong state");
1.210 + return *reinterpret_cast<const Second*>(data);
1.211 + }
1.212 +
1.213 + // \brief Operator form of the \c second()
1.214 + operator Second&() { return second(); }
1.215 + // \brief Operator form of the const \c second()
1.216 + operator const Second&() const { return second(); }
1.217 +
1.218 + // \brief %True when the variant is in the first state
1.219 + //
1.220 + // %True when the variant stores value of the \c First type.
1.221 + bool firstState() const { return flag; }
1.222 +
1.223 + // \brief %True when the variant is in the second state
1.224 + //
1.225 + // %True when the variant stores value of the \c Second type.
1.226 + bool secondState() const { return !flag; }
1.227 +
1.228 + private:
1.229 +
1.230 + void destroy() {
1.231 + if (flag) {
1.232 + reinterpret_cast<First*>(data)->~First();
1.233 + } else {
1.234 + reinterpret_cast<Second*>(data)->~Second();
1.235 + }
1.236 + }
1.237 +
1.238 + char data[_variant_bits::CTMax<sizeof(First), sizeof(Second)>::value];
1.239 + bool flag;
1.240 + };
1.241 +
1.242 + namespace _variant_bits {
1.243 +
1.244 + template <int _idx, typename _TypeMap>
1.245 + struct Memory {
1.246 +
1.247 + typedef typename _TypeMap::template Map<_idx>::Type Current;
1.248 +
1.249 + static void destroy(int index, char* place) {
1.250 + if (index == _idx) {
1.251 + reinterpret_cast<Current*>(place)->~Current();
1.252 + } else {
1.253 + Memory<_idx - 1, _TypeMap>::destroy(index, place);
1.254 + }
1.255 + }
1.256 +
1.257 + static void copy(int index, char* to, const char* from) {
1.258 + if (index == _idx) {
1.259 + new (reinterpret_cast<Current*>(to))
1.260 + Current(reinterpret_cast<const Current*>(from));
1.261 + } else {
1.262 + Memory<_idx - 1, _TypeMap>::copy(index, to, from);
1.263 + }
1.264 + }
1.265 +
1.266 + };
1.267 +
1.268 + template <typename _TypeMap>
1.269 + struct Memory<-1, _TypeMap> {
1.270 +
1.271 + static void destroy(int, char*) {
1.272 + LEMON_DEBUG(false, "Variant wrong index.");
1.273 + }
1.274 +
1.275 + static void copy(int, char*, const char*) {
1.276 + LEMON_DEBUG(false, "Variant wrong index.");
1.277 + }
1.278 + };
1.279 +
1.280 + template <int _idx, typename _TypeMap>
1.281 + struct Size {
1.282 + static const int value =
1.283 + CTMax<sizeof(typename _TypeMap::template Map<_idx>::Type),
1.284 + Size<_idx - 1, _TypeMap>::value>::value;
1.285 + };
1.286 +
1.287 + template <typename _TypeMap>
1.288 + struct Size<0, _TypeMap> {
1.289 + static const int value =
1.290 + sizeof(typename _TypeMap::template Map<0>::Type);
1.291 + };
1.292 +
1.293 + }
1.294 +
1.295 + // \brief Variant type
1.296 + //
1.297 + // Simple Variant type. The Variant type is a type-safe union.
1.298 + // C++ has strong limitations for using unions, for example you
1.299 + // cannot store type with non-default constructor or destructor in
1.300 + // a union. This class always knowns the current state of the
1.301 + // variant and it cares for the proper construction and
1.302 + // destruction.
1.303 + //
1.304 + // \param _num The number of the types which can be stored in the
1.305 + // variant type.
1.306 + // \param _TypeMap This class describes the types of the Variant. The
1.307 + // _TypeMap::Map<index>::Type should be a valid type for each index
1.308 + // in the range {0, 1, ..., _num - 1}. The \c VariantTypeMap is helper
1.309 + // class to define such type mappings up to 10 types.
1.310 + //
1.311 + // And the usage of the class:
1.312 + //\code
1.313 + // typedef Variant<3, VariantTypeMap<int, std::string, double> > MyVariant;
1.314 + // MyVariant var;
1.315 + // var.set<0>(12);
1.316 + // std::cout << var.get<0>() << std::endl;
1.317 + // var.set<1>("alpha");
1.318 + // std::cout << var.get<1>() << std::endl;
1.319 + // var.set<2>(0.75);
1.320 + // std::cout << var.get<2>() << std::endl;
1.321 + //\endcode
1.322 + //
1.323 + // The result of course:
1.324 + //\code
1.325 + // 12
1.326 + // alpha
1.327 + // 0.75
1.328 + //\endcode
1.329 + template <int _num, typename _TypeMap>
1.330 + class Variant {
1.331 + public:
1.332 +
1.333 + static const int num = _num;
1.334 +
1.335 + typedef _TypeMap TypeMap;
1.336 +
1.337 + // \brief Constructor
1.338 + //
1.339 + // This constructor initalizes to the default value of the \c type
1.340 + // with 0 index.
1.341 + Variant() {
1.342 + flag = 0;
1.343 + new(reinterpret_cast<typename TypeMap::template Map<0>::Type*>(data))
1.344 + typename TypeMap::template Map<0>::Type();
1.345 + }
1.346 +
1.347 +
1.348 + // \brief Copy constructor
1.349 + //
1.350 + // Copy constructor
1.351 + Variant(const Variant& variant) {
1.352 + flag = variant.flag;
1.353 + _variant_bits::Memory<num - 1, TypeMap>::copy(flag, data, variant.data);
1.354 + }
1.355 +
1.356 + // \brief Assign operator
1.357 + //
1.358 + // Assign operator
1.359 + Variant& operator=(const Variant& variant) {
1.360 + if (this == &variant) return *this;
1.361 + _variant_bits::Memory<num - 1, TypeMap>::
1.362 + destroy(flag, data);
1.363 + flag = variant.flag;
1.364 + _variant_bits::Memory<num - 1, TypeMap>::
1.365 + copy(flag, data, variant.data);
1.366 + return *this;
1.367 + }
1.368 +
1.369 + // \brief Destrcutor
1.370 + //
1.371 + // Destructor
1.372 + ~Variant() {
1.373 + _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
1.374 + }
1.375 +
1.376 + // \brief Set to the default value of the type with \c _idx index.
1.377 + //
1.378 + // This function sets the variant to the default value of the
1.379 + // type with \c _idx index.
1.380 + template <int _idx>
1.381 + Variant& set() {
1.382 + _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
1.383 + flag = _idx;
1.384 + new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data))
1.385 + typename TypeMap::template Map<_idx>::Type();
1.386 + return *this;
1.387 + }
1.388 +
1.389 + // \brief Set to the given value of the type with \c _idx index.
1.390 + //
1.391 + // This function sets the variant to the given value of the type
1.392 + // with \c _idx index.
1.393 + template <int _idx>
1.394 + Variant& set(const typename _TypeMap::template Map<_idx>::Type& init) {
1.395 + _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
1.396 + flag = _idx;
1.397 + new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data))
1.398 + typename TypeMap::template Map<_idx>::Type(init);
1.399 + return *this;
1.400 + }
1.401 +
1.402 + // \brief Gets the current value of the type with \c _idx index.
1.403 + //
1.404 + // Gets the current value of the type with \c _idx index.
1.405 + template <int _idx>
1.406 + const typename TypeMap::template Map<_idx>::Type& get() const {
1.407 + LEMON_DEBUG(_idx == flag, "Variant wrong index");
1.408 + return *reinterpret_cast<const typename TypeMap::
1.409 + template Map<_idx>::Type*>(data);
1.410 + }
1.411 +
1.412 + // \brief Gets the current value of the type with \c _idx index.
1.413 + //
1.414 + // Gets the current value of the type with \c _idx index.
1.415 + template <int _idx>
1.416 + typename _TypeMap::template Map<_idx>::Type& get() {
1.417 + LEMON_DEBUG(_idx == flag, "Variant wrong index");
1.418 + return *reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>
1.419 + (data);
1.420 + }
1.421 +
1.422 + // \brief Returns the current state of the variant.
1.423 + //
1.424 + // Returns the current state of the variant.
1.425 + int state() const {
1.426 + return flag;
1.427 + }
1.428 +
1.429 + private:
1.430 +
1.431 + char data[_variant_bits::Size<num - 1, TypeMap>::value];
1.432 + int flag;
1.433 + };
1.434 +
1.435 + namespace _variant_bits {
1.436 +
1.437 + template <int _index, typename _List>
1.438 + struct Get {
1.439 + typedef typename Get<_index - 1, typename _List::Next>::Type Type;
1.440 + };
1.441 +
1.442 + template <typename _List>
1.443 + struct Get<0, _List> {
1.444 + typedef typename _List::Type Type;
1.445 + };
1.446 +
1.447 + struct List {};
1.448 +
1.449 + template <typename _Type, typename _List>
1.450 + struct Insert {
1.451 + typedef _List Next;
1.452 + typedef _Type Type;
1.453 + };
1.454 +
1.455 + template <int _idx, typename _T0, typename _T1, typename _T2,
1.456 + typename _T3, typename _T4, typename _T5, typename _T6,
1.457 + typename _T7, typename _T8, typename _T9>
1.458 + struct Mapper {
1.459 + typedef List L10;
1.460 + typedef Insert<_T9, L10> L9;
1.461 + typedef Insert<_T8, L9> L8;
1.462 + typedef Insert<_T7, L8> L7;
1.463 + typedef Insert<_T6, L7> L6;
1.464 + typedef Insert<_T5, L6> L5;
1.465 + typedef Insert<_T4, L5> L4;
1.466 + typedef Insert<_T3, L4> L3;
1.467 + typedef Insert<_T2, L3> L2;
1.468 + typedef Insert<_T1, L2> L1;
1.469 + typedef Insert<_T0, L1> L0;
1.470 + typedef typename Get<_idx, L0>::Type Type;
1.471 + };
1.472 +
1.473 + }
1.474 +
1.475 + // \brief Helper class for Variant
1.476 + //
1.477 + // Helper class to define type mappings for Variant. This class
1.478 + // converts the template parameters to be mappable by integer.
1.479 + // \see Variant
1.480 + template <
1.481 + typename _T0,
1.482 + typename _T1 = void, typename _T2 = void, typename _T3 = void,
1.483 + typename _T4 = void, typename _T5 = void, typename _T6 = void,
1.484 + typename _T7 = void, typename _T8 = void, typename _T9 = void>
1.485 + struct VariantTypeMap {
1.486 + template <int _idx>
1.487 + struct Map {
1.488 + typedef typename _variant_bits::
1.489 + Mapper<_idx, _T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>::Type
1.490 + Type;
1.491 + };
1.492 + };
1.493 +
1.494 +}
1.495 +
1.496 +
1.497 +#endif