00001 /* 00002 * Copyright (c) 1998, University of Amsterdam, The Netherlands. 00003 * All rights reserved. 00004 * 00005 * 00006 * Author(s): 00007 * Dennis Koelma (koelma@wins.uva.nl) 00008 * Edo Poll (poll@wins.uva.nl) 00009 */ 00010 00011 #ifndef HxValue_h 00012 #define HxValue_h 00013 00014 #include "HxScalarInt.h" 00015 #include "HxScalarDouble.h" 00016 #include "HxVec2Int.h" 00017 #include "HxVec2Double.h" 00018 #include "HxVec3Int.h" 00019 #include "HxVec3Double.h" 00020 #include "HxComplex.h" 00021 00022 #include "HxString.h" 00023 00031 class L_HXBASIS HxValue { 00032 public: 00042 enum Tag { SI, SD, V2I, V2D, V3I, V3D, CPL }; 00043 00045 00047 HxValue(int i = 0); 00048 00050 HxValue(double d); 00051 00053 HxValue(HxScalarInt i); 00054 00056 HxValue(HxScalarDouble d); 00057 00059 HxValue(HxVec2Int v); 00060 00062 HxValue(HxVec2Double v); 00063 00065 HxValue(HxVec3Int v); 00066 00068 HxValue(HxVec3Double v); 00069 00071 HxValue(HxComplex v); 00073 00075 00077 Tag tag() const; 00079 00081 00083 HxScalarInt& HxScalarIntValue(); 00084 00086 HxScalarDouble& HxScalarDoubleValue(); 00087 00089 HxVec2Int& HxVec2IntValue(); 00090 00092 HxVec2Double& HxVec2DoubleValue(); 00093 00095 HxVec3Int& HxVec3IntValue(); 00096 00098 HxVec3Double& HxVec3DoubleValue(); 00099 00101 HxComplex& HxComplexValue(); 00103 00105 00107 operator HxScalarInt() const; 00108 00110 operator HxScalarDouble() const; 00111 00113 operator HxVec2Int() const; 00114 00116 operator HxVec2Double() const; 00117 00119 operator HxVec3Int() const; 00120 00122 operator HxVec3Double() const; 00123 00125 operator HxComplex() const; 00127 00128 HxString toString() const; 00129 private: 00130 00131 void check(Tag t) const; 00132 void warn(const char*) const; 00133 friend L_HXBASIS STD_OSTREAM& 00134 operator<<(STD_OSTREAM& os, const HxValue val); 00135 00136 char _val[sizeof(HxVec3Double)]; 00137 union { 00138 Tag _tag; 00139 double _dummy; 00140 } _tag; 00141 00142 00143 }; 00144 00145 inline const char* 00146 ClassName(const HxValue&) 00147 { 00148 return "HxValue"; 00149 } 00150 00151 inline HxString 00152 makeString(const HxValue& val) 00153 { 00154 return val.toString(); 00155 } 00156 00157 inline 00158 HxValue::HxValue(int v) 00159 { 00160 _tag._tag = SI; 00161 new(&_val[0]) HxScalarInt(v); 00162 } 00163 00164 inline 00165 HxValue::HxValue(double v) 00166 { 00167 _tag._tag = SD; 00168 new(&_val[0]) HxScalarDouble(v); 00169 } 00170 00171 inline 00172 HxValue::HxValue(HxScalarInt v) 00173 { 00174 _tag._tag = SI; 00175 new(&_val[0]) HxScalarInt(v); 00176 } 00177 00178 inline 00179 HxValue::HxValue(HxScalarDouble v) 00180 { 00181 _tag._tag = SD; 00182 new(&_val[0]) HxScalarDouble(v); 00183 } 00184 00185 inline 00186 HxValue::HxValue(HxVec2Int v) 00187 { 00188 _tag._tag = V2I; 00189 new(&_val[0]) HxVec2Int(v); 00190 } 00191 00192 inline 00193 HxValue::HxValue(HxVec2Double v) 00194 { 00195 _tag._tag = V2D; 00196 new(&_val[0]) HxVec2Double(v); 00197 } 00198 00199 inline 00200 HxValue::HxValue(HxVec3Int v) 00201 { 00202 _tag._tag = V3I; 00203 new(&_val[0]) HxVec3Int(v); 00204 } 00205 00206 inline 00207 HxValue::HxValue(HxVec3Double v) 00208 { 00209 _tag._tag = V3D; 00210 new(&_val[0]) HxVec3Double(v); 00211 } 00212 00213 inline 00214 HxValue::HxValue(HxComplex v) 00215 { 00216 _tag._tag = CPL; 00217 new(&_val[0]) HxComplex(v); 00218 } 00219 00220 inline HxValue::Tag 00221 HxValue::tag() const 00222 { 00223 return _tag._tag; 00224 } 00225 00226 inline HxScalarInt& 00227 HxValue::HxScalarIntValue() 00228 { 00229 check(SI); 00230 return *(HxScalarInt *) &_val[0]; 00231 } 00232 00233 inline HxScalarDouble& 00234 HxValue::HxScalarDoubleValue() 00235 { 00236 check(SD); 00237 return *(HxScalarDouble *) &_val[0]; 00238 } 00239 00240 inline HxVec2Int& 00241 HxValue::HxVec2IntValue() 00242 { 00243 check(V2I); 00244 return *(HxVec2Int *) &_val[0]; 00245 } 00246 00247 inline HxVec2Double& 00248 HxValue::HxVec2DoubleValue() 00249 { 00250 check(V2D); 00251 return *(HxVec2Double *) &_val[0]; 00252 } 00253 00254 inline HxVec3Int& 00255 HxValue::HxVec3IntValue() 00256 { 00257 check(V3I); 00258 return *(HxVec3Int *) &_val[0]; 00259 } 00260 00261 inline HxVec3Double& 00262 HxValue::HxVec3DoubleValue() 00263 { 00264 check(V3D); 00265 return *(HxVec3Double *) &_val[0]; 00266 } 00267 00268 inline HxComplex& 00269 HxValue::HxComplexValue() 00270 { 00271 check(CPL); 00272 return *(HxComplex *) &_val[0]; 00273 } 00274 00275 inline 00276 HxValue::operator HxScalarInt() const 00277 { 00278 switch(_tag._tag) 00279 { 00280 case SI: return (HxScalarInt) *(HxScalarInt *) &_val[0]; 00281 case SD: return (*(HxScalarDouble *) &_val[0]).operator HxScalarInt(); 00282 case V2I: return (HxScalarInt) *(HxVec2Int *) &_val[0]; 00283 case V2D: return (HxScalarInt) *(HxVec2Double *) &_val[0]; 00284 case V3I: return (HxScalarInt) *(HxVec3Int *) &_val[0]; 00285 case V3D: return (HxScalarInt) *(HxVec3Double *) &_val[0]; 00286 case CPL: return (HxScalarInt) *(HxComplex *) &_val[0]; 00287 default: return (HxScalarInt) *(HxScalarInt *) &_val[0]; 00288 } 00289 } 00290 00291 inline 00292 HxValue::operator HxScalarDouble() const 00293 { 00294 switch(_tag._tag) 00295 { 00296 case SI: return (HxScalarDouble) *(HxScalarInt *) &_val[0]; 00297 case SD: return (HxScalarDouble) *(HxScalarDouble *) &_val[0]; 00298 case V2I: return (HxScalarDouble) *(HxVec2Int *) &_val[0]; 00299 case V2D: return (HxScalarDouble) *(HxVec2Double *) &_val[0]; 00300 case V3I: return (HxScalarDouble) *(HxVec3Int *) &_val[0]; 00301 case V3D: return (HxScalarDouble) *(HxVec3Double *) &_val[0]; 00302 case CPL: return (HxScalarDouble) *(HxComplex *) &_val[0]; 00303 default: return (HxScalarDouble) *(HxScalarDouble *) &_val[0]; 00304 } 00305 } 00306 00307 inline 00308 HxValue::operator HxVec2Int() const 00309 { 00310 switch(_tag._tag) 00311 { 00312 case SI: return (HxVec2Int) *(HxScalarInt *) &_val[0]; 00313 case SD: return (HxVec2Int) *(HxScalarDouble *) &_val[0]; 00314 case V2I: return (HxVec2Int) *(HxVec2Int *) &_val[0]; 00315 case V2D: return (HxVec2Int) *(HxVec2Double *) &_val[0]; 00316 case V3I: return (HxVec2Int) *(HxVec3Int *) &_val[0]; 00317 case V3D: return (HxVec2Int) *(HxVec3Double *) &_val[0]; 00318 case CPL: return (HxVec2Int) *(HxComplex *) &_val[0]; 00319 default: return (HxVec2Int) *(HxVec2Int *) &_val[0]; 00320 } 00321 } 00322 00323 inline 00324 HxValue::operator HxVec2Double() const 00325 { 00326 switch(_tag._tag) 00327 { 00328 case SI: return (HxVec2Double) *(HxScalarInt *) &_val[0]; 00329 case SD: return (HxVec2Double) *(HxScalarDouble *) &_val[0]; 00330 case V2I: return (HxVec2Double) *(HxVec2Int *) &_val[0]; 00331 case V2D: return (HxVec2Double) *(HxVec2Double *) &_val[0]; 00332 case V3I: return (HxVec2Double) *(HxVec3Int *) &_val[0]; 00333 case V3D: return (HxVec2Double) *(HxVec3Double *) &_val[0]; 00334 case CPL: return (HxVec2Double) *(HxComplex *) &_val[0]; 00335 default: return (HxVec2Double) *(HxVec2Double *) &_val[0]; 00336 } 00337 } 00338 00339 inline 00340 HxValue::operator HxVec3Int() const 00341 { 00342 switch(_tag._tag) 00343 { 00344 case SI: return (HxVec3Int) *(HxScalarInt *) &_val[0]; 00345 case SD: return (HxVec3Int) *(HxScalarDouble *) &_val[0]; 00346 case V2I: return (HxVec3Int) *(HxVec2Int *) &_val[0]; 00347 case V2D: return (HxVec3Int) *(HxVec2Double *) &_val[0]; 00348 case V3I: return (HxVec3Int) *(HxVec3Int *) &_val[0]; 00349 case V3D: return (HxVec3Int) *(HxVec3Double *) &_val[0]; 00350 case CPL: return (HxVec3Int) *(HxComplex *) &_val[0]; 00351 default: return (HxVec3Int) *(HxVec3Int *) &_val[0]; 00352 } 00353 } 00354 00355 inline 00356 HxValue::operator HxVec3Double() const 00357 { 00358 switch(_tag._tag) 00359 { 00360 case SI: return (HxVec3Double) *(HxScalarInt *) &_val[0]; 00361 case SD: return (HxVec3Double) *(HxScalarDouble *) &_val[0]; 00362 case V2I: return (HxVec3Double) *(HxVec2Int *) &_val[0]; 00363 case V2D: return (HxVec3Double) *(HxVec2Double *) &_val[0]; 00364 case V3I: return (HxVec3Double) *(HxVec3Int *) &_val[0]; 00365 case V3D: return (HxVec3Double) *(HxVec3Double *) &_val[0]; 00366 case CPL: return (HxVec3Double) *(HxComplex *) &_val[0]; 00367 default: return (HxVec3Double) *(HxVec3Double *) &_val[0]; 00368 } 00369 } 00370 00371 inline 00372 HxValue::operator HxComplex() const 00373 { 00374 switch(_tag._tag) 00375 { 00376 case SI: return (HxComplex) *(HxScalarInt *) &_val[0]; 00377 case SD: return (HxComplex) *(HxScalarDouble *) &_val[0]; 00378 case V2I: return (HxComplex) *(HxVec2Int *) &_val[0]; 00379 case V2D: return (HxComplex) *(HxVec2Double *) &_val[0]; 00380 case V3I: return (HxComplex) *(HxVec3Int *) &_val[0]; 00381 case V3D: return (HxComplex) *(HxVec3Double *) &_val[0]; 00382 case CPL: return (HxComplex) *(HxComplex *) &_val[0]; 00383 default: return (HxComplex) *(HxComplex *) &_val[0]; 00384 } 00385 } 00386 00387 inline void 00388 HxValue::check(Tag t) const 00389 { 00390 if (t != _tag._tag) 00391 warn("HxValue: wrong value access."); 00392 } 00393 00394 #endif