Changeset 2177:416a7030b7e3 in lemon0.x for lemon/bits
 Timestamp:
 08/11/06 16:55:33 (13 years ago)
 Branch:
 default
 Phase:
 public
 Convert:
 svn:c9d7d8f590d60310b91f818b3a526b0e/lemon/trunk@2893
 Location:
 lemon/bits
 Files:

 1 added
 1 edited
Legend:
 Unmodified
 Added
 Removed

lemon/bits/utility.h
r2151 r2177 35 35 #ifndef LEMON_BITS_UTILITY_H 36 36 #define LEMON_BITS_UTILITY_H 37 38 #include <lemon/error.h>39 37 40 38 ///\file … … 75 73 private: 76 74 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 type153 ///154 /// Simple Variant type with two type155 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;287 75 }; 288 76
Note: See TracChangeset
for help on using the changeset viewer.