$darkmode
Qore Programming Language - C/C++ Library 1.19.2
QoreValue.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  QoreValue.h
4 
5  Qore Programming Language
6 
7  Copyright (C) 2003 - 2023 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
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;
61 };
62 
64 namespace detail {
66  template<typename Type>
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<>
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 
114 public:
118  valtype_t type;
119 
121  DLLLOCAL void set(int64 i) {
122  type = QV_Int;
123  v.i = i;
124  }
125 
127  DLLLOCAL void set(double f) {
128  type = QV_Float;
129  v.f = f;
130  }
131 
133  DLLLOCAL void set(bool b) {
134  type = QV_Bool;
135  v.b = b;
136  }
137 
139  DLLEXPORT void set(QoreSimpleValue val);
140 
142  DLLEXPORT void set(AbstractQoreNode* n);
143 
146  set(val);
147  return *this;
148  }
149 
151  DLLLOCAL QoreSimpleValue& assign(int64 i) {
152  set(i);
153  return *this;
154  }
155 
157  DLLLOCAL QoreSimpleValue& assign(double f) {
158  set(f);
159  return *this;
160  }
161 
163  DLLLOCAL QoreSimpleValue& assign(bool b) {
164  set(b);
165  return *this;
166  }
167 
170  set(n);
171  return *this;
172  }
173 
175  DLLEXPORT qore_type_t getType() const;
176 
178  DLLEXPORT const char* getTypeName() const;
179 
181 
184 
187 
189  DLLEXPORT const AbstractQoreNode* getInternalNode() const;
190 
192  DLLEXPORT void clear();
193 
195  DLLEXPORT void discard(ExceptionSink* xsink);
196 
198 
200  template<typename T>
201  DLLLOCAL T* take() {
202  assert(type == QV_Node);
203  assert(dynamic_cast<T*>(v.n));
204  T* rv = reinterpret_cast<T*>(v.n);
205  v.n = 0;
206  return rv;
207  }
208 
210 
213  template<typename T>
214  DLLLOCAL typename detail::QoreValueCastHelper<T>::Result get() {
216  }
217 
219 
222  template<typename T>
223  DLLLOCAL typename detail::QoreValueCastHelper<const T>::Result get() const {
225  }
226 
228  DLLEXPORT bool getAsBool() const;
229 
231  DLLEXPORT int64 getAsBigInt() const;
232 
234  DLLEXPORT double getAsFloat() const;
235 
237  DLLEXPORT bool hasEffect() const;
238 
240  DLLEXPORT bool isNothing() const;
241 
243  DLLEXPORT bool isNull() const;
244 
246  DLLEXPORT bool isNullOrNothing() const;
247 
249  DLLEXPORT bool isValue() const;
250 
252  DLLEXPORT bool needsEval() const;
253 
255 
257  DLLEXPORT bool isScalar() const;
258 
260 
265  DLLEXPORT bool isConstant() const;
266 
268  DLLEXPORT operator bool() const;
269 
270 protected:
273 };
274 
276 struct QoreValue : public QoreSimpleValue {
277  friend class ValueHolder;
278  friend class ValueOptionalRefHolder;
279  template<typename> friend struct detail::QoreValueCastHelper;
280 
281 public:
283  DLLEXPORT QoreValue();
284 
286  DLLEXPORT QoreValue(bool b);
287 
289  DLLEXPORT QoreValue(int i);
290 
292  DLLEXPORT QoreValue(unsigned int i);
293 
295  DLLEXPORT QoreValue(long i);
296 
298  DLLEXPORT QoreValue(unsigned long i);
299 
301  DLLEXPORT QoreValue(unsigned long long i);
302 
304  DLLEXPORT QoreValue(int64 i);
305 
307  DLLEXPORT QoreValue(double f);
308 
311 
313 
319  DLLEXPORT QoreValue(const AbstractQoreNode* n);
320 
322  DLLEXPORT QoreValue(const QoreSimpleValue& v);
323 
325  DLLEXPORT QoreValue(const QoreValue& old);
326 
328  DLLEXPORT void swap(QoreValue& val);
329 
331  DLLEXPORT void ref() const;
332 
334  DLLEXPORT QoreValue refSelf() const;
335 
337 
340  DLLEXPORT AbstractQoreNode* assign(const QoreValue n);
341 
343 
347 
349 
353 
355 
358  DLLEXPORT AbstractQoreNode* assign(double n);
359 
361 
364  DLLEXPORT AbstractQoreNode* assign(bool n);
365 
367 
372 
374  DLLEXPORT bool isEqualSoft(const QoreValue v, ExceptionSink* xsink) const;
375 
377  DLLEXPORT bool isEqualHard(const QoreValue v) const;
378 
380  DLLEXPORT bool isEqualValue(const QoreValue v);
381 
383  DLLEXPORT void sanitize();
384 
386  DLLEXPORT QoreValue& operator=(const QoreValue& n);
387 
389  DLLEXPORT QoreValue& operator=(const QoreSimpleValue& n);
390 
392  DLLEXPORT void discard(ExceptionSink* xsink);
393 
395  DLLEXPORT int getAsString(QoreString& str, int format_offset, ExceptionSink *xsink) const;
396 
398  DLLEXPORT QoreString* getAsString(bool& del, int foff, ExceptionSink* xsink) const;
399 
401  DLLEXPORT QoreValue eval(ExceptionSink* xsink) const;
402 
404  DLLEXPORT QoreValue eval(bool& needs_deref, ExceptionSink* xsink) const;
405 
407  //DLLEXPORT QoreValue refSelf() const;
408 
411 
413 
415  DLLEXPORT const QoreTypeInfo* getTypeInfo() const;
416 
418 
420  DLLEXPORT const QoreTypeInfo* getFullTypeInfo() const;
421 
423 
425  DLLEXPORT const char* getFullTypeName() const;
426 
428 
434  DLLEXPORT const char* getFullTypeName(bool with_namespaces) const;
435 
437 
444  DLLEXPORT const char* getFullTypeName(bool with_namespaces, QoreString& scratch) const;
445 
447  DLLEXPORT bool hasNode() const;
448 
450  DLLEXPORT bool isReferenceCounted() const;
451 
453  DLLEXPORT bool derefCanThrowException() const;
454 };
455 
458 protected:
463 
464 public:
466  DLLLOCAL ValueHolderBase(ExceptionSink* xs) : xsink(xs) {
467  }
468 
470  DLLLOCAL ValueHolderBase(QoreValue n_v, ExceptionSink* xs) : v(n_v), xsink(xs) {
471  }
472 
474  DLLLOCAL QoreValue* operator->() { return &v; }
475 
477  DLLLOCAL const QoreValue* operator->() const { return &v; }
478 
480  DLLLOCAL QoreValue& operator*() { return v; }
481 
483  DLLLOCAL const QoreValue& operator*() const { return v; }
484 };
485 
487 class ValueHolder : public ValueHolderBase {
488 public:
491  }
492 
494  DLLLOCAL ValueHolder(QoreValue n_v, ExceptionSink* xs) : ValueHolderBase(n_v, xs) {
495  }
496 
498  DLLEXPORT ~ValueHolder();
499 
502 
504  DLLEXPORT QoreValue release();
505 
507  DLLLOCAL QoreValue& operator=(QoreValue nv) {
508  v.discard(xsink);
509  v = nv;
510  return v;
511  }
512 
514  DLLLOCAL operator bool() const {
515  return (bool)v;
516  }
517 };
518 
521 private:
522  // not implemented
523  DLLLOCAL QoreValue& operator=(QoreValue& nv);
524 
525 protected:
528 
529 public:
531  DLLLOCAL ValueOptionalRefHolder(QoreValue n_v, bool nd, ExceptionSink* xs) : ValueHolderBase(n_v, xs), needs_deref(nd) {
532  }
533 
536  }
537 
538  DLLEXPORT ~ValueOptionalRefHolder();
539 
541  DLLLOCAL bool isTemp() const { return needs_deref; }
542 
544  DLLLOCAL void clearTemp() {
545  if (needs_deref)
546  needs_deref = false;
547  }
548 
550  DLLLOCAL operator bool() const {
551  return (bool)v;
552  }
553 
555  DLLLOCAL void setValue(QoreValue nv) {
556  if (needs_deref) {
557  v.discard(xsink);
558  needs_deref = false;
559  }
560  v = nv;
561  }
562 
564  DLLLOCAL void setValue(QoreValue nv, bool temp) {
565  if (needs_deref)
566  v.discard(xsink);
567  if (needs_deref != temp)
568  needs_deref = temp;
569  v = nv;
570  }
571 
572  // ensures that the held value is referenced
575  DLLEXPORT void ensureReferencedValue();
576 
578  template<typename T>
579  DLLLOCAL T* takeReferencedNode() {
580  T* rv = v.take<T>();
581  if (needs_deref)
582  needs_deref = false;
583  else
584  rv->ref();
585 
586  return rv;
587  }
588 
591 
593  DLLLOCAL AbstractQoreNode* takeNode(bool& nd) {
594  if (v.type == QV_Node) {
595  nd = needs_deref;
596  return v.takeNodeIntern();
597  }
598  nd = true;
599  return v.takeNode();
600  }
601 
603  DLLLOCAL QoreValue takeValue(bool& nd) {
604  if (v.type == QV_Node) {
605  nd = needs_deref;
606  return v.takeNodeIntern();
607  }
608  nd = false;
609  return v;
610  }
611 
613  DLLLOCAL void takeValueFrom(ValueOptionalRefHolder& val) {
614  if (needs_deref)
615  v.discard(xsink);
616  v = val.takeValue(needs_deref);
617  }
618 
621 };
622 
625 public:
628 
630 
632  DLLEXPORT ValueEvalRefHolder(const QoreValue exp, ExceptionSink* xs);
633 
635 
638 
640 
642  DLLEXPORT int eval(const AbstractQoreNode* exp);
643 
645 
647  DLLEXPORT int eval(const QoreValue exp);
648 
649 protected:
651 
653  DLLLOCAL int evalIntern(const AbstractQoreNode* exp);
654 
656 
658  DLLLOCAL int evalIntern(const QoreValue exp);
659 };
660 
662 DLLEXPORT extern const char* qoreBoolTypeName;
664 DLLEXPORT extern const char* qoreIntTypeName;
666 DLLEXPORT extern const char* qoreFloatTypeName;
667 
668 #endif
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:57
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:50
Base value class; parent of QoreValue; designed to be passed by value.
Definition: QoreValue.h:113
valtype_t type
indicates the value that the union is holding
Definition: QoreValue.h:118
qore_value_u v
the actual value is stored here
Definition: QoreValue.h:116
DLLEXPORT double getAsFloat() const
returns the value as a float
DLLEXPORT bool isValue() const
returns true if the object holds a value, false if it holds an expression
DLLEXPORT AbstractQoreNode * getInternalNode()
returns any AbstractQoreNode value held; if type != QV_Node, returns nullptr
DLLEXPORT bool isNull() const
returns true if the object contains NULL
DLLEXPORT qore_type_t getType() const
returns the type of value contained
DLLEXPORT const char * getTypeName() const
returns a string type description of the value contained (ex: "nothing" for a null AbstractQoreNode p...
DLLEXPORT AbstractQoreNode * takeNode()
returns a referenced AbstractQoreNode pointer leaving "this" empty (value is taken from "this"); the ...
DLLLOCAL detail::QoreValueCastHelper< T >::Result get()
returns the value as the given type
Definition: QoreValue.h:214
DLLLOCAL QoreSimpleValue & assign(QoreSimpleValue &val)
assigns a new value to the object and returns a reference to the object; any current value is overwri...
Definition: QoreValue.h:145
DLLLOCAL T * take()
returns a pointer to an object of the given class; takes the pointer from the object; the caller owns...
Definition: QoreValue.h:201
DLLEXPORT bool isNullOrNothing() const
returns true if the object contains NOTHING or NULL
DLLLOCAL void set(int64 i)
assigns an integer value to the object; any current value is overwritten
Definition: QoreValue.h:121
DLLEXPORT bool isScalar() const
returns true if the value is a scalar (int, bool, float, number, string)
DLLEXPORT bool isConstant() const
returns true if the value is a constant value (does not require evaluation)
DLLEXPORT bool getAsBool() const
returns the value as a bool
DLLEXPORT void discard(ExceptionSink *xsink)
dereferences any contained AbstractQoreNode pointer and sets to 0; does not modify other values
DLLEXPORT bool hasEffect() const
return true if the value needs evaluation and has a side effect
DLLEXPORT bool needsEval() const
return true if the value needs evaluation
DLLEXPORT int64 getAsBigInt() const
returns the value as an int
DLLEXPORT void clear()
unconditionally set the QoreValue to QoreNothingNode (does not dereference any possible contained Abs...
DLLEXPORT AbstractQoreNode * takeNodeIntern()
returns the internal AbstractQoreNode pointer, does not check that type == QV_Node,...
DLLEXPORT bool isNothing() const
returns true if the object contains NOTHING
Qore's string type supported by the QoreEncoding class.
Definition: QoreString.h:93
evaluates an AbstractQoreNode and dereferences the stored value in the destructor
Definition: QoreValue.h:624
DLLEXPORT ValueEvalRefHolder(const AbstractQoreNode *exp, ExceptionSink *xs)
evaluates the exp argument
DLLEXPORT int eval(const AbstractQoreNode *exp)
evaluates the argument, returns -1 for error, 0 = OK
DLLLOCAL int evalIntern(const AbstractQoreNode *exp)
evaluates the argument, returns -1 for error, 0 = OK
base class for holding a QoreValue object
Definition: QoreValue.h:457
DLLLOCAL QoreValue * operator->()
returns the value being managed
Definition: QoreValue.h:474
ExceptionSink * xsink
for possible Qore-language exceptions
Definition: QoreValue.h:462
DLLLOCAL QoreValue & operator*()
returns the value being managed
Definition: QoreValue.h:480
DLLLOCAL ValueHolderBase(ExceptionSink *xs)
creates an ampty object
Definition: QoreValue.h:466
QoreValue v
the value held
Definition: QoreValue.h:460
holds an object and dereferences it in the destructor
Definition: QoreValue.h:487
DLLEXPORT ~ValueHolder()
dereferences any contained node
DLLEXPORT QoreValue release()
returns a QoreValue object and leaves the current object empty; the caller owns any reference contain...
DLLLOCAL ValueHolder(ExceptionSink *xs)
creates an empty object
Definition: QoreValue.h:490
DLLEXPORT QoreValue getReferencedValue()
returns a referenced value; caller owns the reference; the current object is left undisturbed
DLLLOCAL QoreValue & operator=(QoreValue nv)
assigns the object, any currently-held value is dereferenced before the assignment
Definition: QoreValue.h:507
allows storing a value and setting a boolean flag that indicates if the value should be dereference i...
Definition: QoreValue.h:520
DLLLOCAL bool isTemp() const
returns true if the value is temporary (needs dereferencing)
Definition: QoreValue.h:541
DLLLOCAL ValueOptionalRefHolder(QoreValue n_v, bool nd, ExceptionSink *xs)
creates the object with the given values
Definition: QoreValue.h:531
DLLLOCAL AbstractQoreNode * takeNode(bool &nd)
returns the stored AbstractQoreNode pointer and sets the dereference flag as an output variable
Definition: QoreValue.h:593
DLLLOCAL QoreValue takeValue(bool &nd)
returns the stored value and sets the dereference flag as an output variable
Definition: QoreValue.h:603
DLLLOCAL void setValue(QoreValue nv)
assigns a new non-temporary value
Definition: QoreValue.h:555
DLLEXPORT void ensureReferencedValue()
DLLEXPORT QoreValue takeReferencedValue()
returns a QoreValue after incrementing the reference count of any node value stored if necessary
DLLLOCAL void clearTemp()
sets needs_deref = false
Definition: QoreValue.h:544
DLLEXPORT QoreValue getReferencedValue()
returns a referenced value; caller owns the reference; the current object is not disturbed
bool needs_deref
flag indicating if the value should be dereferenced in the destructor or not
Definition: QoreValue.h:527
DLLLOCAL T * takeReferencedNode()
returns the stored node value and leaves the current object empty
Definition: QoreValue.h:579
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:613
int16_t qore_type_t
used to identify unique Qore data and parse types (descendents of AbstractQoreNode)
Definition: common.h:70
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
#define QV_Node
for heap-allocated values
Definition: QoreValue.h:46
#define QV_Bool
for boolean values
Definition: QoreValue.h:43
#define QV_Float
for floating-point values
Definition: QoreValue.h:45
#define QV_Int
for integer values
Definition: QoreValue.h:44
namespace for implementation details of QoreValue functions
Definition: QoreValue.h:64
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:276
DLLEXPORT AbstractQoreNode * takeIfNode()
returns a referenced value; leaving the "this" untouched; the caller owns the reference returned
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
DLLEXPORT const char * getFullTypeName() const
returns a string type description of the full type of the value contained (ex: "nothing" for a null A...
DLLEXPORT void discard(ExceptionSink *xsink)
dereferences any contained AbstractQoreNode pointer and sets to 0; does not modify other values
DLLEXPORT QoreValue & operator=(const QoreValue &n)
assigns a new value
DLLEXPORT const QoreTypeInfo * getTypeInfo() const
returns the type of the value
DLLEXPORT bool isReferenceCounted() const
returns true if the value holds a referenced-counted node
DLLEXPORT const QoreTypeInfo * getFullTypeInfo() const
returns the exact type of the value; i.e. the class type for classes, hashdecl type for hashdecls
DLLEXPORT void swap(QoreValue &val)
exchanges the values
DLLEXPORT bool hasNode() const
returns true if the object contains a non-null AbstractQoreNode pointer (ie type == QV_Node && v....
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...
DLLEXPORT AbstractQoreNode * assign(const QoreValue n)
sets the value of the object and returns any node value held previously
DLLEXPORT QoreValue eval(ExceptionSink *xsink) const
evaluates the node and returns the result
DLLEXPORT bool derefCanThrowException() const
returns true if a dereference could theoretically throw an exception (an object is reachable from thi...
DLLEXPORT QoreValue()
creates with no value (i.e. QoreNothingNode)
DLLEXPORT AbstractQoreNode * assignNothing()
sets the value of the object to QoreNothingNode and returns any node value held previously
DLLEXPORT bool isEqualHard(const QoreValue v) const
returns trus if the argument value is equal to the current value without any type conversions
DLLEXPORT void ref() const
references the contained value if type == QV_Node
DLLEXPORT QoreValue refSelf() const
references the contained value if type == QV_Node, returns itself
DLLEXPORT bool isEqualSoft(const QoreValue v, ExceptionSink *xsink) const
returns trus if the argument value is equal to the current value with type conversions
DLLEXPORT void sanitize()
converts any node pointers to efficient representations if possible and dereferences the node value c...
used in QoreValue::get()
Definition: QoreValue.h:67
this is the union that stores values in QoreValue
Definition: QoreValue.h:56
bool b
for boolean values
Definition: QoreValue.h:57
AbstractQoreNode * n
for all heap-allocated values
Definition: QoreValue.h:60
double f
for double values
Definition: QoreValue.h:59
int64 i
for integer values
Definition: QoreValue.h:58