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