1
// $Id: AnyScalar.cc 59 2007-07-17 14:43:23Z tb $
4
* STX Expression Parser C++ Framework v0.7
5
* Copyright (C) 2007 Timo Bingmann
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.
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
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
22
/** \file AnyScalar.cc
23
* Implementation of the typed scalar value class AnyScalar used by the parser
24
* to represent values.
27
#include "AnyScalar.h"
28
#include "ExpressionParser.h"
34
#include <boost/lexical_cast.hpp>
38
bool AnyScalar::operator==(const AnyScalar &a) const
40
if (atype != a.atype) return false;
44
case ATTRTYPE_INVALID:
51
case ATTRTYPE_INTEGER:
52
return (val._int == a.val._int);
57
return (val._uint == a.val._uint);
60
return (val._long == a.val._long);
63
return (val._ulong == a.val._ulong);
66
return (val._float == a.val._float);
69
return (val._double == a.val._double);
72
assert(val._string && a.val._string);
73
return (*val._string == *a.val._string);
80
AnyScalar::attrtype_t AnyScalar::stringToType(const char* s)
83
std::transform(str.begin(), str.end(), str.begin(), tolower);
85
// Stupid method, but maybe faster than using a biggy std::map with a
86
// case-insensitive equality.
94
return ATTRTYPE_SHORT;
95
if (str == "integer" || str == "int")
96
return ATTRTYPE_INTEGER;
101
return ATTRTYPE_BYTE;
103
return ATTRTYPE_WORD;
105
return ATTRTYPE_DWORD;
107
return ATTRTYPE_QWORD;
110
return ATTRTYPE_FLOAT;
112
return ATTRTYPE_DOUBLE;
115
return ATTRTYPE_STRING;
117
throw(ConversionException("Invalid type name."));
120
bool AnyScalar::isValidAttrtype(attrtype_t at)
125
case ATTRTYPE_INVALID:
131
case ATTRTYPE_INTEGER:
138
case ATTRTYPE_DOUBLE:
139
case ATTRTYPE_STRING:
144
std::string AnyScalar::getTypeString(attrtype_t at)
148
case ATTRTYPE_INVALID: return "invalid";
149
case ATTRTYPE_BOOL: return "bool";
150
case ATTRTYPE_CHAR: return "char";
151
case ATTRTYPE_SHORT: return "short";
152
case ATTRTYPE_INTEGER: return "integer";
153
case ATTRTYPE_LONG: return "long";
154
case ATTRTYPE_BYTE: return "byte";
155
case ATTRTYPE_WORD: return "word";
156
case ATTRTYPE_DWORD: return "dword";
157
case ATTRTYPE_QWORD: return "qword";
158
case ATTRTYPE_FLOAT: return "float";
159
case ATTRTYPE_DOUBLE: return "double";
160
case ATTRTYPE_STRING: return "string";
165
int AnyScalar::getTypeLength(attrtype_t t)
169
case ATTRTYPE_INVALID:
174
// weird value. beware!
181
return sizeof(unsigned char);
184
return sizeof(short);
187
return sizeof(unsigned short);
189
case ATTRTYPE_INTEGER:
193
return sizeof(unsigned int);
196
return sizeof(long long);
199
return sizeof(unsigned long long);
202
return sizeof(float);
204
case ATTRTYPE_DOUBLE:
205
return sizeof(double);
207
case ATTRTYPE_STRING:
215
unsigned int AnyScalar::getValueLength() const
219
case ATTRTYPE_INVALID:
224
// weird value. beware!
231
return sizeof(unsigned char);
234
return sizeof(short);
237
return sizeof(unsigned short);
239
case ATTRTYPE_INTEGER:
243
return sizeof(unsigned int);
246
return sizeof(long long);
249
return sizeof(unsigned long long);
252
return sizeof(float);
254
case ATTRTYPE_DOUBLE:
255
return sizeof(double);
257
case ATTRTYPE_STRING:
259
return sizeof(unsigned char) + static_cast<unsigned int>(val._string->size());
266
bool AnyScalar::setInteger(int i)
270
case ATTRTYPE_INVALID:
275
val._int = (i != 0) ? 1 : 0;
279
if (SCHAR_MIN <= i && i <= SCHAR_MAX) {
283
if (SCHAR_MIN > i) val._int = SCHAR_MIN;
284
if (i > SCHAR_MAX) val._int = SCHAR_MAX;
288
if (i <= UCHAR_MAX) {
289
val._uint = static_cast<unsigned char>(i);
292
if (0 > i) val._uint = 0;
293
if (i > UCHAR_MAX) val._uint = UCHAR_MAX;
297
if (SHRT_MIN <= i && i <= SHRT_MAX) {
301
if (SHRT_MIN > i) val._int = SHRT_MIN;
302
if (i > SHRT_MAX) val._int = SHRT_MAX;
306
if (i <= USHRT_MAX) {
307
val._uint = static_cast<unsigned short>(i);
310
if (0 > i) val._uint = 0;
311
if (i > USHRT_MAX) val._uint = USHRT_MAX;
314
case ATTRTYPE_INTEGER:
315
if (INT_MIN <= i && i <= INT_MAX) {
319
if (INT_MIN > i) val._int = INT_MIN;
320
if (i > INT_MAX) val._int = INT_MAX;
324
if (static_cast<unsigned int>(i) <= UINT_MAX) {
328
if (0 > i) val._uint = 0;
340
val._float = static_cast<float>(i);
343
case ATTRTYPE_DOUBLE:
344
val._double = static_cast<double>(i);
347
case ATTRTYPE_STRING:
349
*val._string = boost::lexical_cast<std::string>(i);
357
bool AnyScalar::setLong(long long l)
361
case ATTRTYPE_INVALID:
366
val._int = (l != 0) ? 1 : 0;
370
if (SCHAR_MIN <= l && l <= SCHAR_MAX) {
371
val._int = static_cast<char>(l);
374
if (SCHAR_MIN > l) val._int = SCHAR_MIN;
375
if (l > SCHAR_MAX) val._int = SCHAR_MAX;
379
if (0 <= l && l <= UCHAR_MAX) {
380
val._uint = static_cast<unsigned char>(l);
383
if (0 > l) val._uint = 0;
384
if (l > UCHAR_MAX) val._uint = UCHAR_MAX;
388
if (SHRT_MIN <= l && l <= SHRT_MAX) {
389
val._int = static_cast<short>(l);
392
if (SHRT_MIN > l) val._int = SHRT_MIN;
393
if (l > SHRT_MAX) val._int = SHRT_MAX;
397
if (l <= USHRT_MAX) {
398
val._uint = static_cast<unsigned short>(l);
401
if (0 > l) val._uint = 0;
402
if (l > USHRT_MAX) val._uint = USHRT_MAX;
405
case ATTRTYPE_INTEGER:
406
if (INT_MIN <= l && l <= INT_MAX) {
407
val._int = static_cast<int>(l);
410
if (INT_MIN > l) val._int = INT_MIN;
411
if (l > INT_MAX) val._int = INT_MAX;
415
if (static_cast<unsigned int>(l) <= UINT_MAX) {
416
val._uint = static_cast<unsigned int>(l);
419
if (0 > l) val._uint = 0;
420
if (l > UINT_MAX) val._uint = UINT_MAX;
432
val._float = static_cast<float>(l);
435
case ATTRTYPE_DOUBLE:
436
val._double = static_cast<double>(l);
439
case ATTRTYPE_STRING:
441
*val._string = boost::lexical_cast<std::string>(l);
449
bool AnyScalar::setDouble(double d)
453
case ATTRTYPE_INVALID:
458
if (0 <= d && d < 0.5) {
462
if (0.5 <= d && d <= 1) {
471
case ATTRTYPE_INTEGER:
472
return setInteger( static_cast<int>(d) );
475
return setLong( static_cast<long long>(d) );
480
return setInteger( static_cast<unsigned int>(d) );
483
return setLong( static_cast<unsigned long long>(d) );
486
val._float = static_cast<float>(d);
489
case ATTRTYPE_DOUBLE:
493
case ATTRTYPE_STRING:
495
*val._string = boost::lexical_cast<std::string>(d);
503
bool AnyScalar::setString(const std::string &s)
507
case ATTRTYPE_INVALID:
512
if (s == "0" || s == "f" || s == "false" || s == "n" || s == "no") {
516
if (s == "1" || s == "t" || s == "true" || s == "y" || s == "yes") {
524
case ATTRTYPE_INTEGER:
527
long i = strtol(s.c_str(), &endptr, 10);
528
if (endptr != NULL && *endptr == 0)
529
return setInteger(i);
537
long long l = strtoll(s.c_str(), &endptr, 10);
539
long long l = _strtoi64(s.c_str(), &endptr, 10);
541
if (endptr != NULL && *endptr == 0)
551
unsigned long u = strtoul(s.c_str(), &endptr, 10);
552
if (endptr != NULL && *endptr == 0)
553
return setInteger(u);
561
unsigned long long u = strtoull(s.c_str(), &endptr, 10);
563
unsigned long long u = _strtoui64(s.c_str(), &endptr, 10);
565
if (endptr != NULL && *endptr == 0)
573
float f = static_cast<float>(strtod(s.c_str(), &endptr));
574
if (endptr != NULL && *endptr == 0) {
581
case ATTRTYPE_DOUBLE:
584
double d = strtod(s.c_str(), &endptr);
585
if (endptr != NULL && *endptr == 0) {
592
case ATTRTYPE_STRING:
604
bool AnyScalar::setStringQuoted(const std::string &s)
607
if (s.size() < 2) return false;
608
if (s[0] != '"') return false;
609
if (s[s.size()-1] != '"') return false;
612
t.reserve(s.size() + s.size() / 32);
614
for(unsigned int i = 1; i + 1 < s.size(); i++)
619
if (i >= s.size() - 1) return false;
623
case 'a': t += '\a'; break;
624
case 'b': t += '\b'; break;
625
case 'f': t += '\f'; break;
626
case 'n': t += '\n'; break;
627
case 'r': t += '\r'; break;
628
case 't': t += '\t'; break;
629
case 'v': t += '\v'; break;
630
case '\'': t += '\''; break;
631
case '"': t += '"'; break;
632
case '\\': t += '\\'; break;
633
case '?': t += '?'; break;
649
AnyScalar& AnyScalar::setAutoString(const std::string &input)
651
// - int: input was readable by strtoll and is small enough.
652
// - long: input was readable by strtoll
656
long long l = strtoll(input.c_str(), &endptr, 10);
658
long long l = _strtoi64(input.c_str(), &endptr, 10);
660
if (endptr != NULL && *endptr == 0)
662
if (INT_MIN <= l && l <= INT_MAX)
664
resetType(ATTRTYPE_INTEGER);
670
resetType(ATTRTYPE_LONG);
677
// - double: input was readble by strtod
680
double d = strtod(input.c_str(), &endptr);
681
if (endptr != NULL && *endptr == 0)
683
resetType(ATTRTYPE_DOUBLE);
689
// - string: all above failed.
690
resetType(ATTRTYPE_STRING);
691
*val._string = input;
696
bool AnyScalar::getBoolean() const
700
case ATTRTYPE_INVALID:
705
return (val._int != 0);
709
case ATTRTYPE_INTEGER:
710
return (val._int != 0);
715
return (val._uint != 0);
718
return (val._long != 0);
721
return (val._ulong != 0);
724
return (val._float != 0.0f);
726
case ATTRTYPE_DOUBLE:
727
return (val._double != 0.0f);
729
case ATTRTYPE_STRING:
733
if (*val._string == "0" || *val._string == "f" || *val._string == "false"
734
|| *val._string == "n" || *val._string == "no") {
737
if (*val._string == "1" || *val._string == "t" || *val._string == "true"
738
|| *val._string == "y" || *val._string == "yes") {
742
throw(ConversionException("Cannot convert string to boolean."));
750
int AnyScalar::getInteger() const
754
case ATTRTYPE_INVALID:
763
case ATTRTYPE_INTEGER:
772
if (val._long > INT_MAX) return INT_MAX;
773
if (val._long < INT_MIN) return INT_MIN;
775
return static_cast<int>(val._long);
778
if (val._ulong > UINT_MAX) return UINT_MAX;
779
return static_cast<int>(val._ulong);
782
return static_cast<int>(val._float);
784
case ATTRTYPE_DOUBLE:
785
return static_cast<int>(val._double);
787
case ATTRTYPE_STRING:
791
long i = strtol(val._string->c_str(), &endptr, 10);
792
if (endptr != NULL && *endptr == 0)
795
throw(ConversionException("Cannot convert string to integer."));
803
unsigned int AnyScalar::getUnsignedInteger() const
807
case ATTRTYPE_INVALID:
814
case ATTRTYPE_INTEGER:
815
return static_cast<unsigned int>(val._int);
823
return static_cast<unsigned int>(val._long);
826
return static_cast<unsigned int>(val._ulong);
829
return static_cast<unsigned int>(val._float);
831
case ATTRTYPE_DOUBLE:
832
return static_cast<unsigned int>(val._double);
834
case ATTRTYPE_STRING:
838
unsigned long i = strtoul(val._string->c_str(), &endptr, 10);
839
if (endptr != NULL && *endptr == 0)
842
throw(ConversionException("Cannot convert string to unsigned integer."));
850
long long AnyScalar::getLong() const
854
case ATTRTYPE_INVALID:
861
case ATTRTYPE_INTEGER:
865
return static_cast<long long>(val._int);
874
return static_cast<long long>(val._float);
876
case ATTRTYPE_DOUBLE:
877
return static_cast<long long>(val._double);
879
case ATTRTYPE_STRING:
884
long long l = strtoll(val._string->c_str(), &endptr, 10);
886
long long l = _strtoi64(val._string->c_str(), &endptr, 10);
888
if (endptr != NULL && *endptr == 0)
891
throw(ConversionException("Cannot convert string to long long."));
899
unsigned long long AnyScalar::getUnsignedLong() const
903
case ATTRTYPE_INVALID:
910
case ATTRTYPE_INTEGER:
911
return static_cast<unsigned long long>(val._int);
916
return static_cast<unsigned long long>(val._uint);
919
return static_cast<unsigned long long>(val._long);
925
return static_cast<unsigned long long>(val._float);
927
case ATTRTYPE_DOUBLE:
928
return static_cast<unsigned long long>(val._double);
930
case ATTRTYPE_STRING:
935
unsigned long long u = strtoull(val._string->c_str(), &endptr, 10);
937
unsigned long long u = _strtoui64(val._string->c_str(), &endptr, 10);
939
if (endptr != NULL && *endptr == 0)
942
throw(ConversionException("Cannot convert string to unsigned long long."));
949
double AnyScalar::getDouble() const
953
case ATTRTYPE_INVALID:
960
case ATTRTYPE_INTEGER:
964
return static_cast<double>(val._int);
967
return static_cast<double>(val._long);
970
return static_cast<double>(val._ulong);
973
return static_cast<double>(val._float);
975
case ATTRTYPE_DOUBLE:
978
case ATTRTYPE_STRING:
982
double d = strtod(val._string->c_str(), &endptr);
983
if (endptr != NULL && *endptr == 0)
986
throw(ConversionException("Cannot convert string to double."));
993
std::string AnyScalar::getString() const
997
case ATTRTYPE_INVALID:
1002
if (val._int == 0) return "false";
1003
if (val._int == 1) return "true";
1008
case ATTRTYPE_SHORT:
1009
case ATTRTYPE_INTEGER:
1011
return boost::lexical_cast<std::string>(val._int);
1016
case ATTRTYPE_DWORD:
1018
return boost::lexical_cast<std::string>(val._uint);
1023
return boost::lexical_cast<std::string>(val._long);
1026
case ATTRTYPE_QWORD:
1028
return boost::lexical_cast<std::string>(val._ulong);
1031
case ATTRTYPE_FLOAT:
1033
return boost::lexical_cast<std::string>(val._float);
1036
case ATTRTYPE_DOUBLE:
1038
return boost::lexical_cast<std::string>(val._double);
1041
case ATTRTYPE_STRING:
1043
assert(val._string);
1044
return *val._string;
1051
std::string AnyScalar::getStringQuoted() const
1053
std::string str = getString();
1054
std::string os = "\"";
1056
os.reserve(2 + str.size() + str.size() / 16);
1059
for(std::string::const_iterator si = str.begin(); si != str.end(); ++si)
1113
void AnyScalar::resetType(attrtype_t t)
1115
// if setting to a string and this is not a string, create the object
1116
if (t == ATTRTYPE_STRING) {
1117
if (atype != ATTRTYPE_STRING) {
1118
val._string = new std::string;
1122
if (atype == ATTRTYPE_STRING) {
1132
bool AnyScalar::convertType(attrtype_t t)
1134
// same source and target type?
1135
if (atype == t) return true;
1137
// special case if this object was initialised with the ATTRTYPE_INVALID:
1138
// all the get...() below would assert.
1139
if (atype == ATTRTYPE_INVALID)
1142
if (atype == ATTRTYPE_STRING) {
1143
val._string = new std::string;
1150
case ATTRTYPE_INVALID:
1156
bool v = getBoolean();
1157
if (atype == ATTRTYPE_STRING) delete val._string;
1164
case ATTRTYPE_SHORT:
1165
case ATTRTYPE_INTEGER:
1167
int v = getInteger();
1168
if (atype == ATTRTYPE_STRING) delete val._string;
1176
case ATTRTYPE_DWORD:
1178
unsigned int v = getUnsignedInteger();
1179
if (atype == ATTRTYPE_STRING) delete val._string;
1187
long long v = getLong();
1188
if (atype == ATTRTYPE_STRING) delete val._string;
1194
case ATTRTYPE_QWORD:
1196
unsigned long long v = getLong();
1197
if (atype == ATTRTYPE_STRING) delete val._string;
1203
case ATTRTYPE_FLOAT:
1205
float f = static_cast<float>(getDouble());
1206
if (atype == ATTRTYPE_STRING) delete val._string;
1212
case ATTRTYPE_DOUBLE:
1214
double d = getDouble();
1215
if (atype == ATTRTYPE_STRING) delete val._string;
1221
case ATTRTYPE_STRING:
1223
val._string = new std::string(getString());
1232
AnyScalar AnyScalar::operator-() const
1234
AnyScalar at = *this;
1238
case ATTRTYPE_INVALID:
1240
throw(ConversionException("Negating invalid type."));
1243
if (at.val._int > 0) at.val._int = 0;
1244
else at.val._int = 1;
1248
case ATTRTYPE_SHORT:
1249
case ATTRTYPE_INTEGER:
1250
at.val._int = - at.val._int;
1255
case ATTRTYPE_DWORD:
1256
at.val._uint = - at.val._uint;
1260
at.val._long = - at.val._long;
1263
case ATTRTYPE_QWORD:
1264
at.val._ulong = - at.val._ulong;
1267
case ATTRTYPE_FLOAT:
1268
at.val._float = - at.val._float;
1271
case ATTRTYPE_DOUBLE:
1272
at.val._double = - at.val._double;
1275
case ATTRTYPE_STRING:
1277
if (!at.convertType(ATTRTYPE_DOUBLE))
1278
throw(ConversionException("Cannot convert string to double for negation."));
1280
at.val._double = - at.val._double;
1288
template <template <typename Type> class Operator, char OpName>
1289
AnyScalar AnyScalar::binary_arith_op(const AnyScalar &b) const
1293
case ATTRTYPE_INVALID:
1295
throw(ConversionException(std::string("Invalid type for first operand of binary operator ")+OpName+"."));
1298
throw(ConversionException("No binary operators are allowed on bool values."));
1301
case ATTRTYPE_SHORT:
1302
case ATTRTYPE_INTEGER:
1306
case ATTRTYPE_INVALID:
1308
throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
1311
throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
1314
case ATTRTYPE_SHORT:
1315
case ATTRTYPE_INTEGER:
1318
if (OpName == '/' && b.val._int == 0) throw(ArithmeticException("Integer division by zero"));
1319
return AnyScalar( op(val._int, b.val._int) );
1324
case ATTRTYPE_DWORD:
1327
if (OpName == '/' && b.val._uint == 0) throw(ArithmeticException("Integer division by zero"));
1328
return AnyScalar( op(val._int, static_cast<signed int>(b.val._uint)) );
1333
Operator<long long> op;
1334
if (OpName == '/' && b.val._long == 0) throw(ArithmeticException("Integer division by zero"));
1335
return AnyScalar( op(val._int, b.val._long) );
1338
case ATTRTYPE_QWORD:
1340
Operator<long long> op;
1341
if (OpName == '/' && b.val._ulong == 0) throw(ArithmeticException("Integer division by zero"));
1342
return AnyScalar( op(static_cast<long long>(val._int), static_cast<long long>(b.val._ulong)) );
1345
case ATTRTYPE_FLOAT:
1348
return AnyScalar( op(static_cast<float>(val._int), b.val._float));
1351
case ATTRTYPE_DOUBLE:
1353
Operator<double> op;
1354
return AnyScalar( op(static_cast<double>(val._int), b.val._double) );
1357
case ATTRTYPE_STRING:
1361
if (!bc.convertType(ATTRTYPE_INTEGER))
1362
throw(ConversionException(std::string("Could not convert string to integer for binary operator ")+OpName+"."));
1366
int bval = bc.getInteger();
1367
if (OpName == '/' && bval == 0) throw(ArithmeticException("Integer division by zero"));
1369
return AnyScalar( op(val._int, bval) );
1377
case ATTRTYPE_DWORD:
1381
case ATTRTYPE_INVALID:
1383
throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
1386
throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
1389
case ATTRTYPE_SHORT:
1390
case ATTRTYPE_INTEGER:
1393
if (OpName == '/' && b.val._int == 0) throw(ArithmeticException("Integer division by zero"));
1394
return AnyScalar( op(static_cast<signed int>(val._uint), b.val._int) );
1399
case ATTRTYPE_DWORD:
1401
Operator<unsigned int> op;
1402
if (OpName == '/' && b.val._uint == 0) throw(ArithmeticException("Integer division by zero"));
1403
return AnyScalar( op(val._uint, b.val._uint) );
1408
Operator<long long> op;
1409
if (OpName == '/' && b.val._long == 0) throw(ArithmeticException("Integer division by zero"));
1410
return AnyScalar( op(static_cast<signed long long>(val._uint), b.val._long) );
1413
case ATTRTYPE_QWORD:
1415
Operator<unsigned long long> op;
1416
if (OpName == '/' && b.val._ulong == 0) throw(ArithmeticException("Integer division by zero"));
1417
return AnyScalar( op(static_cast<unsigned long long>(val._uint), b.val._ulong) );
1420
case ATTRTYPE_FLOAT:
1423
return AnyScalar( op(static_cast<float>(val._uint), b.val._float));
1426
case ATTRTYPE_DOUBLE:
1428
Operator<double> op;
1429
return AnyScalar( op(static_cast<double>(val._uint), b.val._double) );
1432
case ATTRTYPE_STRING:
1436
if (!bc.convertType(ATTRTYPE_DWORD))
1437
throw(ConversionException(std::string("Could not convert string to unsigned integer for binary operator ")+OpName+"."));
1439
Operator<unsigned int> op;
1441
int bval = bc.getInteger();
1442
if (OpName == '/' && bval == 0) throw(ArithmeticException("Integer division by zero"));
1444
return AnyScalar( op(val._int, bval) );
1454
case ATTRTYPE_INVALID:
1456
throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
1459
throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
1462
case ATTRTYPE_SHORT:
1463
case ATTRTYPE_INTEGER:
1465
Operator<long long> op;
1466
if (OpName == '/' && b.val._int == 0) throw(ArithmeticException("Integer division by zero"));
1467
return AnyScalar( op(val._long, static_cast<long long>(b.val._int)) );
1472
case ATTRTYPE_DWORD:
1474
Operator<long long> op;
1475
if (OpName == '/' && b.val._uint == 0) throw(ArithmeticException("Integer division by zero"));
1476
return AnyScalar( op(val._long, static_cast<signed long long>(b.val._uint)) );
1481
Operator<long long> op;
1482
if (OpName == '/' && b.val._long == 0) throw(ArithmeticException("Integer division by zero"));
1483
return AnyScalar( op(val._long, b.val._long) );
1486
case ATTRTYPE_QWORD:
1488
Operator<long long> op;
1489
if (OpName == '/' && b.val._ulong == 0) throw(ArithmeticException("Integer division by zero"));
1490
return AnyScalar( op(val._long, static_cast<signed long long>(b.val._ulong)) );
1493
case ATTRTYPE_FLOAT:
1496
return AnyScalar( op(static_cast<float>(val._long), b.val._float));
1499
case ATTRTYPE_DOUBLE:
1501
Operator<double> op;
1502
return AnyScalar( op(static_cast<double>(val._long), b.val._double) );
1505
case ATTRTYPE_STRING:
1509
if (!bc.convertType(ATTRTYPE_LONG))
1510
throw(ConversionException(std::string("Could not convert string to long for binary operator ")+OpName+"."));
1512
Operator<long long> op;
1514
long long bval = bc.getLong();
1515
if (OpName == '/' && bval == 0) throw(ArithmeticException("Integer division by zero"));
1517
return AnyScalar( op(val._long, bval) );
1523
case ATTRTYPE_QWORD:
1527
case ATTRTYPE_INVALID:
1529
throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
1532
throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
1535
case ATTRTYPE_SHORT:
1536
case ATTRTYPE_INTEGER:
1538
Operator<long long> op;
1539
if (OpName == '/' && b.val._int == 0) throw(ArithmeticException("Integer division by zero"));
1540
return AnyScalar( op(static_cast<signed long long>(val._ulong), b.val._int) );
1545
case ATTRTYPE_DWORD:
1547
Operator<unsigned long long> op;
1548
if (OpName == '/' && b.val._uint == 0) throw(ArithmeticException("Integer division by zero"));
1549
return AnyScalar( op(val._ulong, static_cast<unsigned long long>(b.val._uint)) );
1554
Operator<long long> op;
1555
if (OpName == '/' && b.val._long == 0) throw(ArithmeticException("Integer division by zero"));
1556
return AnyScalar( op(static_cast<signed long long>(val._ulong), b.val._long) );
1559
case ATTRTYPE_QWORD:
1561
Operator<unsigned long long> op;
1562
if (OpName == '/' && b.val._ulong == 0) throw(ArithmeticException("Integer division by zero"));
1563
return AnyScalar( op(val._ulong, b.val._ulong) );
1566
case ATTRTYPE_FLOAT:
1569
return AnyScalar( op(static_cast<float>(val._ulong), b.val._float));
1572
case ATTRTYPE_DOUBLE:
1574
Operator<double> op;
1575
return AnyScalar( op(static_cast<double>(val._ulong), b.val._double) );
1578
case ATTRTYPE_STRING:
1582
if (!bc.convertType(ATTRTYPE_QWORD))
1583
throw(ConversionException(std::string("Could not convert string to unsigned long long for binary operator ")+OpName+"."));
1585
Operator<unsigned long long> op;
1587
long long bval = bc.getLong();
1588
if (OpName == '/' && bval == 0) throw(ArithmeticException("Integer division by zero"));
1590
return AnyScalar( op(val._ulong, bval) );
1596
case ATTRTYPE_FLOAT:
1600
case ATTRTYPE_INVALID:
1602
throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
1605
throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
1608
case ATTRTYPE_SHORT:
1609
case ATTRTYPE_INTEGER:
1612
return AnyScalar( op(val._float, static_cast<float>(b.val._int)) );
1617
case ATTRTYPE_DWORD:
1620
return AnyScalar( op(val._float, static_cast<float>(b.val._uint)) );
1626
return AnyScalar( op(val._float, static_cast<float>(b.val._long)) );
1629
case ATTRTYPE_QWORD:
1632
return AnyScalar( op(val._float, static_cast<float>(b.val._ulong)) );
1635
case ATTRTYPE_FLOAT:
1638
return AnyScalar( op(val._float, b.val._float));
1641
case ATTRTYPE_DOUBLE:
1643
Operator<double> op;
1644
return AnyScalar( op(static_cast<double>(val._float), b.val._double) );
1647
case ATTRTYPE_STRING:
1651
if (!bc.convertType(ATTRTYPE_FLOAT))
1652
throw(ConversionException(std::string("Could not convert string to float for binary operator ")+OpName+"."));
1656
return AnyScalar( op(val._float, bc.val._float) );
1663
case ATTRTYPE_DOUBLE:
1667
case ATTRTYPE_INVALID:
1669
throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
1672
throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
1675
case ATTRTYPE_SHORT:
1676
case ATTRTYPE_INTEGER:
1678
Operator<double> op;
1679
return AnyScalar( op(val._double, static_cast<double>(b.val._int)) );
1684
case ATTRTYPE_DWORD:
1686
Operator<double> op;
1687
return AnyScalar( op(val._double, static_cast<double>(b.val._uint)) );
1692
Operator<double> op;
1693
return AnyScalar( op(val._double, static_cast<double>(b.val._long)) );
1696
case ATTRTYPE_QWORD:
1698
Operator<double> op;
1699
return AnyScalar( op(val._double, static_cast<double>(b.val._ulong)) );
1702
case ATTRTYPE_FLOAT:
1704
Operator<double> op;
1705
return AnyScalar( op(val._double, static_cast<double>(b.val._float)));
1708
case ATTRTYPE_DOUBLE:
1710
Operator<double> op;
1711
return AnyScalar( op(val._double, b.val._double) );
1714
case ATTRTYPE_STRING:
1718
if (!bc.convertType(ATTRTYPE_DOUBLE))
1719
throw(ConversionException(std::string("Could not convert string to double for binary operator ")+OpName+"."));
1721
Operator<double> op;
1723
return AnyScalar( op(val._double, bc.getDouble()) );
1730
// if this is a string, then the other type defines the conversion
1731
case ATTRTYPE_STRING:
1735
case ATTRTYPE_INVALID:
1737
throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpName+"."));
1740
throw(ConversionException(std::string("Binary operator ")+OpName+" is not permitted on bool values."));
1743
case ATTRTYPE_SHORT:
1744
case ATTRTYPE_INTEGER:
1747
if (OpName == '/' && b.val._int == 0) throw(ArithmeticException("Integer division by zero"));
1748
return AnyScalar( op(this->getInteger(), b.val._int) );
1753
case ATTRTYPE_DWORD:
1755
Operator<unsigned int> op;
1756
if (OpName == '/' && b.val._uint == 0) throw(ArithmeticException("Integer division by zero"));
1757
return AnyScalar( op(this->getUnsignedInteger(), b.val._uint) );
1762
Operator<long long> op;
1763
if (OpName == '/' && b.val._long == 0) throw(ArithmeticException("Integer division by zero"));
1764
return AnyScalar( op(this->getLong(), b.val._long) );
1767
case ATTRTYPE_QWORD:
1769
Operator<unsigned long long> op;
1770
if (OpName == '/' && b.val._ulong == 0) throw(ArithmeticException("Integer division by zero"));
1771
return AnyScalar( op(this->getUnsignedLong(), b.val._ulong) );
1774
case ATTRTYPE_FLOAT:
1777
return AnyScalar( op(static_cast<float>(this->getDouble()), b.val._float) );
1780
case ATTRTYPE_DOUBLE:
1782
Operator<double> op;
1783
return AnyScalar( op(this->getDouble(), b.val._double) );
1786
case ATTRTYPE_STRING:
1789
return AnyScalar( *val._string + *b.val._string );
1792
throw(ConversionException(std::string("Binary operator ")+OpName+" is not allowed between two string values."));
1798
throw(ConversionException("Invalid binary operator call. (PROGRAM ERROR)"));
1801
// *** Force instantiation of binary_op for the four arithmetic operators
1803
/// Forced instantiation of binary_arith_op for AnyScalar::operator+()
1804
template AnyScalar AnyScalar::binary_arith_op<std::plus, '+'>(const AnyScalar &b) const;
1806
/// Forced instantiation of binary_arith_op for AnyScalar::operator-()
1807
template AnyScalar AnyScalar::binary_arith_op<std::minus, '-'>(const AnyScalar &b) const;
1809
/// Forced instantiation of binary_arith_op for AnyScalar::operator*()
1810
template AnyScalar AnyScalar::binary_arith_op<std::multiplies, '*'>(const AnyScalar &b) const;
1812
/// Forced instantiation of binary_arith_op for AnyScalar::operator/()
1813
template AnyScalar AnyScalar::binary_arith_op<std::divides, '/'>(const AnyScalar &b) const;
1815
template <template <typename Type> class Operator, int OpNum>
1816
bool AnyScalar::binary_comp_op(const AnyScalar &b) const
1818
static const char *OpNameArray[] = { "==", "!=", "<", ">", "<=", ">=" };
1822
case ATTRTYPE_INVALID:
1824
throw(ConversionException(std::string("Invalid type for first operand of binary operator ")+OpNameArray[OpNum]+"."));
1830
case ATTRTYPE_INVALID:
1832
throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
1837
return op(val._int, b.val._int);
1841
throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
1847
case ATTRTYPE_SHORT:
1848
case ATTRTYPE_INTEGER:
1852
case ATTRTYPE_INVALID:
1854
throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
1857
throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
1860
case ATTRTYPE_SHORT:
1861
case ATTRTYPE_INTEGER:
1864
return op(val._int, b.val._int);
1869
case ATTRTYPE_DWORD:
1872
return op(val._int, static_cast<signed int>(b.val._uint));
1877
Operator<long long> op;
1878
return op(val._int, b.val._long);
1881
case ATTRTYPE_QWORD:
1883
Operator<long long> op;
1884
return op(val._int, static_cast<signed long long>(b.val._ulong));
1887
case ATTRTYPE_FLOAT:
1890
return op(static_cast<float>(val._int), b.val._float);
1893
case ATTRTYPE_DOUBLE:
1895
Operator<double> op;
1896
return op(static_cast<double>(val._int), b.val._double);
1899
case ATTRTYPE_STRING:
1903
if (!bc.convertType(ATTRTYPE_INTEGER))
1904
throw(ConversionException(std::string("Could not convert string to integer for binary operator ")+OpNameArray[OpNum]+"."));
1908
return op(val._int, bc.getInteger());
1916
case ATTRTYPE_DWORD:
1920
case ATTRTYPE_INVALID:
1922
throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
1925
throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
1928
case ATTRTYPE_SHORT:
1929
case ATTRTYPE_INTEGER:
1932
return op(static_cast<signed int>(val._uint), b.val._int);
1937
case ATTRTYPE_DWORD:
1939
Operator<unsigned int> op;
1940
return op(val._uint, b.val._uint);
1945
Operator<long long> op;
1946
return op(static_cast<signed long long>(val._uint), b.val._long);
1949
case ATTRTYPE_QWORD:
1951
Operator<unsigned long long> op;
1952
return op(static_cast<unsigned long long>(val._uint), b.val._ulong);
1955
case ATTRTYPE_FLOAT:
1958
return op(static_cast<float>(val._uint), b.val._float);
1961
case ATTRTYPE_DOUBLE:
1963
Operator<double> op;
1964
return op(static_cast<double>(val._uint), b.val._double);
1967
case ATTRTYPE_STRING:
1971
if (!bc.convertType(ATTRTYPE_DWORD))
1972
throw(ConversionException(std::string("Could not convert string to unsigned integer for binary operator ")+OpNameArray[OpNum]+"."));
1974
Operator<unsigned int> op;
1976
return op(val._int, bc.getInteger());
1986
case ATTRTYPE_INVALID:
1988
throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
1991
throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
1994
case ATTRTYPE_SHORT:
1995
case ATTRTYPE_INTEGER:
1997
Operator<long long> op;
1998
return op(val._long, static_cast<long long>(b.val._int));
2003
case ATTRTYPE_DWORD:
2005
Operator<long long> op;
2006
return op(val._long, static_cast<signed long long>(b.val._uint));
2011
Operator<long long> op;
2012
return op(val._long, b.val._long);
2015
case ATTRTYPE_QWORD:
2017
Operator<long long> op;
2018
return op(val._long, static_cast<signed long long>(b.val._ulong));
2021
case ATTRTYPE_FLOAT:
2024
return op(static_cast<float>(val._long), b.val._float);
2027
case ATTRTYPE_DOUBLE:
2029
Operator<double> op;
2030
return op(static_cast<double>(val._long), b.val._double);
2033
case ATTRTYPE_STRING:
2037
if (!bc.convertType(ATTRTYPE_LONG))
2038
throw(ConversionException(std::string("Could not convert string to long long for binary operator ")+OpNameArray[OpNum]+"."));
2040
Operator<long long> op;
2042
return op(val._long, bc.getLong());
2048
case ATTRTYPE_QWORD:
2052
case ATTRTYPE_INVALID:
2054
throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
2057
throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
2060
case ATTRTYPE_SHORT:
2061
case ATTRTYPE_INTEGER:
2063
Operator<long long> op;
2064
return op(val._ulong, static_cast<signed long long>(b.val._int));
2069
case ATTRTYPE_DWORD:
2071
Operator<unsigned long long> op;
2072
return op(val._ulong, b.val._uint);
2077
Operator<long long> op;
2078
return op(static_cast<signed long long>(val._ulong), b.val._long);
2081
case ATTRTYPE_QWORD:
2083
Operator<unsigned long long> op;
2084
return op(val._ulong, b.val._ulong);
2087
case ATTRTYPE_FLOAT:
2090
return op(static_cast<float>(val._ulong), b.val._float);
2093
case ATTRTYPE_DOUBLE:
2095
Operator<double> op;
2096
return op(static_cast<double>(val._ulong), b.val._double);
2099
case ATTRTYPE_STRING:
2103
if (!bc.convertType(ATTRTYPE_QWORD))
2104
throw(ConversionException(std::string("Could not convert string to unsigned long long for binary operator ")+OpNameArray[OpNum]+"."));
2106
Operator<unsigned long long> op;
2108
return op(val._int, bc.getUnsignedLong());
2114
case ATTRTYPE_FLOAT:
2118
case ATTRTYPE_INVALID:
2120
throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
2123
throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
2126
case ATTRTYPE_SHORT:
2127
case ATTRTYPE_INTEGER:
2130
return op(val._float, static_cast<float>(b.val._int));
2135
case ATTRTYPE_DWORD:
2138
return op(val._float, static_cast<float>(b.val._uint));
2144
return op(val._float, static_cast<float>(b.val._long));
2147
case ATTRTYPE_QWORD:
2150
return op(val._float, static_cast<float>(b.val._ulong));
2153
case ATTRTYPE_FLOAT:
2156
return op(val._float, b.val._float);
2159
case ATTRTYPE_DOUBLE:
2161
Operator<double> op;
2162
return op(static_cast<double>(val._float), b.val._double);
2165
case ATTRTYPE_STRING:
2169
if (!bc.convertType(ATTRTYPE_FLOAT))
2170
throw(ConversionException(std::string("Could not convert string to float for binary operator ")+OpNameArray[OpNum]+"."));
2174
return op(val._float, bc.val._float);
2181
case ATTRTYPE_DOUBLE:
2185
case ATTRTYPE_INVALID:
2187
throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
2190
throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
2193
case ATTRTYPE_SHORT:
2194
case ATTRTYPE_INTEGER:
2196
Operator<double> op;
2197
return op(val._double, static_cast<double>(b.val._int));
2202
case ATTRTYPE_DWORD:
2204
Operator<double> op;
2205
return op(val._double, static_cast<double>(b.val._uint));
2210
Operator<double> op;
2211
return op(val._double, static_cast<double>(b.val._long));
2214
case ATTRTYPE_QWORD:
2216
Operator<double> op;
2217
return op(val._double, static_cast<double>(b.val._ulong));
2220
case ATTRTYPE_FLOAT:
2222
Operator<double> op;
2223
return op(val._double, static_cast<double>(b.val._float));
2226
case ATTRTYPE_DOUBLE:
2228
Operator<double> op;
2229
return op(val._double, b.val._double);
2232
case ATTRTYPE_STRING:
2236
if (!bc.convertType(ATTRTYPE_DOUBLE))
2237
throw(ConversionException(std::string("Could not convert string to double for binary operator ")+OpNameArray[OpNum]+"."));
2239
Operator<double> op;
2241
return op(val._double, bc.getDouble());
2248
// if this is a string, then the other type defines the conversion
2249
case ATTRTYPE_STRING:
2253
case ATTRTYPE_INVALID:
2255
throw(ConversionException(std::string("Invalid type for second operand of binary operator ")+OpNameArray[OpNum]+"."));
2258
throw(ConversionException(std::string("Binary operator ")+OpNameArray[OpNum]+" is not permitted on bool values."));
2261
case ATTRTYPE_SHORT:
2262
case ATTRTYPE_INTEGER:
2265
return op(this->getInteger(), b.val._int);
2270
case ATTRTYPE_DWORD:
2272
Operator<unsigned int> op;
2273
return op(this->getUnsignedInteger(), b.val._int);
2278
Operator<long long> op;
2279
return op(this->getLong(), b.val._long);
2282
case ATTRTYPE_QWORD:
2284
Operator<unsigned long long> op;
2285
return op(this->getUnsignedLong(), b.val._ulong);
2288
case ATTRTYPE_FLOAT:
2291
return op(static_cast<float>(this->getDouble()), b.val._float);
2294
case ATTRTYPE_DOUBLE:
2296
Operator<double> op;
2297
return op(this->getDouble(), b.val._double);
2300
case ATTRTYPE_STRING:
2302
Operator<std::string> op;
2303
return op(*val._string, *b.val._string);
2310
throw(ConversionException("Invalid binary operator call. (PROGRAM ERROR)"));
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;
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;
2319
/// Forced instantiation of binary_comp_op for AnyScalar::less()
2320
template bool AnyScalar::binary_comp_op<std::less, 2>(const AnyScalar &b) const;
2322
/// Forced instantiation of binary_comp_op for AnyScalar::greater()
2323
template bool AnyScalar::binary_comp_op<std::greater, 3>(const AnyScalar &b) const;
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;
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;