| Qore Programming Language - C/C++ Library 1.0.8

QoreValue.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3 QoreValue.h
4
5 Qore Programming Language
6
7 Copyright (C) 2003 - 2021 Qore Technologies, s.r.o.
8
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the "Software"),
11 to deal in the Software without restriction, including without limitation
12 the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 and/or sell copies of the Software, and to permit persons to whom the
14 Software is furnished to do so, subject to the following conditions:
15
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26
27 Note that the Qore library is released under a choice of three open-source
28 licenses: MIT (as above), LGPL 2+, or GPL 2+; see README-LICENSE for more
29 information.
30 */
31
32 #ifndef _QORE_QOREVALUE_H
33 #define _QORE_QOREVALUE_H
34
35 #include <cassert>
36
37 typedef unsigned char valtype_t;
38
40
43 #define QV_Bool (valtype_t)0
44 #define QV_Int (valtype_t)1
45 #define QV_Float (valtype_t)2
46 #define QV_Node (valtype_t)3
47 #define QV_Ref (valtype_t)4
48
49
50 // forward references
51 class AbstractQoreNode;
52 class QoreString;
53 struct QoreValue;
54
56 union qore_value_u {
57 bool b;
58 int64 i;
59 double f;
60 AbstractQoreNode* n;
61 };
62
64 namespace detail {
66 template<typename Type>
67 struct QoreValueCastHelper {
68 typedef Type * Result;
69
70 template<typename QV>
71 static Result cast(QV *qv, valtype_t type) {
72 assert(type == QV_Node);
73 assert(!qv->v.n || dynamic_cast<Result>(qv->v.n));
74 return reinterpret_cast<Result>(qv->v.n);
75 }
76 };
77
79 template<>
80 struct QoreValueCastHelper<bool> {
81 typedef bool Result;
82
83 template<typename QV>
84 static bool cast(QV *qv, valtype_t type) {
85 return qv->getAsBool();
86 }
87 };
88
90 template<>
91 struct QoreValueCastHelper<double> {
92 typedef double Result;
93
94 template<typename QV>
95 static double cast(QV *qv, valtype_t type) {
96 return qv->getAsFloat();
97 }
98 };
99
101 template<>
102 struct QoreValueCastHelper<int64> {
103 typedef int64 Result;
104
105 template<typename QV>
106 static int64 cast(QV *qv, valtype_t type) {
107 return qv->getAsBigInt();
108 }
109 };
110 } // namespace detail
111
112 class QoreSimpleValue {
113 public:
115 qore_value_u v;
117 valtype_t type;
118
120 DLLLOCAL void set(int64 i) {
121 type = QV_Int;
122 v.i = i;
123 }
124
126 DLLLOCAL void set(double f) {
127 type = QV_Float;
128 v.f = f;
129 }
130
132 DLLLOCAL void set(bool b) {
133 type = QV_Bool;
134 v.b = b;
135 }
136
138 DLLEXPORT void set(QoreSimpleValue val);
139
141 DLLEXPORT void set(AbstractQoreNode* n);
142
144 DLLLOCAL QoreSimpleValue& assign(QoreSimpleValue& val) {
145 set(val);
146 return *this;
147 }
148
150 DLLLOCAL QoreSimpleValue& assign(int64 i) {
151 set(i);
152 return *this;
153 }
154
156 DLLLOCAL QoreSimpleValue& assign(double f) {
157 set(f);
158 return *this;
159 }
160
162 DLLLOCAL QoreSimpleValue& assign(bool b) {
163 set(b);
164 return *this;
165 }
166
168 DLLLOCAL QoreSimpleValue& assign(AbstractQoreNode* n) {
169 set(n);
170 return *this;
171 }
172
174 DLLEXPORT qore_type_t getType() const;
175
177 DLLEXPORT const char* getTypeName() const;
178
180
182 DLLEXPORT AbstractQoreNode* takeNode();
183
185 DLLEXPORT AbstractQoreNode* getInternalNode();
186
188 DLLEXPORT const AbstractQoreNode* getInternalNode() const;
189
191 DLLEXPORT void clear();
192
194 DLLEXPORT void discard(ExceptionSink* xsink);
195
197
199 template<typename T>
200 DLLLOCAL T* take() {
201 assert(type == QV_Node);
202 assert(dynamic_cast<T*>(v.n));
203 T* rv = reinterpret_cast<T*>(v.n);
204 v.n = 0;
205 return rv;
206 }
207
209
212 template<typename T>
213 DLLLOCAL typename detail::QoreValueCastHelper<T>::Result get() {
214 return detail::QoreValueCastHelper<T>::cast(this, type);
215 }
216
218
221 template<typename T>
222 DLLLOCAL typename detail::QoreValueCastHelper<const T>::Result get() const {
223 return detail::QoreValueCastHelper<const T>::cast(this, type);
224 }
225
227 DLLEXPORT bool getAsBool() const;
228
230 DLLEXPORT int64 getAsBigInt() const;
231
233 DLLEXPORT double getAsFloat() const;
234
236 DLLEXPORT bool hasEffect() const;
237
239 DLLEXPORT bool isNothing() const;
240
242 DLLEXPORT bool isNull() const;
243
245 DLLEXPORT bool isNullOrNothing() const;
246
248 DLLEXPORT bool isValue() const;
249
251 DLLEXPORT bool needsEval() const;
252
254
256 DLLEXPORT bool isScalar() const;
257
259 DLLEXPORT operator bool() const;
260
261 protected:
263 DLLEXPORT AbstractQoreNode* takeNodeIntern();
264 };
265
267 struct QoreValue : public QoreSimpleValue {
268 friend class ValueHolder;
269 friend class ValueOptionalRefHolder;
270 template<typename> friend struct detail::QoreValueCastHelper;
271
272 public:
274 DLLEXPORT QoreValue();
275
277 DLLEXPORT QoreValue(bool b);
278
280 DLLEXPORT QoreValue(int i);
281
283 DLLEXPORT QoreValue(unsigned int i);
284
286 DLLEXPORT QoreValue(long i);
287
289 DLLEXPORT QoreValue(unsigned long i);
290
292 DLLEXPORT QoreValue(unsigned long long i);
293
295 DLLEXPORT QoreValue(int64 i);
296
298 DLLEXPORT QoreValue(double f);
299
301 DLLEXPORT QoreValue(AbstractQoreNode* n);
302
304
310 DLLEXPORT QoreValue(const AbstractQoreNode* n);
311
313 DLLEXPORT QoreValue(const QoreSimpleValue& v);
314
316 DLLEXPORT QoreValue(const QoreValue& old);
317
319 DLLEXPORT void swap(QoreValue& val);
320
322 DLLEXPORT void ref() const;
323
325 DLLEXPORT QoreValue refSelf() const;
326
328
331 DLLEXPORT AbstractQoreNode* assign(const QoreValue n);
332
334
337 DLLEXPORT AbstractQoreNode* assign(AbstractQoreNode* n);
338
340
343 DLLEXPORT AbstractQoreNode* assign(int64 n);
344
346
349 DLLEXPORT AbstractQoreNode* assign(double n);
350
352
355 DLLEXPORT AbstractQoreNode* assign(bool n);
356
358
362 DLLEXPORT AbstractQoreNode* assignNothing();
363
365 DLLEXPORT bool isEqualSoft(const QoreValue v, ExceptionSink* xsink) const;
366
368 DLLEXPORT bool isEqualHard(const QoreValue v) const;
369
371 DLLEXPORT bool isEqualValue(const QoreValue v);
372
374 DLLEXPORT void sanitize();
375
377 DLLEXPORT QoreValue& operator=(const QoreValue& n);
378
380 DLLEXPORT QoreValue& operator=(const QoreSimpleValue& n);
381
383 DLLEXPORT void discard(ExceptionSink* xsink);
384
386 DLLEXPORT int getAsString(QoreString& str, int format_offset, ExceptionSink *xsink) const;
387
389 DLLEXPORT QoreString* getAsString(bool& del, int foff, ExceptionSink* xsink) const;
390
392 DLLEXPORT QoreValue eval(ExceptionSink* xsink) const;
393
395 DLLEXPORT QoreValue eval(bool& needs_deref, ExceptionSink* xsink) const;
396
398 //DLLEXPORT QoreValue refSelf() const;
399
401 DLLEXPORT AbstractQoreNode* takeIfNode();
402
404
406 DLLEXPORT const QoreTypeInfo* getTypeInfo() const;
407
409
411 DLLEXPORT const QoreTypeInfo* getFullTypeInfo() const;
412
414
416 DLLEXPORT const char* getFullTypeName() const;
417
419
425 DLLEXPORT const char* getFullTypeName(bool with_namespaces) const;
426
428 DLLEXPORT bool hasNode() const;
429
431 DLLEXPORT bool isReferenceCounted() const;
432
434 DLLEXPORT bool derefCanThrowException() const;
435 };
436
438 class ValueHolderBase {
439 protected:
441 QoreValue v;
443 ExceptionSink* xsink;
444
445 public:
447 DLLLOCAL ValueHolderBase(ExceptionSink* xs) : xsink(xs) {
448 }
449
451 DLLLOCAL ValueHolderBase(QoreValue n_v, ExceptionSink* xs) : v(n_v), xsink(xs) {
452 }
453
455 DLLLOCAL QoreValue* operator->() { return &v; }
456
458 DLLLOCAL const QoreValue* operator->() const { return &v; }
459
461 DLLLOCAL QoreValue& operator*() { return v; }
462
464 DLLLOCAL const QoreValue& operator*() const { return v; }
465 };
466
468 class ValueHolder : public ValueHolderBase {
469 public:
471 DLLLOCAL ValueHolder(ExceptionSink* xs) : ValueHolderBase(xs) {
472 }
473
475 DLLLOCAL ValueHolder(QoreValue n_v, ExceptionSink* xs) : ValueHolderBase(n_v, xs) {
476 }
477
479 DLLEXPORT ~ValueHolder();
480
482 DLLEXPORT QoreValue getReferencedValue();
483
485 DLLEXPORT QoreValue release();
486
488 DLLLOCAL QoreValue& operator=(QoreValue nv) {
489 v.discard(xsink);
490 v = nv;
491 return v;
492 }
493
495 DLLLOCAL operator bool() const {
496 return (bool)v;
497 }
498 };
499
501 class ValueOptionalRefHolder : public ValueHolderBase {
502 private:
503 // not implemented
504 DLLLOCAL QoreValue& operator=(QoreValue& nv);
505
506 protected:
508 bool needs_deref;
509
510 public:
512 DLLLOCAL ValueOptionalRefHolder(QoreValue n_v, bool nd, ExceptionSink* xs) : ValueHolderBase(n_v, xs), needs_deref(nd) {
513 }
514
516 DLLLOCAL ValueOptionalRefHolder(ExceptionSink* xs) : ValueHolderBase(xs), needs_deref(false) {
517 }
518
519 DLLEXPORT ~ValueOptionalRefHolder();
520
522 DLLLOCAL bool isTemp() const { return needs_deref; }
523
525 DLLLOCAL void clearTemp() {
526 if (needs_deref)
527 needs_deref = false;
528 }
529
531 DLLLOCAL operator bool() const {
532 return (bool)v;
533 }
534
536 DLLLOCAL void setValue(QoreValue nv) {
537 if (needs_deref) {
538 v.discard(xsink);
539 needs_deref = false;
540 }
541 v = nv;
542 }
543
545 DLLLOCAL void setValue(QoreValue nv, bool temp) {
546 if (needs_deref)
547 v.discard(xsink);
548 if (needs_deref != temp)
549 needs_deref = temp;
550 v = nv;
551 }
552
553 // ensures that the held value is referenced
556 DLLEXPORT void ensureReferencedValue();
557
559 template<typename T>
560 DLLLOCAL T* takeReferencedNode() {
561 T* rv = v.take<T>();
562 if (needs_deref)
563 needs_deref = false;
564 else
565 rv->ref();
566
567 return rv;
568 }
569
571 DLLEXPORT QoreValue getReferencedValue();
572
574 DLLLOCAL AbstractQoreNode* takeNode(bool& nd) {
575 if (v.type == QV_Node) {
576 nd = needs_deref;
577 return v.takeNodeIntern();
578 }
579 nd = true;
580 return v.takeNode();
581 }
582
584 DLLLOCAL QoreValue takeValue(bool& nd) {
585 if (v.type == QV_Node) {
586 nd = needs_deref;
587 return v.takeNodeIntern();
588 }
589 nd = false;
590 return v;
591 }
592
594 DLLLOCAL void takeValueFrom(ValueOptionalRefHolder& val) {
595 if (needs_deref)
596 v.discard(xsink);
597 v = val.takeValue(needs_deref);
598 }
599
601 DLLEXPORT QoreValue takeReferencedValue();
602 };
603
605 class ValueEvalRefHolder : public ValueOptionalRefHolder {
606 public:
608 DLLEXPORT ValueEvalRefHolder(const AbstractQoreNode* exp, ExceptionSink* xs);
609
611
613 DLLEXPORT ValueEvalRefHolder(const QoreValue exp, ExceptionSink* xs);
614
616
618 DLLEXPORT ValueEvalRefHolder(ExceptionSink* xs);
619
621
623 DLLEXPORT int eval(const AbstractQoreNode* exp);
624
626
628 DLLEXPORT int eval(const QoreValue exp);
629
630 protected:
632
634 DLLLOCAL int evalIntern(const AbstractQoreNode* exp);
635
637
639 DLLLOCAL int evalIntern(const QoreValue exp);
640 };
641
643 DLLEXPORT extern const char* qoreBoolTypeName;
645 DLLEXPORT extern const char* qoreIntTypeName;
647 DLLEXPORT extern const char* qoreFloatTypeName;
648
649 #endif
QoreValue::QoreValue
DLLEXPORT QoreValue()
creates with no value (i.e. QoreNothingNode)
QoreValue::swap
DLLEXPORT void swap(QoreValue &val)
exchanges the values
ValueHolder::~ValueHolder
DLLEXPORT ~ValueHolder()
dereferences any contained node
ValueHolder::getReferencedValue
DLLEXPORT QoreValue getReferencedValue()
returns a referenced value; caller owns the reference; the current object is left undisturbed ...
qore_value_u::f
double f
for double values
Definition: QoreValue.h:59
ValueEvalRefHolder::evalIntern
DLLLOCAL int evalIntern(const AbstractQoreNode *exp)
evaluates the argument, returns -1 for error, 0 = OK
QoreValue::isEqualSoft
DLLEXPORT bool isEqualSoft(const QoreValue v, ExceptionSink *xsink) const
returns trus if the argument value is equal to the current value with type conversions ...
ValueHolderBase
base class for holding a QoreValue object
Definition: QoreValue.h:438
QoreValue::isReferenceCounted
DLLEXPORT bool isReferenceCounted() const
returns true if the value holds a referenced-counted node
QV_Int
#define QV_Int
for integer values
Definition: QoreValue.h:44
qore_value_u
this is the union that stores values in QoreValue
Definition: QoreValue.h:56
QoreValue::assignNothing
DLLEXPORT AbstractQoreNode * assignNothing()
sets the value of the object to QoreNothingNode and returns any node value held previously ...
ValueHolder::release
DLLEXPORT QoreValue release()
returns a QoreValue object and leaves the current object empty; the caller owns any reference contain...
ValueHolder::ValueHolder
DLLLOCAL ValueHolder(ExceptionSink *xs)
creates an empty object
Definition: QoreValue.h:471
ValueOptionalRefHolder
allows storing a value and setting a boolean flag that indicates if the value should be dereference i...
Definition: QoreValue.h:501
ValueOptionalRefHolder::takeReferencedNode
DLLLOCAL T * takeReferencedNode()
returns the stored node value and leaves the current object empty
Definition: QoreValue.h:560
ValueEvalRefHolder
evaluates an AbstractQoreNode and dereferences the stored value in the destructor ...
Definition: QoreValue.h:605
QoreValue::getAsString
DLLEXPORT int getAsString(QoreString &str, int format_offset, ExceptionSink *xsink) const
appends the string value of the contained node to the string argument with optional formatting ...
AbstractQoreNode
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:57
QoreValue::getFullTypeName
DLLEXPORT const char * getFullTypeName() const
returns a string type description of the full type of the value contained (ex: "nothing" for a null A...
QoreValue::operator=
DLLEXPORT QoreValue & operator=(const QoreValue &n)
assigns a new value
ValueOptionalRefHolder::isTemp
DLLLOCAL bool isTemp() const
returns true if the value is temporary (needs dereferencing)
Definition: QoreValue.h:522
discard
static void discard(AbstractQoreNode *n, ExceptionSink *xsink)
to deref an AbstractQoreNode (when the pointer may be 0)
Definition: QoreLib.h:324
ValueOptionalRefHolder::ValueOptionalRefHolder
DLLLOCAL ValueOptionalRefHolder(QoreValue n_v, bool nd, ExceptionSink *xs)
creates the object with the given values
Definition: QoreValue.h:512
ValueOptionalRefHolder::takeNode
DLLLOCAL AbstractQoreNode * takeNode(bool &nd)
returns the stored AbstractQoreNode pointer and sets the dereference flag as an output variable ...
Definition: QoreValue.h:574
ValueOptionalRefHolder::needs_deref
bool needs_deref
flag indicating if the value should be dereferenced in the destructor or not
Definition: QoreValue.h:508
QoreValue::ref
DLLEXPORT void ref() const
references the contained value if type == QV_Node
QoreString
Qore&#39;s string type supported by the QoreEncoding class.
Definition: QoreString.h:81
ValueHolderBase::xsink
ExceptionSink * xsink
for possible Qore-language exceptions
Definition: QoreValue.h:443
detail::QoreValueCastHelper
used in QoreValue::get()
Definition: QoreValue.h:67
QV_Node
#define QV_Node
for heap-allocated values
Definition: QoreValue.h:46
detail
namespace for implementation details of QoreValue functions
Definition: QoreValue.h:64
QoreValue::derefCanThrowException
DLLEXPORT bool derefCanThrowException() const
returns true if a dereference could theoretically throw an exception (an object is reachable from thi...
QoreValue::getFullTypeInfo
DLLEXPORT const QoreTypeInfo * getFullTypeInfo() const
returns the exact type of the value; i.e. the class type for classes, hashdecl type for hashdecls ...
QoreValue::takeIfNode
DLLEXPORT AbstractQoreNode * takeIfNode()
returns a referenced value; leaving the "this" untouched; the caller owns the reference returned ...
QoreValue::sanitize
DLLEXPORT void sanitize()
converts any node pointers to efficient representations if possible and dereferences the node value c...
ValueOptionalRefHolder::getReferencedValue
DLLEXPORT QoreValue getReferencedValue()
returns a referenced value; caller owns the reference; the current object is not disturbed ...
ValueOptionalRefHolder::takeValue
DLLLOCAL QoreValue takeValue(bool &nd)
returns the stored value and sets the dereference flag as an output variable
Definition: QoreValue.h:584
QV_Bool
#define QV_Bool
for boolean values
Definition: QoreValue.h:43
ValueOptionalRefHolder::setValue
DLLLOCAL void setValue(QoreValue nv)
assigns a new non-temporary value
Definition: QoreValue.h:536
ValueHolderBase::v
QoreValue v
the value held
Definition: QoreValue.h:441
ValueOptionalRefHolder::takeValueFrom
DLLLOCAL void takeValueFrom(ValueOptionalRefHolder &val)
returns the stored value which must be dereferenced if it is a node object (i.e. type == QV_Node) ...
Definition: QoreValue.h:594
QoreValue::isEqualValue
DLLEXPORT bool isEqualValue(const QoreValue v)
returns true of the argument is exactly the same value as the current value, meaning also that if bot...
QoreValue
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:267
qore_value_u::n
AbstractQoreNode * n
for all heap-allocated values
Definition: QoreValue.h:60
ExceptionSink
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:48
QoreValue::assign
DLLEXPORT AbstractQoreNode * assign(const QoreValue n)
sets the value of the object and returns any node value held previously
QoreValue::getTypeInfo
DLLEXPORT const QoreTypeInfo * getTypeInfo() const
returns the type of the value
ValueOptionalRefHolder::takeReferencedValue
DLLEXPORT QoreValue takeReferencedValue()
returns a QoreValue after incrementing the reference count of any node value stored if necessary ...
ValueHolderBase::operator*
DLLLOCAL QoreValue & operator*()
returns the value being managed
Definition: QoreValue.h:461
int64
long long int64
64bit integer type, cannot use int64_t here since it breaks the API on some 64-bit systems due to equ...
Definition: common.h:260
ValueHolder::operator=
DLLLOCAL QoreValue & operator=(QoreValue nv)
assigns the object, any currently-held value is dereferenced before the assignment ...
Definition: QoreValue.h:488
qore_value_u::i
int64 i
for integer values
Definition: QoreValue.h:58
ValueHolderBase::ValueHolderBase
DLLLOCAL ValueHolderBase(ExceptionSink *xs)
creates an ampty object
Definition: QoreValue.h:447
QV_Float
#define QV_Float
for floating-point values
Definition: QoreValue.h:45
qore_type_t
int16_t qore_type_t
used to identify unique Qore data and parse types (descendents of AbstractQoreNode) ...
Definition: common.h:70
QoreValue::eval
DLLEXPORT QoreValue eval(ExceptionSink *xsink) const
evaluates the node and returns the result
ValueEvalRefHolder::ValueEvalRefHolder
DLLEXPORT ValueEvalRefHolder(const AbstractQoreNode *exp, ExceptionSink *xs)
evaluates the exp argument
qore_value_u::b
bool b
for boolean values
Definition: QoreValue.h:57
ValueHolderBase::operator->
DLLLOCAL QoreValue * operator->()
returns the value being managed
Definition: QoreValue.h:455
ValueEvalRefHolder::eval
DLLEXPORT int eval(const AbstractQoreNode *exp)
evaluates the argument, returns -1 for error, 0 = OK
QoreValue::isEqualHard
DLLEXPORT bool isEqualHard(const QoreValue v) const
returns trus if the argument value is equal to the current value without any type conversions ...
ValueHolder
holds an object and dereferences it in the destructor
Definition: QoreValue.h:468
QoreValue::hasNode
DLLEXPORT bool hasNode() const
returns true if the object contains a non-null AbstractQoreNode pointer (ie type == QV_Node && v...
ValueOptionalRefHolder::clearTemp
DLLLOCAL void clearTemp()
sets needs_deref = false
Definition: QoreValue.h:525
QoreValue::refSelf
DLLEXPORT QoreValue refSelf() const
references the contained value if type == QV_Node, returns itself
ValueOptionalRefHolder::ensureReferencedValue
DLLEXPORT void ensureReferencedValue()
QoreValue::discard
DLLEXPORT void discard(ExceptionSink *xsink)
dereferences any contained AbstractQoreNode pointer and sets to 0; does not modify other values ...