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