lemon/bits/variant.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
child 2292 38d985e82205
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

The tests have been modified to the current implementation
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
 *
deba@2177
     5
 * Copyright (C) 2003-2006
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@2177
    24
namespace lemon {
deba@2177
    25
deba@2177
    26
  template <bool left, bool right>
deba@2177
    27
  struct CTOr {
deba@2177
    28
    static const bool value = true;
deba@2177
    29
  };
deba@2177
    30
deba@2177
    31
  template <>
deba@2177
    32
  struct CTOr<false, false> {
deba@2177
    33
    static const bool value = false;
deba@2177
    34
  };
deba@2177
    35
deba@2177
    36
  template <bool left, bool right>
deba@2177
    37
  struct CTAnd {
deba@2177
    38
    static const bool value = false;
deba@2177
    39
  };
deba@2177
    40
deba@2177
    41
  template <>
deba@2177
    42
  struct CTAnd<true, true> {
deba@2177
    43
    static const bool value = true;
deba@2177
    44
  };
deba@2177
    45
deba@2177
    46
  template <int left, int right>
deba@2177
    47
  struct CTEqual {
deba@2177
    48
    static const bool value = false;
deba@2177
    49
  };
deba@2177
    50
deba@2177
    51
  template <int val>
deba@2177
    52
  struct CTEqual<val, val> {
deba@2177
    53
    static const bool value = true;
deba@2177
    54
  };
deba@2177
    55
deba@2177
    56
deba@2177
    57
  template <int left, int right>
deba@2177
    58
  struct CTLess {
deba@2177
    59
    static const bool value = left < right;
deba@2177
    60
  };
deba@2177
    61
deba@2177
    62
  template <int left>
deba@2177
    63
  struct CTLess<left, 0> {
deba@2177
    64
    static const bool value = false;
deba@2177
    65
  };
deba@2177
    66
deba@2177
    67
  template <int right>
deba@2177
    68
  struct CTLess<0, right> {
deba@2177
    69
    static const bool value = true;
deba@2177
    70
  };
deba@2177
    71
deba@2177
    72
  template <>
deba@2177
    73
  struct CTLess<0, 0> {
deba@2177
    74
    static const bool value = false;
deba@2177
    75
  };
deba@2177
    76
deba@2177
    77
  template <>
deba@2177
    78
  struct CTLess<1, 1> {
deba@2177
    79
    static const bool value = false;
deba@2177
    80
  };
deba@2177
    81
deba@2177
    82
  template <bool less, int left, int right>
deba@2177
    83
  struct CTMaxImpl {
deba@2177
    84
    static const int value = left;    
deba@2177
    85
  };
deba@2177
    86
deba@2177
    87
  template <int left, int right>
deba@2177
    88
  struct CTMaxImpl<true, left, right> {
deba@2177
    89
    static const int value = right;
deba@2177
    90
  };
deba@2177
    91
  
deba@2177
    92
  template <int left, int right>
deba@2177
    93
  struct CTMax {
deba@2177
    94
    static const int value = 
deba@2177
    95
    CTMaxImpl<CTLess<left, right>::value, left, right>::value;
deba@2177
    96
  };
deba@2177
    97
deba@2177
    98
deba@2177
    99
  /// \brief Simple Variant type with two type
deba@2177
   100
  ///
deba@2177
   101
  /// Simple Variant type with two type
deba@2177
   102
  template <typename _First, typename _Second>
deba@2177
   103
  class BiVariant {
deba@2177
   104
  public:
deba@2177
   105
deba@2177
   106
    typedef _First First;
deba@2177
   107
    typedef _Second Second;
deba@2177
   108
deba@2177
   109
    struct WrongStateError : public lemon::LogicError {
deba@2177
   110
    public:
deba@2177
   111
      virtual const char* what() const throw() {
deba@2177
   112
        return "lemon::BiVariant::WrongStateError";
deba@2177
   113
      }
deba@2177
   114
    };
deba@2177
   115
deba@2177
   116
    BiVariant() {
deba@2177
   117
      flag = true;
deba@2177
   118
      new(reinterpret_cast<First*>(data)) First();
deba@2177
   119
    }
deba@2177
   120
deba@2177
   121
    BiVariant(const First& first) {
deba@2177
   122
      flag = true;
deba@2177
   123
      new(reinterpret_cast<First*>(data)) First(first);
deba@2177
   124
    }
deba@2177
   125
deba@2177
   126
    BiVariant(const Second& second) {
deba@2177
   127
      flag = false;
deba@2177
   128
      new(reinterpret_cast<Second*>(data)) Second(second);
deba@2177
   129
    }
deba@2177
   130
deba@2177
   131
    BiVariant(const BiVariant& bivariant) {
deba@2177
   132
      flag = bivariant.flag;
deba@2177
   133
      if (flag) {
deba@2177
   134
        new(reinterpret_cast<First*>(data)) First(bivariant.first());      
deba@2177
   135
      } else {
deba@2177
   136
        new(reinterpret_cast<Second*>(data)) Second(bivariant.second());      
deba@2177
   137
      }
deba@2177
   138
    }
deba@2177
   139
deba@2177
   140
    ~BiVariant() {
deba@2177
   141
      destroy();
deba@2177
   142
    }
deba@2177
   143
deba@2177
   144
    BiVariant& setFirst() {
deba@2177
   145
      destroy();
deba@2177
   146
      flag = true;
deba@2177
   147
      new(reinterpret_cast<First*>(data)) First();   
deba@2177
   148
      return *this;
deba@2177
   149
    }
deba@2177
   150
deba@2177
   151
    BiVariant& setFirst(const First& first) {
deba@2177
   152
      destroy();
deba@2177
   153
      flag = true;
deba@2177
   154
      new(reinterpret_cast<First*>(data)) First(first);   
deba@2177
   155
      return *this;
deba@2177
   156
    }
deba@2177
   157
deba@2177
   158
    BiVariant& setSecond() {
deba@2177
   159
      destroy();
deba@2177
   160
      flag = false;
deba@2177
   161
      new(reinterpret_cast<Second*>(data)) Second();   
deba@2177
   162
      return *this;
deba@2177
   163
    }
deba@2177
   164
deba@2177
   165
    BiVariant& setSecond(const Second& second) {
deba@2177
   166
      destroy();
deba@2177
   167
      flag = false;
deba@2177
   168
      new(reinterpret_cast<Second*>(data)) Second(second);   
deba@2177
   169
      return *this;
deba@2177
   170
    }
deba@2177
   171
deba@2177
   172
    BiVariant& operator=(const First& first) {
deba@2177
   173
      return setFirst(first);
deba@2177
   174
    }
deba@2177
   175
deba@2177
   176
    BiVariant& operator=(const Second& second) {
deba@2177
   177
      return setSecond(second);
deba@2177
   178
    }
deba@2177
   179
deba@2177
   180
deba@2177
   181
    BiVariant& operator=(const BiVariant& bivariant) {
deba@2177
   182
      if (this == &bivariant) return *this;
deba@2177
   183
      destroy();
deba@2177
   184
      flag = bivariant.flag;
deba@2177
   185
      if (flag) {
deba@2177
   186
        new(reinterpret_cast<First*>(data)) First(bivariant.first());      
deba@2177
   187
      } else {
deba@2177
   188
        new(reinterpret_cast<Second*>(data)) Second(bivariant.second());      
deba@2177
   189
      }
deba@2177
   190
      return *this;
deba@2177
   191
    }
deba@2177
   192
deba@2177
   193
    First& first() {
deba@2177
   194
      LEMON_ASSERT(flag, WrongStateError());
deba@2177
   195
      return *reinterpret_cast<First*>(data); 
deba@2177
   196
    }
deba@2177
   197
deba@2177
   198
    const First& first() const { 
deba@2177
   199
      LEMON_ASSERT(flag, WrongStateError());
deba@2177
   200
      return *reinterpret_cast<const First*>(data); 
deba@2177
   201
    }
deba@2177
   202
deba@2177
   203
    operator First&() { return first(); }
deba@2177
   204
    operator const First&() const { return first(); }
deba@2177
   205
deba@2177
   206
    Second& second() { 
deba@2177
   207
      LEMON_ASSERT(!flag, WrongStateError());
deba@2177
   208
      return *reinterpret_cast<Second*>(data); 
deba@2177
   209
    }
deba@2177
   210
deba@2177
   211
    const Second& second() const { 
deba@2177
   212
      LEMON_ASSERT(!flag, WrongStateError());
deba@2177
   213
      return *reinterpret_cast<const Second*>(data); 
deba@2177
   214
    }
deba@2177
   215
deba@2177
   216
    operator Second&() { return second(); }
deba@2177
   217
    operator const Second&() const { return second(); }
deba@2177
   218
deba@2177
   219
    bool firstState() const { return flag; }
deba@2177
   220
    bool secondState() const { return !flag; }
deba@2177
   221
deba@2177
   222
  private:
deba@2177
   223
deba@2177
   224
    void destroy() {
deba@2177
   225
      if (flag) {
deba@2177
   226
        reinterpret_cast<First*>(data)->~First();
deba@2177
   227
      } else {
deba@2177
   228
        reinterpret_cast<Second*>(data)->~Second();
deba@2177
   229
      }
deba@2177
   230
    }
deba@2177
   231
    
deba@2177
   232
    char data[CTMax<sizeof(First), sizeof(Second)>::value];
deba@2177
   233
    bool flag;
deba@2177
   234
  };
deba@2177
   235
deba@2177
   236
}
deba@2177
   237
deba@2177
   238
deba@2177
   239
#endif