Qore Programming Language - C/C++ Library  0.8.13.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
QoreValue.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  QoreValue.h
4 
5  Qore Programming Language
6 
7  Copyright (C) 2003 - 2017 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 <assert.h>
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 reference
51 class AbstractQoreNode;
52 class QoreString;
53 
55 union qore_value_u {
56  bool b;
57  int64 i;
58  double f;
60 };
61 
63 namespace detail {
65  template<typename Type>
67  typedef Type * Result;
68 
69  template<typename QV>
70  static Result cast(QV *qv, valtype_t type) {
71  assert(type == QV_Node);
72  assert(!qv->v.n || dynamic_cast<Result>(qv->v.n));
73  return reinterpret_cast<Result>(qv->v.n);
74  }
75  };
76 
78  template<>
79  struct QoreValueCastHelper<bool> {
80  typedef bool Result;
81 
82  template<typename QV>
83  static bool cast(QV *qv, valtype_t type) {
84  return qv->getAsBool();
85  }
86  };
87 
89  template<>
90  struct QoreValueCastHelper<double> {
91  typedef double Result;
92 
93  template<typename QV>
94  static double cast(QV *qv, valtype_t type) {
95  return qv->getAsFloat();
96  }
97  };
98 
100  template<>
102  typedef int64 Result;
103 
104  template<typename QV>
105  static int64 cast(QV *qv, valtype_t type) {
106  return qv->getAsBigInt();
107  }
108  };
109 } // namespace detail
110 
112 struct QoreValue {
113  friend class ValueHolder;
114  friend class ValueOptionalRefHolder;
115  template<typename> friend struct detail::QoreValueCastHelper;
116 
117 protected:
119  DLLEXPORT AbstractQoreNode* takeNodeIntern();
120 
121 public:
125  valtype_t type;
126 
128  DLLEXPORT QoreValue();
129 
131  DLLEXPORT QoreValue(bool b);
132 
134  DLLEXPORT QoreValue(int i);
135 
137  DLLEXPORT QoreValue(unsigned int i);
138 
140  DLLEXPORT QoreValue(long i);
141 
143  DLLEXPORT QoreValue(unsigned long i);
144 
146  DLLEXPORT QoreValue(unsigned long long i);
147 
149  DLLEXPORT QoreValue(int64 i);
150 
152  DLLEXPORT QoreValue(double f);
153 
155  DLLEXPORT QoreValue(AbstractQoreNode* n);
156 
158 
164  DLLEXPORT QoreValue(const AbstractQoreNode* n);
165 
167  DLLEXPORT QoreValue(const QoreValue& old);
168 
170  DLLEXPORT void swap(QoreValue& val);
171 
173  DLLEXPORT bool getAsBool() const;
174 
176  DLLEXPORT int64 getAsBigInt() const;
177 
179  DLLEXPORT double getAsFloat() const;
180 
182  DLLEXPORT void ref() const;
183 
185  DLLEXPORT QoreValue refSelf() const;
186 
188  DLLEXPORT AbstractQoreNode* getInternalNode();
189 
191  DLLEXPORT const AbstractQoreNode* getInternalNode() const;
192 
194 
198 
200 
203  DLLEXPORT AbstractQoreNode* assignAndSanitize(const QoreValue n);
204 
206 
209  DLLEXPORT AbstractQoreNode* assign(int64 n);
210 
212 
215  DLLEXPORT AbstractQoreNode* assign(double n);
216 
218 
221  DLLEXPORT AbstractQoreNode* assign(bool n);
222 
224 
228  DLLEXPORT AbstractQoreNode* assignNothing();
229 
231  DLLEXPORT bool isEqualSoft(const QoreValue v, ExceptionSink* xsink) const;
232 
234  DLLEXPORT bool isEqualHard(const QoreValue v) const;
235 
237  DLLEXPORT void sanitize();
238 
240  DLLEXPORT QoreValue& operator=(const QoreValue& n);
241 
243  DLLEXPORT void discard(ExceptionSink* xsink);
244 
246  DLLEXPORT void clear();
247 
249  DLLEXPORT int getAsString(QoreString& str, int format_offset, ExceptionSink *xsink) const;
250 
252  DLLEXPORT QoreString* getAsString(bool& del, int foff, ExceptionSink* xsink) const;
253 
255 
257  template<typename T>
258  DLLLOCAL T* take() {
259  assert(type == QV_Node);
260  assert(dynamic_cast<T*>(v.n));
261  T* rv = reinterpret_cast<T*>(v.n);
262  v.n = 0;
263  return rv;
264  }
265 
267 
269  template<typename T>
270  DLLLOCAL typename detail::QoreValueCastHelper<T>::Result get() {
272  }
273 
275 
277  template<typename T>
278  DLLLOCAL typename detail::QoreValueCastHelper<const T>::Result get() const {
280  }
281 
283  DLLEXPORT AbstractQoreNode* getReferencedValue() const;
284 
286  DLLEXPORT AbstractQoreNode* takeNode();
287 
289  DLLEXPORT AbstractQoreNode* takeIfNode();
290 
292 
294  DLLEXPORT const QoreTypeInfo* getTypeInfo() const;
295 
297  DLLEXPORT qore_type_t getType() const;
298 
300  DLLEXPORT const char* getTypeName() const;
301 
303  DLLEXPORT const char* getFullTypeName() const;
304 
306  DLLEXPORT bool hasNode() const;
307 
309  DLLEXPORT bool isNothing() const;
310 
312  DLLEXPORT bool isNull() const;
313 
315  DLLEXPORT bool isNullOrNothing() const;
316 };
317 
320 protected:
325 
326 public:
328  DLLLOCAL ValueHolderBase(ExceptionSink* xs) : xsink(xs) {
329  }
330 
332  DLLLOCAL ValueHolderBase(QoreValue n_v, ExceptionSink* xs) : v(n_v), xsink(xs) {
333  }
334 
336  DLLLOCAL QoreValue* operator->() { return &v; }
337 
339  DLLLOCAL QoreValue& operator*() { return v; }
340 };
341 
343 class ValueHolder : public ValueHolderBase {
344 public:
347  }
348 
350  DLLLOCAL ValueHolder(QoreValue n_v, ExceptionSink* xs) : ValueHolderBase(n_v, xs) {
351  }
352 
354  DLLEXPORT ~ValueHolder();
355 
358 
360  DLLEXPORT QoreValue release();
361 
363  DLLLOCAL QoreValue& operator=(QoreValue nv) {
364  v.discard(xsink);
365  v = nv;
366  return v;
367  }
368 
370  DLLLOCAL operator bool() const {
371  return v.type == QV_Node && v.v.n;
372  }
373 };
374 
377 private:
378  // not implemented
379  DLLLOCAL QoreValue& operator=(QoreValue& nv);
380 
381 protected:
384 
385 public:
387  DLLLOCAL ValueOptionalRefHolder(QoreValue n_v, bool nd, ExceptionSink* xs) : ValueHolderBase(n_v, xs), needs_deref(nd) {
388  }
389 
392  }
393 
394  DLLEXPORT ~ValueOptionalRefHolder();
395 
397  DLLLOCAL bool isTemp() const { return needs_deref; }
398 
400  DLLLOCAL void clearTemp() {
401  if (needs_deref)
402  needs_deref = false;
403  }
404 
406  DLLLOCAL operator bool() const {
407  return v.type == QV_Node && v.v.n;
408  }
409 
411  DLLLOCAL void setValue(QoreValue nv) {
412  if (needs_deref) {
413  v.discard(xsink);
414  needs_deref = false;
415  }
416  v = nv;
417  }
418 
420  DLLLOCAL void setValue(QoreValue nv, bool temp) {
421  if (needs_deref)
422  v.discard(xsink);
423  if (needs_deref != temp)
424  needs_deref = temp;
425  v = nv;
426  }
427 
428  // ensures that the held value is referenced
431  DLLEXPORT void ensureReferencedValue();
432 
434  template<typename T>
435  DLLLOCAL T* takeReferencedNode() {
436  T* rv = v.take<T>();
437  if (needs_deref)
438  needs_deref = false;
439  else
440  rv->ref();
441 
442  return rv;
443  }
444 
447 
449  DLLLOCAL AbstractQoreNode* takeNode(bool& nd) {
450  if (v.type == QV_Node) {
451  nd = needs_deref;
452  return v.takeNodeIntern();
453  }
454  nd = true;
455  return v.takeNode();
456  }
457 
459  DLLLOCAL QoreValue takeValue(bool& nd) {
460  if (v.type == QV_Node) {
461  nd = needs_deref;
462  return v.takeNodeIntern();
463  }
464  nd = false;
465  return v;
466  }
467 
469  DLLLOCAL void takeValueFrom(ValueOptionalRefHolder& val) {
470  if (needs_deref)
471  v.discard(xsink);
472  v = val.takeValue(needs_deref);
473  }
474 
476  DLLEXPORT QoreValue takeReferencedValue();
477 
478  // FIXME: remove with new API/ABI
480  DLLEXPORT void sanitize();
481 };
482 
485 public:
487  DLLEXPORT ValueEvalRefHolder(const AbstractQoreNode* exp, ExceptionSink* xs);
488 
490 
492  DLLEXPORT ValueEvalRefHolder(ExceptionSink* xs);
493 
495 
497  DLLEXPORT int eval(const AbstractQoreNode* exp);
498 
499 protected:
501 
503  DLLLOCAL void evalIntern(const AbstractQoreNode* exp);
504 };
505 
506 #endif
DLLEXPORT AbstractQoreNode * takeNodeIntern()
returns the internal AbstractQoreNode pointer, does not check that type == QV_Node, leaves the object empty
DLLEXPORT QoreValue()
creates with no value (i.e. QoreNothingNode)
DLLEXPORT void swap(QoreValue &val)
exchanges the values
DLLEXPORT ~ValueHolder()
dereferences any contained node
double f
for double values
Definition: QoreValue.h:58
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:258
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 AbstractQoreNode * takeNode()
returns a referenced AbstractQoreNode pointer leaving &quot;this&quot; empty (value is taken from &quot;this&quot;); the ...
base class for holding a QoreValue object
Definition: QoreValue.h:319
this is the union that stores values in QoreValue
Definition: QoreValue.h:55
DLLEXPORT AbstractQoreNode * assignNothing()
sets the value of the object to QoreNothingNode and returns any node value held previously ...
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:346
qore_value_u v
the actual value is stored here
Definition: QoreValue.h:123
allows storing a value and setting a boolean flag that indicates if the value should be dereference i...
Definition: QoreValue.h:376
DLLEXPORT double getAsFloat() const
returns the value as a float
DLLLOCAL T * takeReferencedNode()
returns the stored node value and leaves the current object empty
Definition: QoreValue.h:435
evaluates an AbstractQoreNode and dereferences the stored value in the destructor ...
Definition: QoreValue.h:484
DLLEXPORT void ref() const
references the contained value if type == QV_Node
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:54
DLLEXPORT QoreValue & operator=(const QoreValue &n)
assigns a new value
DLLEXPORT bool isNothing() const
returns true if the object contains NOTHING
DLLLOCAL ValueOptionalRefHolder(QoreValue n_v, bool nd, ExceptionSink *xs)
creates the object with the given values
Definition: QoreValue.h:387
DLLEXPORT AbstractQoreNode * assignAndSanitize(const QoreValue n)
sets the value of the object and returns any node value held previously
DLLLOCAL AbstractQoreNode * takeNode(bool &nd)
returns the stored AbstractQoreNode pointer and sets the dereference flag as an output variable ...
Definition: QoreValue.h:449
bool needs_deref
flag indicating if the value should be dereferenced in the destructor or not
Definition: QoreValue.h:383
DLLEXPORT bool isNullOrNothing() const
returns true if the object contains NOTHING or NULL
DLLEXPORT void sanitize()
converts pointers to efficient representations and manages the reference count
Qore&#39;s string type supported by the QoreEncoding class.
Definition: QoreString.h:82
ExceptionSink * xsink
for possible Qore-language exceptions
Definition: QoreValue.h:324
used in QoreValue::get()
Definition: QoreValue.h:66
#define QV_Node
for heap-allocated values
Definition: QoreValue.h:46
DLLEXPORT AbstractQoreNode * getReferencedValue()
returns a referenced AbstractQoreNode ptr; caller owns the reference; the current object is left empt...
DLLEXPORT AbstractQoreNode * takeIfNode()
returns a referenced AbstractQoreNode pointer only if the contained value is an AbstractQoreNode poin...
DLLEXPORT void sanitize()
converts any node pointers to efficient representations if possible and dereferences the node value c...
valtype_t type
indicates the value that the union is holding
Definition: QoreValue.h:125
DLLEXPORT AbstractQoreNode * getReferencedValue()
returns a referenced AbstractQoreNode ptr; caller owns the reference; the current object is left empt...
DLLLOCAL bool isTemp() const
returns true if the value is temporary (needs dereferencing)
Definition: QoreValue.h:397
DLLLOCAL QoreValue takeValue(bool &nd)
returns the stored value and sets the dereference flag as an output variable
Definition: QoreValue.h:459
DLLLOCAL void setValue(QoreValue nv)
assigns a new non-temporary value
Definition: QoreValue.h:411
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 const char * getTypeName() const
returns a string type description of the value contained (ex: &quot;nothing&quot; for a null AbstractQoreNode p...
DLLEXPORT int64 getAsBigInt() const
returns the value as an int
QoreValue v
the vlaue held
Definition: QoreValue.h:322
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:469
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:112
AbstractQoreNode * n
for all heap-allocated values
Definition: QoreValue.h:59
container for holding Qore-language exception information and also for registering a &quot;thread_exit&quot; ca...
Definition: ExceptionSink.h:47
DLLEXPORT QoreValue takeReferencedValue()
returns a QoreValue after incrementing the reference count of any node value stored ...
DLLLOCAL QoreValue & operator*()
returns the value being managed
Definition: QoreValue.h:339
DLLEXPORT void clear()
unconditionally set the QoreValue to QoreNothingNode (does not dereference any possible contained Abs...
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:241
DLLLOCAL QoreValue & operator=(QoreValue nv)
assigns the object, any currently-held value is dereferenced before the assignment ...
Definition: QoreValue.h:363
DLLEXPORT bool isEqualHard(const QoreValue v) const
returns trus if the argument value is equal to the current value without any type conversions ...
DLLLOCAL ValueHolder(QoreValue n_v, ExceptionSink *xs)
creates the object with the given value
Definition: QoreValue.h:350
int64 i
for integer values
Definition: QoreValue.h:57
DLLEXPORT AbstractQoreNode * getInternalNode()
returns any AbstractQoreNode value held; if type != QV_Node, returns NULL
DLLEXPORT AbstractQoreNode * assign(AbstractQoreNode *n)
the QoreValue object takes the reference of the argument
DLLEXPORT bool hasNode() const
returns true if the object contains a non-null AbstractQoreNode pointer (ie type == QV_Node &amp;&amp; v...
DLLLOCAL ValueHolderBase(ExceptionSink *xs)
creates an ampty object
Definition: QoreValue.h:328
int16_t qore_type_t
used to identify unique Qore data and parse types (descendents of AbstractQoreNode) ...
Definition: common.h:71
DLLLOCAL void evalIntern(const AbstractQoreNode *exp)
evaluates the argument, returns -1 for error, 0 = OK
DLLEXPORT ValueEvalRefHolder(const AbstractQoreNode *exp, ExceptionSink *xs)
evaluates the AbstractQoreNode argument
DLLEXPORT qore_type_t getType() const
returns the type of value contained
DLLEXPORT const QoreTypeInfo * getTypeInfo() const
returns the type of the value
bool b
for boolean values
Definition: QoreValue.h:56
DLLLOCAL QoreValue * operator->()
returns the value being managed
Definition: QoreValue.h:336
DLLEXPORT const char * getFullTypeName() const
returns a string type description of the full type of the value contained (ex: &quot;nothing&quot; for a null A...
DLLEXPORT bool isNull() const
returns true if the object contains NULL
DLLLOCAL void setValue(QoreValue nv, bool temp)
assigns a new value
Definition: QoreValue.h:420
DLLEXPORT int eval(const AbstractQoreNode *exp)
evaluates the argument, returns -1 for error, 0 = OK
DLLEXPORT QoreValue refSelf() const
references the contained value if type == QV_Node, returns itself
DLLEXPORT bool getAsBool() const
returns the value as a bool
DLLEXPORT AbstractQoreNode * getReferencedValue() const
returns a referenced AbstractQoreNode pointer; leaving the &quot;this&quot; untouched; the caller owns the refe...
holds an object and dereferences it in the destructor
Definition: QoreValue.h:343
DLLLOCAL void clearTemp()
sets needs_deref = false
Definition: QoreValue.h:400
DLLEXPORT void ensureReferencedValue()
DLLLOCAL ValueOptionalRefHolder(ExceptionSink *xs)
creates an empty object
Definition: QoreValue.h:391
DLLEXPORT void discard(ExceptionSink *xsink)
dereferences any contained AbstractQoreNode pointer and sets to 0; does not modify other values ...
DLLLOCAL ValueHolderBase(QoreValue n_v, ExceptionSink *xs)
creates the object with the given value
Definition: QoreValue.h:332