00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #ifndef _STX_AnyScalar_H_
00028 #define _STX_AnyScalar_H_
00029
00030 #include <string>
00031 #include <stdexcept>
00032 #include <functional>
00033 #include <ostream>
00034 #include <assert.h>
00035
00036 namespace stx {
00037
00045 class AnyScalar
00046 {
00047 public:
00051 enum attrtype_t
00052 {
00054 ATTRTYPE_INVALID = 0x00,
00055
00057 ATTRTYPE_BOOL = 0x01,
00058
00061 ATTRTYPE_CHAR = 0x10,
00062
00064 ATTRTYPE_SHORT = 0x11,
00065
00067 ATTRTYPE_INTEGER = 0x12,
00068
00070 ATTRTYPE_LONG = 0x13,
00071
00074 ATTRTYPE_BYTE = 0x20,
00075
00077 ATTRTYPE_WORD = 0x21,
00078
00080 ATTRTYPE_DWORD = 0x22,
00081
00083 ATTRTYPE_QWORD = 0x23,
00084
00086 ATTRTYPE_FLOAT = 0x30,
00087
00089 ATTRTYPE_DOUBLE = 0x31,
00090
00093 ATTRTYPE_STRING = 0x40
00094 };
00095
00096 private:
00098 attrtype_t atype;
00099
00101 union value_t
00102 {
00104 int _int;
00105
00107 unsigned int _uint;
00108
00110 long long _long;
00111
00113 unsigned long long _ulong;
00114
00116 float _float;
00117
00119 double _double;
00120
00122 std::string* _string;
00123 };
00124
00126 union value_t val;
00127
00128 public:
00130 explicit inline AnyScalar(attrtype_t t = ATTRTYPE_INVALID)
00131 : atype(t)
00132 {
00133 if (atype == ATTRTYPE_STRING) {
00134 val._string = new std::string;
00135 }
00136 else {
00137 val._ulong = 0;
00138 }
00139 }
00140
00141
00142
00145 inline AnyScalar(bool b)
00146 : atype(ATTRTYPE_BOOL)
00147 {
00148 val._int = b;
00149 }
00150
00151 #ifndef SWIG // This constructor confuses SWIG into calling it with
00152
00155 inline AnyScalar(char c)
00156 : atype(ATTRTYPE_CHAR)
00157 {
00158 val._int = c;
00159 }
00160 #endif
00163 inline AnyScalar(short s)
00164 : atype(ATTRTYPE_SHORT)
00165 {
00166 val._int = s;
00167 }
00170 inline AnyScalar(int i)
00171 : atype(ATTRTYPE_INTEGER)
00172 {
00173 val._int = i;
00174 }
00177 inline AnyScalar(long i)
00178 : atype(ATTRTYPE_INTEGER)
00179 {
00180 val._int = i;
00181 }
00184 inline AnyScalar(long long l)
00185 : atype(ATTRTYPE_LONG)
00186 {
00187 val._long = l;
00188 }
00191 inline AnyScalar(unsigned char c)
00192 : atype(ATTRTYPE_BYTE)
00193 {
00194 val._uint = c;
00195 }
00198 inline AnyScalar(unsigned short s)
00199 : atype(ATTRTYPE_WORD)
00200 {
00201 val._uint = s;
00202 }
00205 inline AnyScalar(unsigned int i)
00206 : atype(ATTRTYPE_DWORD)
00207 {
00208 val._uint = i;
00209 }
00212 inline AnyScalar(unsigned long i)
00213 : atype(ATTRTYPE_DWORD)
00214 {
00215 val._uint = i;
00216 }
00219 inline AnyScalar(unsigned long long l)
00220 : atype(ATTRTYPE_QWORD)
00221 {
00222 val._ulong = l;
00223 }
00226 inline AnyScalar(float f)
00227 : atype(ATTRTYPE_FLOAT)
00228 {
00229 val._float = f;
00230 }
00233 inline AnyScalar(double d)
00234 : atype(ATTRTYPE_DOUBLE)
00235 {
00236 val._double = d;
00237 }
00240 inline AnyScalar(const char *s)
00241 : atype(ATTRTYPE_STRING)
00242 {
00243 if (s == NULL)
00244 val._string = new std::string;
00245 else
00246 val._string = new std::string(s);
00247 }
00250 inline AnyScalar(const std::string &s)
00251 : atype(ATTRTYPE_STRING)
00252 {
00253 val._string = new std::string(s);
00254 }
00255
00257 inline ~AnyScalar()
00258 {
00259 if (atype == ATTRTYPE_STRING) {
00260 delete val._string;
00261 val._string = NULL;
00262 }
00263 }
00264
00267 inline AnyScalar(const AnyScalar &a)
00268 : atype(a.atype)
00269 {
00270 switch(atype)
00271 {
00272 case ATTRTYPE_INVALID:
00273 break;
00274
00275 case ATTRTYPE_BOOL:
00276 case ATTRTYPE_CHAR:
00277 case ATTRTYPE_SHORT:
00278 case ATTRTYPE_INTEGER:
00279 val._int = a.val._int;
00280 break;
00281
00282 case ATTRTYPE_BYTE:
00283 case ATTRTYPE_WORD:
00284 case ATTRTYPE_DWORD:
00285 val._uint = a.val._uint;
00286 break;
00287
00288 case ATTRTYPE_LONG:
00289 val._long = a.val._long;
00290 break;
00291
00292 case ATTRTYPE_QWORD:
00293 val._ulong = a.val._ulong;
00294 break;
00295
00296 case ATTRTYPE_FLOAT:
00297 val._float = a.val._float;
00298 break;
00299
00300 case ATTRTYPE_DOUBLE:
00301 val._double = a.val._double;
00302 break;
00303
00304 case ATTRTYPE_STRING:
00305 val._string = new std::string(*a.val._string);
00306 break;
00307 }
00308 }
00309
00312 inline AnyScalar& operator=(const AnyScalar &a)
00313 {
00314
00315 if (this == &a) return *this;
00316
00317 if (atype == ATTRTYPE_STRING) {
00318 delete val._string;
00319 val._string = NULL;
00320 }
00321
00322 atype = a.atype;
00323
00324 switch(atype)
00325 {
00326 case ATTRTYPE_INVALID:
00327 assert(0);
00328 break;
00329
00330 case ATTRTYPE_BOOL:
00331 case ATTRTYPE_CHAR:
00332 case ATTRTYPE_SHORT:
00333 case ATTRTYPE_INTEGER:
00334 val._int = a.val._int;
00335 break;
00336
00337 case ATTRTYPE_BYTE:
00338 case ATTRTYPE_WORD:
00339 case ATTRTYPE_DWORD:
00340 val._uint = a.val._uint;
00341 break;
00342
00343 case ATTRTYPE_LONG:
00344 val._long = a.val._long;
00345 break;
00346
00347 case ATTRTYPE_QWORD:
00348 val._ulong = a.val._ulong;
00349 break;
00350
00351 case ATTRTYPE_FLOAT:
00352 val._float = a.val._float;
00353 break;
00354
00355 case ATTRTYPE_DOUBLE:
00356 val._double = a.val._double;
00357 break;
00358
00359 case ATTRTYPE_STRING:
00360 val._string = new std::string(*a.val._string);
00361 break;
00362 }
00363
00364 return *this;
00365 }
00366
00369 bool operator==(const AnyScalar &a) const;
00370
00373 inline bool operator!=(const AnyScalar &a) const
00374 { return !(*this == a); }
00375
00377 inline attrtype_t getType() const
00378 {
00379 return atype;
00380 }
00381
00383 inline bool isBooleanType() const
00384 {
00385 return (atype == ATTRTYPE_BOOL);
00386 }
00387
00389 inline bool isIntegerType() const
00390 {
00391 return (atype == ATTRTYPE_BOOL ||
00392 atype == ATTRTYPE_CHAR || atype == ATTRTYPE_SHORT ||
00393 atype == ATTRTYPE_INTEGER || atype == ATTRTYPE_LONG ||
00394 atype == ATTRTYPE_BYTE || atype == ATTRTYPE_WORD ||
00395 atype == ATTRTYPE_DWORD || atype == ATTRTYPE_QWORD);
00396 }
00397
00399 inline bool isFloatingType() const
00400 {
00401 return (atype == ATTRTYPE_FLOAT || atype == ATTRTYPE_DOUBLE);
00402 }
00403
00408 bool convertType(attrtype_t t);
00409
00412 void resetType(attrtype_t t);
00413
00414
00415
00417 static bool isValidAttrtype(attrtype_t at);
00418
00421 static attrtype_t stringToType(const std::string &s)
00422 {
00423 return stringToType(s.c_str());
00424 }
00425
00428 static attrtype_t stringToType(const char *s);
00429
00431 static std::string getTypeString(attrtype_t at);
00432
00434 inline std::string getTypeString() const
00435 {
00436 return getTypeString(atype);
00437 }
00438
00439
00440
00443 inline int getTypeLength() const
00444 {
00445 return getTypeLength(atype);
00446 }
00447
00450 static int getTypeLength(attrtype_t t);
00451
00453 static bool isFixedLength(attrtype_t t)
00454 {
00455 return getTypeLength(t) >= 0;
00456 }
00457
00459 inline bool isFixedLength() const
00460 {
00461 return isFixedLength(atype);
00462 }
00463
00466 unsigned int getValueLength() const;
00467
00468
00469
00470
00471
00472
00473
00490 bool setInteger(int i);
00491
00509 bool setLong(long long l);
00510
00527 bool setDouble(double d);
00528
00552 bool setString(const std::string &s);
00553
00556 bool setStringQuoted(const std::string &s);
00557
00558
00573 AnyScalar& setAutoString(const std::string &input);
00574
00575
00576
00577
00578
00579
00580
00592 bool getBoolean() const;
00593
00605 int getInteger() const;
00606
00618 unsigned int getUnsignedInteger() const;
00619
00621 inline int getInt() const
00622 {
00623 return getInteger();
00624 }
00625
00627 inline unsigned int getUInt() const
00628 {
00629 return getUnsignedInteger();
00630 }
00631
00643 long long getLong() const;
00644
00656 unsigned long long getUnsignedLong() const;
00657
00659 unsigned long long getULong() const
00660 {
00661 return getUnsignedLong();
00662 }
00663
00674 double getDouble() const;
00675
00685 std::string getString() const;
00686
00690 std::string getStringQuoted() const;
00691
00692
00693
00704 AnyScalar operator-() const;
00705
00706
00707
00708
00709
00710
00711 #ifndef SWIG // obviously too strange for SWIG
00712 private:
00735 template <template <typename Type> class Operator, char OpName>
00736 AnyScalar binary_arith_op(const AnyScalar &b) const;
00737 #endif
00738
00739 public:
00741 inline AnyScalar operator+(const AnyScalar &b) const
00742 {
00743 return binary_arith_op<std::plus, '+'>(b);
00744 }
00745
00747 inline AnyScalar operator-(const AnyScalar &b) const
00748 {
00749 return binary_arith_op<std::minus, '-'>(b);
00750 }
00751
00753 inline AnyScalar operator*(const AnyScalar &b) const
00754 {
00755 return binary_arith_op<std::multiplies, '*'>(b);
00756 }
00757
00759 inline AnyScalar operator/(const AnyScalar &b) const
00760 {
00761 return binary_arith_op<std::divides, '/'>(b);
00762 }
00763
00765 inline AnyScalar add(const AnyScalar &b) const
00766 {
00767 return (*this + b);
00768 }
00769
00771 inline AnyScalar subtract(const AnyScalar &b) const
00772 {
00773 return (*this - b);
00774 }
00775
00777 inline AnyScalar multiply(const AnyScalar &b) const
00778 {
00779 return (*this * b);
00780 }
00781
00783 inline AnyScalar divide(const AnyScalar &b) const
00784 {
00785 return (*this / b);
00786 }
00787
00788 #ifndef SWIG // obviously too strange for SWIG
00789 private:
00815 template <template <typename Type> class Operator, int OpNum>
00816 bool binary_comp_op(const AnyScalar &b) const;
00817 #endif
00818
00819
00820
00821 public:
00823 inline bool equal_to(const AnyScalar &b) const
00824 {
00825 return binary_comp_op<std::equal_to, 0>(b);
00826 }
00827
00829 inline bool not_equal_to(const AnyScalar &b) const
00830 {
00831 return binary_comp_op<std::not_equal_to, 1>(b);
00832 }
00833
00835 inline bool less(const AnyScalar &b) const
00836 {
00837 return binary_comp_op<std::less, 2>(b);
00838 }
00839
00841 inline bool " greater-than.">greater(const AnyScalar &b) const
00842 {
00843 return binary_comp_op<std::greater, 3>(b);
00844 }
00845
00847 inline bool less_equal(const AnyScalar &b) const
00848 {
00849 return binary_comp_op<std::less_equal, 4>(b);
00850 }
00851
00853 inline bool =" greater-or-equal-than.">greater_equal(const AnyScalar &b) const
00854 {
00855 return binary_comp_op<std::greater_equal, 5>(b);
00856 }
00857 };
00858
00860 static inline std::ostream& operator<< (std::ostream &stream, const AnyScalar &as)
00861 {
00862 return stream << as.getString();
00863 }
00864
00865 }
00866
00867 #endif // VGS_AnyScalar_H