lemon/bits/variant.h
author Peter Kovacs <kpeter@inf.elte.hu>
Fri, 03 Apr 2009 18:59:15 +0200
changeset 600 6ac5d9ae1d3d
parent 431 9dfaf6efc36f
permissions -rw-r--r--
Support real types + numerical stability fix in NS (#254)

- Real types are supported by appropriate inicialization.
- A feature of the XTI spanning tree structure is removed to ensure
numerical stability (could cause problems using integer types).
The node potentials are updated always on the lower subtree,
in order to prevent overflow problems.
The former method isn't notably faster during to our tests.
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library.
     4  *
     5  * Copyright (C) 2003-2009
     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-safe
    42   // union. C++ has strong limitations for using unions, for
    43   // example you cannot store a type with non-default constructor or
    44   // destructor in a 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.
   295   // C++ has strong limitations for using unions, for example you
   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 _T4, typename _T5, 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 _T4 = void, typename _T5 = 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