LTP GCOV extension - code coverage report
Current view: directory - libstx-exparser - AnyScalar.cc
Test: STX ExpressionParser Testsuite
Date: 2007-07-17 Instrumented lines: 742
Code covered: 32.2 % Executed lines: 239

       1                 : // $Id: AnyScalar.cc 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.cc
      23                 :  * Implementation of the typed scalar value class AnyScalar used by the parser
      24                 :  * to represent values.
      25                 :  */
      26                 : 
      27                 : #include "AnyScalar.h"
      28                 : #include "ExpressionParser.h"
      29                 : 
      30                 : #include <stdlib.h>
      31                 : #include <functional>
      32                 : #include <algorithm>
      33                 : 
      34                 : #include <boost/lexical_cast.hpp>
      35                 : 
      36                 : namespace stx {
      37                 : 
      38              23 : bool AnyScalar::operator==(const AnyScalar &a) const
      39                 : {
      40              23 :     if (atype != a.atype) return false;
      41                 : 
      42              22 :     switch(atype)
      43                 :     {
      44                 :     case ATTRTYPE_INVALID:
      45               0 :         assert(0);
      46                 :         return false;
      47                 : 
      48                 :     case ATTRTYPE_BOOL:
      49                 :     case ATTRTYPE_CHAR:
      50                 :     case ATTRTYPE_SHORT:
      51                 :     case ATTRTYPE_INTEGER:
      52              14 :         return (val._int == a.val._int);
      53                 : 
      54                 :     case ATTRTYPE_BYTE:
      55                 :     case ATTRTYPE_WORD:
      56                 :     case ATTRTYPE_DWORD:
      57               0 :         return (val._uint == a.val._uint);
      58                 : 
      59                 :     case ATTRTYPE_LONG:
      60               0 :         return (val._long == a.val._long);
      61                 : 
      62                 :     case ATTRTYPE_QWORD:
      63               0 :         return (val._ulong == a.val._ulong);
      64                 : 
      65                 :     case ATTRTYPE_FLOAT:
      66               0 :         return (val._float == a.val._float);
      67                 : 
      68                 :     case ATTRTYPE_DOUBLE:
      69               4 :         return (val._double == a.val._double);
      70                 : 
      71                 :     case ATTRTYPE_STRING:
      72               4 :         assert(val._string && a.val._string);
      73               4 :         return (*val._string == *a.val._string);
      74                 :     }
      75                 : 
      76               0 :     assert(0);
      77                 :     return false;
      78                 : }
      79                 : 
      80               6 : AnyScalar::attrtype_t AnyScalar::stringToType(const char* s)
      81                 : {
      82               6 :     std::string str = s;
      83              12 :     std::transform(str.begin(), str.end(), str.begin(), tolower);
      84                 : 
      85                 :     // Stupid method, but maybe faster than using a biggy std::map with a
      86                 :     // case-insensitive equality.
      87                 : 
      88               6 :     if (str == "bool")
      89               1 :         return ATTRTYPE_BOOL;
      90                 : 
      91               5 :     if (str == "char")
      92               1 :         return ATTRTYPE_CHAR;
      93               4 :     if (str == "short")
      94               0 :         return ATTRTYPE_SHORT;
      95               4 :     if (str == "integer" || str == "int")
      96               4 :         return ATTRTYPE_INTEGER;
      97               0 :     if (str == "long")
      98               0 :         return ATTRTYPE_LONG;
      99                 : 
     100               0 :     if (str == "byte")
     101               0 :         return ATTRTYPE_BYTE;
     102               0 :     if (str == "word")
     103               0 :         return ATTRTYPE_WORD;
     104               0 :     if (str == "dword")
     105               0 :         return ATTRTYPE_DWORD;
     106               0 :     if (str == "qword")
     107               0 :         return ATTRTYPE_QWORD;
     108                 :     
     109               0 :     if (str == "float")
     110               0 :         return ATTRTYPE_FLOAT;
     111               0 :     if (str == "double")
     112               0 :         return ATTRTYPE_DOUBLE;
     113                 : 
     114               0 :     if (str == "string")
     115               0 :         return ATTRTYPE_STRING;
     116                 : 
     117               0 :     throw(ConversionException("Invalid type name."));
     118                 : }
     119                 : 
     120               0 : bool AnyScalar::isValidAttrtype(attrtype_t at)
     121                 : {
     122               0 :     switch(at)
     123                 :     {
     124                 :     default:
     125                 :     case ATTRTYPE_INVALID:
     126               0 :         return false;
     127                 : 
     128                 :     case ATTRTYPE_BOOL:
     129                 :     case ATTRTYPE_CHAR:
     130                 :     case ATTRTYPE_SHORT:
     131                 :     case ATTRTYPE_INTEGER:
     132                 :     case ATTRTYPE_LONG:
     133                 :     case ATTRTYPE_BYTE:
     134                 :     case ATTRTYPE_WORD:
     135                 :     case ATTRTYPE_DWORD:
     136                 :     case ATTRTYPE_QWORD:
     137                 :     case ATTRTYPE_FLOAT:
     138                 :     case ATTRTYPE_DOUBLE:
     139                 :     case ATTRTYPE_STRING:
     140               0 :         return true;
     141                 :     }
     142                 : }
     143                 : 
     144              10 : std::string AnyScalar::getTypeString(attrtype_t at)
     145                 : {
     146              10 :     switch(at)
     147                 :     {
     148               0 :     case ATTRTYPE_INVALID:      return "invalid";
     149               1 :     case ATTRTYPE_BOOL:         return "bool";
     150               1 :     case ATTRTYPE_CHAR:         return "char";
     151               1 :     case ATTRTYPE_SHORT:        return "short";
     152               4 :     case ATTRTYPE_INTEGER:      return "integer";
     153               1 :     case ATTRTYPE_LONG:         return "long";
     154               0 :     case ATTRTYPE_BYTE:         return "byte";
     155               0 :     case ATTRTYPE_WORD:         return "word";
     156               0 :     case ATTRTYPE_DWORD:        return "dword";
     157               0 :     case ATTRTYPE_QWORD:        return "qword";
     158               0 :     case ATTRTYPE_FLOAT:        return "float";
     159               1 :     case ATTRTYPE_DOUBLE:       return "double";
     160               1 :     case ATTRTYPE_STRING:       return "string";
     161                 :     }
     162               0 :     return "unknown";
     163                 : }
     164                 : 
     165               4 : int AnyScalar::getTypeLength(attrtype_t t)
     166                 : {
     167               4 :     switch(t)
     168                 :     {
     169                 :     case ATTRTYPE_INVALID:
     170               0 :         assert(0);
     171                 :         return 0;
     172                 : 
     173                 :     case ATTRTYPE_BOOL:
     174                 :         // weird value. beware!
     175               1 :         return 0;
     176                 : 
     177                 :     case ATTRTYPE_CHAR:
     178               1 :         return sizeof(char);
     179                 : 
     180                 :     case ATTRTYPE_BYTE:
     181               0 :         return sizeof(unsigned char);
     182                 : 
     183                 :     case ATTRTYPE_SHORT:
     184               1 :         return sizeof(short);
     185                 : 
     186                 :     case ATTRTYPE_WORD:
     187               0 :         return sizeof(unsigned short);
     188                 : 
     189                 :     case ATTRTYPE_INTEGER:
     190               1 :         return sizeof(int);
     191                 : 
     192                 :     case ATTRTYPE_DWORD:
     193               0 :         return sizeof(unsigned int);
     194                 : 
     195                 :     case ATTRTYPE_LONG:
     196               0 :         return sizeof(long long);
     197                 : 
     198                 :     case ATTRTYPE_QWORD:
     199               0 :         return sizeof(unsigned long long);
     200                 : 
     201                 :     case ATTRTYPE_FLOAT:
     202               0 :         return sizeof(float);
     203                 : 
     204                 :     case ATTRTYPE_DOUBLE:
     205               0 :         return sizeof(double);
     206                 : 
     207                 :     case ATTRTYPE_STRING:
     208               0 :         return -1;
     209                 : 
     210                 :     }
     211               0 :     assert(0);
     212                 :     return -1;
     213                 : }
     214                 : 
     215               4 : unsigned int AnyScalar::getValueLength() const
     216                 : {
     217               4 :     switch(atype)
     218                 :     {
     219                 :     case ATTRTYPE_INVALID:
     220               0 :         assert(0);
     221                 :         return 0;
     222                 : 
     223                 :     case ATTRTYPE_BOOL:
     224                 :         // weird value. beware!
     225               1 :         return 0;
     226                 : 
     227                 :     case ATTRTYPE_CHAR:
     228               1 :         return sizeof(char);
     229                 : 
     230                 :     case ATTRTYPE_BYTE:
     231               0 :         return sizeof(unsigned char);
     232                 : 
     233                 :     case ATTRTYPE_SHORT:
     234               1 :         return sizeof(short);
     235                 : 
     236                 :     case ATTRTYPE_WORD:
     237               0 :         return sizeof(unsigned short);
     238                 : 
     239                 :     case ATTRTYPE_INTEGER:
     240               1 :         return sizeof(int);
     241                 : 
     242                 :     case ATTRTYPE_DWORD:
     243               0 :         return sizeof(unsigned int);
     244                 : 
     245                 :     case ATTRTYPE_LONG:
     246               0 :         return sizeof(long long);
     247                 : 
     248                 :     case ATTRTYPE_QWORD:
     249               0 :         return sizeof(unsigned long long);
     250                 : 
     251                 :     case ATTRTYPE_FLOAT:
     252               0 :         return sizeof(float);
     253                 : 
     254                 :     case ATTRTYPE_DOUBLE:
     255               0 :         return sizeof(double);
     256                 : 
     257                 :     case ATTRTYPE_STRING:
     258               0 :         assert(val._string);
     259               0 :         return sizeof(unsigned char) + static_cast<unsigned int>(val._string->size());
     260                 :     }
     261                 : 
     262               0 :     assert(0);
     263                 :     return 0;
     264                 : }
     265                 : 
     266              85 : bool AnyScalar::setInteger(int i)
     267                 : {
     268              85 :     switch(atype)
     269                 :     {
     270                 :     case ATTRTYPE_INVALID:
     271               0 :         assert(0);
     272                 :         return false;
     273                 : 
     274                 :     case ATTRTYPE_BOOL:
     275               2 :         val._int = (i != 0) ? 1 : 0;
     276               2 :         return true;
     277                 : 
     278                 :     case ATTRTYPE_CHAR:
     279               5 :         if (SCHAR_MIN <= i && i <= SCHAR_MAX) {
     280               4 :             val._int = i;
     281               4 :             return true;
     282                 :         }
     283               1 :         if (SCHAR_MIN > i) val._int = SCHAR_MIN;
     284               1 :         if (i > SCHAR_MAX) val._int = SCHAR_MAX;
     285               1 :         return false;
     286                 : 
     287                 :     case ATTRTYPE_BYTE:
     288               0 :         if (i <= UCHAR_MAX) {
     289               0 :             val._uint = static_cast<unsigned char>(i);
     290               0 :             return true;
     291                 :         }
     292               0 :         if (0 > i) val._uint = 0;
     293               0 :         if (i > UCHAR_MAX) val._uint = UCHAR_MAX;
     294               0 :         return false;
     295                 : 
     296                 :     case ATTRTYPE_SHORT:
     297               5 :         if (SHRT_MIN <= i && i <= SHRT_MAX) {
     298               4 :             val._int = i;
     299               4 :             return true;
     300                 :         }
     301               1 :         if (SHRT_MIN > i) val._int = SHRT_MIN;
     302               1 :         if (i > SHRT_MAX) val._int = SHRT_MAX;
     303               1 :         return false;
     304                 : 
     305                 :     case ATTRTYPE_WORD:
     306               0 :         if (i <= USHRT_MAX) {
     307               0 :             val._uint = static_cast<unsigned short>(i);
     308               0 :             return true;
     309                 :         }
     310               0 :         if (0 > i) val._uint = 0;
     311               0 :         if (i > USHRT_MAX) val._uint = USHRT_MAX;
     312               0 :         return false;
     313                 : 
     314                 :     case ATTRTYPE_INTEGER:
     315                 :         if (INT_MIN <= i && i <= INT_MAX) {
     316              70 :             val._int = i;
     317              70 :             return true;
     318                 :         }
     319                 :         if (INT_MIN > i) val._int = INT_MIN;
     320                 :         if (i > INT_MAX) val._int = INT_MAX;
     321                 :         return false;
     322                 : 
     323                 :     case ATTRTYPE_DWORD:
     324                 :         if (static_cast<unsigned int>(i) <= UINT_MAX) {
     325               0 :             val._uint = i;
     326               0 :             return true;
     327                 :         }
     328                 :         if (0 > i) val._uint = 0;
     329                 :         return false;
     330                 : 
     331                 :     case ATTRTYPE_LONG:
     332               0 :         val._long = i;
     333               0 :         return true;
     334                 : 
     335                 :     case ATTRTYPE_QWORD:
     336               0 :         val._ulong = i;
     337               0 :         return true;
     338                 : 
     339                 :     case ATTRTYPE_FLOAT:
     340               0 :         val._float = static_cast<float>(i);
     341               0 :         return true;
     342                 : 
     343                 :     case ATTRTYPE_DOUBLE:
     344               0 :         val._double = static_cast<double>(i);
     345               0 :         return true;
     346                 : 
     347                 :     case ATTRTYPE_STRING:
     348               3 :         assert(val._string);
     349               3 :         *val._string = boost::lexical_cast<std::string>(i);
     350               3 :         return true;
     351                 :     }
     352                 : 
     353               0 :     assert(0);
     354                 :     return false;
     355                 : }
     356                 : 
     357               1 : bool AnyScalar::setLong(long long l)
     358                 : {
     359               1 :     switch(atype)
     360                 :     {
     361                 :     case ATTRTYPE_INVALID:
     362               0 :         assert(0);
     363                 :         return false;
     364                 : 
     365                 :     case ATTRTYPE_BOOL:
     366               0 :         val._int = (l != 0) ? 1 : 0;
     367               0 :         return true;
     368                 : 
     369                 :     case ATTRTYPE_CHAR:
     370               0 :         if (SCHAR_MIN <= l && l <= SCHAR_MAX) {
     371               0 :             val._int = static_cast<char>(l);
     372               0 :             return true;
     373                 :         }
     374               0 :         if (SCHAR_MIN > l) val._int = SCHAR_MIN;
     375               0 :         if (l > SCHAR_MAX) val._int = SCHAR_MAX;
     376               0 :         return false;
     377                 : 
     378                 :     case ATTRTYPE_BYTE:
     379               0 :         if (0 <= l && l <= UCHAR_MAX) {
     380               0 :             val._uint = static_cast<unsigned char>(l);
     381               0 :             return true;
     382                 :         }
     383               0 :         if (0 > l) val._uint = 0;
     384               0 :         if (l > UCHAR_MAX) val._uint = UCHAR_MAX;
     385               0 :         return false;
     386                 : 
     387                 :     case ATTRTYPE_SHORT:
     388               0 :         if (SHRT_MIN <= l && l <= SHRT_MAX) {
     389               0 :             val._int = static_cast<short>(l);
     390               0 :             return true;
     391                 :         }
     392               0 :         if (SHRT_MIN > l) val._int = SHRT_MIN;
     393               0 :         if (l > SHRT_MAX) val._int = SHRT_MAX;
     394               0 :         return false;
     395                 : 
     396                 :     case ATTRTYPE_WORD:
     397               0 :         if (l <= USHRT_MAX) {
     398               0 :             val._uint = static_cast<unsigned short>(l);
     399               0 :             return true;
     400                 :         }
     401               0 :         if (0 > l) val._uint = 0;
     402               0 :         if (l > USHRT_MAX) val._uint = USHRT_MAX;
     403               0 :         return false;
     404                 : 
     405                 :     case ATTRTYPE_INTEGER:
     406               1 :         if (INT_MIN <= l && l <= INT_MAX) {
     407               0 :             val._int = static_cast<int>(l);
     408               0 :             return true;
     409                 :         }
     410               1 :         if (INT_MIN > l) val._int = INT_MIN;
     411               1 :         if (l > INT_MAX) val._int = INT_MAX;
     412               1 :         return false;
     413                 : 
     414                 :     case ATTRTYPE_DWORD:
     415                 :         if (static_cast<unsigned int>(l) <= UINT_MAX) {
     416               0 :             val._uint = static_cast<unsigned int>(l);
     417               0 :             return true;
     418                 :         }
     419                 :         if (0 > l) val._uint = 0;
     420                 :         if (l > UINT_MAX) val._uint = UINT_MAX;
     421                 :         return false;
     422                 : 
     423                 :     case ATTRTYPE_LONG:
     424               0 :         val._long = l;
     425               0 :         return true;
     426                 : 
     427                 :     case ATTRTYPE_QWORD:
     428               0 :         val._ulong = l;
     429               0 :         return true;
     430                 : 
     431                 :     case ATTRTYPE_FLOAT:
     432               0 :         val._float = static_cast<float>(l);
     433               0 :         return true;
     434                 : 
     435                 :     case ATTRTYPE_DOUBLE:
     436               0 :         val._double = static_cast<double>(l);
     437               0 :         return true;
     438                 : 
     439                 :     case ATTRTYPE_STRING:
     440               0 :         assert(val._string);
     441               0 :         *val._string = boost::lexical_cast<std::string>(l);
     442               0 :         return true;
     443                 :     }
     444                 : 
     445               0 :     assert(0);
     446                 :     return false;
     447                 : }
     448                 : 
     449               7 : bool AnyScalar::setDouble(double d)
     450                 : {
     451               7 :     switch(atype)
     452                 :     {
     453                 :     case ATTRTYPE_INVALID:
     454               0 :         assert(0);
     455                 :         return false;
     456                 : 
     457                 :     case ATTRTYPE_BOOL:
     458               1 :         if (0 <= d && d < 0.5) {
     459               1 :             val._int = 0;
     460               1 :             return true;
     461                 :         }
     462               0 :         if (0.5 <= d && d <= 1) {
     463               0 :             val._int = 1;
     464               0 :             return true;
     465                 :         }
     466               0 :         val._int = 1;
     467               0 :         return false;
     468                 : 
     469                 :     case ATTRTYPE_CHAR:
     470                 :     case ATTRTYPE_SHORT:
     471                 :     case ATTRTYPE_INTEGER:
     472               4 :         return setInteger( static_cast<int>(d) );
     473                 : 
     474                 :     case ATTRTYPE_LONG:
     475               0 :         return setLong( static_cast<long long>(d) );
     476                 : 
     477                 :     case ATTRTYPE_BYTE:
     478                 :     case ATTRTYPE_WORD:
     479                 :     case ATTRTYPE_DWORD:
     480               0 :         return setInteger( static_cast<unsigned int>(d) );
     481                 : 
     482                 :     case ATTRTYPE_QWORD:
     483               0 :         return setLong( static_cast<unsigned long long>(d) );
     484                 : 
     485                 :     case ATTRTYPE_FLOAT:
     486               2 :         val._float = static_cast<float>(d);
     487               2 :         return true;
     488                 : 
     489                 :     case ATTRTYPE_DOUBLE:
     490               0 :         val._double = d;
     491               0 :         return true;
     492                 : 
     493                 :     case ATTRTYPE_STRING:
     494               0 :         assert(val._string);
     495               0 :         *val._string = boost::lexical_cast<std::string>(d);
     496               0 :         return true;
     497                 :     }
     498                 : 
     499               0 :     assert(0);
     500                 :     return false;
     501                 : }
     502                 : 
     503              94 : bool AnyScalar::setString(const std::string &s)
     504                 : {
     505              94 :     switch(atype)
     506                 :     {
     507                 :     case ATTRTYPE_INVALID:
     508               0 :         assert(0);
     509                 :         return false;
     510                 : 
     511                 :     case ATTRTYPE_BOOL:
     512               8 :         if (s == "0" || s == "f" || s == "false" || s == "n" || s == "no") {
     513               1 :             val._int = 0;
     514               1 :             return true;
     515                 :         }
     516               7 :         if (s == "1" || s == "t" || s == "true" || s == "y" || s == "yes") {
     517               6 :             val._int = 1;
     518               6 :             return true;
     519                 :         }
     520               1 :         return false;
     521                 : 
     522                 :     case ATTRTYPE_CHAR:
     523                 :     case ATTRTYPE_SHORT:
     524                 :     case ATTRTYPE_INTEGER:
     525                 :     {
     526                 :         char *endptr;
     527              68 :         long i = strtol(s.c_str(), &endptr, 10);
     528              68 :         if (endptr != NULL && *endptr == 0)
     529              67 :             return setInteger(i);
     530               1 :         return false;
     531                 :     }
     532                 : 
     533                 :     case ATTRTYPE_LONG:
     534                 :     {
     535                 :         char *endptr;
     536                 : #ifndef _MSC_VER
     537               0 :         long long l = strtoll(s.c_str(), &endptr, 10);
     538                 : #else
     539                 :         long long l = _strtoi64(s.c_str(), &endptr, 10);
     540                 : #endif
     541               0 :         if (endptr != NULL && *endptr == 0)
     542               0 :             return setLong(l);
     543               0 :         return false;
     544                 :     }
     545                 : 
     546                 :     case ATTRTYPE_BYTE:
     547                 :     case ATTRTYPE_WORD:
     548                 :     case ATTRTYPE_DWORD:
     549                 :     {
     550                 :         char *endptr;
     551               0 :         unsigned long u = strtoul(s.c_str(), &endptr, 10);
     552               0 :         if (endptr != NULL && *endptr == 0)
     553               0 :             return setInteger(u);
     554               0 :         return false;
     555                 :     }
     556                 :     
     557                 :     case ATTRTYPE_QWORD:
     558                 :     {
     559                 :         char *endptr;
     560                 : #ifndef _MSC_VER
     561               0 :         unsigned long long u = strtoull(s.c_str(), &endptr, 10);
     562                 : #else
     563                 :         unsigned long long u = _strtoui64(s.c_str(), &endptr, 10);
     564                 : #endif
     565               0 :         if (endptr != NULL && *endptr == 0)
     566               0 :             return setLong(u);
     567               0 :         return false;
     568                 :     }
     569                 : 
     570                 :     case ATTRTYPE_FLOAT:
     571                 :     {
     572                 :         char *endptr;
     573               1 :         float f = static_cast<float>(strtod(s.c_str(), &endptr));
     574               1 :         if (endptr != NULL && *endptr == 0) {
     575               1 :             val._float = f;
     576               1 :             return true;
     577                 :         }
     578               0 :         return false;
     579                 :     }
     580                 : 
     581                 :     case ATTRTYPE_DOUBLE:
     582                 :     {
     583                 :         char *endptr;
     584              10 :         double d = strtod(s.c_str(), &endptr);
     585              10 :         if (endptr != NULL && *endptr == 0) {
     586              10 :             val._double = d;
     587              10 :             return true;
     588                 :         }
     589               0 :         return false;
     590                 :     }
     591                 : 
     592                 :     case ATTRTYPE_STRING:
     593                 :     {
     594               7 :         assert(val._string);
     595               7 :         *val._string = s;
     596               7 :         return true;
     597                 :     }
     598                 :     }
     599                 : 
     600               0 :     assert(0);
     601                 :     return false;
     602                 : }
     603                 : 
     604               7 : bool AnyScalar::setStringQuoted(const std::string &s)
     605                 : {
     606                 :     // unescape string
     607               7 :     if (s.size() < 2) return false;
     608               7 :     if (s[0] != '"') return false;
     609               7 :     if (s[s.size()-1] != '"') return false;
     610                 : 
     611               7 :     std::string t;
     612               7 :     t.reserve(s.size() + s.size() / 32);
     613                 : 
     614              86 :     for(unsigned int i = 1; i + 1 < s.size(); i++)
     615                 :     {
     616              79 :         if (s[i] == '\\')
     617                 :         {
     618              16 :             i++;
     619              23 :             if (i >= s.size() - 1) return false;
     620                 : 
     621              16 :             switch(s[i])
     622                 :             {
     623               1 :             case 'a':   t += '\a';      break;
     624               1 :             case 'b':   t += '\b';      break;
     625               1 :             case 'f':   t += '\f';      break;
     626               3 :             case 'n':   t += '\n';      break;
     627               1 :             case 'r':   t += '\r';      break;
     628               1 :             case 't':   t += '\t';      break;
     629               1 :             case 'v':   t += '\v';      break;
     630               1 :             case '\'':  t += '\'';      break;
     631               3 :             case '"':      t += '"';  break;
     632               3 :             case '\\':  t += '\\';      break;
     633               0 :             case '?':   t += '?';       break;
     634                 : 
     635                 :             default:
     636               0 :                 t += '\\';
     637               0 :                 t += s[i];
     638                 :                 break;
     639                 :             }
     640                 :         }
     641                 :         else {
     642              63 :             t += s[i];
     643                 :         }
     644                 :     }
     645                 : 
     646               7 :     return setString(t);
     647                 : }
     648                 : 
     649               8 : AnyScalar& AnyScalar::setAutoString(const std::string &input)
     650                 : {
     651                 :     // - int: input was readable by strtoll and is small enough.
     652                 :     // - long: input was readable by strtoll
     653                 :     {
     654                 :         char *endptr;
     655                 : #ifndef _MSC_VER
     656               8 :         long long l = strtoll(input.c_str(), &endptr, 10);
     657                 : #else
     658                 :         long long l = _strtoi64(input.c_str(), &endptr, 10);
     659                 : #endif
     660               8 :         if (endptr != NULL && *endptr == 0)
     661                 :         {
     662               5 :             if (INT_MIN <= l && l <= INT_MAX)
     663                 :             {
     664               3 :                 resetType(ATTRTYPE_INTEGER);
     665               3 :                 val._int = l;
     666               3 :                 return *this;
     667                 :             }
     668                 :             else
     669                 :             {
     670               2 :                 resetType(ATTRTYPE_LONG);
     671               2 :                 val._long = l;
     672               2 :                 return *this;
     673                 :             }
     674                 :         }
     675                 :     }
     676                 : 
     677                 :     // - double: input was readble by strtod
     678                 :     {
     679                 :         char *endptr;
     680               3 :         double d = strtod(input.c_str(), &endptr);
     681               3 :         if (endptr != NULL && *endptr == 0)
     682                 :         {
     683               1 :             resetType(ATTRTYPE_DOUBLE);
     684               1 :             val._double = d;
     685               1 :             return *this;
     686                 :         }
     687                 :     }
     688                 : 
     689                 :     // - string: all above failed.
     690               2 :     resetType(ATTRTYPE_STRING);
     691               2 :     *val._string = input;
     692                 : 
     693               2 :     return *this;
     694                 : }
     695                 : 
     696              14 : bool AnyScalar::getBoolean() const
     697                 : {
     698              14 :     switch(atype)
     699                 :     {
     700                 :     case ATTRTYPE_INVALID:
     701               0 :         assert(0);
     702                 :         return false;
     703                 : 
     704                 :     case ATTRTYPE_BOOL:
     705               2 :         return (val._int != 0);
     706                 : 
     707                 :     case ATTRTYPE_CHAR:
     708                 :     case ATTRTYPE_SHORT:
     709                 :     case ATTRTYPE_INTEGER:
     710               9 :         return (val._int != 0);
     711                 : 
     712                 :     case ATTRTYPE_BYTE:
     713                 :     case ATTRTYPE_WORD:
     714                 :     case ATTRTYPE_DWORD:
     715               0 :         return (val._uint != 0);
     716                 : 
     717                 :     case ATTRTYPE_LONG:
     718               0 :         return (val._long != 0);
     719                 : 
     720                 :     case ATTRTYPE_QWORD:
     721               0 :         return (val._ulong != 0);
     722                 : 
     723                 :     case ATTRTYPE_FLOAT:
     724               1 :         return (val._float != 0.0f);
     725                 : 
     726                 :     case ATTRTYPE_DOUBLE:
     727               0 :         return (val._double != 0.0f);
     728                 : 
     729                 :     case ATTRTYPE_STRING:
     730                 :     {
     731               2 :         assert(val._string);
     732                 : 
     733               2 :         if (*val._string == "0" || *val._string == "f" || *val._string == "false"
     734                 :             || *val._string == "n" || *val._string == "no") {
     735               1 :             return false;
     736                 :         }
     737               1 :         if (*val._string == "1" || *val._string == "t" || *val._string == "true"
     738                 :             || *val._string == "y" || *val._string == "yes") {
     739               0 :             return true;
     740                 :         }
     741                 : 
     742               1 :         throw(ConversionException("Cannot convert string to boolean."));
     743                 :     }
     744                 :     }
     745                 : 
     746               0 :     assert(0);
     747                 :     return false;
     748                 : }
     749                 : 
     750              41 : int AnyScalar::getInteger() const
     751                 : {
     752              41 :     switch(atype)
     753                 :     {
     754                 :     case ATTRTYPE_INVALID:
     755               0 :         assert(0);
     756                 :         return false;
     757                 : 
     758                 :     case ATTRTYPE_BOOL:
     759              29 :         return val._int;
     760                 : 
     761                 :     case ATTRTYPE_CHAR:
     762                 :     case ATTRTYPE_SHORT:
     763                 :     case ATTRTYPE_INTEGER:
     764               6 :         return val._int;
     765                 : 
     766                 :     case ATTRTYPE_BYTE:
     767                 :     case ATTRTYPE_WORD:
     768                 :     case ATTRTYPE_DWORD:
     769               0 :         return val._uint;
     770                 : 
     771                 :     case ATTRTYPE_LONG:
     772               0 :         if (val._long > INT_MAX) return INT_MAX;
     773               0 :         if (val._long < INT_MIN) return INT_MIN;
     774                 : 
     775               0 :         return static_cast<int>(val._long);
     776                 : 
     777                 :     case ATTRTYPE_QWORD:
     778               0 :         if (val._ulong > UINT_MAX) return UINT_MAX;
     779               0 :         return static_cast<int>(val._ulong);
     780                 : 
     781                 :     case ATTRTYPE_FLOAT:
     782               3 :         return static_cast<int>(val._float);
     783                 : 
     784                 :     case ATTRTYPE_DOUBLE:
     785               2 :         return static_cast<int>(val._double);
     786                 : 
     787                 :     case ATTRTYPE_STRING:
     788                 :     {
     789               1 :         assert(val._string);
     790                 :         char *endptr;
     791               1 :         long i = strtol(val._string->c_str(), &endptr, 10);
     792               1 :         if (endptr != NULL && *endptr == 0)
     793               1 :             return i;
     794                 : 
     795               0 :         throw(ConversionException("Cannot convert string to integer."));
     796                 :     }
     797                 :     }
     798                 : 
     799               0 :     assert(0);
     800                 :     return false;
     801                 : }
     802                 : 
     803               0 : unsigned int AnyScalar::getUnsignedInteger() const
     804                 : {
     805               0 :     switch(atype)
     806                 :     {
     807                 :     case ATTRTYPE_INVALID:
     808               0 :         assert(0);
     809                 :         return false;
     810                 : 
     811                 :     case ATTRTYPE_BOOL:
     812                 :     case ATTRTYPE_CHAR:
     813                 :     case ATTRTYPE_SHORT:
     814                 :     case ATTRTYPE_INTEGER:
     815               0 :         return static_cast<unsigned int>(val._int);
     816                 : 
     817                 :     case ATTRTYPE_BYTE:
     818                 :     case ATTRTYPE_WORD:
     819                 :     case ATTRTYPE_DWORD:
     820               0 :         return val._uint;
     821                 : 
     822                 :     case ATTRTYPE_LONG:
     823               0 :         return static_cast<unsigned int>(val._long);
     824                 : 
     825                 :     case ATTRTYPE_QWORD:
     826               0 :         return static_cast<unsigned int>(val._ulong);
     827                 : 
     828                 :     case ATTRTYPE_FLOAT:
     829               0 :         return static_cast<unsigned int>(val._float);
     830                 : 
     831                 :     case ATTRTYPE_DOUBLE:
     832               0 :         return static_cast<unsigned int>(val._double);
     833                 : 
     834                 :     case ATTRTYPE_STRING:
     835                 :     {
     836               0 :         assert(val._string);
     837                 :         char *endptr;
     838               0 :         unsigned long i = strtoul(val._string->c_str(), &endptr, 10);
     839               0 :         if (endptr != NULL && *endptr == 0)
     840               0 :             return i;
     841                 : 
     842               0 :         throw(ConversionException("Cannot convert string to unsigned integer."));
     843                 :     }
     844                 :     }
     845                 : 
     846               0 :     assert(0);
     847                 :     return false;
     848                 : }
     849                 : 
     850               0 : long long AnyScalar::getLong() const
     851                 : {
     852               0 :     switch(atype)
     853                 :     {
     854                 :     case ATTRTYPE_INVALID:
     855               0 :         assert(0);
     856                 :         return false;
     857                 : 
     858                 :     case ATTRTYPE_BOOL:
     859                 :     case ATTRTYPE_CHAR:
     860                 :     case ATTRTYPE_SHORT:
     861                 :     case ATTRTYPE_INTEGER:
     862                 :     case ATTRTYPE_BYTE:
     863                 :     case ATTRTYPE_WORD:
     864                 :     case ATTRTYPE_DWORD:
     865               0 :         return static_cast<long long>(val._int);
     866                 : 
     867                 :     case ATTRTYPE_LONG:
     868               0 :         return val._long;
     869                 : 
     870                 :     case ATTRTYPE_QWORD:
     871               0 :         return val._ulong;
     872                 : 
     873                 :     case ATTRTYPE_FLOAT:
     874               0 :         return static_cast<long long>(val._float);
     875                 : 
     876                 :     case ATTRTYPE_DOUBLE:
     877               0 :         return static_cast<long long>(val._double);
     878                 : 
     879                 :     case ATTRTYPE_STRING:
     880                 :     {
     881               0 :         assert(val._string);
     882                 :         char *endptr;
     883                 : #ifndef _MSC_VER
     884               0 :         long long l = strtoll(val._string->c_str(), &endptr, 10);
     885                 : #else
     886                 :         long long l = _strtoi64(val._string->c_str(), &endptr, 10);
     887                 : #endif
     888               0 :         if (endptr != NULL && *endptr == 0)
     889               0 :             return l;
     890                 : 
     891               0 :         throw(ConversionException("Cannot convert string to long long."));
     892                 :     }
     893                 :     }
     894                 : 
     895               0 :     assert(0);
     896                 :     return false;
     897                 : }
     898                 : 
     899               0 : unsigned long long AnyScalar::getUnsignedLong() const
     900                 : {
     901               0 :     switch(atype)
     902                 :     {
     903                 :     case ATTRTYPE_INVALID:
     904               0 :         assert(0);
     905                 :         return false;
     906                 : 
     907                 :     case ATTRTYPE_BOOL:
     908                 :     case ATTRTYPE_CHAR:
     909                 :     case ATTRTYPE_SHORT:
     910                 :     case ATTRTYPE_INTEGER:
     911               0 :         return static_cast<unsigned long long>(val._int);
     912                 : 
     913                 :     case ATTRTYPE_BYTE:
     914                 :     case ATTRTYPE_WORD:
     915                 :     case ATTRTYPE_DWORD:
     916               0 :         return static_cast<unsigned long long>(val._uint);
     917                 : 
     918                 :     case ATTRTYPE_LONG:
     919               0 :         return static_cast<unsigned long long>(val._long);
     920                 : 
     921                 :     case ATTRTYPE_QWORD:
     922               0 :         return val._ulong;
     923                 : 
     924                 :     case ATTRTYPE_FLOAT:
     925               0 :         return static_cast<unsigned long long>(val._float);
     926                 : 
     927                 :     case ATTRTYPE_DOUBLE:
     928               0 :         return static_cast<unsigned long long>(val._double);
     929                 : 
     930                 :     case ATTRTYPE_STRING:
     931                 :     {
     932               0 :         assert(val._string);
     933                 :         char *endptr;
     934                 : #ifndef _MSC_VER
     935               0 :         unsigned long long u = strtoull(val._string->c_str(), &endptr, 10);
     936                 : #else
     937                 :         unsigned long long u = _strtoui64(val._string->c_str(), &endptr, 10);
     938                 : #endif
     939               0 :         if (endptr != NULL && *endptr == 0)
     940               0 :             return u;
     941                 : 
     942               0 :         throw(ConversionException("Cannot convert string to unsigned long long."));
     943                 :     }
     944                 :     }
     945               0 :     assert(0);
     946                 :     return false;
     947                 : }
     948                 : 
     949               8 : double AnyScalar::getDouble() const
     950                 : {
     951               8 :     switch(atype)
     952                 :     {
     953                 :     case ATTRTYPE_INVALID:
     954               0 :         assert(0);
     955                 :         return false;
     956                 : 
     957                 :     case ATTRTYPE_BOOL:
     958                 :     case ATTRTYPE_CHAR:
     959                 :     case ATTRTYPE_SHORT:
     960                 :     case ATTRTYPE_INTEGER:
     961                 :     case ATTRTYPE_BYTE:
     962                 :     case ATTRTYPE_WORD:
     963                 :     case ATTRTYPE_DWORD:
     964               4 :         return static_cast<double>(val._int);
     965                 : 
     966                 :     case ATTRTYPE_LONG:
     967               0 :         return static_cast<double>(val._long);
     968                 : 
     969                 :     case ATTRTYPE_QWORD:
     970               0 :         return static_cast<double>(val._ulong);
     971                 : 
     972                 :     case ATTRTYPE_FLOAT:
     973               1 :         return static_cast<double>(val._float);
     974                 : 
     975                 :     case ATTRTYPE_DOUBLE:
     976               2 :         return val._double;
     977                 : 
     978                 :     case ATTRTYPE_STRING:
     979                 :     {
     980               1 :         assert(val._string);
     981                 :         char *endptr;
     982               1 :         double d = strtod(val._string->c_str(), &endptr);
     983               1 :         if (endptr != NULL && *endptr == 0)
     984               1 :             return d;
     985                 : 
     986               0 :         throw(ConversionException("Cannot convert string to double."));
     987                 :     }
     988                 :     }
     989               0 :     assert(0);
     990                 :     return false;
     991                 : }
     992                 : 
     993              79 : std::string AnyScalar::getString() const
     994                 : {
     995              79 :     switch(atype)
     996                 :     {
     997                 :     case ATTRTYPE_INVALID:
     998               0 :         assert(0);
     999                 :         return false;
    1000                 : 
    1001                 :     case ATTRTYPE_BOOL:
    1002               9 :         if (val._int == 0) return "false";
    1003               8 :         if (val._int == 1) return "true";
    1004               0 :         assert(0);
    1005                 :         return "invalid";
    1006                 : 
    1007                 :     case ATTRTYPE_CHAR:
    1008                 :     case ATTRTYPE_SHORT:
    1009                 :     case ATTRTYPE_INTEGER:
    1010                 :     {
    1011              50 :         return boost::lexical_cast<std::string>(val._int);
    1012                 :     }
    1013                 : 
    1014                 :     case ATTRTYPE_BYTE:
    1015                 :     case ATTRTYPE_WORD:
    1016                 :     case ATTRTYPE_DWORD:
    1017                 :     {
    1018               0 :         return boost::lexical_cast<std::string>(val._uint);
    1019                 :     }
    1020                 : 
    1021                 :     case ATTRTYPE_LONG:
    1022                 :     {
    1023               0 :         return boost::lexical_cast<std::string>(val._long);
    1024                 :     }
    1025                 : 
    1026                 :     case ATTRTYPE_QWORD:
    1027                 :     {
    1028               0 :         return boost::lexical_cast<std::string>(val._ulong);
    1029                 :     }
    1030                 : 
    1031                 :     case ATTRTYPE_FLOAT:
    1032                 :     {
    1033               3 :         return boost::lexical_cast<std::string>(val._float);
    1034                 :     }
    1035                 : 
    1036                 :     case ATTRTYPE_DOUBLE:
    1037                 :     {
    1038               7 :         return boost::lexical_cast<std::string>(val._double);
    1039                 :     }
    1040                 : 
    1041                 :     case ATTRTYPE_STRING:
    1042                 :     {
    1043              10 :         assert(val._string);
    1044              10 :         return *val._string;
    1045                 :     } 
    1046                 :     }
    1047               0 :     assert(0);
    1048                 :     return false;
    1049                 : }
    1050                 : 
    1051               4 : std::string AnyScalar::getStringQuoted() const
    1052                 : {
    1053               4 :     std::string str = getString();
    1054               4 :     std::string os = "\"";
    1055                 : 
    1056               8 :     os.reserve(2 + str.size() + str.size() / 16);
    1057                 : 
    1058                 :     // escape string s
    1059              68 :     for(std::string::const_iterator si = str.begin(); si != str.end(); ++si)
    1060                 :     {
    1061              64 :         switch(*si)
    1062                 :         {
    1063                 :         case '\a':
    1064               0 :             os += "\\a";
    1065               0 :             break;
    1066                 : 
    1067                 :         case '\b':
    1068               0 :             os += "\\b";
    1069               0 :             break;
    1070                 : 
    1071                 :         case '\f':
    1072               0 :             os += "\\f";
    1073               0 :             break;
    1074                 : 
    1075                 :         case '\n':
    1076               2 :             os += "\\n";
    1077               2 :             break;
    1078                 : 
    1079                 :         case '\r':
    1080               0 :             os += "\\r";
    1081               0 :             break;
    1082                 : 
    1083                 :         case '\t':
    1084               0 :             os += "\\t";
    1085               0 :             break;
    1086                 :     
    1087                 :         case '\v':
    1088               0 :             os += "\\v";
    1089               0 :             break;
    1090                 : 
    1091                 :         case '\\':
    1092               2 :             os += "\\\\";
    1093               2 :             break;
    1094                 : 
    1095                 :         case '"':
    1096               2 :             os += "\\\"";
    1097               2 :             break;
    1098                 : 
    1099                 :         case '\'':
    1100               0 :             os += "\\'";
    1101               0 :             break;
    1102                 : 
    1103                 :         default:
    1104              58 :             os += *si;
    1105                 :             break;
    1106                 :         }
    1107                 :     }
    1108                 : 
    1109               4 :     os += "\"";
    1110               4 :     return os;
    1111                 : }
    1112                 : 
    1113               8 : void AnyScalar::resetType(attrtype_t t)
    1114                 : {
    1115                 :     // if setting to a string and this is not a string, create the object
    1116               8 :     if (t == ATTRTYPE_STRING) {
    1117               2 :         if (atype != ATTRTYPE_STRING) {
    1118               2 :             val._string = new std::string;
    1119                 :         }
    1120                 :     }
    1121                 :     else {
    1122               6 :         if (atype == ATTRTYPE_STRING) {
    1123               1 :             delete val._string;
    1124                 :         }
    1125                 : 
    1126               6 :         val._ulong = 0;
    1127                 :     }
    1128                 : 
    1129               8 :     atype = t;
    1130               8 : }
    1131                 : 
    1132               4 : bool AnyScalar::convertType(attrtype_t t)
    1133                 : {
    1134                 :     // same source and target type?
    1135               4 :     if (atype == t) return true;
    1136                 : 
    1137                 :     // special case if this object was initialised with the ATTRTYPE_INVALID:
    1138                 :     // all the get...() below would assert.
    1139               4 :     if (atype == ATTRTYPE_INVALID)
    1140                 :     {
    1141               0 :         atype = t;
    1142               0 :         if (atype == ATTRTYPE_STRING) {
    1143               0 :             val._string = new std::string;
    1144                 :         }
    1145               0 :         return true;
    1146                 :     }
    1147                 :     
    1148               4 :     switch(t)
    1149                 :     {
    1150                 :     case ATTRTYPE_INVALID:
    1151               0 :         assert(0);
    1152                 :         return false;
    1153                 : 
    1154                 :     case ATTRTYPE_BOOL:
    1155                 :     {
    1156               0 :         bool v = getBoolean();
    1157               0 :         if (atype == ATTRTYPE_STRING) delete val._string;
    1158               0 :         val._int = v;
    1159               0 :         atype = t;
    1160               0 :         return true;
    1161                 :     }
    1162                 : 
    1163                 :     case ATTRTYPE_CHAR:
    1164                 :     case ATTRTYPE_SHORT:
    1165                 :     case ATTRTYPE_INTEGER:
    1166                 :     {
    1167               3 :         int v = getInteger();
    1168               3 :         if (atype == ATTRTYPE_STRING) delete val._string;
    1169               3 :         val._int = v;
    1170               3 :         atype = t;
    1171               3 :         return true;
    1172                 :     }
    1173                 : 
    1174                 :     case ATTRTYPE_BYTE:
    1175                 :     case ATTRTYPE_WORD:
    1176                 :     case ATTRTYPE_DWORD:
    1177                 :     {
    1178               0 :         unsigned int v = getUnsignedInteger();
    1179               0 :         if (atype == ATTRTYPE_STRING) delete val._string;
    1180               0 :         val._uint = v;
    1181               0 :         atype = t;
    1182               0 :         return true;
    1183                 :     }
    1184                 : 
    1185                 :     case ATTRTYPE_LONG:
    1186                 :     {
    1187               0 :         long long v = getLong();
    1188               0 :         if (atype == ATTRTYPE_STRING) delete val._string;
    1189               0 :         val._long = v;
    1190               0 :         atype = t;
    1191               0 :         return true;
    1192                 :     }
    1193                 : 
    1194                 :     case ATTRTYPE_QWORD:
    1195                 :     {
    1196               0 :         unsigned long long v = getLong();
    1197               0 :         if (atype == ATTRTYPE_STRING) delete val._string;
    1198               0 :         val._ulong = v;
    1199               0 :         atype = t;
    1200               0 :         return true;
    1201                 :     }
    1202                 : 
    1203                 :     case ATTRTYPE_FLOAT:
    1204                 :     {
    1205               0 :         float f = static_cast<float>(getDouble());
    1206               0 :         if (atype == ATTRTYPE_STRING) delete val._string;
    1207               0 :         val._float = f;
    1208               0 :         atype = t;
    1209               0 :         return true;
    1210                 :     }
    1211                 : 
    1212                 :     case ATTRTYPE_DOUBLE:
    1213                 :     {
    1214               0 :         double d = getDouble();
    1215               0 :         if (atype == ATTRTYPE_STRING) delete val._string;
    1216               0 :         val._double = d;
    1217               0 :         atype = t;
    1218               0 :         return true;
    1219                 :     }
    1220                 : 
    1221                 :     case ATTRTYPE_STRING:
    1222                 :     {
    1223               1 :         val._string = new std::string(getString());
    1224               1 :         atype = t;
    1225               1 :         return true;
    1226                 :     } 
    1227                 :     }
    1228               0 :     assert(0);
    1229                 :     return false;
    1230                 : }
    1231                 : 
    1232               7 : AnyScalar AnyScalar::operator-() const
    1233                 : {
    1234               7 :     AnyScalar at = *this;
    1235                 :     
    1236               7 :     switch(at.atype)
    1237                 :     {
    1238                 :     case ATTRTYPE_INVALID:
    1239               0 :         assert(0);
    1240                 :         throw(ConversionException("Negating invalid type."));
    1241                 :         
    1242                 :     case ATTRTYPE_BOOL:
    1243               2 :         if (at.val._int > 0) at.val._int = 0;
    1244               1 :         else at.val._int = 1;
    1245               2 :         break;
    1246                 : 
    1247                 :     case ATTRTYPE_CHAR:
    1248                 :     case ATTRTYPE_SHORT:
    1249                 :     case ATTRTYPE_INTEGER:
    1250               3 :         at.val._int = - at.val._int;
    1251               3 :         break;
    1252                 : 
    1253                 :     case ATTRTYPE_BYTE:
    1254                 :     case ATTRTYPE_WORD:
    1255                 :     case ATTRTYPE_DWORD:
    1256               0 :         at.val._uint = - at.val._uint;
    1257               0 :         break;
    1258                 : 
    1259                 :     case ATTRTYPE_LONG:
    1260               0 :         at.val._long = - at.val._long;
    1261               0 :         break;
    1262                 : 
    1263                 :     case ATTRTYPE_QWORD:
    1264               0 :         at.val._ulong = - at.val._ulong;
    1265               0 :         break;
    1266                 : 
    1267                 :     case ATTRTYPE_FLOAT:
    1268               0 :         at.val._float = - at.val._float;
    1269               0 :         break;
    1270                 : 
    1271                 :     case ATTRTYPE_DOUBLE:
    1272               2 :         at.val._double = - at.val._double;
    1273               2 :         break;
    1274                 : 
    1275                 :     case ATTRTYPE_STRING:
    1276                 :     {
    1277               0 :         if (!at.convertType(ATTRTYPE_DOUBLE))
    1278               0 :             throw(ConversionException("Cannot convert string to double for negation."));
    1279                 : 
    1280               0 :         at.val._double = - at.val._double;
    1281                 :         break;
    1282                 :     }
    1283                 :     }
    1284                 : 
    1285               0 :     return at;
    1286                 : }
    1287                 : 
    1288                 : template <template <typename Type> class Operator, char OpName>
    1289                 : AnyScalar AnyScalar::binary_arith_op(const AnyScalar &b) const
    1290                 : {
    1291              25 :     switch(atype)
    1292                 :     {
    1293                 :     case ATTRTYPE_INVALID:
    1294               0 :         assert(0);
    1295                 :         throw(ConversionException(std::string("Invalid type for first operand of binary operator ")+OpName+"."));
    1296                 : 
    1297                 :     case ATTRTYPE_BOOL:
    1298               0 :         throw(ConversionException("No binary operators are allowed on bool values."));
    1299                 : 
    1300                 :     case ATTRTYPE_CHAR:
    1301                 :     case ATTRTYPE_SHORT:
    1302                 :     case ATTRTYPE_INTEGER:
    1303                 :     {
    1304              18 :         switch(b.atype)
    1305                 :         {
    1306                 :         case ATTRTYPE_INVALID:
    1307               0 :             assert(0);
    1308                 :             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
    1309                 : 
    1310                 :         case ATTRTYPE_BOOL:
    1311               0 :             throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
    1312                 : 
    1313                 :         case ATTRTYPE_CHAR:
    1314                 :         case ATTRTYPE_SHORT:
    1315                 :         case ATTRTYPE_INTEGER:
    1316                 :         {
    1317                 :             Operator<int> op;
    1318               1 :             if (OpName == '/' && b.val._int == 0) throw(ArithmeticException("Integer division by zero"));
    1319              13 :             return AnyScalar( op(val._int, b.val._int) );
    1320                 :         }
    1321                 : 
    1322                 :         case ATTRTYPE_BYTE:
    1323                 :         case ATTRTYPE_WORD:
    1324                 :         case ATTRTYPE_DWORD:
    1325                 :         {
    1326                 :             Operator<int> op;
    1327               0 :             if (OpName == '/' && b.val._uint == 0) throw(ArithmeticException("Integer division by zero"));
    1328               0 :             return AnyScalar( op(val._int, static_cast<signed int>(b.val._uint)) );
    1329                 :         }
    1330                 : 
    1331                 :         case ATTRTYPE_LONG:
    1332                 :         {
    1333                 :             Operator<long long> op;
    1334               0 :             if (OpName == '/' && b.val._long == 0) throw(ArithmeticException("Integer division by zero"));
    1335               0 :             return AnyScalar( op(val._int, b.val._long) );
    1336                 :         }
    1337                 :             
    1338                 :         case ATTRTYPE_QWORD:
    1339                 :         {
    1340                 :             Operator<long long> op;
    1341               0 :             if (OpName == '/' && b.val._ulong == 0) throw(ArithmeticException("Integer division by zero"));
    1342               0 :             return AnyScalar( op(static_cast<long long>(val._int), static_cast<long long>(b.val._ulong)) );
    1343                 :         }
    1344                 :             
    1345                 :         case ATTRTYPE_FLOAT:
    1346                 :         {
    1347                 :             Operator<float> op;
    1348               0 :             return AnyScalar( op(static_cast<float>(val._int), b.val._float));
    1349                 :         }
    1350                 : 
    1351                 :         case ATTRTYPE_DOUBLE:
    1352                 :         {
    1353                 :             Operator<double> op;
    1354               5 :             return AnyScalar( op(static_cast<double>(val._int), b.val._double) );
    1355                 :         }
    1356                 : 
    1357                 :         case ATTRTYPE_STRING:
    1358                 :         {
    1359               0 :             AnyScalar bc = b;
    1360                 :             
    1361               0 :             if (!bc.convertType(ATTRTYPE_INTEGER))
    1362               0 :                 throw(ConversionException(std::string("Could not convert string to integer for binary operator ")+OpName+"."));
    1363                 : 
    1364                 :             Operator<int> op;
    1365                 : 
    1366               0 :             int bval = bc.getInteger();
    1367               0 :             if (OpName == '/' && bval == 0) throw(ArithmeticException("Integer division by zero"));
    1368                 : 
    1369               0 :             return AnyScalar( op(val._int, bval) );
    1370                 :         }
    1371                 :         }
    1372               0 :         break;
    1373                 :     }
    1374                 : 
    1375                 :     case ATTRTYPE_BYTE:
    1376                 :     case ATTRTYPE_WORD:
    1377                 :     case ATTRTYPE_DWORD:
    1378                 :     {
    1379               0 :         switch(b.atype)
    1380                 :         {
    1381                 :         case ATTRTYPE_INVALID:
    1382               0 :             assert(0);
    1383                 :             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
    1384                 : 
    1385                 :         case ATTRTYPE_BOOL:
    1386               0 :             throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
    1387                 : 
    1388                 :         case ATTRTYPE_CHAR:
    1389                 :         case ATTRTYPE_SHORT:
    1390                 :         case ATTRTYPE_INTEGER:
    1391                 :         {
    1392                 :             Operator<int> op;
    1393               0 :             if (OpName == '/' && b.val._int == 0) throw(ArithmeticException("Integer division by zero"));
    1394               0 :             return AnyScalar( op(static_cast<signed int>(val._uint), b.val._int) );
    1395                 :         }
    1396                 : 
    1397                 :         case ATTRTYPE_BYTE:
    1398                 :         case ATTRTYPE_WORD:
    1399                 :         case ATTRTYPE_DWORD:
    1400                 :         {
    1401                 :             Operator<unsigned int> op;
    1402               0 :             if (OpName == '/' && b.val._uint == 0) throw(ArithmeticException("Integer division by zero"));
    1403               0 :             return AnyScalar( op(val._uint, b.val._uint) );
    1404                 :         }
    1405                 :             
    1406                 :         case ATTRTYPE_LONG:
    1407                 :         {
    1408                 :             Operator<long long> op;
    1409               0 :             if (OpName == '/' && b.val._long == 0) throw(ArithmeticException("Integer division by zero"));
    1410               0 :             return AnyScalar( op(static_cast<signed long long>(val._uint), b.val._long) );
    1411                 :         }
    1412                 : 
    1413                 :         case ATTRTYPE_QWORD:
    1414                 :         {
    1415                 :             Operator<unsigned long long> op;
    1416               0 :             if (OpName == '/' && b.val._ulong == 0) throw(ArithmeticException("Integer division by zero"));
    1417               0 :             return AnyScalar( op(static_cast<unsigned long long>(val._uint), b.val._ulong) );
    1418                 :         }
    1419                 :             
    1420                 :         case ATTRTYPE_FLOAT:
    1421                 :         {
    1422                 :             Operator<float> op;
    1423               0 :             return AnyScalar( op(static_cast<float>(val._uint), b.val._float));
    1424                 :         }
    1425                 : 
    1426                 :         case ATTRTYPE_DOUBLE:
    1427                 :         {
    1428                 :             Operator<double> op;
    1429               0 :             return AnyScalar( op(static_cast<double>(val._uint), b.val._double) );
    1430                 :         }
    1431                 : 
    1432                 :         case ATTRTYPE_STRING:
    1433                 :         {
    1434               0 :             AnyScalar bc = b;
    1435                 :             
    1436               0 :             if (!bc.convertType(ATTRTYPE_DWORD))
    1437               0 :                 throw(ConversionException(std::string("Could not convert string to unsigned integer for binary operator ")+OpName+"."));
    1438                 : 
    1439                 :             Operator<unsigned int> op;
    1440                 : 
    1441               0 :             int bval = bc.getInteger();
    1442               0 :             if (OpName == '/' && bval == 0) throw(ArithmeticException("Integer division by zero"));
    1443                 : 
    1444               0 :             return AnyScalar( op(val._int, bval) );
    1445                 :         }
    1446                 :         }
    1447               0 :         break;
    1448                 :     }
    1449                 : 
    1450                 :     case ATTRTYPE_LONG:
    1451                 :     {
    1452               0 :         switch(b.atype)
    1453                 :         {
    1454                 :         case ATTRTYPE_INVALID:
    1455               0 :             assert(0);
    1456                 :             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
    1457                 : 
    1458                 :         case ATTRTYPE_BOOL:
    1459               0 :             throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
    1460                 : 
    1461                 :         case ATTRTYPE_CHAR:
    1462                 :         case ATTRTYPE_SHORT:
    1463                 :         case ATTRTYPE_INTEGER:
    1464                 :         {
    1465                 :             Operator<long long> op;
    1466               0 :             if (OpName == '/' && b.val._int == 0) throw(ArithmeticException("Integer division by zero"));
    1467               0 :             return AnyScalar( op(val._long, static_cast<long long>(b.val._int)) );
    1468                 :         }
    1469                 : 
    1470                 :         case ATTRTYPE_BYTE:
    1471                 :         case ATTRTYPE_WORD:
    1472                 :         case ATTRTYPE_DWORD:
    1473                 :         {
    1474                 :             Operator<long long> op;
    1475               0 :             if (OpName == '/' && b.val._uint == 0) throw(ArithmeticException("Integer division by zero"));
    1476               0 :             return AnyScalar( op(val._long, static_cast<signed long long>(b.val._uint)) );
    1477                 :         }
    1478                 :             
    1479                 :         case ATTRTYPE_LONG:
    1480                 :         {
    1481                 :             Operator<long long> op;
    1482               0 :             if (OpName == '/' && b.val._long == 0) throw(ArithmeticException("Integer division by zero"));
    1483               0 :             return AnyScalar( op(val._long, b.val._long) );
    1484                 :         }
    1485                 : 
    1486                 :         case ATTRTYPE_QWORD:
    1487                 :         {
    1488                 :             Operator<long long> op;
    1489               0 :             if (OpName == '/' && b.val._ulong == 0) throw(ArithmeticException("Integer division by zero"));
    1490               0 :             return AnyScalar( op(val._long, static_cast<signed long long>(b.val._ulong)) );
    1491                 :         }
    1492                 :             
    1493                 :         case ATTRTYPE_FLOAT:
    1494                 :         {
    1495                 :             Operator<float> op;
    1496               0 :             return AnyScalar( op(static_cast<float>(val._long), b.val._float));
    1497                 :         }
    1498                 : 
    1499                 :         case ATTRTYPE_DOUBLE:
    1500                 :         {
    1501                 :             Operator<double> op;
    1502               0 :             return AnyScalar( op(static_cast<double>(val._long), b.val._double) );
    1503                 :         }
    1504                 : 
    1505                 :         case ATTRTYPE_STRING:
    1506                 :         {
    1507               0 :             AnyScalar bc = b;
    1508                 :             
    1509               0 :             if (!bc.convertType(ATTRTYPE_LONG))
    1510               0 :                 throw(ConversionException(std::string("Could not convert string to long for binary operator ")+OpName+"."));
    1511                 : 
    1512                 :             Operator<long long> op;
    1513                 : 
    1514               0 :             long long bval = bc.getLong();
    1515               0 :             if (OpName == '/' && bval == 0) throw(ArithmeticException("Integer division by zero"));
    1516                 : 
    1517               0 :             return AnyScalar( op(val._long, bval) );
    1518                 :         }
    1519                 :         }
    1520               0 :         break;
    1521                 :     }
    1522                 : 
    1523                 :     case ATTRTYPE_QWORD:
    1524                 :     {
    1525               0 :         switch(b.atype)
    1526                 :         {
    1527                 :         case ATTRTYPE_INVALID:
    1528               0 :             assert(0);
    1529                 :             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
    1530                 : 
    1531                 :         case ATTRTYPE_BOOL:
    1532               0 :             throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
    1533                 : 
    1534                 :         case ATTRTYPE_CHAR:
    1535                 :         case ATTRTYPE_SHORT:
    1536                 :         case ATTRTYPE_INTEGER:
    1537                 :         {
    1538                 :             Operator<long long> op;
    1539               0 :             if (OpName == '/' && b.val._int == 0) throw(ArithmeticException("Integer division by zero"));
    1540               0 :             return AnyScalar( op(static_cast<signed long long>(val._ulong), b.val._int) );
    1541                 :         }
    1542                 : 
    1543                 :         case ATTRTYPE_BYTE:
    1544                 :         case ATTRTYPE_WORD:
    1545                 :         case ATTRTYPE_DWORD:
    1546                 :         {
    1547                 :             Operator<unsigned long long> op;
    1548               0 :             if (OpName == '/' && b.val._uint == 0) throw(ArithmeticException("Integer division by zero"));
    1549               0 :             return AnyScalar( op(val._ulong, static_cast<unsigned long long>(b.val._uint)) );
    1550                 :         }
    1551                 :             
    1552                 :         case ATTRTYPE_LONG:
    1553                 :         {
    1554                 :             Operator<long long> op;
    1555               0 :             if (OpName == '/' && b.val._long == 0) throw(ArithmeticException("Integer division by zero"));
    1556               0 :             return AnyScalar( op(static_cast<signed long long>(val._ulong), b.val._long) );
    1557                 :         }
    1558                 : 
    1559                 :         case ATTRTYPE_QWORD:
    1560                 :         {
    1561                 :             Operator<unsigned long long> op;
    1562               0 :             if (OpName == '/' && b.val._ulong == 0) throw(ArithmeticException("Integer division by zero"));
    1563               0 :             return AnyScalar( op(val._ulong, b.val._ulong) );
    1564                 :         }
    1565                 :             
    1566                 :         case ATTRTYPE_FLOAT:
    1567                 :         {
    1568                 :             Operator<float> op;
    1569               0 :             return AnyScalar( op(static_cast<float>(val._ulong), b.val._float));
    1570                 :         }
    1571                 : 
    1572                 :         case ATTRTYPE_DOUBLE:
    1573                 :         {
    1574                 :             Operator<double> op;
    1575               0 :             return AnyScalar( op(static_cast<double>(val._ulong), b.val._double) );
    1576                 :         }
    1577                 : 
    1578                 :         case ATTRTYPE_STRING:
    1579                 :         {
    1580               0 :             AnyScalar bc = b;
    1581                 :             
    1582               0 :             if (!bc.convertType(ATTRTYPE_QWORD))
    1583               0 :                 throw(ConversionException(std::string("Could not convert string to unsigned long long for binary operator ")+OpName+"."));
    1584                 : 
    1585                 :             Operator<unsigned long long> op;
    1586                 : 
    1587               0 :             long long bval = bc.getLong();
    1588               0 :             if (OpName == '/' && bval == 0) throw(ArithmeticException("Integer division by zero"));
    1589                 : 
    1590               0 :             return AnyScalar( op(val._ulong, bval) );
    1591                 :         }
    1592                 :         }
    1593               0 :         break;
    1594                 :     }
    1595                 : 
    1596                 :     case ATTRTYPE_FLOAT:
    1597                 :     {
    1598               0 :         switch(b.atype)
    1599                 :         {
    1600                 :         case ATTRTYPE_INVALID:
    1601               0 :             assert(0);
    1602                 :             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
    1603                 : 
    1604                 :         case ATTRTYPE_BOOL:
    1605               0 :             throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
    1606                 : 
    1607                 :         case ATTRTYPE_CHAR:
    1608                 :         case ATTRTYPE_SHORT:
    1609                 :         case ATTRTYPE_INTEGER:
    1610                 :         {
    1611                 :             Operator<float> op;
    1612               0 :             return AnyScalar( op(val._float, static_cast<float>(b.val._int)) );
    1613                 :         }
    1614                 : 
    1615                 :         case ATTRTYPE_BYTE:
    1616                 :         case ATTRTYPE_WORD:
    1617                 :         case ATTRTYPE_DWORD:
    1618                 :         {
    1619                 :             Operator<float> op;
    1620               0 :             return AnyScalar( op(val._float, static_cast<float>(b.val._uint)) );
    1621                 :         }
    1622                 :             
    1623                 :         case ATTRTYPE_LONG:
    1624                 :         {
    1625                 :             Operator<float> op;
    1626               0 :             return AnyScalar( op(val._float, static_cast<float>(b.val._long)) );
    1627                 :         }
    1628                 : 
    1629                 :         case ATTRTYPE_QWORD:
    1630                 :         {
    1631                 :             Operator<float> op;
    1632               0 :             return AnyScalar( op(val._float, static_cast<float>(b.val._ulong)) );
    1633                 :         }
    1634                 : 
    1635                 :         case ATTRTYPE_FLOAT:
    1636                 :         {
    1637                 :             Operator<float> op;
    1638               0 :             return AnyScalar( op(val._float, b.val._float));
    1639                 :         }
    1640                 : 
    1641                 :         case ATTRTYPE_DOUBLE:
    1642                 :         {
    1643                 :             Operator<double> op;
    1644               0 :             return AnyScalar( op(static_cast<double>(val._float), b.val._double) );
    1645                 :         }
    1646                 : 
    1647                 :         case ATTRTYPE_STRING:
    1648                 :         {
    1649               0 :             AnyScalar bc = b;
    1650                 :             
    1651               0 :             if (!bc.convertType(ATTRTYPE_FLOAT))
    1652               0 :                 throw(ConversionException(std::string("Could not convert string to float for binary operator ")+OpName+"."));
    1653                 : 
    1654                 :             Operator<float> op;
    1655                 : 
    1656               0 :             return AnyScalar( op(val._float, bc.val._float) );
    1657                 :         }
    1658                 :         }
    1659                 : 
    1660               0 :         break;
    1661                 :     }
    1662                 : 
    1663                 :     case ATTRTYPE_DOUBLE:
    1664                 :     {
    1665               3 :         switch(b.atype)
    1666                 :         {
    1667                 :         case ATTRTYPE_INVALID:
    1668               0 :             assert(0);
    1669                 :             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
    1670                 : 
    1671                 :         case ATTRTYPE_BOOL:
    1672               0 :             throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
    1673                 : 
    1674                 :         case ATTRTYPE_CHAR:
    1675                 :         case ATTRTYPE_SHORT:
    1676                 :         case ATTRTYPE_INTEGER:
    1677                 :         {
    1678                 :             Operator<double> op;
    1679               2 :             return AnyScalar( op(val._double, static_cast<double>(b.val._int)) );
    1680                 :         }
    1681                 : 
    1682                 :         case ATTRTYPE_BYTE:
    1683                 :         case ATTRTYPE_WORD:
    1684                 :         case ATTRTYPE_DWORD:
    1685                 :         {
    1686                 :             Operator<double> op;
    1687               0 :             return AnyScalar( op(val._double, static_cast<double>(b.val._uint)) );
    1688                 :         }
    1689                 :             
    1690                 :         case ATTRTYPE_LONG:
    1691                 :         {
    1692                 :             Operator<double> op;
    1693               0 :             return AnyScalar( op(val._double, static_cast<double>(b.val._long)) );
    1694                 :         }
    1695                 : 
    1696                 :         case ATTRTYPE_QWORD:
    1697                 :         {
    1698                 :             Operator<double> op;
    1699               0 :             return AnyScalar( op(val._double, static_cast<double>(b.val._ulong)) );
    1700                 :         }
    1701                 : 
    1702                 :         case ATTRTYPE_FLOAT:
    1703                 :         {
    1704                 :             Operator<double> op;
    1705               0 :             return AnyScalar( op(val._double, static_cast<double>(b.val._float)));
    1706                 :         }
    1707                 : 
    1708                 :         case ATTRTYPE_DOUBLE:
    1709                 :         {
    1710                 :             Operator<double> op;
    1711               1 :             return AnyScalar( op(val._double, b.val._double) );
    1712                 :         }
    1713                 : 
    1714                 :         case ATTRTYPE_STRING:
    1715                 :         {
    1716               0 :             AnyScalar bc = b;
    1717                 :             
    1718               0 :             if (!bc.convertType(ATTRTYPE_DOUBLE))
    1719               0 :                 throw(ConversionException(std::string("Could not convert string to double for binary operator ")+OpName+"."));
    1720                 : 
    1721                 :             Operator<double> op;
    1722                 : 
    1723               0 :             return AnyScalar( op(val._double, bc.getDouble()) );
    1724                 :         }
    1725                 :         }
    1726                 : 
    1727               0 :         break;
    1728                 :     }
    1729                 : 
    1730                 :     // if this is a string, then the other type defines the conversion
    1731                 :     case ATTRTYPE_STRING:
    1732                 :     {
    1733               4 :         switch(b.atype)
    1734                 :         {
    1735                 :         case ATTRTYPE_INVALID:
    1736               0 :             assert(0);
    1737                 :             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
    1738                 : 
    1739                 :         case ATTRTYPE_BOOL:
    1740               0 :             throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
    1741                 : 
    1742                 :         case ATTRTYPE_CHAR:
    1743                 :         case ATTRTYPE_SHORT:
    1744                 :         case ATTRTYPE_INTEGER:
    1745                 :         {
    1746                 :             Operator<int> op;
    1747               0 :             if (OpName == '/' && b.val._int == 0) throw(ArithmeticException("Integer division by zero"));
    1748               0 :             return AnyScalar( op(this->getInteger(), b.val._int) );
    1749                 :         }
    1750                 : 
    1751                 :         case ATTRTYPE_BYTE:
    1752                 :         case ATTRTYPE_WORD:
    1753                 :         case ATTRTYPE_DWORD:
    1754                 :         {
    1755                 :             Operator<unsigned int> op;
    1756               0 :             if (OpName == '/' && b.val._uint == 0) throw(ArithmeticException("Integer division by zero"));
    1757               0 :             return AnyScalar( op(this->getUnsignedInteger(), b.val._uint) );
    1758                 :         }
    1759                 :             
    1760                 :         case ATTRTYPE_LONG:
    1761                 :         {
    1762                 :             Operator<long long> op;
    1763               0 :             if (OpName == '/' && b.val._long == 0) throw(ArithmeticException("Integer division by zero"));
    1764               0 :             return AnyScalar( op(this->getLong(), b.val._long) );
    1765                 :         }
    1766                 : 
    1767                 :         case ATTRTYPE_QWORD:
    1768                 :         {
    1769                 :             Operator<unsigned long long> op;
    1770               0 :             if (OpName == '/' && b.val._ulong == 0) throw(ArithmeticException("Integer division by zero"));
    1771               0 :             return AnyScalar( op(this->getUnsignedLong(), b.val._ulong) );
    1772                 :         }
    1773                 : 
    1774                 :         case ATTRTYPE_FLOAT:
    1775                 :         {
    1776                 :             Operator<float> op;
    1777               0 :             return AnyScalar( op(static_cast<float>(this->getDouble()), b.val._float) );
    1778                 :         }
    1779                 : 
    1780                 :         case ATTRTYPE_DOUBLE:
    1781                 :         {
    1782                 :             Operator<double> op;
    1783               1 :             return AnyScalar( op(this->getDouble(), b.val._double) );
    1784                 :         }
    1785                 : 
    1786                 :         case ATTRTYPE_STRING:
    1787                 :             if (OpName == '+')
    1788                 :             {
    1789               3 :                 return AnyScalar( *val._string + *b.val._string );
    1790                 :             }
    1791                 : 
    1792               0 :             throw(ConversionException(std::string("Binary operator ")+OpName+" is not allowed between two string values."));
    1793                 :         }
    1794                 :         break;
    1795                 :     }
    1796                 :     }
    1797               0 :     assert(0);
    1798                 :     throw(ConversionException("Invalid binary operator call. (PROGRAM ERROR)"));
    1799                 : }
    1800                 : 
    1801                 : // *** Force instantiation of binary_op for the four arithmetic operators
    1802                 : 
    1803                 : /// Forced instantiation of binary_arith_op for AnyScalar::operator+()
    1804                 : template AnyScalar AnyScalar::binary_arith_op<std::plus, '+'>(const AnyScalar &b) const;
    1805                 : 
    1806                 : /// Forced instantiation of binary_arith_op for AnyScalar::operator-()
    1807                 : template AnyScalar AnyScalar::binary_arith_op<std::minus, '-'>(const AnyScalar &b) const;
    1808                 : 
    1809                 : /// Forced instantiation of binary_arith_op for AnyScalar::operator*()
    1810                 : template AnyScalar AnyScalar::binary_arith_op<std::multiplies, '*'>(const AnyScalar &b) const;
    1811                 : 
    1812                 : /// Forced instantiation of binary_arith_op for AnyScalar::operator/()
    1813                 : template AnyScalar AnyScalar::binary_arith_op<std::divides, '/'>(const AnyScalar &b) const;
    1814                 : 
    1815                 : template <template <typename Type> class Operator, int OpNum>
    1816                 : bool AnyScalar::binary_comp_op(const AnyScalar &b) const
    1817                 : {
    1818                 :     static const char *OpNameArray[] = { "==", "!=", "<", ">", "<=", ">=" };
    1819                 : 
    1820              15 :     switch(atype)
    1821                 :     {
    1822                 :     case ATTRTYPE_INVALID:
    1823               0 :         assert(0);
    1824                 :         throw(ConversionException(std::string("Invalid type for first operand of binary operator ")+OpNameArray[OpNum]+"."));
    1825                 : 
    1826                 :     case ATTRTYPE_BOOL:
    1827                 :     {
    1828               0 :         switch(b.atype)
    1829                 :         {
    1830                 :         case ATTRTYPE_INVALID:
    1831               0 :             assert(0);
    1832                 :             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
    1833                 : 
    1834                 :         case ATTRTYPE_BOOL:
    1835                 :         {
    1836                 :             Operator<bool> op;
    1837               0 :             return op(val._int, b.val._int);
    1838                 :         }
    1839                 : 
    1840                 :         default:
    1841               0 :             throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
    1842                 :         }
    1843                 :         break;
    1844                 :     }
    1845                 : 
    1846                 :     case ATTRTYPE_CHAR:
    1847                 :     case ATTRTYPE_SHORT:
    1848                 :     case ATTRTYPE_INTEGER:
    1849                 :     {
    1850              12 :         switch(b.atype)
    1851                 :         {
    1852                 :         case ATTRTYPE_INVALID:
    1853               0 :             assert(0);
    1854                 :             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
    1855                 : 
    1856                 :         case ATTRTYPE_BOOL:
    1857               0 :             throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
    1858                 : 
    1859                 :         case ATTRTYPE_CHAR:
    1860                 :         case ATTRTYPE_SHORT:
    1861                 :         case ATTRTYPE_INTEGER:
    1862                 :         {
    1863                 :             Operator<int> op;
    1864              12 :             return op(val._int, b.val._int);
    1865                 :         }
    1866                 : 
    1867                 :         case ATTRTYPE_BYTE:
    1868                 :         case ATTRTYPE_WORD:
    1869                 :         case ATTRTYPE_DWORD:
    1870                 :         {
    1871                 :             Operator<int> op;
    1872               0 :             return op(val._int, static_cast<signed int>(b.val._uint));
    1873                 :         }
    1874                 : 
    1875                 :         case ATTRTYPE_LONG:
    1876                 :         {
    1877                 :             Operator<long long> op;
    1878               0 :             return op(val._int, b.val._long);
    1879                 :         }
    1880                 : 
    1881                 :         case ATTRTYPE_QWORD:
    1882                 :         {
    1883                 :             Operator<long long> op;
    1884               0 :             return op(val._int, static_cast<signed long long>(b.val._ulong));
    1885                 :         }
    1886                 : 
    1887                 :         case ATTRTYPE_FLOAT:
    1888                 :         {
    1889                 :             Operator<float> op;
    1890               0 :             return op(static_cast<float>(val._int), b.val._float);
    1891                 :         }
    1892                 : 
    1893                 :         case ATTRTYPE_DOUBLE:
    1894                 :         {
    1895                 :             Operator<double> op;
    1896               0 :             return op(static_cast<double>(val._int), b.val._double);
    1897                 :         }
    1898                 : 
    1899                 :         case ATTRTYPE_STRING:
    1900                 :         {
    1901               0 :             AnyScalar bc = b;
    1902                 :             
    1903               0 :             if (!bc.convertType(ATTRTYPE_INTEGER))
    1904               0 :                 throw(ConversionException(std::string("Could not convert string to integer for binary operator ")+OpNameArray[OpNum]+"."));
    1905                 : 
    1906                 :             Operator<int> op;
    1907                 : 
    1908               0 :             return op(val._int, bc.getInteger());
    1909                 :         }
    1910                 :         }
    1911               0 :         break;
    1912                 :     }
    1913                 : 
    1914                 :     case ATTRTYPE_BYTE:
    1915                 :     case ATTRTYPE_WORD:
    1916                 :     case ATTRTYPE_DWORD:
    1917                 :     {
    1918               0 :         switch(b.atype)
    1919                 :         {
    1920                 :         case ATTRTYPE_INVALID:
    1921               0 :             assert(0);
    1922                 :             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
    1923                 : 
    1924                 :         case ATTRTYPE_BOOL:
    1925               0 :             throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
    1926                 : 
    1927                 :         case ATTRTYPE_CHAR:
    1928                 :         case ATTRTYPE_SHORT:
    1929                 :         case ATTRTYPE_INTEGER:
    1930                 :         {
    1931                 :             Operator<int> op;
    1932               0 :             return op(static_cast<signed int>(val._uint), b.val._int);
    1933                 :         }
    1934                 : 
    1935                 :         case ATTRTYPE_BYTE:
    1936                 :         case ATTRTYPE_WORD:
    1937                 :         case ATTRTYPE_DWORD:
    1938                 :         {
    1939                 :             Operator<unsigned int> op;
    1940               0 :             return op(val._uint, b.val._uint);
    1941                 :         }
    1942                 :             
    1943                 :         case ATTRTYPE_LONG:
    1944                 :         {
    1945                 :             Operator<long long> op;
    1946               0 :             return op(static_cast<signed long long>(val._uint), b.val._long);
    1947                 :         }
    1948                 : 
    1949                 :         case ATTRTYPE_QWORD:
    1950                 :         {
    1951                 :             Operator<unsigned long long> op;
    1952               0 :             return op(static_cast<unsigned long long>(val._uint), b.val._ulong);
    1953                 :         }
    1954                 : 
    1955                 :         case ATTRTYPE_FLOAT:
    1956                 :         {
    1957                 :             Operator<float> op;
    1958               0 :             return op(static_cast<float>(val._uint), b.val._float);
    1959                 :         }
    1960                 : 
    1961                 :         case ATTRTYPE_DOUBLE:
    1962                 :         {
    1963                 :             Operator<double> op;
    1964               0 :             return op(static_cast<double>(val._uint), b.val._double);
    1965                 :         }
    1966                 : 
    1967                 :         case ATTRTYPE_STRING:
    1968                 :         {
    1969               0 :             AnyScalar bc = b;
    1970                 :             
    1971               0 :             if (!bc.convertType(ATTRTYPE_DWORD))
    1972               0 :                 throw(ConversionException(std::string("Could not convert string to unsigned integer for binary operator ")+OpNameArray[OpNum]+"."));
    1973                 : 
    1974                 :             Operator<unsigned int> op;
    1975                 : 
    1976               0 :             return op(val._int, bc.getInteger());
    1977                 :         }
    1978                 :         }
    1979               0 :         break;
    1980                 :     }
    1981                 : 
    1982                 :     case ATTRTYPE_LONG:
    1983                 :     {
    1984               0 :         switch(b.atype)
    1985                 :         {
    1986                 :         case ATTRTYPE_INVALID:
    1987               0 :             assert(0);
    1988                 :             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
    1989                 : 
    1990                 :         case ATTRTYPE_BOOL:
    1991               0 :             throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
    1992                 : 
    1993                 :         case ATTRTYPE_CHAR:
    1994                 :         case ATTRTYPE_SHORT:
    1995                 :         case ATTRTYPE_INTEGER:
    1996                 :         {
    1997                 :             Operator<long long> op;
    1998               0 :             return op(val._long, static_cast<long long>(b.val._int));
    1999                 :         }
    2000                 : 
    2001                 :         case ATTRTYPE_BYTE:
    2002                 :         case ATTRTYPE_WORD:
    2003                 :         case ATTRTYPE_DWORD:
    2004                 :         {
    2005                 :             Operator<long long> op;
    2006               0 :             return op(val._long, static_cast<signed long long>(b.val._uint));
    2007                 :         }
    2008                 : 
    2009                 :         case ATTRTYPE_LONG:
    2010                 :         {
    2011                 :             Operator<long long> op;
    2012               0 :             return op(val._long, b.val._long);
    2013                 :         }
    2014                 : 
    2015                 :         case ATTRTYPE_QWORD:
    2016                 :         {
    2017                 :             Operator<long long> op;
    2018               0 :             return op(val._long, static_cast<signed long long>(b.val._ulong));
    2019                 :         }
    2020                 : 
    2021                 :         case ATTRTYPE_FLOAT:
    2022                 :         {
    2023                 :             Operator<float> op;
    2024               0 :             return op(static_cast<float>(val._long), b.val._float);
    2025                 :         }
    2026                 : 
    2027                 :         case ATTRTYPE_DOUBLE:
    2028                 :         {
    2029                 :             Operator<double> op;
    2030               0 :             return op(static_cast<double>(val._long), b.val._double);
    2031                 :         }
    2032                 : 
    2033                 :         case ATTRTYPE_STRING:
    2034                 :         {
    2035               0 :             AnyScalar bc = b;
    2036                 :             
    2037               0 :             if (!bc.convertType(ATTRTYPE_LONG))
    2038               0 :                 throw(ConversionException(std::string("Could not convert string to long long for binary operator ")+OpNameArray[OpNum]+"."));
    2039                 : 
    2040                 :             Operator<long long> op;
    2041                 : 
    2042               0 :             return op(val._long, bc.getLong());
    2043                 :         }
    2044                 :         }
    2045               0 :         break;
    2046                 :     }
    2047                 : 
    2048                 :     case ATTRTYPE_QWORD:
    2049                 :     {
    2050               0 :         switch(b.atype)
    2051                 :         {
    2052                 :         case ATTRTYPE_INVALID:
    2053               0 :             assert(0);
    2054                 :             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
    2055                 : 
    2056                 :         case ATTRTYPE_BOOL:
    2057               0 :             throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
    2058                 : 
    2059                 :         case ATTRTYPE_CHAR:
    2060                 :         case ATTRTYPE_SHORT:
    2061                 :         case ATTRTYPE_INTEGER:
    2062                 :         {
    2063                 :             Operator<long long> op;
    2064               0 :             return op(val._ulong, static_cast<signed long long>(b.val._int));
    2065                 :         }
    2066                 : 
    2067                 :         case ATTRTYPE_BYTE:
    2068                 :         case ATTRTYPE_WORD:
    2069                 :         case ATTRTYPE_DWORD:
    2070                 :         {
    2071                 :             Operator<unsigned long long> op;
    2072               0 :             return op(val._ulong, b.val._uint);
    2073                 :         }
    2074                 :             
    2075                 :         case ATTRTYPE_LONG:
    2076                 :         {
    2077                 :             Operator<long long> op;
    2078               0 :             return op(static_cast<signed long long>(val._ulong), b.val._long);
    2079                 :         }
    2080                 : 
    2081                 :         case ATTRTYPE_QWORD:
    2082                 :         {
    2083                 :             Operator<unsigned long long> op;
    2084               0 :             return op(val._ulong, b.val._ulong);
    2085                 :         }
    2086                 : 
    2087                 :         case ATTRTYPE_FLOAT:
    2088                 :         {
    2089                 :             Operator<float> op;
    2090               0 :             return op(static_cast<float>(val._ulong), b.val._float);
    2091                 :         }
    2092                 : 
    2093                 :         case ATTRTYPE_DOUBLE:
    2094                 :         {
    2095                 :             Operator<double> op;
    2096               0 :             return op(static_cast<double>(val._ulong), b.val._double);
    2097                 :         }
    2098                 : 
    2099                 :         case ATTRTYPE_STRING:
    2100                 :         {
    2101               0 :             AnyScalar bc = b;
    2102                 :             
    2103               0 :             if (!bc.convertType(ATTRTYPE_QWORD))
    2104               0 :                 throw(ConversionException(std::string("Could not convert string to unsigned long long for binary operator ")+OpNameArray[OpNum]+"."));
    2105                 : 
    2106                 :             Operator<unsigned long long> op;
    2107                 : 
    2108               0 :             return op(val._int, bc.getUnsignedLong());
    2109                 :         }
    2110                 :         }
    2111               0 :         break;
    2112                 :     }
    2113                 : 
    2114                 :     case ATTRTYPE_FLOAT:
    2115                 :     {
    2116               0 :         switch(b.atype)
    2117                 :         {
    2118                 :         case ATTRTYPE_INVALID:
    2119               0 :             assert(0);
    2120                 :             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
    2121                 : 
    2122                 :         case ATTRTYPE_BOOL:
    2123               0 :             throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
    2124                 : 
    2125                 :         case ATTRTYPE_CHAR:
    2126                 :         case ATTRTYPE_SHORT:
    2127                 :         case ATTRTYPE_INTEGER:
    2128                 :         {
    2129                 :             Operator<float> op;
    2130               0 :             return op(val._float, static_cast<float>(b.val._int));
    2131                 :         }
    2132                 : 
    2133                 :         case ATTRTYPE_BYTE:
    2134                 :         case ATTRTYPE_WORD:
    2135                 :         case ATTRTYPE_DWORD:
    2136                 :         {
    2137                 :             Operator<float> op;
    2138               0 :             return op(val._float, static_cast<float>(b.val._uint));
    2139                 :         }
    2140                 :             
    2141                 :         case ATTRTYPE_LONG:
    2142                 :         {
    2143                 :             Operator<float> op;
    2144               0 :             return op(val._float, static_cast<float>(b.val._long));
    2145                 :         }
    2146                 : 
    2147                 :         case ATTRTYPE_QWORD:
    2148                 :         {
    2149                 :             Operator<float> op;
    2150               0 :             return op(val._float, static_cast<float>(b.val._ulong));
    2151                 :         }
    2152                 :             
    2153                 :         case ATTRTYPE_FLOAT:
    2154                 :         {
    2155                 :             Operator<float> op;
    2156               0 :             return op(val._float, b.val._float);
    2157                 :         }
    2158                 : 
    2159                 :         case ATTRTYPE_DOUBLE:
    2160                 :         {
    2161                 :             Operator<double> op;
    2162               0 :             return op(static_cast<double>(val._float), b.val._double);
    2163                 :         }
    2164                 : 
    2165                 :         case ATTRTYPE_STRING:
    2166                 :         {
    2167               0 :             AnyScalar bc = b;
    2168                 :             
    2169               0 :             if (!bc.convertType(ATTRTYPE_FLOAT))
    2170               0 :                 throw(ConversionException(std::string("Could not convert string to float for binary operator ")+OpNameArray[OpNum]+"."));
    2171                 : 
    2172                 :             Operator<float> op;
    2173                 : 
    2174               0 :             return op(val._float, bc.val._float);
    2175                 :         }
    2176                 :         }
    2177                 : 
    2178               0 :         break;
    2179                 :     }
    2180                 : 
    2181                 :     case ATTRTYPE_DOUBLE:
    2182                 :     {
    2183               3 :         switch(b.atype)
    2184                 :         {
    2185                 :         case ATTRTYPE_INVALID:
    2186               0 :             assert(0);
    2187                 :             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
    2188                 : 
    2189                 :         case ATTRTYPE_BOOL:
    2190               0 :             throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
    2191                 : 
    2192                 :         case ATTRTYPE_CHAR:
    2193                 :         case ATTRTYPE_SHORT:
    2194                 :         case ATTRTYPE_INTEGER:
    2195                 :         {
    2196                 :             Operator<double> op;
    2197               2 :             return op(val._double, static_cast<double>(b.val._int));
    2198                 :         }
    2199                 : 
    2200                 :         case ATTRTYPE_BYTE:
    2201                 :         case ATTRTYPE_WORD:
    2202                 :         case ATTRTYPE_DWORD:
    2203                 :         {
    2204                 :             Operator<double> op;
    2205               0 :             return op(val._double, static_cast<double>(b.val._uint));
    2206                 :         }
    2207                 :             
    2208                 :         case ATTRTYPE_LONG:
    2209                 :         {
    2210                 :             Operator<double> op;
    2211               0 :             return op(val._double, static_cast<double>(b.val._long));
    2212                 :         }
    2213                 : 
    2214                 :         case ATTRTYPE_QWORD:
    2215                 :         {
    2216                 :             Operator<double> op;
    2217               0 :             return op(val._double, static_cast<double>(b.val._ulong));
    2218                 :         }
    2219                 :             
    2220                 :         case ATTRTYPE_FLOAT:
    2221                 :         {
    2222                 :             Operator<double> op;
    2223               0 :             return op(val._double, static_cast<double>(b.val._float));
    2224                 :         }
    2225                 : 
    2226                 :         case ATTRTYPE_DOUBLE:
    2227                 :         {
    2228                 :             Operator<double> op;
    2229               1 :             return op(val._double, b.val._double);
    2230                 :         }
    2231                 : 
    2232                 :         case ATTRTYPE_STRING:
    2233                 :         {
    2234               0 :             AnyScalar bc = b;
    2235                 :             
    2236               0 :             if (!bc.convertType(ATTRTYPE_DOUBLE))
    2237               0 :                 throw(ConversionException(std::string("Could not convert string to double for binary operator ")+OpNameArray[OpNum]+"."));
    2238                 : 
    2239                 :             Operator<double> op;
    2240                 : 
    2241               0 :             return op(val._double, bc.getDouble());
    2242                 :         }
    2243                 :         }
    2244                 : 
    2245               0 :         break;
    2246                 :     }
    2247                 : 
    2248                 :     // if this is a string, then the other type defines the conversion
    2249                 :     case ATTRTYPE_STRING:
    2250                 :     {
    2251               0 :         switch(b.atype)
    2252                 :         {
    2253                 :         case ATTRTYPE_INVALID:
    2254               0 :             assert(0);
    2255                 :             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
    2256                 : 
    2257                 :         case ATTRTYPE_BOOL:
    2258               0 :             throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
    2259                 : 
    2260                 :         case ATTRTYPE_CHAR:
    2261                 :         case ATTRTYPE_SHORT:
    2262                 :         case ATTRTYPE_INTEGER:
    2263                 :         {
    2264                 :             Operator<int> op;
    2265               0 :             return op(this->getInteger(), b.val._int);
    2266                 :         }
    2267                 : 
    2268                 :         case ATTRTYPE_BYTE:
    2269                 :         case ATTRTYPE_WORD:
    2270                 :         case ATTRTYPE_DWORD:
    2271                 :         {
    2272                 :             Operator<unsigned int> op;
    2273               0 :             return op(this->getUnsignedInteger(), b.val._int);
    2274                 :         }
    2275                 :             
    2276                 :         case ATTRTYPE_LONG:
    2277                 :         {
    2278                 :             Operator<long long> op;
    2279               0 :             return op(this->getLong(), b.val._long);
    2280                 :         }
    2281                 : 
    2282                 :         case ATTRTYPE_QWORD:
    2283                 :         {
    2284                 :             Operator<unsigned long long> op;
    2285               0 :             return op(this->getUnsignedLong(), b.val._ulong);
    2286                 :         }
    2287                 : 
    2288                 :         case ATTRTYPE_FLOAT:
    2289                 :         {
    2290                 :             Operator<float> op;
    2291               0 :             return op(static_cast<float>(this->getDouble()), b.val._float);
    2292                 :         }
    2293                 : 
    2294                 :         case ATTRTYPE_DOUBLE:
    2295                 :         {
    2296                 :             Operator<double> op;
    2297               0 :             return op(this->getDouble(), b.val._double);
    2298                 :         }
    2299                 : 
    2300                 :         case ATTRTYPE_STRING:
    2301                 :         {
    2302                 :             Operator<std::string> op;
    2303               0 :             return op(*val._string, *b.val._string);
    2304                 :         }
    2305                 :         }
    2306                 :         break;
    2307                 :     }
    2308                 :     }
    2309               0 :     assert(0);
    2310                 :     throw(ConversionException("Invalid binary operator call. (PROGRAM ERROR)"));
    2311                 : }
    2312                 : 
    2313                 : /// Forced instantiation of binary_comp_op for AnyScalar::equal_to()
    2314                 : template bool AnyScalar::binary_comp_op<std::equal_to, 0>(const AnyScalar &b) const;
    2315                 : 
    2316                 : /// Forced instantiation of binary_comp_op for AnyScalar::not_equal_to()
    2317                 : template bool AnyScalar::binary_comp_op<std::not_equal_to, 1>(const AnyScalar &b) const;
    2318                 : 
    2319                 : /// Forced instantiation of binary_comp_op for AnyScalar::less()
    2320                 : template bool AnyScalar::binary_comp_op<std::less, 2>(const AnyScalar &b) const;
    2321                 : 
    2322                 : /// Forced instantiation of binary_comp_op for AnyScalar::greater()
    2323                 : template bool AnyScalar::binary_comp_op<std::greater, 3>(const AnyScalar &b) const;
    2324                 : 
    2325                 : /// Forced instantiation of binary_comp_op for AnyScalar::less_equal()
    2326                 : template bool AnyScalar::binary_comp_op<std::less_equal, 4>(const AnyScalar &b) const;
    2327                 : 
    2328                 : /// Forced instantiation of binary_comp_op for AnyScalar::greater_equal()
    2329                 : template bool AnyScalar::binary_comp_op<std::greater_equal, 5>(const AnyScalar &b) const;
    2330               0 : 
    2331                 : } // namespace stx

Generated by: LTP GCOV extension version 1.4