lemon/bits/variant.h
author Balazs Dezso <deba@inf.elte.hu>
Sun, 30 Nov 2008 19:18:32 +0100
changeset 432 76287c8caa26
parent 430 05357da973ce
child 451 09e416d35896
permissions -rw-r--r--
Reorganication of graph adaptors and doc improvements (#67)

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