Qore Programming Language  1.12.2
QoreValue.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  QoreValue.h
4 
5  Qore Programming Language
6 
7  Copyright (C) 2003 - 2022 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 hashdecl 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  hashdecl 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  hashdecl 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 
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 {
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 
264  DLLEXPORT bool isConstant() const;
265 
267  DLLEXPORT operator bool() const;
268 
269 protected:
271  DLLEXPORT AbstractQoreNode* takeNodeIntern();
272 };
273 
275 hashdecl QoreValue : public QoreSimpleValue {
276  friend class ValueHolder;
277  friend class ValueOptionalRefHolder;
278  template<typename> friend hashdecl detail::QoreValueCastHelper;
279 
280 public:
282  DLLEXPORT QoreValue();
283 
285  DLLEXPORT QoreValue(bool b);
286 
288  DLLEXPORT QoreValue(int i);
289 
291  DLLEXPORT QoreValue(unsigned int i);
292 
294  DLLEXPORT QoreValue(long i);
295 
297  DLLEXPORT QoreValue(unsigned long i);
298 
300  DLLEXPORT QoreValue(unsigned long long i);
301 
303  DLLEXPORT QoreValue(int64 i);
304 
306  DLLEXPORT QoreValue(double f);
307 
310 
312 
318  DLLEXPORT QoreValue(const AbstractQoreNode* n);
319 
321  DLLEXPORT QoreValue(const QoreSimpleValue& v);
322 
324  DLLEXPORT QoreValue(const QoreValue& old);
325 
327  DLLEXPORT void swap(QoreValue& val);
328 
330  DLLEXPORT void ref() const;
331 
333  DLLEXPORT QoreValue refSelf() const;
334 
336 
339  DLLEXPORT AbstractQoreNode* assign(const QoreValue n);
340 
342 
346 
348 
352 
354 
357  DLLEXPORT AbstractQoreNode* assign(double n);
358 
360 
363  DLLEXPORT AbstractQoreNode* assign(bool n);
364 
366 
371 
373  DLLEXPORT bool isEqualSoft(const QoreValue v, ExceptionSink* xsink) const;
374 
376  DLLEXPORT bool isEqualHard(const QoreValue v) const;
377 
379  DLLEXPORT bool isEqualValue(const QoreValue v);
380 
382  DLLEXPORT void sanitize();
383 
385  DLLEXPORT QoreValue& operator=(const QoreValue& n);
386 
388  DLLEXPORT QoreValue& operator=(const QoreSimpleValue& n);
389 
391  DLLEXPORT void discard(ExceptionSink* xsink);
392 
394  DLLEXPORT int getAsString(QoreString& str, int format_offset, ExceptionSink *xsink) const;
395 
397  DLLEXPORT QoreString* getAsString(bool& del, int foff, ExceptionSink* xsink) const;
398 
400  DLLEXPORT QoreValue eval(ExceptionSink* xsink) const;
401 
403  DLLEXPORT QoreValue eval(bool& needs_deref, ExceptionSink* xsink) const;
404 
406  //DLLEXPORT QoreValue refSelf() const;
407 
410 
412 
414  DLLEXPORT const QoreTypeInfo* getTypeInfo() const;
415 
417 
419  DLLEXPORT const QoreTypeInfo* getFullTypeInfo() const;
420 
422 
424  DLLEXPORT const char* getFullTypeName() const;
425 
427 
433  DLLEXPORT const char* getFullTypeName(bool with_namespaces) const;
434 
436  DLLEXPORT bool hasNode() const;
437 
439  DLLEXPORT bool isReferenceCounted() const;
440 
442  DLLEXPORT bool derefCanThrowException() const;
443 };
444 
447 protected:
452 
453 public:
455  DLLLOCAL ValueHolderBase(ExceptionSink* xs) : xsink(xs) {
456  }
457 
459  DLLLOCAL ValueHolderBase(QoreValue n_v, ExceptionSink* xs) : v(n_v), xsink(xs) {
460  }
461 
463  DLLLOCAL QoreValue* operator->() { return &v; }
464 
466  DLLLOCAL const QoreValue* operator->() const { return &v; }
467 
469  DLLLOCAL QoreValue& operator*() { return v; }
470 
472  DLLLOCAL const QoreValue& operator*() const { return v; }
473 };
474 
476 class ValueHolder : public ValueHolderBase {
477 public:
480  }
481 
483  DLLLOCAL ValueHolder(QoreValue n_v, ExceptionSink* xs) : ValueHolderBase(n_v, xs) {
484  }
485 
487  DLLEXPORT ~ValueHolder();
488 
491 
493  DLLEXPORT QoreValue release();
494 
496  DLLLOCAL QoreValue& operator=(QoreValue nv) {
497  v.discard(xsink);
498  v = nv;
499  return v;
500  }
501 
503  DLLLOCAL operator bool() const {
504  return (bool)v;
505  }
506 };
507 
510 private:
511  // not implemented
512  DLLLOCAL QoreValue& operator=(QoreValue& nv);
513 
514 protected:
517 
518 public:
520  DLLLOCAL ValueOptionalRefHolder(QoreValue n_v, bool nd, ExceptionSink* xs) : ValueHolderBase(n_v, xs), needs_deref(nd) {
521  }
522 
525  }
526 
527  DLLEXPORT ~ValueOptionalRefHolder();
528 
530  DLLLOCAL bool isTemp() const { return needs_deref; }
531 
533  DLLLOCAL void clearTemp() {
534  if (needs_deref)
535  needs_deref = false;
536  }
537 
539  DLLLOCAL operator bool() const {
540  return (bool)v;
541  }
542 
544  DLLLOCAL void setValue(QoreValue nv) {
545  if (needs_deref) {
546  v.discard(xsink);
547  needs_deref = false;
548  }
549  v = nv;
550  }
551 
553  DLLLOCAL void setValue(QoreValue nv, bool temp) {
554  if (needs_deref)
555  v.discard(xsink);
556  if (needs_deref != temp)
557  needs_deref = temp;
558  v = nv;
559  }
560 
561  // ensures that the held value is referenced
564  DLLEXPORT void ensureReferencedValue();
565 
567  template<typename T>
568  DLLLOCAL T* takeReferencedNode() {
569  T* rv = v.take<T>();
570  if (needs_deref)
571  needs_deref = false;
572  else
573  rv->ref();
574 
575  return rv;
576  }
577 
580 
582  DLLLOCAL AbstractQoreNode* takeNode(bool& nd) {
583  if (v.type == QV_Node) {
584  nd = needs_deref;
585  return v.takeNodeIntern();
586  }
587  nd = true;
588  return v.takeNode();
589  }
590 
592  DLLLOCAL QoreValue takeValue(bool& nd) {
593  if (v.type == QV_Node) {
594  nd = needs_deref;
595  return v.takeNodeIntern();
596  }
597  nd = false;
598  return v;
599  }
600 
602  DLLLOCAL void takeValueFrom(ValueOptionalRefHolder& val) {
603  if (needs_deref)
604  v.discard(xsink);
605  v = val.takeValue(needs_deref);
606  }
607 
610 };
611 
614 public:
617 
619 
621  DLLEXPORT ValueEvalRefHolder(const QoreValue exp, ExceptionSink* xs);
622 
624 
627 
629 
631  DLLEXPORT int eval(const AbstractQoreNode* exp);
632 
634 
636  DLLEXPORT int eval(const QoreValue exp);
637 
638 protected:
640 
642  DLLLOCAL int evalIntern(const AbstractQoreNode* exp);
643 
645 
647  DLLLOCAL int evalIntern(const QoreValue exp);
648 };
649 
651 DLLEXPORT extern const char* qoreBoolTypeName;
653 DLLEXPORT extern const char* qoreIntTypeName;
655 DLLEXPORT extern const char* qoreFloatTypeName;
656 
657 #endif
static void discard(AbstractQoreNode *n, ExceptionSink *xsink)
to deref an AbstractQoreNode (when the pointer may be 0)
Definition: QoreLib.h:324
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:48
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:613
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:446
DLLLOCAL QoreValue * operator->()
returns the value being managed
Definition: QoreValue.h:463
ExceptionSink * xsink
for possible Qore-language exceptions
Definition: QoreValue.h:451
DLLLOCAL QoreValue & operator*()
returns the value being managed
Definition: QoreValue.h:469
DLLLOCAL ValueHolderBase(ExceptionSink *xs)
creates an ampty object
Definition: QoreValue.h:455
QoreValue v
the value held
Definition: QoreValue.h:449
holds an object and dereferences it in the destructor
Definition: QoreValue.h:476
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:479
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:496
allows storing a value and setting a boolean flag that indicates if the value should be dereference i...
Definition: QoreValue.h:509
DLLLOCAL bool isTemp() const
returns true if the value is temporary (needs dereferencing)
Definition: QoreValue.h:530
DLLLOCAL ValueOptionalRefHolder(QoreValue n_v, bool nd, ExceptionSink *xs)
creates the object with the given values
Definition: QoreValue.h:520
DLLLOCAL AbstractQoreNode * takeNode(bool &nd)
returns the stored AbstractQoreNode pointer and sets the dereference flag as an output variable
Definition: QoreValue.h:582
DLLLOCAL QoreValue takeValue(bool &nd)
returns the stored value and sets the dereference flag as an output variable
Definition: QoreValue.h:592
DLLLOCAL void setValue(QoreValue nv)
assigns a new non-temporary value
Definition: QoreValue.h:544
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:533
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:516
DLLLOCAL T * takeReferencedNode()
returns the stored node value and leaves the current object empty
Definition: QoreValue.h:568
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:602
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
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:275
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