libstx-exparser/AnyScalar.h

Go to the documentation of this file.
00001 // $Id: AnyScalar.h 59 2007-07-17 14:43:23Z tb $
00002 
00003 /*
00004  * STX Expression Parser C++ Framework v0.7
00005  * Copyright (C) 2007 Timo Bingmann
00006  *
00007  * This library is free software; you can redistribute it and/or modify it
00008  * under the terms of the GNU Lesser General Public License as published by the
00009  * Free Software Foundation; either version 2.1 of the License, or (at your
00010  * option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
00015  * for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public License
00018  * along with this library; if not, write to the Free Software Foundation,
00019  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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     // *** Constructors for the various types
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                 // one-character strings
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         // check if we are to assign ourself
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     // *** attrtype_t to string and string to attrtype_t functions
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     // *** Type and Value Length Functions
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     // *** Setters
00469 
00470     // Sets the value, converting the input to the currently set type if
00471     // necessary. Returns false if the input could not be converted into the
00472     // right type.
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     // *** Getters
00576 
00577     // Return the enclosed value in different types, converting if
00578     // necessary. If the enclosed value cannot be converted these functions
00579     // throw a ConversionError exception.
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     // *** Unary Operators
00693     
00704     AnyScalar           operator-() const;
00705 
00706     // *** Binary Operators
00707 
00708     // These will convert the two operands to the largest common type of the
00709     // same field.
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     // *** Don't use the operators themselves, because operator== is defined
00820     // *** differently above.
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 } // namespace stx
00866 
00867 #endif // VGS_AnyScalar_H

Generated on Tue Jul 17 16:51:58 2007 for STX Expression Parser by  doxygen 1.5.2