COIN-OR::LEMON - Graph Library

Changeset 2177:416a7030b7e3 in lemon-0.x for lemon/bits


Ignore:
Timestamp:
08/11/06 16:55:33 (13 years ago)
Author:
Balazs Dezso
Branch:
default
Phase:
public
Convert:
svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@2893
Message:

BiVariant? moved to lemon/bits/variant.h

Location:
lemon/bits
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • lemon/bits/utility.h

    r2151 r2177  
    3535#ifndef LEMON_BITS_UTILITY_H
    3636#define LEMON_BITS_UTILITY_H
    37 
    38 #include <lemon/error.h>
    3937
    4038///\file
     
    7573  private:
    7674    InvalidType();
    77   };
    78 
    79   template <bool left, bool right>
    80   struct CTOr {
    81     static const bool value = true;
    82   };
    83 
    84   template <>
    85   struct CTOr<false, false> {
    86     static const bool value = false;
    87   };
    88 
    89   template <bool left, bool right>
    90   struct CTAnd {
    91     static const bool value = false;
    92   };
    93 
    94   template <>
    95   struct CTAnd<true, true> {
    96     static const bool value = true;
    97   };
    98 
    99   template <int left, int right>
    100   struct CTEqual {
    101     static const bool value = false;
    102   };
    103 
    104   template <int val>
    105   struct CTEqual<val, val> {
    106     static const bool value = true;
    107   };
    108 
    109 
    110   template <int left, int right>
    111   struct CTLess {
    112     static const bool value = left < right;
    113   };
    114 
    115   template <int left>
    116   struct CTLess<left, 0> {
    117     static const bool value = false;
    118   };
    119 
    120   template <int right>
    121   struct CTLess<0, right> {
    122     static const bool value = true;
    123   };
    124 
    125   template <>
    126   struct CTLess<0, 0> {
    127     static const bool value = false;
    128   };
    129 
    130   template <>
    131   struct CTLess<1, 1> {
    132     static const bool value = false;
    133   };
    134 
    135   template <bool less, int left, int right>
    136   struct CTMaxImpl {
    137     static const int value = left;   
    138   };
    139 
    140   template <int left, int right>
    141   struct CTMaxImpl<true, left, right> {
    142     static const int value = right;
    143   };
    144  
    145   template <int left, int right>
    146   struct CTMax {
    147     static const int value =
    148     CTMaxImpl<CTLess<left, right>::value, left, right>::value;
    149   };
    150 
    151 
    152   /// \brief Simple Variant type with two type
    153   ///
    154   /// Simple Variant type with two type
    155   template <typename _First, typename _Second>
    156   class BiVariant {
    157   public:
    158 
    159     typedef _First First;
    160     typedef _Second Second;
    161 
    162     struct WrongStateError : public lemon::LogicError {
    163     public:
    164       virtual const char* what() const throw() {
    165         return "lemon::BiVariant::WrongStateError";
    166       }
    167     };
    168 
    169     BiVariant() {
    170       flag = true;
    171       new(reinterpret_cast<First*>(data)) First();
    172     }
    173 
    174     BiVariant(const First& first) {
    175       flag = true;
    176       new(reinterpret_cast<First*>(data)) First(first);
    177     }
    178 
    179     BiVariant(const Second& second) {
    180       flag = false;
    181       new(reinterpret_cast<Second*>(data)) Second(second);
    182     }
    183 
    184     BiVariant(const BiVariant& bivariant) {
    185       flag = bivariant.flag;
    186       if (flag) {
    187         new(reinterpret_cast<First*>(data)) First(bivariant.first());     
    188       } else {
    189         new(reinterpret_cast<Second*>(data)) Second(bivariant.second());     
    190       }
    191     }
    192 
    193     ~BiVariant() {
    194       destroy();
    195     }
    196 
    197     BiVariant& setFirst() {
    198       destroy();
    199       flag = true;
    200       new(reinterpret_cast<First*>(data)) First();   
    201       return *this;
    202     }
    203 
    204     BiVariant& setFirst(const First& first) {
    205       destroy();
    206       flag = true;
    207       new(reinterpret_cast<First*>(data)) First(first);   
    208       return *this;
    209     }
    210 
    211     BiVariant& setSecond() {
    212       destroy();
    213       flag = false;
    214       new(reinterpret_cast<Second*>(data)) Second();   
    215       return *this;
    216     }
    217 
    218     BiVariant& setSecond(const Second& second) {
    219       destroy();
    220       flag = false;
    221       new(reinterpret_cast<Second*>(data)) Second(second);   
    222       return *this;
    223     }
    224 
    225     BiVariant& operator=(const First& first) {
    226       return setFirst(first);
    227     }
    228 
    229     BiVariant& operator=(const Second& second) {
    230       return setSecond(second);
    231     }
    232 
    233 
    234     BiVariant& operator=(const BiVariant& bivariant) {
    235       if (this == &bivariant) return *this;
    236       destroy();
    237       flag = bivariant.flag;
    238       if (flag) {
    239         new(reinterpret_cast<First*>(data)) First(bivariant.first());     
    240       } else {
    241         new(reinterpret_cast<Second*>(data)) Second(bivariant.second());     
    242       }
    243       return *this;
    244     }
    245 
    246     First& first() {
    247       LEMON_ASSERT(flag, WrongStateError());
    248       return *reinterpret_cast<First*>(data);
    249     }
    250 
    251     const First& first() const {
    252       LEMON_ASSERT(flag, WrongStateError());
    253       return *reinterpret_cast<const First*>(data);
    254     }
    255 
    256     operator First&() { return first(); }
    257     operator const First&() const { return first(); }
    258 
    259     Second& second() {
    260       LEMON_ASSERT(!flag, WrongStateError());
    261       return *reinterpret_cast<Second*>(data);
    262     }
    263 
    264     const Second& second() const {
    265       LEMON_ASSERT(!flag, WrongStateError());
    266       return *reinterpret_cast<const Second*>(data);
    267     }
    268 
    269     operator Second&() { return second(); }
    270     operator const Second&() const { return second(); }
    271 
    272     bool firstState() const { return flag; }
    273     bool secondState() const { return !flag; }
    274 
    275   private:
    276 
    277     void destroy() {
    278       if (flag) {
    279         reinterpret_cast<First*>(data)->~First();
    280       } else {
    281         reinterpret_cast<Second*>(data)->~Second();
    282       }
    283     }
    284    
    285     char data[CTMax<sizeof(First), sizeof(Second)>::value];
    286     bool flag;
    28775  };
    28876
Note: See TracChangeset for help on using the changeset viewer.