LTP GCOV extension - code coverage report
Current view: directory - libstx-exparser - AnyScalar.h
Test: STX ExpressionParser Testsuite
Date: 2007-07-17 Instrumented lines: 133
Code covered: 71.4 % Executed lines: 95

       1                 : // $Id: AnyScalar.h 59 2007-07-17 14:43:23Z tb $
       2                 : 
       3                 : /*
       4                 :  * STX Expression Parser C++ Framework v0.7
       5                 :  * Copyright (C) 2007 Timo Bingmann
       6                 :  *
       7                 :  * This library is free software; you can redistribute it and/or modify it
       8                 :  * under the terms of the GNU Lesser General Public License as published by the
       9                 :  * Free Software Foundation; either version 2.1 of the License, or (at your
      10                 :  * option) any later version.
      11                 :  *
      12                 :  * This library is distributed in the hope that it will be useful, but WITHOUT
      13                 :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14                 :  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
      15                 :  * for more details.
      16                 :  *
      17                 :  * You should have received a copy of the GNU Lesser General Public License
      18                 :  * along with this library; if not, write to the Free Software Foundation,
      19                 :  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20                 :  */
      21                 : 
      22                 : /** \file AnyScalar.h
      23                 :  * Definition of a typed scalar value class AnyScalar used by the parser to
      24                 :  * represent values.
      25                 :  */
      26                 : 
      27                 : #ifndef _STX_AnyScalar_H_
      28                 : #define _STX_AnyScalar_H_
      29                 : 
      30                 : #include <string>
      31                 : #include <stdexcept>
      32                 : #include <functional>
      33                 : #include <ostream>
      34                 : #include <assert.h>
      35                 : 
      36                 : namespace stx {
      37                 : 
      38                 : /** AnyScalar constructs objects holding a typed scalar value. It supports
      39                 :  * boolean values, integer values both signed and unsigned, floating point
      40                 :  * values and strings. The class provides operators which will compare scalars
      41                 :  * between other scalars by converting them into a common domain. Furthermore
      42                 :  * arithmetic operator will compose one or two scalars where the calculation is
      43                 :  * done in the "higher" domain. */
      44                 : 
      45                 : class AnyScalar
      46                 : {
      47                 : public:
      48                 :     /// Enumeration establishing identifiers for all supported types. All
      49                 :     /// "small" integer types are included, because the class use originally
      50                 :     /// designed for serializing large amounts of data.
      51                 :     enum attrtype_t
      52                 :     {
      53                 :         /// Flag identifier for an uninitialized object.
      54                 :         ATTRTYPE_INVALID = 0x00,
      55                 : 
      56                 :         /// A boolean type holding only true and false.
      57                 :         ATTRTYPE_BOOL = 0x01,
      58                 : 
      59                 :         /// Character type, not viewed as a letter or digit, but as 8 bit
      60                 :         /// signed integer.
      61                 :         ATTRTYPE_CHAR = 0x10,
      62                 : 
      63                 :         /// Short signed integer type, 2 bytes long.
      64                 :         ATTRTYPE_SHORT = 0x11,
      65                 : 
      66                 :         /// Medium signed integer type, 4 bytes long.
      67                 :         ATTRTYPE_INTEGER = 0x12,
      68                 : 
      69                 :         /// Long (long) signed integer type, 8 bytes long.
      70                 :         ATTRTYPE_LONG = 0x13,
      71                 : 
      72                 :         /// Byte type, not viewed as a letter or digit, but as 8 bit unsigned
      73                 :         /// integer.
      74                 :         ATTRTYPE_BYTE = 0x20,
      75                 : 
      76                 :         /// Short unsigned integer type, 2 bytes long.
      77                 :         ATTRTYPE_WORD = 0x21,
      78                 : 
      79                 :         /// Medium unsigned integer type, 4 bytes long.
      80                 :         ATTRTYPE_DWORD = 0x22,
      81                 : 
      82                 :         /// Long (long) unsigned integer type, 8 bytes long.
      83                 :         ATTRTYPE_QWORD = 0x23,
      84                 : 
      85                 :         /// Single precision floating point type, 4 bytes long.
      86                 :         ATTRTYPE_FLOAT = 0x30,
      87                 : 
      88                 :         /// Double precision floating point type, 8 bytes long.
      89                 :         ATTRTYPE_DOUBLE = 0x31,
      90                 : 
      91                 :         /// String type, variable length. Needs much extra care to handle
      92                 :         /// memory allocation.
      93                 :         ATTRTYPE_STRING = 0x40
      94                 :     };
      95                 : 
      96                 : private:
      97                 :     /// The currently set type in the union.
      98                 :     attrtype_t          atype;
      99                 : 
     100                 :     /// Union type to holding the current value of an AnyScalar.
     101                 :     union value_t
     102                 :     {
     103                 :         /// Used for ATTRTYPE_BOOL, ATTRTYPE_CHAR, ATTRTYPE_SHORT, ATTRTYPE_INTEGER
     104                 :         int                     _int;
     105                 : 
     106                 :         /// Used for ATTRTYPE_BYTE, ATTRTYPE_WORD, ATTRTYPE_DWORD
     107                 :         unsigned int            _uint;
     108                 : 
     109                 :         /// Used for ATTRTYPE_LONG
     110                 :         long long               _long;
     111                 : 
     112                 :         /// Used for ATTRTYPE_QWORD
     113                 :         unsigned long long      _ulong;
     114                 : 
     115                 :         /// Used for ATTRTYPE_FLOAT
     116                 :         float                   _float;
     117                 : 
     118                 :         /// Used for ATTRTYPE_DOUBLE
     119                 :         double                  _double;
     120                 : 
     121                 :         /// Used for ATTRTYPE_STRING, make sure it get delete'ed correctly.
     122                 :         std::string*            _string;
     123                 :     };
     124                 : 
     125                 :     /// Union holding the current value of set type.
     126                 :     union value_t       val;
     127                 :     
     128                 : public:
     129                 :     /// Create a new empty AnyScalar object of given type.
     130             248 :     explicit inline AnyScalar(attrtype_t t = ATTRTYPE_INVALID)
     131             248 :         : atype(t)
     132                 :     { 
     133             248 :         if (atype == ATTRTYPE_STRING) {
     134               7 :             val._string = new std::string;
     135                 :         }
     136                 :         else {
     137             241 :             val._ulong = 0;
     138                 :         }
     139             248 :     }
     140                 : 
     141                 :     // *** Constructors for the various types
     142                 : 
     143                 :     /// Construct a new AnyScalar object of type ATTRTYPE_BOOL and set the given
     144                 :     /// boolean value.
     145              36 :     inline AnyScalar(bool b)
     146              36 :         : atype(ATTRTYPE_BOOL)
     147                 :     {
     148              36 :         val._int = b;
     149              36 :     }
     150                 : 
     151                 : #ifndef SWIG    // This constructor confuses SWIG into calling it with
     152                 :                 // one-character strings
     153                 :     /// Construct a new AnyScalar object of type ATTRTYPE_CHAR and set the given
     154                 :     /// char value.
     155               6 :     inline AnyScalar(char c)
     156               6 :         : atype(ATTRTYPE_CHAR)
     157                 :     {
     158               6 :         val._int = c;
     159               6 :     }
     160                 : #endif
     161                 :     /// Construct a new AnyScalar object of type ATTRTYPE_SHORT and set the given
     162                 :     /// short value.
     163               3 :     inline AnyScalar(short s)
     164               3 :         : atype(ATTRTYPE_SHORT)
     165                 :     {
     166               3 :         val._int = s;
     167               3 :     }
     168                 :     /// Construct a new AnyScalar object of type ATTRTYPE_INTEGER and set the
     169                 :     /// given integer value.
     170              43 :     inline AnyScalar(int i)
     171              43 :         : atype(ATTRTYPE_INTEGER)
     172                 :     {
     173              43 :         val._int = i;
     174              43 :     }
     175                 :     /// Construct a new AnyScalar object of type ATTRTYPE_INTEGER and set the
     176                 :     /// given integer value.
     177                 :     inline AnyScalar(long i)
     178                 :         : atype(ATTRTYPE_INTEGER)
     179                 :     {
     180                 :         val._int = i;
     181                 :     }
     182                 :     /// Construct a new AnyScalar object of type ATTRTYPE_LONG and set the
     183                 :     /// given long value.
     184               0 :     inline AnyScalar(long long l)
     185               0 :         : atype(ATTRTYPE_LONG)
     186                 :     {
     187               0 :         val._long = l;
     188               0 :     }
     189                 :     /// Construct a new AnyScalar object of type ATTRTYPE_BYTE and set the given
     190                 :     /// unsigned value.
     191                 :     inline AnyScalar(unsigned char c)
     192                 :         : atype(ATTRTYPE_BYTE)
     193                 :     {
     194                 :         val._uint = c;
     195                 :     }
     196                 :     /// Construct a new AnyScalar object of type ATTRTYPE_WORD and set the given
     197                 :     /// unsigned value.
     198                 :     inline AnyScalar(unsigned short s)
     199                 :         : atype(ATTRTYPE_WORD)
     200                 :     {
     201                 :         val._uint = s;
     202                 :     }
     203                 :     /// Construct a new AnyScalar object of type ATTRTYPE_DWORD and set the given
     204                 :     /// unsigned value.
     205               0 :     inline AnyScalar(unsigned int i)
     206               0 :         : atype(ATTRTYPE_DWORD)
     207                 :     {
     208               0 :         val._uint = i;
     209               0 :     }
     210                 :     /// Construct a new AnyScalar object of type ATTRTYPE_DWORD and set the given
     211                 :     /// unsigned value.
     212                 :     inline AnyScalar(unsigned long i)
     213                 :         : atype(ATTRTYPE_DWORD)
     214                 :     {
     215                 :         val._uint = i;
     216                 :     }
     217                 :     /// Construct a new AnyScalar object of type ATTRTYPE_QWORD and set the given
     218                 :     /// unsigned value.
     219               0 :     inline AnyScalar(unsigned long long l)
     220               0 :         : atype(ATTRTYPE_QWORD)
     221                 :     {
     222               0 :         val._ulong = l;
     223               0 :     }
     224                 :     /// Construct a new AnyScalar object of type ATTRTYPE_FLOAT and set the given
     225                 :     /// floating point value.
     226               0 :     inline AnyScalar(float f)
     227               0 :         : atype(ATTRTYPE_FLOAT)
     228                 :     {
     229               0 :         val._float = f;
     230               0 :     }
     231                 :     /// Construct a new AnyScalar object of type ATTRTYPE_DOUBLE and set the
     232                 :     /// given floating point value.
     233              36 :     inline AnyScalar(double d)
     234              36 :         : atype(ATTRTYPE_DOUBLE)
     235                 :     {
     236              36 :         val._double = d;
     237              36 :     }
     238                 :     /// Construct a new AnyScalar object of type ATTRTYPE_STRING and set the
     239                 :     /// given string value.
     240               6 :     inline AnyScalar(const char *s)
     241               6 :         : atype(ATTRTYPE_STRING)
     242                 :     {
     243               6 :         if (s == NULL) 
     244               0 :             val._string = new std::string;
     245                 :         else
     246               6 :             val._string = new std::string(s);
     247               6 :     }
     248                 :     /// Construct a new AnyScalar object of type ATTRTYPE_STRING and set the
     249                 :     /// given string value.
     250               3 :     inline AnyScalar(const std::string &s)
     251               3 :         : atype(ATTRTYPE_STRING)
     252                 :     {
     253               3 :         val._string = new std::string(s);
     254               3 :     }
     255                 : 
     256                 :     /// Destroy the object: free associated string memory if necessary.
     257             539 :     inline ~AnyScalar()
     258                 :     {
     259             539 :         if (atype == ATTRTYPE_STRING) {
     260              28 :             delete val._string;
     261              28 :             val._string = NULL;
     262                 :         }
     263             539 :     }
     264                 :     
     265                 :     /// Copy-constructor to deal with enclosed strings. Transfers type and
     266                 :     /// value.
     267             158 :     inline AnyScalar(const AnyScalar &a)
     268             158 :         : atype(a.atype)
     269                 :     {
     270             158 :         switch(atype)
     271                 :         {
     272                 :         case ATTRTYPE_INVALID:
     273              68 :             break;
     274                 : 
     275                 :         case ATTRTYPE_BOOL:
     276                 :         case ATTRTYPE_CHAR:
     277                 :         case ATTRTYPE_SHORT:
     278                 :         case ATTRTYPE_INTEGER:
     279              70 :             val._int = a.val._int;
     280              70 :             break;
     281                 : 
     282                 :         case ATTRTYPE_BYTE:
     283                 :         case ATTRTYPE_WORD:
     284                 :         case ATTRTYPE_DWORD:
     285               0 :             val._uint = a.val._uint;
     286               0 :             break;
     287                 : 
     288                 :         case ATTRTYPE_LONG:
     289               0 :             val._long = a.val._long;
     290               0 :             break;
     291                 : 
     292                 :         case ATTRTYPE_QWORD:
     293               0 :             val._ulong = a.val._ulong;
     294               0 :             break;
     295                 : 
     296                 :         case ATTRTYPE_FLOAT:
     297               0 :             val._float = a.val._float;
     298               0 :             break;
     299                 : 
     300                 :         case ATTRTYPE_DOUBLE:
     301              15 :             val._double = a.val._double;
     302              15 :             break;
     303                 : 
     304                 :         case ATTRTYPE_STRING:
     305               5 :             val._string = new std::string(*a.val._string);
     306                 :             break;
     307                 :         }
     308             158 :     }
     309                 : 
     310                 :     /// Assignment operator to deal with enclosed strings. Transfers type and
     311                 :     /// value.
     312             166 :     inline AnyScalar& operator=(const AnyScalar &a)
     313                 :     {
     314                 :         // check if we are to assign ourself
     315             166 :         if (this == &a) return *this;
     316                 : 
     317             166 :         if (atype == ATTRTYPE_STRING) {
     318               1 :             delete val._string;
     319               1 :             val._string = NULL;
     320                 :         }
     321                 : 
     322             166 :         atype = a.atype;
     323                 :         
     324             166 :         switch(atype)
     325                 :         {
     326                 :         case ATTRTYPE_INVALID:
     327               0 :             assert(0);
     328                 :             break;
     329                 : 
     330                 :         case ATTRTYPE_BOOL:
     331                 :         case ATTRTYPE_CHAR:
     332                 :         case ATTRTYPE_SHORT:
     333                 :         case ATTRTYPE_INTEGER:
     334             125 :             val._int = a.val._int;
     335             125 :             break;
     336                 : 
     337                 :         case ATTRTYPE_BYTE:
     338                 :         case ATTRTYPE_WORD:
     339                 :         case ATTRTYPE_DWORD:
     340               0 :             val._uint = a.val._uint;
     341               0 :             break;
     342                 : 
     343                 :         case ATTRTYPE_LONG:
     344               0 :             val._long = a.val._long;
     345               0 :             break;
     346                 : 
     347                 :         case ATTRTYPE_QWORD:
     348               0 :             val._ulong = a.val._ulong;
     349               0 :             break;
     350                 : 
     351                 :         case ATTRTYPE_FLOAT:
     352               0 :             val._float = a.val._float;
     353               0 :             break;
     354                 : 
     355                 :         case ATTRTYPE_DOUBLE:
     356              35 :             val._double = a.val._double;
     357              35 :             break;
     358                 : 
     359                 :         case ATTRTYPE_STRING:
     360               6 :             val._string = new std::string(*a.val._string);
     361                 :             break;
     362                 :         }
     363                 : 
     364             166 :         return *this;
     365                 :     }
     366                 : 
     367                 :     /// Comparison operator. Directly compares type _and_ value. Does NOT
     368                 :     /// attempt to convert the values into a common domain.
     369                 :     bool operator==(const AnyScalar &a) const;
     370                 : 
     371                 :     /// Comparison operator: Directly compares type _and_ value. Does NOT
     372                 :     /// attempt to convert the values into a common domain.
     373               1 :     inline bool operator!=(const AnyScalar &a) const
     374               1 :     { return !(*this == a); }
     375                 : 
     376                 :     /// Return the type identifier of the object.
     377              82 :     inline attrtype_t   getType() const
     378                 :     {
     379              82 :         return atype;
     380                 :     }
     381                 : 
     382                 :     /// Returns true if this object contains a boolean value.
     383                 :     inline bool         isBooleanType() const
     384                 :     {
     385                 :         return (atype == ATTRTYPE_BOOL);
     386                 :     }
     387                 : 
     388                 :     /// Returns true if this object contains one of the integer types.
     389               0 :     inline bool         isIntegerType() const
     390                 :     {
     391                 :         return (atype == ATTRTYPE_BOOL ||
     392                 :                 atype == ATTRTYPE_CHAR || atype == ATTRTYPE_SHORT ||
     393                 :                 atype == ATTRTYPE_INTEGER || atype == ATTRTYPE_LONG ||
     394                 :                 atype == ATTRTYPE_BYTE || atype == ATTRTYPE_WORD ||
     395               0 :                 atype == ATTRTYPE_DWORD || atype == ATTRTYPE_QWORD);
     396                 :     }
     397                 : 
     398                 :     /// Returns true if this object contains one of the floating point types.
     399               0 :     inline bool         isFloatingType() const
     400                 :     {
     401               0 :         return (atype == ATTRTYPE_FLOAT || atype == ATTRTYPE_DOUBLE);
     402                 :     }
     403                 : 
     404                 :     /// Attempts to convert the current type/value into the given type. Returns
     405                 :     /// false if the value could not be represented in the new type, the new
     406                 :     /// type is set nonetheless. See the getXXX below on how the new value is
     407                 :     /// computed from the old type.
     408                 :     bool        convertType(attrtype_t t);
     409                 : 
     410                 :     /// Changes the current type and resets the contents without attempting to
     411                 :     /// convert the enclosed value.
     412                 :     void        resetType(attrtype_t t);
     413                 : 
     414                 :     // *** attrtype_t to string and string to attrtype_t functions
     415                 : 
     416                 :     /// Returns true if the attrtype_t is a valid type identifier.
     417                 :     static bool isValidAttrtype(attrtype_t at);
     418                 :     
     419                 :     /// Returns the attrtype identifier of a string, throws ConversionException
     420                 :     /// if s does not specify a valid type name.
     421               4 :     static attrtype_t stringToType(const std::string &s)
     422                 :     {
     423               4 :         return stringToType(s.c_str());
     424                 :     }
     425                 : 
     426                 :     /// Returns the attrtype identifier a string, throws ConversionException if
     427                 :     /// it does not specify a valid type name.
     428                 :     static attrtype_t stringToType(const char *s);
     429                 : 
     430                 :     /// Returns a const char* for each attrtype_t.
     431                 :     static std::string getTypeString(attrtype_t at);
     432                 : 
     433                 :     /// Returns a string for this AnyScalar's type.
     434               8 :     inline std::string getTypeString() const
     435                 :     {
     436               8 :         return getTypeString(atype);
     437                 :     }
     438                 : 
     439                 :     // *** Type and Value Length Functions
     440                 :     
     441                 :     /// Return the storage length of the type in bytes. Beware that
     442                 :     /// getTypeLength(bool) == 0.
     443               4 :     inline int  getTypeLength() const
     444                 :     {
     445               4 :         return getTypeLength(atype);
     446                 :     }
     447                 : 
     448                 :     /// Return the storage length of the type in bytes. Beware that
     449                 :     /// getTypeLength(bool) == 0.
     450                 :     static int  getTypeLength(attrtype_t t);
     451                 : 
     452                 :     /// Boolean check if this type is of fixed length.
     453                 :     static bool isFixedLength(attrtype_t t)
     454                 :     {
     455                 :         return getTypeLength(t) >= 0;
     456                 :     }
     457                 : 
     458                 :     /// Boolean check if this type is of fixed length.
     459                 :     inline bool isFixedLength() const
     460                 :     {
     461                 :         return isFixedLength(atype);
     462                 :     }
     463                 : 
     464                 :     /// Return the storage length of this value (mark the different to
     465                 :     /// getTypeLength())
     466                 :     unsigned int getValueLength() const;
     467                 : 
     468                 :     // *** Setters
     469                 : 
     470                 :     // Sets the value, converting the input to the currently set type if
     471                 :     // necessary. Returns false if the input could not be converted into the
     472                 :     // right type.
     473                 : 
     474                 :     /** Change the value of the current object to i. Converting the integer
     475                 :      * to this object's type if necessary.
     476                 :      *
     477                 :      * - boolean: the integer i is cut to 0 or 1.
     478                 :      * - char: cut to -128..127 returns false if out of range.
     479                 :      * - short: cut to -32768..32767 return false if out of range.
     480                 :      * - byte: cut to 0..255 returns false if out of range.
     481                 :      * - word: cut to 0..65536 returns false if out of range.
     482                 :      * - int: no conversion.
     483                 :      * - dword: cut to 0..4294967295 return false if it was negative.
     484                 :      * - long: no cutting necessary.
     485                 :      * - qword: cut to positive number.
     486                 :      * - float: integer stored as floating point
     487                 :      * - double: integer stored as floating point
     488                 :      * - string: integer is stringified.
     489                 :      */ 
     490                 :     bool                setInteger(int i);
     491                 : 
     492                 :     /** Change the value of the current object to l. Converting the long
     493                 :      * long integer to this object's type if necessary. If the long long does
     494                 :      * not fully fit into the current type, then this function returns false.
     495                 :      *
     496                 :      * - boolean: the long i is cut to 0 or 1.
     497                 :      * - char: cut to -128..127 returns false if out of range.
     498                 :      * - short: cut to -32768..32767 return false if out of range.
     499                 :      * - int: cut to -2147483646..2147483647 returns false if out of range.
     500                 :      * - byte: cut to 0..255 returns false if out of range.
     501                 :      * - word: cut to 0..65536 returns false if out of range.
     502                 :      * - dword: cut to 0..4294967295 return false if out of range.
     503                 :      * - long: no conversion
     504                 :      * - qword: cut to positive number.
     505                 :      * - float: long stored as floating point
     506                 :      * - double: long stored as floating point
     507                 :      * - string: long is stringified.
     508                 :      */
     509                 :     bool                setLong(long long l);
     510                 : 
     511                 :     /** Change the value of the current object to d. Converting the floating
     512                 :      * point to this object's type if necessary.
     513                 :      *
     514                 :      * - boolean: [0:0.5] is false, (0.5:1] is true. else true and return false.
     515                 :      * - char: truncated to integer ranged -128..127 returns false if out of range.
     516                 :      * - short: truncated to integer ranged -32768..32767 return false if out of range.
     517                 :      * - int: truncated to integer ranged -2147483646..2147483647 returns false if out of range.
     518                 :      * - byte: truncated to integer ranged 0..255 returns false if out of range.
     519                 :      * - word: truncated to integer ranged 0..65536 returns false if out of range.
     520                 :      * - dword: truncated to integer ranged 0..4294967295 return false if out of range.
     521                 :      * - long: truncated to integer ranged -9223372036854775806..9223372036854775807
     522                 :      * - qword: truncated to integer ranged 0..18446744073709551615
     523                 :      * - float: truncated to single-precision
     524                 :      * - double: no conversion
     525                 :      * - string: double is stringified.
     526                 :      */
     527                 :     bool                setDouble(double d);
     528                 : 
     529                 :     /** Change the value of the current object to s. Converting the string
     530                 :      * to this object's type if necessary. If this string cannot be converted
     531                 :      * to say an integer, then this function returns false.
     532                 :      *
     533                 :      * - boolean: "0", "f", "false", "n" and "no" are false,
     534                 :      *            "1", "t", "true", "y" and "yes" are true. else returns false.
     535                 :      * - char: string read using strtol and truncated to -128..127
     536                 :                returns false if out of range or unparseable.
     537                 :      * - short: string read using strtol and truncated to -32768..32767
     538                 :                 returns false if out of range or unparseable.
     539                 :      * - int: string read using strtol returns false if out of range or unparseable.
     540                 :      * - long: string read using strtoll returns false if out of range or unparseable.
     541                 :      * - byte: string read using strtoul and truncated to 0..255
     542                 :                returns false if out of range or unparseable.
     543                 :      * - word: string read using strtoul and truncated to 0..65535
     544                 :                returns false if out of range or unparseable.
     545                 :      * - dword: string read using strtoul returns false if out of range or unparseable.
     546                 :      * - qword: string read using strtoull returns false if out of range or unparseable.
     547                 :      * - float: string read using strtod and converted to single-precision
     548                 :                 returns false if unparseable.
     549                 :      * - double: string read using strtod returns false if unparseable.
     550                 :      * - string: no conversion
     551                 :      */
     552                 :     bool                setString(const std::string &s);
     553                 :     
     554                 :     /// Change the value of the current object to s. This string s must be
     555                 :     /// quoted: "str". This function resolves escape sequences like \n.
     556                 :     bool                setStringQuoted(const std::string &s);
     557                 : 
     558                 : 
     559                 :     /** Change the type _and_ value of the current object to s. The current
     560                 :      * type is set if the given string can be converted to an integer or a
     561                 :      * floating point number. This was required because e.g. the usual input
     562                 :      * from files or perl are all untyped strings. The following input
     563                 :      * conversions are tested and yield the given types:
     564                 :      *
     565                 :      * - boolean: no boolean strings are matched!
     566                 :      * - int: input was readable by strtoll and is small enough.
     567                 :      * - long: input was readable by strtoll
     568                 :      * - double: input was readble by strtod
     569                 :      * - string: all above failed.
     570                 :      *
     571                 :      * @return reference to this for chaining.
     572                 :      */
     573                 :     AnyScalar&              setAutoString(const std::string &input);
     574                 : 
     575                 :     // *** Getters
     576                 : 
     577                 :     // Return the enclosed value in different types, converting if
     578                 :     // necessary. If the enclosed value cannot be converted these functions
     579                 :     // throw a ConversionError exception.
     580                 : 
     581                 :     /** Return the value converted to a boolean. If the enclosed value could
     582                 :      * not be converted this function throws a ConversionException.
     583                 :      *
     584                 :      * - boolean: no conversion
     585                 :      * - char/short/int/long: test integer != 0
     586                 :      * - byte/word/dword/qword: test integer != 0
     587                 :      * - float/double: test float != 0.0
     588                 :      * - string: "0", "f", "false", "n", "no" are false,
     589                 :      *           "1", "t", "true", "y", "yes" are true
     590                 :      *           other strings throw ConversionException.
     591                 :      */
     592                 :     bool                getBoolean() const;
     593                 : 
     594                 :     /** Return the value converted to an integer. If the enclosed value could
     595                 :      * not be converted this function throws a ConversionException.
     596                 :      *
     597                 :      * - boolean: returns 0 or 1.
     598                 :      * - char/short/int: return the integer
     599                 :      * - byte/word/dword: return the integer (possibly as a negative number)
     600                 :      * - long: cut to -2147483646..2147483647.
     601                 :      * - qword: cut to 0..4294967295
     602                 :      * - float/double: machine-conversion floating point to integer
     603                 :      * - string: Attempt to strtol the string, throws ConversionException if this fails.
     604                 :      */
     605                 :     int                 getInteger() const;
     606                 : 
     607                 :     /** Return the value converted to an unsigned integer. If the enclosed
     608                 :      * value could not be converted this function throws a ConversionException.
     609                 :      *
     610                 :      * - boolean: returns 0 or 1.
     611                 :      * - char/short/int: return the integer (possibly representing a negative number as positive)
     612                 :      * - byte/word/dword: return the unsigned integer
     613                 :      * - long: cut to 0..4294967295 (also misrepresenting because of machine-conversion)
     614                 :      * - qword: cut to 0..4294967295
     615                 :      * - float/double: machine-conversion floating point to unsigned integer.
     616                 :      * - string: Attempt to strtoul the string, throws ConversionException if this fails.
     617                 :      */
     618                 :     unsigned int        getUnsignedInteger() const;
     619                 : 
     620                 :     /// Alias for getInteger()
     621                 :     inline int          getInt() const
     622                 :     {
     623                 :         return getInteger();
     624                 :     }
     625                 : 
     626                 :     /// Alias for getUnsignedInteger()
     627                 :     inline unsigned int getUInt() const
     628                 :     {
     629                 :         return getUnsignedInteger();
     630                 :     }
     631                 : 
     632                 :     /** Return the value converted to a long integer. If the enclosed value
     633                 :      * could not be converted this function throws a ConversionException.
     634                 :      *
     635                 :      * - boolean: returns 0 or 1.
     636                 :      * - char/short/int: return the integer (possibly representing a negative number as positive)
     637                 :      * - byte/word/dword: return the unsigned integer
     638                 :      * - long: no conversion
     639                 :      * - qword: return the integer (possibly converting a large long to a negative)
     640                 :      * - float/double: machine-conversion floating point to long long.
     641                 :      * - string: Attempt to strtoll the string, throws ConversionException if this fails.
     642                 :      */
     643                 :     long long           getLong() const;
     644                 : 
     645                 :     /** Return the value converted to an unsigned long integer. If the enclosed
     646                 :      * value could not be converted this function throws a ConversionException.
     647                 :      *
     648                 :      * - boolean: returns 0 or 1.
     649                 :      * - char/short/int: return the integer (possibly representing a negative number as positive)
     650                 :      * - byte/word/dword: return the unsigned integer
     651                 :      * - long: return the long (possibly interpreting a negative long as a large positive)
     652                 :      * - qword: no conversion
     653                 :      * - float/double: machine-conversion floating point to unsigned long long.
     654                 :      * - string: Attempt to strtoull the string, throws ConversionException if this fails.
     655                 :      */
     656                 :     unsigned long long  getUnsignedLong() const;
     657                 : 
     658                 :     /// Alias for getUnsignedLong()
     659                 :     unsigned long long  getULong() const
     660                 :     {
     661                 :         return getUnsignedLong();
     662                 :     }
     663                 : 
     664                 :     /** Return the value converted to a double. If the enclosed value could not
     665                 :      * be converted this function throws a ConversionException.
     666                 :      *
     667                 :      * - boolean: returns 0 or 1.0.
     668                 :      * - char/short/int/long: return the integer as a float
     669                 :      * - byte/word/dword/qword: return the unsigned integer as a float
     670                 :      * - float: cast to double.
     671                 :      * - double: no conversion
     672                 :      * - string: Attempt to strtod the string, throws ConversionException if this fails.
     673                 :      */
     674                 :     double              getDouble() const;
     675                 : 
     676                 :     /** Return the value converted to a string. This function never throws
     677                 :      * ConversionException.
     678                 :      *
     679                 :      * - boolean: returns "false" or "true"
     680                 :      * - char/short/int/long: return the integer as a string using boost::lexical_cast
     681                 :      * - byte/word/dword/qword: return the unsigned integer as a string using boost::lexical_cast
     682                 :      * - float/double: return float as a string using boost::lexical_cast
     683                 :      * - string: return the string.
     684                 :      */
     685                 :     std::string         getString() const;
     686                 : 
     687                 :     /** Return the value converted to a quoted string. This function never
     688                 :      * throws ConversionException. It calls getString() and adds " and escape
     689                 :      * sequences. */
     690                 :     std::string         getStringQuoted() const;
     691                 :     
     692                 :     // *** Unary Operators
     693                 :     
     694                 :     /** Unary prefix - operator. Attempts to convert the AnyScalar to a numeric
     695                 :      * value.
     696                 :      *
     697                 :      * - bool: invert the boolean value
     698                 :      * - char/short/int/long: switch sign
     699                 :      * - byte/word/dword/qword: negated the number even tho it doesn't make sense.
     700                 :      * - float/double: switch sign
     701                 :      * - string: attempt to convert the string to a double and negate it!
     702                 :      *           May throw a ConversionException
     703                 :      */
     704                 :     AnyScalar           operator-() const;
     705                 : 
     706                 :     // *** Binary Operators
     707                 : 
     708                 :     // These will convert the two operands to the largest common type of the
     709                 :     // same field.
     710                 : 
     711                 : #ifndef SWIG    // obviously too strange for SWIG
     712                 : private:
     713                 :     /** Binary arithmetic template operator. Converts the two AnyScalars into the
     714                 :      * largest type of their common field. If a string cannot be converted to a
     715                 :      * numeric of the same field as the other operand a ConversionException is
     716                 :      * thrown.
     717                 :      
     718                 :      * Conversion chart: * signifies the operator
     719                 :      
     720                 :      - bool * (any): ConversionException. Don't consider boolean as the field F_2.
     721                 :      - char|short|int * char|short|int: return AnyScalar is an integer.
     722                 :      - byte|word|dword * char|short|int: returned AnyScalar is a signed integer.
     723                 :      - byte|word|dword * byte|word|dword: returned AnyScalar is an unsigned integer.
     724                 :      - long * char|short|int|long|byte|word|dword|qword: returned AnyScalar is a signed long (long).
     725                 :      - qword * char|short|int|long: : returned AnyScalar is a signed long (long).
     726                 :      - qword * byte|word|dword|qword: : returned AnyScalar is an unsigned long (long).
     727                 :      - float|double * char|short|int|long|byte|word|dword|qword: calculate as floating point number
     728                 :      - string * char|short|int: convert string to integer, calculate as signed integer.
     729                 :      - string * byte|word|dword: convert string to unsigned integer, calculate as unsigned integer.
     730                 :      - string * long: convert string to long integer, calculate as long.
     731                 :      - string * qword: convert string to unsigned long integer, calculate as unsigned long.
     732                 :      - string * float|double: convert string to floating point, calculate as floating point.
     733                 :      - string * string: only valid for "+" operator as string concatenation.
     734                 :     */
     735                 :     template <template <typename Type> class Operator, char OpName>
     736              25 :     AnyScalar           binary_arith_op(const AnyScalar &b) const;
     737                 : #endif
     738                 :     
     739                 : public:
     740                 :     /// Instantiation of binary_arith_op for "+" plus.
     741              18 :     inline AnyScalar    operator+(const AnyScalar &b) const
     742                 :     {
     743              18 :         return binary_arith_op<std::plus, '+'>(b);
     744                 :     }
     745                 : 
     746                 :     /// Instantiation of binary_arith_op for "-" minus.
     747               1 :     inline AnyScalar    operator-(const AnyScalar &b) const
     748                 :     {
     749               1 :         return binary_arith_op<std::minus, '-'>(b);
     750                 :     }
     751                 : 
     752                 :     /// Instantiation of binary_arith_op for "*" multiplication.
     753               5 :     inline AnyScalar    operator*(const AnyScalar &b) const
     754                 :     {
     755               5 :         return binary_arith_op<std::multiplies, '*'>(b);
     756                 :     }
     757                 : 
     758                 :     /// Instantiation of binary_arith_op for "/" division.
     759               1 :     inline AnyScalar    operator/(const AnyScalar &b) const
     760                 :     {
     761               1 :         return binary_arith_op<std::divides, '/'>(b);
     762                 :     }
     763                 : 
     764                 :     /// Alias for operator+ in script languages
     765                 :     inline AnyScalar    add(const AnyScalar &b) const
     766                 :     {
     767                 :         return (*this + b);
     768                 :     }
     769                 : 
     770                 :     /// Alias for operator- in script languages
     771                 :     inline AnyScalar    subtract(const AnyScalar &b) const
     772                 :     {
     773                 :         return (*this - b);
     774                 :     }
     775                 : 
     776                 :     /// Alias for operator* in script languages
     777                 :     inline AnyScalar    multiply(const AnyScalar &b) const
     778                 :     {
     779                 :         return (*this * b);
     780                 :     }
     781                 : 
     782                 :     /// Alias for operator/ in script languages
     783                 :     inline AnyScalar    divide(const AnyScalar &b) const
     784                 :     {
     785                 :         return (*this / b);
     786                 :     }
     787                 : 
     788                 : #ifndef SWIG    // obviously too strange for SWIG
     789                 : private:
     790                 :     /** Binary comparison template operator. Converts the two AnyScalars into the
     791                 :      * largest type of their common field. If a string cannot be converted to a
     792                 :      * numeric of the same field as the other operand a ConversionException is
     793                 :      * thrown. Operator is the STL operator class. OpNum is an identifier for
     794                 :      * the operator name string within the template.
     795                 : 
     796                 :      * Conversion chart: * signifies the operator
     797                 :      
     798                 :      - bool * bool: usual comparison
     799                 :      - bool * (any): ConversionException. Don't consider boolean as the field F_2.
     800                 : 
     801                 :      - char|short|int * char|short|int: compare as signed integers.
     802                 :      - byte|word|dword * char|short|int: compare as signed integers.
     803                 :      - byte|word|dword * byte|word|dword: compare as unsigned integers.
     804                 :      - long * char|short|int|long|byte|word|dword|qword: compare as signed long integer
     805                 :      - qword * char|short|int|long: : compare as signed long integer
     806                 :      - qword * byte|word|dword|qword: : compare an unsigned long (long).
     807                 :      - float|double * char|short|int|long|byte|word|dword|qword: compare as floating point numbers
     808                 :      - string * char|short|int: convert string to integer, compare as signed integer.
     809                 :      - string * byte|word|dword: convert string to unsigned integer, compare as unsigned integer.
     810                 :      - string * long: convert string to long integer, compare as long.
     811                 :      - string * qword: convert string to unsigned long integer, compare as unsigned long.
     812                 :      - string * float|double: convert string to floating point, compare as floating point.
     813                 :      - string * string: usual string comparison operators.
     814                 :     */
     815                 :     template <template <typename Type> class Operator, int OpNum>
     816              15 :     bool                binary_comp_op(const AnyScalar &b) const;
     817                 : #endif
     818                 : 
     819                 :     // *** Don't use the operators themselves, because operator== is defined
     820                 :     // *** differently above.
     821                 : public:
     822                 :     /// Instantiation of binary_comp_op for "==" equality.
     823               5 :     inline bool         equal_to(const AnyScalar &b) const
     824                 :     {
     825               5 :         return binary_comp_op<std::equal_to, 0>(b);
     826                 :     }
     827                 : 
     828                 :     /// Instantiation of binary_comp_op for "!=" inequality.
     829               1 :     inline bool         not_equal_to(const AnyScalar &b) const
     830                 :     {
     831               1 :         return binary_comp_op<std::not_equal_to, 1>(b);
     832                 :     }
     833                 : 
     834                 :     /// Instantiation of binary_comp_op for "<" less-than.
     835               1 :     inline bool         less(const AnyScalar &b) const
     836                 :     {
     837               1 :         return binary_comp_op<std::less, 2>(b);
     838                 :     }
     839                 : 
     840                 :     /// Instantiation of binary_comp_op for ">" greater-than.
     841               2 :     inline bool         greater(const AnyScalar &b) const
     842                 :     {
     843               2 :         return binary_comp_op<std::greater, 3>(b);
     844                 :     }
     845                 : 
     846                 :     /// Instantiation of binary_comp_op for "<=" less-or-equal-than.
     847               3 :     inline bool         less_equal(const AnyScalar &b) const
     848                 :     {
     849               3 :         return binary_comp_op<std::less_equal, 4>(b);
     850                 :     }
     851                 : 
     852                 :     /// Instantiation of binary_comp_op for ">=" greater-or-equal-than.
     853               3 :     inline bool         greater_equal(const AnyScalar &b) const
     854                 :     {
     855               3 :         return binary_comp_op<std::greater_equal, 5>(b);
     856                 :     }
     857                 : };
     858                 : 
     859                 : /// Make AnyScalar outputtable to ostream
     860                 : static inline std::ostream& operator<< (std::ostream &stream, const AnyScalar &as)
     861                 : {
     862                 :     return stream << as.getString();
     863                 : }
     864                 : 
     865                 : } // namespace stx
     866                 : 
     867                 : #endif // VGS_AnyScalar_H

Generated by: LTP GCOV extension version 1.4