~dominik-burgdoerfer/webplodder/0.4

« back to all changes in this revision

Viewing changes to libstx-exparser/src/stx/AnyScalar.cc

  • Committer: Dominik Burgdörfer
  • Date: 2010-07-09 20:05:23 UTC
  • Revision ID: dominik@domachine-20100709200523-xq8qj0x5lj5eq4pg
removed unused libstx-exparser

Show diffs side-by-side

added added

removed removed

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