libstx-exparser/AnyScalar.cc

Go to the documentation of this file.
00001 // $Id: AnyScalar.cc 59 2007-07-17 14:43:23Z tb $
00002 
00003 /*
00004  * STX Expression Parser C++ Framework v0.7
00005  * Copyright (C) 2007 Timo Bingmann
00006  *
00007  * This library is free software; you can redistribute it and/or modify it
00008  * under the terms of the GNU Lesser General Public License as published by the
00009  * Free Software Foundation; either version 2.1 of the License, or (at your
00010  * option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
00015  * for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public License
00018  * along with this library; if not, write to the Free Software Foundation,
00019  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00027 #include "AnyScalar.h"
00028 #include "ExpressionParser.h"
00029 
00030 #include <stdlib.h>
00031 #include <functional>
00032 #include <algorithm>
00033 
00034 #include <boost/lexical_cast.hpp>
00035 
00036 namespace stx {
00037 
00038 bool AnyScalar::operator==(const AnyScalar &a) const
00039 {
00040     if (atype != a.atype) return false;
00041 
00042     switch(atype)
00043     {
00044     case ATTRTYPE_INVALID:
00045         assert(0);
00046         return false;
00047 
00048     case ATTRTYPE_BOOL:
00049     case ATTRTYPE_CHAR:
00050     case ATTRTYPE_SHORT:
00051     case ATTRTYPE_INTEGER:
00052         return (val._int == a.val._int);
00053 
00054     case ATTRTYPE_BYTE:
00055     case ATTRTYPE_WORD:
00056     case ATTRTYPE_DWORD:
00057         return (val._uint == a.val._uint);
00058 
00059     case ATTRTYPE_LONG:
00060         return (val._long == a.val._long);
00061 
00062     case ATTRTYPE_QWORD:
00063         return (val._ulong == a.val._ulong);
00064 
00065     case ATTRTYPE_FLOAT:
00066         return (val._float == a.val._float);
00067 
00068     case ATTRTYPE_DOUBLE:
00069         return (val._double == a.val._double);
00070 
00071     case ATTRTYPE_STRING:
00072         assert(val._string && a.val._string);
00073         return (*val._string == *a.val._string);
00074     }
00075 
00076     assert(0);
00077     return false;
00078 }
00079 
00080 AnyScalar::attrtype_t AnyScalar::stringToType(const char* s)
00081 {
00082     std::string str = s;
00083     std::transform(str.begin(), str.end(), str.begin(), tolower);
00084 
00085     // Stupid method, but maybe faster than using a biggy std::map with a
00086     // case-insensitive equality.
00087 
00088     if (str == "bool")
00089         return ATTRTYPE_BOOL;
00090 
00091     if (str == "char")
00092         return ATTRTYPE_CHAR;
00093     if (str == "short")
00094         return ATTRTYPE_SHORT;
00095     if (str == "integer" || str == "int")
00096         return ATTRTYPE_INTEGER;
00097     if (str == "long")
00098         return ATTRTYPE_LONG;
00099 
00100     if (str == "byte")
00101         return ATTRTYPE_BYTE;
00102     if (str == "word")
00103         return ATTRTYPE_WORD;
00104     if (str == "dword")
00105         return ATTRTYPE_DWORD;
00106     if (str == "qword")
00107         return ATTRTYPE_QWORD;
00108     
00109     if (str == "float")
00110         return ATTRTYPE_FLOAT;
00111     if (str == "double")
00112         return ATTRTYPE_DOUBLE;
00113 
00114     if (str == "string")
00115         return ATTRTYPE_STRING;
00116 
00117     throw(ConversionException("Invalid type name."));
00118 }
00119 
00120 bool AnyScalar::isValidAttrtype(attrtype_t at)
00121 {
00122     switch(at)
00123     {
00124     default:
00125     case ATTRTYPE_INVALID:
00126         return false;
00127 
00128     case ATTRTYPE_BOOL:
00129     case ATTRTYPE_CHAR:
00130     case ATTRTYPE_SHORT:
00131     case ATTRTYPE_INTEGER:
00132     case ATTRTYPE_LONG:
00133     case ATTRTYPE_BYTE:
00134     case ATTRTYPE_WORD:
00135     case ATTRTYPE_DWORD:
00136     case ATTRTYPE_QWORD:
00137     case ATTRTYPE_FLOAT:
00138     case ATTRTYPE_DOUBLE:
00139     case ATTRTYPE_STRING:
00140         return true;
00141     }
00142 }
00143 
00144 std::string AnyScalar::getTypeString(attrtype_t at)
00145 {
00146     switch(at)
00147     {
00148     case ATTRTYPE_INVALID:      return "invalid";
00149     case ATTRTYPE_BOOL:         return "bool";
00150     case ATTRTYPE_CHAR:         return "char";
00151     case ATTRTYPE_SHORT:        return "short";
00152     case ATTRTYPE_INTEGER:      return "integer";
00153     case ATTRTYPE_LONG:         return "long";
00154     case ATTRTYPE_BYTE:         return "byte";
00155     case ATTRTYPE_WORD:         return "word";
00156     case ATTRTYPE_DWORD:        return "dword";
00157     case ATTRTYPE_QWORD:        return "qword";
00158     case ATTRTYPE_FLOAT:        return "float";
00159     case ATTRTYPE_DOUBLE:       return "double";
00160     case ATTRTYPE_STRING:       return "string";
00161     }
00162     return "unknown";
00163 }
00164 
00165 int AnyScalar::getTypeLength(attrtype_t t)
00166 {
00167     switch(t)
00168     {
00169     case ATTRTYPE_INVALID:
00170         assert(0);
00171         return 0;
00172 
00173     case ATTRTYPE_BOOL:
00174         // weird value. beware!
00175         return 0;
00176 
00177     case ATTRTYPE_CHAR:
00178         return sizeof(char);
00179 
00180     case ATTRTYPE_BYTE:
00181         return sizeof(unsigned char);
00182 
00183     case ATTRTYPE_SHORT:
00184         return sizeof(short);
00185 
00186     case ATTRTYPE_WORD:
00187         return sizeof(unsigned short);
00188 
00189     case ATTRTYPE_INTEGER:
00190         return sizeof(int);
00191 
00192     case ATTRTYPE_DWORD:
00193         return sizeof(unsigned int);
00194 
00195     case ATTRTYPE_LONG:
00196         return sizeof(long long);
00197 
00198     case ATTRTYPE_QWORD:
00199         return sizeof(unsigned long long);
00200 
00201     case ATTRTYPE_FLOAT:
00202         return sizeof(float);
00203 
00204     case ATTRTYPE_DOUBLE:
00205         return sizeof(double);
00206 
00207     case ATTRTYPE_STRING:
00208         return -1;
00209 
00210     }
00211     assert(0);
00212     return -1;
00213 }
00214 
00215 unsigned int AnyScalar::getValueLength() const
00216 {
00217     switch(atype)
00218     {
00219     case ATTRTYPE_INVALID:
00220         assert(0);
00221         return 0;
00222 
00223     case ATTRTYPE_BOOL:
00224         // weird value. beware!
00225         return 0;
00226 
00227     case ATTRTYPE_CHAR:
00228         return sizeof(char);
00229 
00230     case ATTRTYPE_BYTE:
00231         return sizeof(unsigned char);
00232 
00233     case ATTRTYPE_SHORT:
00234         return sizeof(short);
00235 
00236     case ATTRTYPE_WORD:
00237         return sizeof(unsigned short);
00238 
00239     case ATTRTYPE_INTEGER:
00240         return sizeof(int);
00241 
00242     case ATTRTYPE_DWORD:
00243         return sizeof(unsigned int);
00244 
00245     case ATTRTYPE_LONG:
00246         return sizeof(long long);
00247 
00248     case ATTRTYPE_QWORD:
00249         return sizeof(unsigned long long);
00250 
00251     case ATTRTYPE_FLOAT:
00252         return sizeof(float);
00253 
00254     case ATTRTYPE_DOUBLE:
00255         return sizeof(double);
00256 
00257     case ATTRTYPE_STRING:
00258         assert(val._string);
00259         return sizeof(unsigned char) + static_cast<unsigned int>(val._string->size());
00260     }
00261 
00262     assert(0);
00263     return 0;
00264 }
00265 
00266 bool AnyScalar::setInteger(int i)
00267 {
00268     switch(atype)
00269     {
00270     case ATTRTYPE_INVALID:
00271         assert(0);
00272         return false;
00273 
00274     case ATTRTYPE_BOOL:
00275         val._int = (i != 0) ? 1 : 0;
00276         return true;
00277 
00278     case ATTRTYPE_CHAR:
00279         if (SCHAR_MIN <= i && i <= SCHAR_MAX) {
00280             val._int = i;
00281             return true;
00282         }
00283         if (SCHAR_MIN > i) val._int = SCHAR_MIN;
00284         if (i > SCHAR_MAX) val._int = SCHAR_MAX;
00285         return false;
00286 
00287     case ATTRTYPE_BYTE:
00288         if (i <= UCHAR_MAX) {
00289             val._uint = static_cast<unsigned char>(i);
00290             return true;
00291         }
00292         if (0 > i) val._uint = 0;
00293         if (i > UCHAR_MAX) val._uint = UCHAR_MAX;
00294         return false;
00295 
00296     case ATTRTYPE_SHORT:
00297         if (SHRT_MIN <= i && i <= SHRT_MAX) {
00298             val._int = i;
00299             return true;
00300         }
00301         if (SHRT_MIN > i) val._int = SHRT_MIN;
00302         if (i > SHRT_MAX) val._int = SHRT_MAX;
00303         return false;
00304 
00305     case ATTRTYPE_WORD:
00306         if (i <= USHRT_MAX) {
00307             val._uint = static_cast<unsigned short>(i);
00308             return true;
00309         }
00310         if (0 > i) val._uint = 0;
00311         if (i > USHRT_MAX) val._uint = USHRT_MAX;
00312         return false;
00313 
00314     case ATTRTYPE_INTEGER:
00315         if (INT_MIN <= i && i <= INT_MAX) {
00316             val._int = i;
00317             return true;
00318         }
00319         if (INT_MIN > i) val._int = INT_MIN;
00320         if (i > INT_MAX) val._int = INT_MAX;
00321         return false;
00322 
00323     case ATTRTYPE_DWORD:
00324         if (static_cast<unsigned int>(i) <= UINT_MAX) {
00325             val._uint = i;
00326             return true;
00327         }
00328         if (0 > i) val._uint = 0;
00329         return false;
00330 
00331     case ATTRTYPE_LONG:
00332         val._long = i;
00333         return true;
00334 
00335     case ATTRTYPE_QWORD:
00336         val._ulong = i;
00337         return true;
00338 
00339     case ATTRTYPE_FLOAT:
00340         val._float = static_cast<float>(i);
00341         return true;
00342 
00343     case ATTRTYPE_DOUBLE:
00344         val._double = static_cast<double>(i);
00345         return true;
00346 
00347     case ATTRTYPE_STRING:
00348         assert(val._string);
00349         *val._string = boost::lexical_cast<std::string>(i);
00350         return true;
00351     }
00352 
00353     assert(0);
00354     return false;
00355 }
00356 
00357 bool AnyScalar::setLong(long long l)
00358 {
00359     switch(atype)
00360     {
00361     case ATTRTYPE_INVALID:
00362         assert(0);
00363         return false;
00364 
00365     case ATTRTYPE_BOOL:
00366         val._int = (l != 0) ? 1 : 0;
00367         return true;
00368 
00369     case ATTRTYPE_CHAR:
00370         if (SCHAR_MIN <= l && l <= SCHAR_MAX) {
00371             val._int = static_cast<char>(l);
00372             return true;
00373         }
00374         if (SCHAR_MIN > l) val._int = SCHAR_MIN;
00375         if (l > SCHAR_MAX) val._int = SCHAR_MAX;
00376         return false;
00377 
00378     case ATTRTYPE_BYTE:
00379         if (0 <= l && l <= UCHAR_MAX) {
00380             val._uint = static_cast<unsigned char>(l);
00381             return true;
00382         }
00383         if (0 > l) val._uint = 0;
00384         if (l > UCHAR_MAX) val._uint = UCHAR_MAX;
00385         return false;
00386 
00387     case ATTRTYPE_SHORT:
00388         if (SHRT_MIN <= l && l <= SHRT_MAX) {
00389             val._int = static_cast<short>(l);
00390             return true;
00391         }
00392         if (SHRT_MIN > l) val._int = SHRT_MIN;
00393         if (l > SHRT_MAX) val._int = SHRT_MAX;
00394         return false;
00395 
00396     case ATTRTYPE_WORD:
00397         if (l <= USHRT_MAX) {
00398             val._uint = static_cast<unsigned short>(l);
00399             return true;
00400         }
00401         if (0 > l) val._uint = 0;
00402         if (l > USHRT_MAX) val._uint = USHRT_MAX;
00403         return false;
00404 
00405     case ATTRTYPE_INTEGER:
00406         if (INT_MIN <= l && l <= INT_MAX) {
00407             val._int = static_cast<int>(l);
00408             return true;
00409         }
00410         if (INT_MIN > l) val._int = INT_MIN;
00411         if (l > INT_MAX) val._int = INT_MAX;
00412         return false;
00413 
00414     case ATTRTYPE_DWORD:
00415         if (static_cast<unsigned int>(l) <= UINT_MAX) {
00416             val._uint = static_cast<unsigned int>(l);
00417             return true;
00418         }
00419         if (0 > l) val._uint = 0;
00420         if (l > UINT_MAX) val._uint = UINT_MAX;
00421         return false;
00422 
00423     case ATTRTYPE_LONG:
00424         val._long = l;
00425         return true;
00426 
00427     case ATTRTYPE_QWORD:
00428         val._ulong = l;
00429         return true;
00430 
00431     case ATTRTYPE_FLOAT:
00432         val._float = static_cast<float>(l);
00433         return true;
00434 
00435     case ATTRTYPE_DOUBLE:
00436         val._double = static_cast<double>(l);
00437         return true;
00438 
00439     case ATTRTYPE_STRING:
00440         assert(val._string);
00441         *val._string = boost::lexical_cast<std::string>(l);
00442         return true;
00443     }
00444 
00445     assert(0);
00446     return false;
00447 }
00448 
00449 bool AnyScalar::setDouble(double d)
00450 {
00451     switch(atype)
00452     {
00453     case ATTRTYPE_INVALID:
00454         assert(0);
00455         return false;
00456 
00457     case ATTRTYPE_BOOL:
00458         if (0 <= d && d < 0.5) {
00459             val._int = 0;
00460             return true;
00461         }
00462         if (0.5 <= d && d <= 1) {
00463             val._int = 1;
00464             return true;
00465         }
00466         val._int = 1;
00467         return false;
00468 
00469     case ATTRTYPE_CHAR:
00470     case ATTRTYPE_SHORT:
00471     case ATTRTYPE_INTEGER:
00472         return setInteger( static_cast<int>(d) );
00473 
00474     case ATTRTYPE_LONG:
00475         return setLong( static_cast<long long>(d) );
00476 
00477     case ATTRTYPE_BYTE:
00478     case ATTRTYPE_WORD:
00479     case ATTRTYPE_DWORD:
00480         return setInteger( static_cast<unsigned int>(d) );
00481 
00482     case ATTRTYPE_QWORD:
00483         return setLong( static_cast<unsigned long long>(d) );
00484 
00485     case ATTRTYPE_FLOAT:
00486         val._float = static_cast<float>(d);
00487         return true;
00488 
00489     case ATTRTYPE_DOUBLE:
00490         val._double = d;
00491         return true;
00492 
00493     case ATTRTYPE_STRING:
00494         assert(val._string);
00495         *val._string = boost::lexical_cast<std::string>(d);
00496         return true;
00497     }
00498 
00499     assert(0);
00500     return false;
00501 }
00502 
00503 bool AnyScalar::setString(const std::string &s)
00504 {
00505     switch(atype)
00506     {
00507     case ATTRTYPE_INVALID:
00508         assert(0);
00509         return false;
00510 
00511     case ATTRTYPE_BOOL:
00512         if (s == "0" || s == "f" || s == "false" || s == "n" || s == "no") {
00513             val._int = 0;
00514             return true;
00515         }
00516         if (s == "1" || s == "t" || s == "true" || s == "y" || s == "yes") {
00517             val._int = 1;
00518             return true;
00519         }
00520         return false;
00521 
00522     case ATTRTYPE_CHAR:
00523     case ATTRTYPE_SHORT:
00524     case ATTRTYPE_INTEGER:
00525     {
00526         char *endptr;
00527         long i = strtol(s.c_str(), &endptr, 10);
00528         if (endptr != NULL && *endptr == 0)
00529             return setInteger(i);
00530         return false;
00531     }
00532 
00533     case ATTRTYPE_LONG:
00534     {
00535         char *endptr;
00536 #ifndef _MSC_VER
00537         long long l = strtoll(s.c_str(), &endptr, 10);
00538 #else
00539         long long l = _strtoi64(s.c_str(), &endptr, 10);
00540 #endif
00541         if (endptr != NULL && *endptr == 0)
00542             return setLong(l);
00543         return false;
00544     }
00545 
00546     case ATTRTYPE_BYTE:
00547     case ATTRTYPE_WORD:
00548     case ATTRTYPE_DWORD:
00549     {
00550         char *endptr;
00551         unsigned long u = strtoul(s.c_str(), &endptr, 10);
00552         if (endptr != NULL && *endptr == 0)
00553             return setInteger(u);
00554         return false;
00555     }
00556     
00557     case ATTRTYPE_QWORD:
00558     {
00559         char *endptr;
00560 #ifndef _MSC_VER
00561         unsigned long long u = strtoull(s.c_str(), &endptr, 10);
00562 #else
00563         unsigned long long u = _strtoui64(s.c_str(), &endptr, 10);
00564 #endif
00565         if (endptr != NULL && *endptr == 0)
00566             return setLong(u);
00567         return false;
00568     }
00569 
00570     case ATTRTYPE_FLOAT:
00571     {
00572         char *endptr;
00573         float f = static_cast<float>(strtod(s.c_str(), &endptr));
00574         if (endptr != NULL && *endptr == 0) {
00575             val._float = f;
00576             return true;
00577         }
00578         return false;
00579     }
00580 
00581     case ATTRTYPE_DOUBLE:
00582     {
00583         char *endptr;
00584         double d = strtod(s.c_str(), &endptr);
00585         if (endptr != NULL && *endptr == 0) {
00586             val._double = d;
00587             return true;
00588         }
00589         return false;
00590     }
00591 
00592     case ATTRTYPE_STRING:
00593     {
00594         assert(val._string);
00595         *val._string = s;
00596         return true;
00597     }
00598     }
00599 
00600     assert(0);
00601     return false;
00602 }
00603 
00604 bool AnyScalar::setStringQuoted(const std::string &s)
00605 {
00606     // unescape string
00607     if (s.size() < 2) return false;
00608     if (s[0] != '"') return false;
00609     if (s[s.size()-1] != '"') return false;
00610 
00611     std::string t;
00612     t.reserve(s.size() + s.size() / 32);
00613 
00614     for(unsigned int i = 1; i + 1 < s.size(); i++)
00615     {
00616         if (s[i] == '\\')
00617         {
00618             i++;
00619             if (i >= s.size() - 1) return false;
00620 
00621             switch(s[i])
00622             {
00623             case 'a':   t += '\a';      break;
00624             case 'b':   t += '\b';      break;
00625             case 'f':   t += '\f';      break;
00626             case 'n':   t += '\n';      break;
00627             case 'r':   t += '\r';      break;
00628             case 't':   t += '\t';      break;
00629             case 'v':   t += '\v';      break;
00630             case '\'':  t += '\'';      break;
00631             case '"':   t += '"';       break;
00632             case '\\':  t += '\\';      break;
00633             case '?':   t += '?';       break;
00634 
00635             default:
00636                 t += '\\';
00637                 t += s[i];
00638                 break;
00639             }
00640         }
00641         else {
00642             t += s[i];
00643         }
00644     }
00645 
00646     return setString(t);
00647 }
00648 
00649 AnyScalar& AnyScalar::setAutoString(const std::string &input)
00650 {
00651     // - int: input was readable by strtoll and is small enough.
00652     // - long: input was readable by strtoll
00653     {
00654         char *endptr;
00655 #ifndef _MSC_VER
00656         long long l = strtoll(input.c_str(), &endptr, 10);
00657 #else
00658         long long l = _strtoi64(input.c_str(), &endptr, 10);
00659 #endif
00660         if (endptr != NULL && *endptr == 0)
00661         {
00662             if (INT_MIN <= l && l <= INT_MAX)
00663             {
00664                 resetType(ATTRTYPE_INTEGER);
00665                 val._int = l;
00666                 return *this;
00667             }
00668             else
00669             {
00670                 resetType(ATTRTYPE_LONG);
00671                 val._long = l;
00672                 return *this;
00673             }
00674         }
00675     }
00676 
00677     // - double: input was readble by strtod
00678     {
00679         char *endptr;
00680         double d = strtod(input.c_str(), &endptr);
00681         if (endptr != NULL && *endptr == 0)
00682         {
00683             resetType(ATTRTYPE_DOUBLE);
00684             val._double = d;
00685             return *this;
00686         }
00687     }
00688 
00689     // - string: all above failed.
00690     resetType(ATTRTYPE_STRING);
00691     *val._string = input;
00692 
00693     return *this;
00694 }
00695 
00696 bool AnyScalar::getBoolean() const
00697 {
00698     switch(atype)
00699     {
00700     case ATTRTYPE_INVALID:
00701         assert(0);
00702         return false;
00703 
00704     case ATTRTYPE_BOOL:
00705         return (val._int != 0);
00706 
00707     case ATTRTYPE_CHAR:
00708     case ATTRTYPE_SHORT:
00709     case ATTRTYPE_INTEGER:
00710         return (val._int != 0);
00711 
00712     case ATTRTYPE_BYTE:
00713     case ATTRTYPE_WORD:
00714     case ATTRTYPE_DWORD:
00715         return (val._uint != 0);
00716 
00717     case ATTRTYPE_LONG:
00718         return (val._long != 0);
00719 
00720     case ATTRTYPE_QWORD:
00721         return (val._ulong != 0);
00722 
00723     case ATTRTYPE_FLOAT:
00724         return (val._float != 0.0f);
00725 
00726     case ATTRTYPE_DOUBLE:
00727         return (val._double != 0.0f);
00728 
00729     case ATTRTYPE_STRING:
00730     {
00731         assert(val._string);
00732 
00733         if (*val._string == "0" || *val._string == "f" || *val._string == "false"
00734             || *val._string == "n" || *val._string == "no") {
00735             return false;
00736         }
00737         if (*val._string == "1" || *val._string == "t" || *val._string == "true"
00738             || *val._string == "y" || *val._string == "yes") {
00739             return true;
00740         }
00741 
00742         throw(ConversionException("Cannot convert string to boolean."));
00743     }
00744     }
00745 
00746     assert(0);
00747     return false;
00748 }
00749 
00750 int AnyScalar::getInteger() const
00751 {
00752     switch(atype)
00753     {
00754     case ATTRTYPE_INVALID:
00755         assert(0);
00756         return false;
00757 
00758     case ATTRTYPE_BOOL:
00759         return val._int;
00760 
00761     case ATTRTYPE_CHAR:
00762     case ATTRTYPE_SHORT:
00763     case ATTRTYPE_INTEGER:
00764         return val._int;
00765 
00766     case ATTRTYPE_BYTE:
00767     case ATTRTYPE_WORD:
00768     case ATTRTYPE_DWORD:
00769         return val._uint;
00770 
00771     case ATTRTYPE_LONG:
00772         if (val._long > INT_MAX) return INT_MAX;
00773         if (val._long < INT_MIN) return INT_MIN;
00774 
00775         return static_cast<int>(val._long);
00776 
00777     case ATTRTYPE_QWORD:
00778         if (val._ulong > UINT_MAX) return UINT_MAX;
00779         return static_cast<int>(val._ulong);
00780 
00781     case ATTRTYPE_FLOAT:
00782         return static_cast<int>(val._float);
00783 
00784     case ATTRTYPE_DOUBLE:
00785         return static_cast<int>(val._double);
00786 
00787     case ATTRTYPE_STRING:
00788     {
00789         assert(val._string);
00790         char *endptr;
00791         long i = strtol(val._string->c_str(), &endptr, 10);
00792         if (endptr != NULL && *endptr == 0)
00793             return i;
00794 
00795         throw(ConversionException("Cannot convert string to integer."));
00796     }
00797     }
00798 
00799     assert(0);
00800     return false;
00801 }
00802 
00803 unsigned int AnyScalar::getUnsignedInteger() const
00804 {
00805     switch(atype)
00806     {
00807     case ATTRTYPE_INVALID:
00808         assert(0);
00809         return false;
00810 
00811     case ATTRTYPE_BOOL:
00812     case ATTRTYPE_CHAR:
00813     case ATTRTYPE_SHORT:
00814     case ATTRTYPE_INTEGER:
00815         return static_cast<unsigned int>(val._int);
00816 
00817     case ATTRTYPE_BYTE:
00818     case ATTRTYPE_WORD:
00819     case ATTRTYPE_DWORD:
00820         return val._uint;
00821 
00822     case ATTRTYPE_LONG:
00823         return static_cast<unsigned int>(val._long);
00824 
00825     case ATTRTYPE_QWORD:
00826         return static_cast<unsigned int>(val._ulong);
00827 
00828     case ATTRTYPE_FLOAT:
00829         return static_cast<unsigned int>(val._float);
00830 
00831     case ATTRTYPE_DOUBLE:
00832         return static_cast<unsigned int>(val._double);
00833 
00834     case ATTRTYPE_STRING:
00835     {
00836         assert(val._string);
00837         char *endptr;
00838         unsigned long i = strtoul(val._string->c_str(), &endptr, 10);
00839         if (endptr != NULL && *endptr == 0)
00840             return i;
00841 
00842         throw(ConversionException("Cannot convert string to unsigned integer."));
00843     }
00844     }
00845 
00846     assert(0);
00847     return false;
00848 }
00849 
00850 long long AnyScalar::getLong() const
00851 {
00852     switch(atype)
00853     {
00854     case ATTRTYPE_INVALID:
00855         assert(0);
00856         return false;
00857 
00858     case ATTRTYPE_BOOL:
00859     case ATTRTYPE_CHAR:
00860     case ATTRTYPE_SHORT:
00861     case ATTRTYPE_INTEGER:
00862     case ATTRTYPE_BYTE:
00863     case ATTRTYPE_WORD:
00864     case ATTRTYPE_DWORD:
00865         return static_cast<long long>(val._int);
00866 
00867     case ATTRTYPE_LONG:
00868         return val._long;
00869 
00870     case ATTRTYPE_QWORD:
00871         return val._ulong;
00872 
00873     case ATTRTYPE_FLOAT:
00874         return static_cast<long long>(val._float);
00875 
00876     case ATTRTYPE_DOUBLE:
00877         return static_cast<long long>(val._double);
00878 
00879     case ATTRTYPE_STRING:
00880     {
00881         assert(val._string);
00882         char *endptr;
00883 #ifndef _MSC_VER
00884         long long l = strtoll(val._string->c_str(), &endptr, 10);
00885 #else
00886         long long l = _strtoi64(val._string->c_str(), &endptr, 10);
00887 #endif
00888         if (endptr != NULL && *endptr == 0)
00889             return l;
00890 
00891         throw(ConversionException("Cannot convert string to long long."));
00892     }
00893     }
00894 
00895     assert(0);
00896     return false;
00897 }
00898 
00899 unsigned long long AnyScalar::getUnsignedLong() const
00900 {
00901     switch(atype)
00902     {
00903     case ATTRTYPE_INVALID:
00904         assert(0);
00905         return false;
00906 
00907     case ATTRTYPE_BOOL:
00908     case ATTRTYPE_CHAR:
00909     case ATTRTYPE_SHORT:
00910     case ATTRTYPE_INTEGER:
00911         return static_cast<unsigned long long>(val._int);
00912 
00913     case ATTRTYPE_BYTE:
00914     case ATTRTYPE_WORD:
00915     case ATTRTYPE_DWORD:
00916         return static_cast<unsigned long long>(val._uint);
00917 
00918     case ATTRTYPE_LONG:
00919         return static_cast<unsigned long long>(val._long);
00920 
00921     case ATTRTYPE_QWORD:
00922         return val._ulong;
00923 
00924     case ATTRTYPE_FLOAT:
00925         return static_cast<unsigned long long>(val._float);
00926 
00927     case ATTRTYPE_DOUBLE:
00928         return static_cast<unsigned long long>(val._double);
00929 
00930     case ATTRTYPE_STRING:
00931     {
00932         assert(val._string);
00933         char *endptr;
00934 #ifndef _MSC_VER
00935         unsigned long long u = strtoull(val._string->c_str(), &endptr, 10);
00936 #else
00937         unsigned long long u = _strtoui64(val._string->c_str(), &endptr, 10);
00938 #endif
00939         if (endptr != NULL && *endptr == 0)
00940             return u;
00941 
00942         throw(ConversionException("Cannot convert string to unsigned long long."));
00943     }
00944     }
00945     assert(0);
00946     return false;
00947 }
00948 
00949 double AnyScalar::getDouble() const
00950 {
00951     switch(atype)
00952     {
00953     case ATTRTYPE_INVALID:
00954         assert(0);
00955         return false;
00956 
00957     case ATTRTYPE_BOOL:
00958     case ATTRTYPE_CHAR:
00959     case ATTRTYPE_SHORT:
00960     case ATTRTYPE_INTEGER:
00961     case ATTRTYPE_BYTE:
00962     case ATTRTYPE_WORD:
00963     case ATTRTYPE_DWORD:
00964         return static_cast<double>(val._int);
00965 
00966     case ATTRTYPE_LONG:
00967         return static_cast<double>(val._long);
00968 
00969     case ATTRTYPE_QWORD:
00970         return static_cast<double>(val._ulong);
00971 
00972     case ATTRTYPE_FLOAT:
00973         return static_cast<double>(val._float);
00974 
00975     case ATTRTYPE_DOUBLE:
00976         return val._double;
00977 
00978     case ATTRTYPE_STRING:
00979     {
00980         assert(val._string);
00981         char *endptr;
00982         double d = strtod(val._string->c_str(), &endptr);
00983         if (endptr != NULL && *endptr == 0)
00984             return d;
00985 
00986         throw(ConversionException("Cannot convert string to double."));
00987     }
00988     }
00989     assert(0);
00990     return false;
00991 }
00992 
00993 std::string AnyScalar::getString() const
00994 {
00995     switch(atype)
00996     {
00997     case ATTRTYPE_INVALID:
00998         assert(0);
00999         return false;
01000 
01001     case ATTRTYPE_BOOL:
01002         if (val._int == 0) return "false";
01003         if (val._int == 1) return "true";
01004         assert(0);
01005         return "invalid";
01006 
01007     case ATTRTYPE_CHAR:
01008     case ATTRTYPE_SHORT:
01009     case ATTRTYPE_INTEGER:
01010     {
01011         return boost::lexical_cast<std::string>(val._int);
01012     }
01013 
01014     case ATTRTYPE_BYTE:
01015     case ATTRTYPE_WORD:
01016     case ATTRTYPE_DWORD:
01017     {
01018         return boost::lexical_cast<std::string>(val._uint);
01019     }
01020 
01021     case ATTRTYPE_LONG:
01022     {
01023         return boost::lexical_cast<std::string>(val._long);
01024     }
01025 
01026     case ATTRTYPE_QWORD:
01027     {
01028         return boost::lexical_cast<std::string>(val._ulong);
01029     }
01030 
01031     case ATTRTYPE_FLOAT:
01032     {
01033         return boost::lexical_cast<std::string>(val._float);
01034     }
01035 
01036     case ATTRTYPE_DOUBLE:
01037     {
01038         return boost::lexical_cast<std::string>(val._double);
01039     }
01040 
01041     case ATTRTYPE_STRING:
01042     {
01043         assert(val._string);
01044         return *val._string;
01045     } 
01046     }
01047     assert(0);
01048     return false;
01049 }
01050 
01051 std::string AnyScalar::getStringQuoted() const
01052 {
01053     std::string str = getString();
01054     std::string os = "\"";
01055 
01056     os.reserve(2 + str.size() + str.size() / 16);
01057 
01058     // escape string s
01059     for(std::string::const_iterator si = str.begin(); si != str.end(); ++si)
01060     {
01061         switch(*si)
01062         {
01063         case '\a':
01064             os += "\\a";
01065             break;
01066 
01067         case '\b':
01068             os += "\\b";
01069             break;
01070 
01071         case '\f':
01072             os += "\\f";
01073             break;
01074 
01075         case '\n':
01076             os += "\\n";
01077             break;
01078 
01079         case '\r':
01080             os += "\\r";
01081             break;
01082 
01083         case '\t':
01084             os += "\\t";
01085             break;
01086     
01087         case '\v':
01088             os += "\\v";
01089             break;
01090 
01091         case '\\':
01092             os += "\\\\";
01093             break;
01094 
01095         case '"':
01096             os += "\\\"";
01097             break;
01098 
01099         case '\'':
01100             os += "\\'";
01101             break;
01102 
01103         default:
01104             os += *si;
01105             break;
01106         }
01107     }
01108 
01109     os += "\"";
01110     return os;
01111 }
01112 
01113 void AnyScalar::resetType(attrtype_t t)
01114 {
01115     // if setting to a string and this is not a string, create the object
01116     if (t == ATTRTYPE_STRING) {
01117         if (atype != ATTRTYPE_STRING) {
01118             val._string = new std::string;
01119         }
01120     }
01121     else {
01122         if (atype == ATTRTYPE_STRING) {
01123             delete val._string;
01124         }
01125 
01126         val._ulong = 0;
01127     }
01128 
01129     atype = t;
01130 }
01131 
01132 bool AnyScalar::convertType(attrtype_t t)
01133 {
01134     // same source and target type?
01135     if (atype == t) return true;
01136 
01137     // special case if this object was initialised with the ATTRTYPE_INVALID:
01138     // all the get...() below would assert.
01139     if (atype == ATTRTYPE_INVALID)
01140     {
01141         atype = t;
01142         if (atype == ATTRTYPE_STRING) {
01143             val._string = new std::string;
01144         }
01145         return true;
01146     }
01147     
01148     switch(t)
01149     {
01150     case ATTRTYPE_INVALID:
01151         assert(0);
01152         return false;
01153 
01154     case ATTRTYPE_BOOL:
01155     {
01156         bool v = getBoolean();
01157         if (atype == ATTRTYPE_STRING) delete val._string;
01158         val._int = v;
01159         atype = t;
01160         return true;
01161     }
01162 
01163     case ATTRTYPE_CHAR:
01164     case ATTRTYPE_SHORT:
01165     case ATTRTYPE_INTEGER:
01166     {
01167         int v = getInteger();
01168         if (atype == ATTRTYPE_STRING) delete val._string;
01169         val._int = v;
01170         atype = t;
01171         return true;
01172     }
01173 
01174     case ATTRTYPE_BYTE:
01175     case ATTRTYPE_WORD:
01176     case ATTRTYPE_DWORD:
01177     {
01178         unsigned int v = getUnsignedInteger();
01179         if (atype == ATTRTYPE_STRING) delete val._string;
01180         val._uint = v;
01181         atype = t;
01182         return true;
01183     }
01184 
01185     case ATTRTYPE_LONG:
01186     {
01187         long long v = getLong();
01188         if (atype == ATTRTYPE_STRING) delete val._string;
01189         val._long = v;
01190         atype = t;
01191         return true;
01192     }
01193 
01194     case ATTRTYPE_QWORD:
01195     {
01196         unsigned long long v = getLong();
01197         if (atype == ATTRTYPE_STRING) delete val._string;
01198         val._ulong = v;
01199         atype = t;
01200         return true;
01201     }
01202 
01203     case ATTRTYPE_FLOAT:
01204     {
01205         float f = static_cast<float>(getDouble());
01206         if (atype == ATTRTYPE_STRING) delete val._string;
01207         val._float = f;
01208         atype = t;
01209         return true;
01210     }
01211 
01212     case ATTRTYPE_DOUBLE:
01213     {
01214         double d = getDouble();
01215         if (atype == ATTRTYPE_STRING) delete val._string;
01216         val._double = d;
01217         atype = t;
01218         return true;
01219     }
01220 
01221     case ATTRTYPE_STRING:
01222     {
01223         val._string = new std::string(getString());
01224         atype = t;
01225         return true;
01226     } 
01227     }
01228     assert(0);
01229     return false;
01230 }
01231 
01232 AnyScalar AnyScalar::operator-() const
01233 {
01234     AnyScalar at = *this;
01235     
01236     switch(at.atype)
01237     {
01238     case ATTRTYPE_INVALID:
01239         assert(0);
01240         throw(ConversionException("Negating invalid type."));
01241         
01242     case ATTRTYPE_BOOL:
01243         if (at.val._int > 0) at.val._int = 0;
01244         else at.val._int = 1;
01245         break;
01246 
01247     case ATTRTYPE_CHAR:
01248     case ATTRTYPE_SHORT:
01249     case ATTRTYPE_INTEGER:
01250         at.val._int = - at.val._int;
01251         break;
01252 
01253     case ATTRTYPE_BYTE:
01254     case ATTRTYPE_WORD:
01255     case ATTRTYPE_DWORD:
01256         at.val._uint = - at.val._uint;
01257         break;
01258 
01259     case ATTRTYPE_LONG:
01260         at.val._long = - at.val._long;
01261         break;
01262 
01263     case ATTRTYPE_QWORD:
01264         at.val._ulong = - at.val._ulong;
01265         break;
01266 
01267     case ATTRTYPE_FLOAT:
01268         at.val._float = - at.val._float;
01269         break;
01270 
01271     case ATTRTYPE_DOUBLE:
01272         at.val._double = - at.val._double;
01273         break;
01274 
01275     case ATTRTYPE_STRING:
01276     {
01277         if (!at.convertType(ATTRTYPE_DOUBLE))
01278             throw(ConversionException("Cannot convert string to double for negation."));
01279 
01280         at.val._double = - at.val._double;
01281         break;
01282     }
01283     }
01284 
01285     return at;
01286 }
01287 
01288 template <template <typename Type> class Operator, char OpName>
01289 AnyScalar AnyScalar::binary_arith_op(const AnyScalar &b) const
01290 {
01291     switch(atype)
01292     {
01293     case ATTRTYPE_INVALID:
01294         assert(0);
01295         throw(ConversionException(std::string("Invalid type for first operand of binary operator ")+OpName+"."));
01296 
01297     case ATTRTYPE_BOOL:
01298         throw(ConversionException("No binary operators are allowed on bool values."));
01299 
01300     case ATTRTYPE_CHAR:
01301     case ATTRTYPE_SHORT:
01302     case ATTRTYPE_INTEGER:
01303     {
01304         switch(b.atype)
01305         {
01306         case ATTRTYPE_INVALID:
01307             assert(0);
01308             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
01309 
01310         case ATTRTYPE_BOOL:
01311             throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
01312 
01313         case ATTRTYPE_CHAR:
01314         case ATTRTYPE_SHORT:
01315         case ATTRTYPE_INTEGER:
01316         {
01317             Operator<int> op;
01318             if (OpName == '/' && b.val._int == 0) throw(ArithmeticException("Integer division by zero"));
01319             return AnyScalar( op(val._int, b.val._int) );
01320         }
01321 
01322         case ATTRTYPE_BYTE:
01323         case ATTRTYPE_WORD:
01324         case ATTRTYPE_DWORD:
01325         {
01326             Operator<int> op;
01327             if (OpName == '/' && b.val._uint == 0) throw(ArithmeticException("Integer division by zero"));
01328             return AnyScalar( op(val._int, static_cast<signed int>(b.val._uint)) );
01329         }
01330 
01331         case ATTRTYPE_LONG:
01332         {
01333             Operator<long long> op;
01334             if (OpName == '/' && b.val._long == 0) throw(ArithmeticException("Integer division by zero"));
01335             return AnyScalar( op(val._int, b.val._long) );
01336         }
01337             
01338         case ATTRTYPE_QWORD:
01339         {
01340             Operator<long long> op;
01341             if (OpName == '/' && b.val._ulong == 0) throw(ArithmeticException("Integer division by zero"));
01342             return AnyScalar( op(static_cast<long long>(val._int), static_cast<long long>(b.val._ulong)) );
01343         }
01344             
01345         case ATTRTYPE_FLOAT:
01346         {
01347             Operator<float> op;
01348             return AnyScalar( op(static_cast<float>(val._int), b.val._float));
01349         }
01350 
01351         case ATTRTYPE_DOUBLE:
01352         {
01353             Operator<double> op;
01354             return AnyScalar( op(static_cast<double>(val._int), b.val._double) );
01355         }
01356 
01357         case ATTRTYPE_STRING:
01358         {
01359             AnyScalar bc = b;
01360             
01361             if (!bc.convertType(ATTRTYPE_INTEGER))
01362                 throw(ConversionException(std::string("Could not convert string to integer for binary operator ")+OpName+"."));
01363 
01364             Operator<int> op;
01365 
01366             int bval = bc.getInteger();
01367             if (OpName == '/' && bval == 0) throw(ArithmeticException("Integer division by zero"));
01368 
01369             return AnyScalar( op(val._int, bval) );
01370         }
01371         }
01372         break;
01373     }
01374 
01375     case ATTRTYPE_BYTE:
01376     case ATTRTYPE_WORD:
01377     case ATTRTYPE_DWORD:
01378     {
01379         switch(b.atype)
01380         {
01381         case ATTRTYPE_INVALID:
01382             assert(0);
01383             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
01384 
01385         case ATTRTYPE_BOOL:
01386             throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
01387 
01388         case ATTRTYPE_CHAR:
01389         case ATTRTYPE_SHORT:
01390         case ATTRTYPE_INTEGER:
01391         {
01392             Operator<int> op;
01393             if (OpName == '/' && b.val._int == 0) throw(ArithmeticException("Integer division by zero"));
01394             return AnyScalar( op(static_cast<signed int>(val._uint), b.val._int) );
01395         }
01396 
01397         case ATTRTYPE_BYTE:
01398         case ATTRTYPE_WORD:
01399         case ATTRTYPE_DWORD:
01400         {
01401             Operator<unsigned int> op;
01402             if (OpName == '/' && b.val._uint == 0) throw(ArithmeticException("Integer division by zero"));
01403             return AnyScalar( op(val._uint, b.val._uint) );
01404         }
01405             
01406         case ATTRTYPE_LONG:
01407         {
01408             Operator<long long> op;
01409             if (OpName == '/' && b.val._long == 0) throw(ArithmeticException("Integer division by zero"));
01410             return AnyScalar( op(static_cast<signed long long>(val._uint), b.val._long) );
01411         }
01412 
01413         case ATTRTYPE_QWORD:
01414         {
01415             Operator<unsigned long long> op;
01416             if (OpName == '/' && b.val._ulong == 0) throw(ArithmeticException("Integer division by zero"));
01417             return AnyScalar( op(static_cast<unsigned long long>(val._uint), b.val._ulong) );
01418         }
01419             
01420         case ATTRTYPE_FLOAT:
01421         {
01422             Operator<float> op;
01423             return AnyScalar( op(static_cast<float>(val._uint), b.val._float));
01424         }
01425 
01426         case ATTRTYPE_DOUBLE:
01427         {
01428             Operator<double> op;
01429             return AnyScalar( op(static_cast<double>(val._uint), b.val._double) );
01430         }
01431 
01432         case ATTRTYPE_STRING:
01433         {
01434             AnyScalar bc = b;
01435             
01436             if (!bc.convertType(ATTRTYPE_DWORD))
01437                 throw(ConversionException(std::string("Could not convert string to unsigned integer for binary operator ")+OpName+"."));
01438 
01439             Operator<unsigned int> op;
01440 
01441             int bval = bc.getInteger();
01442             if (OpName == '/' && bval == 0) throw(ArithmeticException("Integer division by zero"));
01443 
01444             return AnyScalar( op(val._int, bval) );
01445         }
01446         }
01447         break;
01448     }
01449 
01450     case ATTRTYPE_LONG:
01451     {
01452         switch(b.atype)
01453         {
01454         case ATTRTYPE_INVALID:
01455             assert(0);
01456             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
01457 
01458         case ATTRTYPE_BOOL:
01459             throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
01460 
01461         case ATTRTYPE_CHAR:
01462         case ATTRTYPE_SHORT:
01463         case ATTRTYPE_INTEGER:
01464         {
01465             Operator<long long> op;
01466             if (OpName == '/' && b.val._int == 0) throw(ArithmeticException("Integer division by zero"));
01467             return AnyScalar( op(val._long, static_cast<long long>(b.val._int)) );
01468         }
01469 
01470         case ATTRTYPE_BYTE:
01471         case ATTRTYPE_WORD:
01472         case ATTRTYPE_DWORD:
01473         {
01474             Operator<long long> op;
01475             if (OpName == '/' && b.val._uint == 0) throw(ArithmeticException("Integer division by zero"));
01476             return AnyScalar( op(val._long, static_cast<signed long long>(b.val._uint)) );
01477         }
01478             
01479         case ATTRTYPE_LONG:
01480         {
01481             Operator<long long> op;
01482             if (OpName == '/' && b.val._long == 0) throw(ArithmeticException("Integer division by zero"));
01483             return AnyScalar( op(val._long, b.val._long) );
01484         }
01485 
01486         case ATTRTYPE_QWORD:
01487         {
01488             Operator<long long> op;
01489             if (OpName == '/' && b.val._ulong == 0) throw(ArithmeticException("Integer division by zero"));
01490             return AnyScalar( op(val._long, static_cast<signed long long>(b.val._ulong)) );
01491         }
01492             
01493         case ATTRTYPE_FLOAT:
01494         {
01495             Operator<float> op;
01496             return AnyScalar( op(static_cast<float>(val._long), b.val._float));
01497         }
01498 
01499         case ATTRTYPE_DOUBLE:
01500         {
01501             Operator<double> op;
01502             return AnyScalar( op(static_cast<double>(val._long), b.val._double) );
01503         }
01504 
01505         case ATTRTYPE_STRING:
01506         {
01507             AnyScalar bc = b;
01508             
01509             if (!bc.convertType(ATTRTYPE_LONG))
01510                 throw(ConversionException(std::string("Could not convert string to long for binary operator ")+OpName+"."));
01511 
01512             Operator<long long> op;
01513 
01514             long long bval = bc.getLong();
01515             if (OpName == '/' && bval == 0) throw(ArithmeticException("Integer division by zero"));
01516 
01517             return AnyScalar( op(val._long, bval) );
01518         }
01519         }
01520         break;
01521     }
01522 
01523     case ATTRTYPE_QWORD:
01524     {
01525         switch(b.atype)
01526         {
01527         case ATTRTYPE_INVALID:
01528             assert(0);
01529             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
01530 
01531         case ATTRTYPE_BOOL:
01532             throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
01533 
01534         case ATTRTYPE_CHAR:
01535         case ATTRTYPE_SHORT:
01536         case ATTRTYPE_INTEGER:
01537         {
01538             Operator<long long> op;
01539             if (OpName == '/' && b.val._int == 0) throw(ArithmeticException("Integer division by zero"));
01540             return AnyScalar( op(static_cast<signed long long>(val._ulong), b.val._int) );
01541         }
01542 
01543         case ATTRTYPE_BYTE:
01544         case ATTRTYPE_WORD:
01545         case ATTRTYPE_DWORD:
01546         {
01547             Operator<unsigned long long> op;
01548             if (OpName == '/' && b.val._uint == 0) throw(ArithmeticException("Integer division by zero"));
01549             return AnyScalar( op(val._ulong, static_cast<unsigned long long>(b.val._uint)) );
01550         }
01551             
01552         case ATTRTYPE_LONG:
01553         {
01554             Operator<long long> op;
01555             if (OpName == '/' && b.val._long == 0) throw(ArithmeticException("Integer division by zero"));
01556             return AnyScalar( op(static_cast<signed long long>(val._ulong), b.val._long) );
01557         }
01558 
01559         case ATTRTYPE_QWORD:
01560         {
01561             Operator<unsigned long long> op;
01562             if (OpName == '/' && b.val._ulong == 0) throw(ArithmeticException("Integer division by zero"));
01563             return AnyScalar( op(val._ulong, b.val._ulong) );
01564         }
01565             
01566         case ATTRTYPE_FLOAT:
01567         {
01568             Operator<float> op;
01569             return AnyScalar( op(static_cast<float>(val._ulong), b.val._float));
01570         }
01571 
01572         case ATTRTYPE_DOUBLE:
01573         {
01574             Operator<double> op;
01575             return AnyScalar( op(static_cast<double>(val._ulong), b.val._double) );
01576         }
01577 
01578         case ATTRTYPE_STRING:
01579         {
01580             AnyScalar bc = b;
01581             
01582             if (!bc.convertType(ATTRTYPE_QWORD))
01583                 throw(ConversionException(std::string("Could not convert string to unsigned long long for binary operator ")+OpName+"."));
01584 
01585             Operator<unsigned long long> op;
01586 
01587             long long bval = bc.getLong();
01588             if (OpName == '/' && bval == 0) throw(ArithmeticException("Integer division by zero"));
01589 
01590             return AnyScalar( op(val._ulong, bval) );
01591         }
01592         }
01593         break;
01594     }
01595 
01596     case ATTRTYPE_FLOAT:
01597     {
01598         switch(b.atype)
01599         {
01600         case ATTRTYPE_INVALID:
01601             assert(0);
01602             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
01603 
01604         case ATTRTYPE_BOOL:
01605             throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
01606 
01607         case ATTRTYPE_CHAR:
01608         case ATTRTYPE_SHORT:
01609         case ATTRTYPE_INTEGER:
01610         {
01611             Operator<float> op;
01612             return AnyScalar( op(val._float, static_cast<float>(b.val._int)) );
01613         }
01614 
01615         case ATTRTYPE_BYTE:
01616         case ATTRTYPE_WORD:
01617         case ATTRTYPE_DWORD:
01618         {
01619             Operator<float> op;
01620             return AnyScalar( op(val._float, static_cast<float>(b.val._uint)) );
01621         }
01622             
01623         case ATTRTYPE_LONG:
01624         {
01625             Operator<float> op;
01626             return AnyScalar( op(val._float, static_cast<float>(b.val._long)) );
01627         }
01628 
01629         case ATTRTYPE_QWORD:
01630         {
01631             Operator<float> op;
01632             return AnyScalar( op(val._float, static_cast<float>(b.val._ulong)) );
01633         }
01634 
01635         case ATTRTYPE_FLOAT:
01636         {
01637             Operator<float> op;
01638             return AnyScalar( op(val._float, b.val._float));
01639         }
01640 
01641         case ATTRTYPE_DOUBLE:
01642         {
01643             Operator<double> op;
01644             return AnyScalar( op(static_cast<double>(val._float), b.val._double) );
01645         }
01646 
01647         case ATTRTYPE_STRING:
01648         {
01649             AnyScalar bc = b;
01650             
01651             if (!bc.convertType(ATTRTYPE_FLOAT))
01652                 throw(ConversionException(std::string("Could not convert string to float for binary operator ")+OpName+"."));
01653 
01654             Operator<float> op;
01655 
01656             return AnyScalar( op(val._float, bc.val._float) );
01657         }
01658         }
01659 
01660         break;
01661     }
01662 
01663     case ATTRTYPE_DOUBLE:
01664     {
01665         switch(b.atype)
01666         {
01667         case ATTRTYPE_INVALID:
01668             assert(0);
01669             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
01670 
01671         case ATTRTYPE_BOOL:
01672             throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
01673 
01674         case ATTRTYPE_CHAR:
01675         case ATTRTYPE_SHORT:
01676         case ATTRTYPE_INTEGER:
01677         {
01678             Operator<double> op;
01679             return AnyScalar( op(val._double, static_cast<double>(b.val._int)) );
01680         }
01681 
01682         case ATTRTYPE_BYTE:
01683         case ATTRTYPE_WORD:
01684         case ATTRTYPE_DWORD:
01685         {
01686             Operator<double> op;
01687             return AnyScalar( op(val._double, static_cast<double>(b.val._uint)) );
01688         }
01689             
01690         case ATTRTYPE_LONG:
01691         {
01692             Operator<double> op;
01693             return AnyScalar( op(val._double, static_cast<double>(b.val._long)) );
01694         }
01695 
01696         case ATTRTYPE_QWORD:
01697         {
01698             Operator<double> op;
01699             return AnyScalar( op(val._double, static_cast<double>(b.val._ulong)) );
01700         }
01701 
01702         case ATTRTYPE_FLOAT:
01703         {
01704             Operator<double> op;
01705             return AnyScalar( op(val._double, static_cast<double>(b.val._float)));
01706         }
01707 
01708         case ATTRTYPE_DOUBLE:
01709         {
01710             Operator<double> op;
01711             return AnyScalar( op(val._double, b.val._double) );
01712         }
01713 
01714         case ATTRTYPE_STRING:
01715         {
01716             AnyScalar bc = b;
01717             
01718             if (!bc.convertType(ATTRTYPE_DOUBLE))
01719                 throw(ConversionException(std::string("Could not convert string to double for binary operator ")+OpName+"."));
01720 
01721             Operator<double> op;
01722 
01723             return AnyScalar( op(val._double, bc.getDouble()) );
01724         }
01725         }
01726 
01727         break;
01728     }
01729 
01730     // if this is a string, then the other type defines the conversion
01731     case ATTRTYPE_STRING:
01732     {
01733         switch(b.atype)
01734         {
01735         case ATTRTYPE_INVALID:
01736             assert(0);
01737             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
01738 
01739         case ATTRTYPE_BOOL:
01740             throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
01741 
01742         case ATTRTYPE_CHAR:
01743         case ATTRTYPE_SHORT:
01744         case ATTRTYPE_INTEGER:
01745         {
01746             Operator<int> op;
01747             if (OpName == '/' && b.val._int == 0) throw(ArithmeticException("Integer division by zero"));
01748             return AnyScalar( op(this->getInteger(), b.val._int) );
01749         }
01750 
01751         case ATTRTYPE_BYTE:
01752         case ATTRTYPE_WORD:
01753         case ATTRTYPE_DWORD:
01754         {
01755             Operator<unsigned int> op;
01756             if (OpName == '/' && b.val._uint == 0) throw(ArithmeticException("Integer division by zero"));
01757             return AnyScalar( op(this->getUnsignedInteger(), b.val._uint) );
01758         }
01759             
01760         case ATTRTYPE_LONG:
01761         {
01762             Operator<long long> op;
01763             if (OpName == '/' && b.val._long == 0) throw(ArithmeticException("Integer division by zero"));
01764             return AnyScalar( op(this->getLong(), b.val._long) );
01765         }
01766 
01767         case ATTRTYPE_QWORD:
01768         {
01769             Operator<unsigned long long> op;
01770             if (OpName == '/' && b.val._ulong == 0) throw(ArithmeticException("Integer division by zero"));
01771             return AnyScalar( op(this->getUnsignedLong(), b.val._ulong) );
01772         }
01773 
01774         case ATTRTYPE_FLOAT:
01775         {
01776             Operator<float> op;
01777             return AnyScalar( op(static_cast<float>(this->getDouble()), b.val._float) );
01778         }
01779 
01780         case ATTRTYPE_DOUBLE:
01781         {
01782             Operator<double> op;
01783             return AnyScalar( op(this->getDouble(), b.val._double) );
01784         }
01785 
01786         case ATTRTYPE_STRING:
01787             if (OpName == '+')
01788             {
01789                 return AnyScalar( *val._string + *b.val._string );
01790             }
01791 
01792             throw(ConversionException(std::string("Binary operator ")+OpName+" is not allowed between two string values."));
01793         }
01794         break;
01795     }
01796     }
01797     assert(0);
01798     throw(ConversionException("Invalid binary operator call. (PROGRAM ERROR)"));
01799 }
01800 
01801 // *** Force instantiation of binary_op for the four arithmetic operators
01802 
01804 template AnyScalar AnyScalar::binary_arith_op<std::plus, '+'>(const AnyScalar &b) const;
01805 
01807 template AnyScalar AnyScalar::binary_arith_op<std::minus, '-'>(const AnyScalar &b) const;
01808 
01810 template AnyScalar AnyScalar::binary_arith_op<std::multiplies, '*'>(const AnyScalar &b) const;
01811 
01813 template AnyScalar AnyScalar::binary_arith_op<std::divides, '/'>(const AnyScalar &b) const;
01814 
01815 template <template <typename Type> class Operator, int OpNum>
01816 bool AnyScalar::binary_comp_op(const AnyScalar &b) const
01817 {
01818     static const char *OpNameArray[] = { "==", "!=", "<", ">", "<=", ">=" };
01819 
01820     switch(atype)
01821     {
01822     case ATTRTYPE_INVALID:
01823         assert(0);
01824         throw(ConversionException(std::string("Invalid type for first operand of binary operator ")+OpNameArray[OpNum]+"."));
01825 
01826     case ATTRTYPE_BOOL:
01827     {
01828         switch(b.atype)
01829         {
01830         case ATTRTYPE_INVALID:
01831             assert(0);
01832             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
01833 
01834         case ATTRTYPE_BOOL:
01835         {
01836             Operator<bool> op;
01837             return op(val._int, b.val._int);
01838         }
01839 
01840         default:
01841             throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
01842         }
01843         break;
01844     }
01845 
01846     case ATTRTYPE_CHAR:
01847     case ATTRTYPE_SHORT:
01848     case ATTRTYPE_INTEGER:
01849     {
01850         switch(b.atype)
01851         {
01852         case ATTRTYPE_INVALID:
01853             assert(0);
01854             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
01855 
01856         case ATTRTYPE_BOOL:
01857             throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
01858 
01859         case ATTRTYPE_CHAR:
01860         case ATTRTYPE_SHORT:
01861         case ATTRTYPE_INTEGER:
01862         {
01863             Operator<int> op;
01864             return op(val._int, b.val._int);
01865         }
01866 
01867         case ATTRTYPE_BYTE:
01868         case ATTRTYPE_WORD:
01869         case ATTRTYPE_DWORD:
01870         {
01871             Operator<int> op;
01872             return op(val._int, static_cast<signed int>(b.val._uint));
01873         }
01874 
01875         case ATTRTYPE_LONG:
01876         {
01877             Operator<long long> op;
01878             return op(val._int, b.val._long);
01879         }
01880 
01881         case ATTRTYPE_QWORD:
01882         {
01883             Operator<long long> op;
01884             return op(val._int, static_cast<signed long long>(b.val._ulong));
01885         }
01886 
01887         case ATTRTYPE_FLOAT:
01888         {
01889             Operator<float> op;
01890             return op(static_cast<float>(val._int), b.val._float);
01891         }
01892 
01893         case ATTRTYPE_DOUBLE:
01894         {
01895             Operator<double> op;
01896             return op(static_cast<double>(val._int), b.val._double);
01897         }
01898 
01899         case ATTRTYPE_STRING:
01900         {
01901             AnyScalar bc = b;
01902             
01903             if (!bc.convertType(ATTRTYPE_INTEGER))
01904                 throw(ConversionException(std::string("Could not convert string to integer for binary operator ")+OpNameArray[OpNum]+"."));
01905 
01906             Operator<int> op;
01907 
01908             return op(val._int, bc.getInteger());
01909         }
01910         }
01911         break;
01912     }
01913 
01914     case ATTRTYPE_BYTE:
01915     case ATTRTYPE_WORD:
01916     case ATTRTYPE_DWORD:
01917     {
01918         switch(b.atype)
01919         {
01920         case ATTRTYPE_INVALID:
01921             assert(0);
01922             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
01923 
01924         case ATTRTYPE_BOOL:
01925             throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
01926 
01927         case ATTRTYPE_CHAR:
01928         case ATTRTYPE_SHORT:
01929         case ATTRTYPE_INTEGER:
01930         {
01931             Operator<int> op;
01932             return op(static_cast<signed int>(val._uint), b.val._int);
01933         }
01934 
01935         case ATTRTYPE_BYTE:
01936         case ATTRTYPE_WORD:
01937         case ATTRTYPE_DWORD:
01938         {
01939             Operator<unsigned int> op;
01940             return op(val._uint, b.val._uint);
01941         }
01942             
01943         case ATTRTYPE_LONG:
01944         {
01945             Operator<long long> op;
01946             return op(static_cast<signed long long>(val._uint), b.val._long);
01947         }
01948 
01949         case ATTRTYPE_QWORD:
01950         {
01951             Operator<unsigned long long> op;
01952             return op(static_cast<unsigned long long>(val._uint), b.val._ulong);
01953         }
01954 
01955         case ATTRTYPE_FLOAT:
01956         {
01957             Operator<float> op;
01958             return op(static_cast<float>(val._uint), b.val._float);
01959         }
01960 
01961         case ATTRTYPE_DOUBLE:
01962         {
01963             Operator<double> op;
01964             return op(static_cast<double>(val._uint), b.val._double);
01965         }
01966 
01967         case ATTRTYPE_STRING:
01968         {
01969             AnyScalar bc = b;
01970             
01971             if (!bc.convertType(ATTRTYPE_DWORD))
01972                 throw(ConversionException(std::string("Could not convert string to unsigned integer for binary operator ")+OpNameArray[OpNum]+"."));
01973 
01974             Operator<unsigned int> op;
01975 
01976             return op(val._int, bc.getInteger());
01977         }
01978         }
01979         break;
01980     }
01981 
01982     case ATTRTYPE_LONG:
01983     {
01984         switch(b.atype)
01985         {
01986         case ATTRTYPE_INVALID:
01987             assert(0);
01988             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
01989 
01990         case ATTRTYPE_BOOL:
01991             throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
01992 
01993         case ATTRTYPE_CHAR:
01994         case ATTRTYPE_SHORT:
01995         case ATTRTYPE_INTEGER:
01996         {
01997             Operator<long long> op;
01998             return op(val._long, static_cast<long long>(b.val._int));
01999         }
02000 
02001         case ATTRTYPE_BYTE:
02002         case ATTRTYPE_WORD:
02003         case ATTRTYPE_DWORD:
02004         {
02005             Operator<long long> op;
02006             return op(val._long, static_cast<signed long long>(b.val._uint));
02007         }
02008 
02009         case ATTRTYPE_LONG:
02010         {
02011             Operator<long long> op;
02012             return op(val._long, b.val._long);
02013         }
02014 
02015         case ATTRTYPE_QWORD:
02016         {
02017             Operator<long long> op;
02018             return op(val._long, static_cast<signed long long>(b.val._ulong));
02019         }
02020 
02021         case ATTRTYPE_FLOAT:
02022         {
02023             Operator<float> op;
02024             return op(static_cast<float>(val._long), b.val._float);
02025         }
02026 
02027         case ATTRTYPE_DOUBLE:
02028         {
02029             Operator<double> op;
02030             return op(static_cast<double>(val._long), b.val._double);
02031         }
02032 
02033         case ATTRTYPE_STRING:
02034         {
02035             AnyScalar bc = b;
02036             
02037             if (!bc.convertType(ATTRTYPE_LONG))
02038                 throw(ConversionException(std::string("Could not convert string to long long for binary operator ")+OpNameArray[OpNum]+"."));
02039 
02040             Operator<long long> op;
02041 
02042             return op(val._long, bc.getLong());
02043         }
02044         }
02045         break;
02046     }
02047 
02048     case ATTRTYPE_QWORD:
02049     {
02050         switch(b.atype)
02051         {
02052         case ATTRTYPE_INVALID:
02053             assert(0);
02054             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
02055 
02056         case ATTRTYPE_BOOL:
02057             throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
02058 
02059         case ATTRTYPE_CHAR:
02060         case ATTRTYPE_SHORT:
02061         case ATTRTYPE_INTEGER:
02062         {
02063             Operator<long long> op;
02064             return op(val._ulong, static_cast<signed long long>(b.val._int));
02065         }
02066 
02067         case ATTRTYPE_BYTE:
02068         case ATTRTYPE_WORD:
02069         case ATTRTYPE_DWORD:
02070         {
02071             Operator<unsigned long long> op;
02072             return op(val._ulong, b.val._uint);
02073         }
02074             
02075         case ATTRTYPE_LONG:
02076         {
02077             Operator<long long> op;
02078             return op(static_cast<signed long long>(val._ulong), b.val._long);
02079         }
02080 
02081         case ATTRTYPE_QWORD:
02082         {
02083             Operator<unsigned long long> op;
02084             return op(val._ulong, b.val._ulong);
02085         }
02086 
02087         case ATTRTYPE_FLOAT:
02088         {
02089             Operator<float> op;
02090             return op(static_cast<float>(val._ulong), b.val._float);
02091         }
02092 
02093         case ATTRTYPE_DOUBLE:
02094         {
02095             Operator<double> op;
02096             return op(static_cast<double>(val._ulong), b.val._double);
02097         }
02098 
02099         case ATTRTYPE_STRING:
02100         {
02101             AnyScalar bc = b;
02102             
02103             if (!bc.convertType(ATTRTYPE_QWORD))
02104                 throw(ConversionException(std::string("Could not convert string to unsigned long long for binary operator ")+OpNameArray[OpNum]+"."));
02105 
02106             Operator<unsigned long long> op;
02107 
02108             return op(val._int, bc.getUnsignedLong());
02109         }
02110         }
02111         break;
02112     }
02113 
02114     case ATTRTYPE_FLOAT:
02115     {
02116         switch(b.atype)
02117         {
02118         case ATTRTYPE_INVALID:
02119             assert(0);
02120             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
02121 
02122         case ATTRTYPE_BOOL:
02123             throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
02124 
02125         case ATTRTYPE_CHAR:
02126         case ATTRTYPE_SHORT:
02127         case ATTRTYPE_INTEGER:
02128         {
02129             Operator<float> op;
02130             return op(val._float, static_cast<float>(b.val._int));
02131         }
02132 
02133         case ATTRTYPE_BYTE:
02134         case ATTRTYPE_WORD:
02135         case ATTRTYPE_DWORD:
02136         {
02137             Operator<float> op;
02138             return op(val._float, static_cast<float>(b.val._uint));
02139         }
02140             
02141         case ATTRTYPE_LONG:
02142         {
02143             Operator<float> op;
02144             return op(val._float, static_cast<float>(b.val._long));
02145         }
02146 
02147         case ATTRTYPE_QWORD:
02148         {
02149             Operator<float> op;
02150             return op(val._float, static_cast<float>(b.val._ulong));
02151         }
02152             
02153         case ATTRTYPE_FLOAT:
02154         {
02155             Operator<float> op;
02156             return op(val._float, b.val._float);
02157         }
02158 
02159         case ATTRTYPE_DOUBLE:
02160         {
02161             Operator<double> op;
02162             return op(static_cast<double>(val._float), b.val._double);
02163         }
02164 
02165         case ATTRTYPE_STRING:
02166         {
02167             AnyScalar bc = b;
02168             
02169             if (!bc.convertType(ATTRTYPE_FLOAT))
02170                 throw(ConversionException(std::string("Could not convert string to float for binary operator ")+OpNameArray[OpNum]+"."));
02171 
02172             Operator<float> op;
02173 
02174             return op(val._float, bc.val._float);
02175         }
02176         }
02177 
02178         break;
02179     }
02180 
02181     case ATTRTYPE_DOUBLE:
02182     {
02183         switch(b.atype)
02184         {
02185         case ATTRTYPE_INVALID:
02186             assert(0);
02187             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
02188 
02189         case ATTRTYPE_BOOL:
02190             throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
02191 
02192         case ATTRTYPE_CHAR:
02193         case ATTRTYPE_SHORT:
02194         case ATTRTYPE_INTEGER:
02195         {
02196             Operator<double> op;
02197             return op(val._double, static_cast<double>(b.val._int));
02198         }
02199 
02200         case ATTRTYPE_BYTE:
02201         case ATTRTYPE_WORD:
02202         case ATTRTYPE_DWORD:
02203         {
02204             Operator<double> op;
02205             return op(val._double, static_cast<double>(b.val._uint));
02206         }
02207             
02208         case ATTRTYPE_LONG:
02209         {
02210             Operator<double> op;
02211             return op(val._double, static_cast<double>(b.val._long));
02212         }
02213 
02214         case ATTRTYPE_QWORD:
02215         {
02216             Operator<double> op;
02217             return op(val._double, static_cast<double>(b.val._ulong));
02218         }
02219             
02220         case ATTRTYPE_FLOAT:
02221         {
02222             Operator<double> op;
02223             return op(val._double, static_cast<double>(b.val._float));
02224         }
02225 
02226         case ATTRTYPE_DOUBLE:
02227         {
02228             Operator<double> op;
02229             return op(val._double, b.val._double);
02230         }
02231 
02232         case ATTRTYPE_STRING:
02233         {
02234             AnyScalar bc = b;
02235             
02236             if (!bc.convertType(ATTRTYPE_DOUBLE))
02237                 throw(ConversionException(std::string("Could not convert string to double for binary operator ")+OpNameArray[OpNum]+"."));
02238 
02239             Operator<double> op;
02240 
02241             return op(val._double, bc.getDouble());
02242         }
02243         }
02244 
02245         break;
02246     }
02247 
02248     // if this is a string, then the other type defines the conversion
02249     case ATTRTYPE_STRING:
02250     {
02251         switch(b.atype)
02252         {
02253         case ATTRTYPE_INVALID:
02254             assert(0);
02255             throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
02256 
02257         case ATTRTYPE_BOOL:
02258             throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
02259 
02260         case ATTRTYPE_CHAR:
02261         case ATTRTYPE_SHORT:
02262         case ATTRTYPE_INTEGER:
02263         {
02264             Operator<int> op;
02265             return op(this->getInteger(), b.val._int);
02266         }
02267 
02268         case ATTRTYPE_BYTE:
02269         case ATTRTYPE_WORD:
02270         case ATTRTYPE_DWORD:
02271         {
02272             Operator<unsigned int> op;
02273             return op(this->getUnsignedInteger(), b.val._int);
02274         }
02275             
02276         case ATTRTYPE_LONG:
02277         {
02278             Operator<long long> op;
02279             return op(this->getLong(), b.val._long);
02280         }
02281 
02282         case ATTRTYPE_QWORD:
02283         {
02284             Operator<unsigned long long> op;
02285             return op(this->getUnsignedLong(), b.val._ulong);
02286         }
02287 
02288         case ATTRTYPE_FLOAT:
02289         {
02290             Operator<float> op;
02291             return op(static_cast<float>(this->getDouble()), b.val._float);
02292         }
02293 
02294         case ATTRTYPE_DOUBLE:
02295         {
02296             Operator<double> op;
02297             return op(this->getDouble(), b.val._double);
02298         }
02299 
02300         case ATTRTYPE_STRING:
02301         {
02302             Operator<std::string> op;
02303             return op(*val._string, *b.val._string);
02304         }
02305         }
02306         break;
02307     }
02308     }
02309     assert(0);
02310     throw(ConversionException("Invalid binary operator call. (PROGRAM ERROR)"));
02311 }
02312 
02314 template bool AnyScalar::binary_comp_op<std::equal_to, 0>(const AnyScalar &b) const;
02315 
02317 template bool AnyScalar::binary_comp_op<std::not_equal_to, 1>(const AnyScalar &b) const;
02318 
02320 template bool AnyScalar::binary_comp_op<std::less, 2>(const AnyScalar &b) const;
02321 
02323 template bool AnyScalar::binary_comp_op<std::greater, 3>(const AnyScalar &b) const;
02324 
02326 template bool AnyScalar::binary_comp_op<std::less_equal, 4>(const AnyScalar &b) const;
02327 
02329 template bool AnyScalar::binary_comp_op<std::greater_equal, 5>(const AnyScalar &b) const;
02330 
02331 } // namespace stx

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