Changeset 2077:d687c0033bb5 in lemon-0.x
- Timestamp:
- 05/12/06 11:52:28 (18 years ago)
- Branch:
- default
- Phase:
- public
- Convert:
- svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@2740
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/bits/utility.h
r1993 r2077 35 35 #ifndef LEMON_BITS_UTILITY_H 36 36 #define LEMON_BITS_UTILITY_H 37 38 #include <lemon/error.h> 37 39 38 40 ///\file … … 74 76 InvalidType(); 75 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 template <bool sless, bool sequal, bool bless> 110 struct CTLessImpl { 111 static const bool value = 112 CTOr<sless, CTAnd<sequal, bless>::value>::value; 113 }; 114 115 template <int left, int right> 116 struct CTLess { 117 static const bool value = 118 CTLessImpl<CTLess<left >> 1, right >> 1>::value, 119 CTEqual<left >> 1, right >> 1>::value, 120 CTLess<left & 1, right & 1>::value >::value; 121 }; 122 123 template <int left> 124 struct CTLess<left, 0> { 125 static const bool value = false; 126 }; 127 128 template <int right> 129 struct CTLess<0, right> { 130 static const bool value = true; 131 }; 132 133 template <> 134 struct CTLess<0, 0> { 135 static const bool value = false; 136 }; 137 138 template <> 139 struct CTLess<1, 1> { 140 static const bool value = false; 141 }; 142 143 template <bool less, int left, int right> 144 struct CTMaxImpl { 145 static const int value = left; 146 }; 147 148 template <int left, int right> 149 struct CTMaxImpl<true, left, right> { 150 static const int value = right; 151 }; 76 152 153 template <int left, int right> 154 struct CTMax { 155 static const int value = 156 CTMaxImpl<CTLess<left, right>::value, left, right>::value; 157 }; 158 159 160 /// \brief Simple Variant type with two type 161 /// 162 /// Simple Variant type with two type 163 template <typename _First, typename _Second> 164 class BiVariant { 165 public: 166 167 typedef _First First; 168 typedef _Second Second; 169 170 struct WrongStateError : public lemon::LogicError { 171 public: 172 virtual const char* exceptionName() const { 173 return "lemon::BiVariant::WrongStateError"; 174 } 175 }; 176 177 BiVariant() { 178 flag = true; 179 new(reinterpret_cast<First*>(data)) First(); 180 } 181 182 BiVariant(const First& first) { 183 flag = true; 184 new(reinterpret_cast<First*>(data)) First(first); 185 } 186 187 BiVariant(const Second& second) { 188 flag = false; 189 new(reinterpret_cast<Second*>(data)) Second(second); 190 } 191 192 BiVariant(const BiVariant& bivariant) { 193 flag = bivariant.flag; 194 if (flag) { 195 new(reinterpret_cast<First*>(data)) First(bivariant.first()); 196 } else { 197 new(reinterpret_cast<Second*>(data)) Second(bivariant.second()); 198 } 199 } 200 201 ~BiVariant() { 202 destroy(); 203 } 204 205 BiVariant& setFirst() { 206 destroy(); 207 flag = true; 208 new(reinterpret_cast<First*>(data)) First(); 209 return *this; 210 } 211 212 BiVariant& setFirst(const First& first) { 213 destroy(); 214 flag = true; 215 new(reinterpret_cast<First*>(data)) First(first); 216 return *this; 217 } 218 219 BiVariant& setSecond() { 220 destroy(); 221 flag = false; 222 new(reinterpret_cast<Second*>(data)) Second(); 223 return *this; 224 } 225 226 BiVariant& setSecond(const Second& second) { 227 destroy(); 228 flag = false; 229 new(reinterpret_cast<Second*>(data)) Second(second); 230 return *this; 231 } 232 233 BiVariant& operator=(const First& first) { 234 return setFirst(first); 235 } 236 237 BiVariant& operator=(const Second& second) { 238 return setSecond(second); 239 } 240 241 242 BiVariant& operator=(const BiVariant& bivariant) { 243 if (this == &bivariant) return *this; 244 destroy(); 245 flag = bivariant.flag; 246 if (flag) { 247 new(reinterpret_cast<First*>(data)) First(bivariant.first()); 248 } else { 249 new(reinterpret_cast<Second*>(data)) Second(bivariant.second()); 250 } 251 return *this; 252 } 253 254 First& first() { 255 LEMON_ASSERT(flag, WrongStateError()); 256 return *reinterpret_cast<First*>(data); 257 } 258 259 const First& first() const { 260 LEMON_ASSERT(flag, WrongStateError()); 261 return *reinterpret_cast<const First*>(data); 262 } 263 264 operator First&() { return first(); } 265 operator const First&() const { return first(); } 266 267 Second& second() { 268 LEMON_ASSERT(!flag, WrongStateError()); 269 return *reinterpret_cast<Second*>(data); 270 } 271 272 const Second& second() const { 273 LEMON_ASSERT(!flag, WrongStateError()); 274 return *reinterpret_cast<const Second*>(data); 275 } 276 277 operator Second&() { return second(); } 278 operator const Second&() const { return second(); } 279 280 bool firstState() const { return flag; } 281 bool secondState() const { return !flag; } 282 283 private: 284 285 void destroy() { 286 if (flag) { 287 reinterpret_cast<First*>(data)->~First(); 288 } else { 289 reinterpret_cast<Second*>(data)->~Second(); 290 } 291 } 292 293 char data[CTMax<sizeof(First), sizeof(Second)>::value]; 294 bool flag; 295 }; 77 296 78 297 template <typename T>
Note: See TracChangeset
for help on using the changeset viewer.