Qore Programming Language - C/C++ Library  0.8.12.2
 All Classes 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 - 2016 David Nichols
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 
39 #define QV_Bool (valtype_t)0
40 #define QV_Int (valtype_t)1
41 #define QV_Float (valtype_t)2
42 #define QV_Node (valtype_t)3
43 #define QV_Ref (valtype_t)4
44 
45 // forward reference
46 class AbstractQoreNode;
47 class QoreString;
48 
49 union qore_value_u {
50  bool b;
51  int64 i;
52  double f;
54 // void* p;
55 };
56 
57 namespace detail {
59  template<typename Type>
61  typedef Type * Result;
62 
63  template<typename QV>
64  static Result cast(QV *qv, valtype_t type) {
65  assert(type == QV_Node);
66  assert(!qv->v.n || dynamic_cast<Result>(qv->v.n));
67  return reinterpret_cast<Result>(qv->v.n);
68  }
69  };
70 
72  template<>
73  struct QoreValueCastHelper<bool> {
74  typedef bool Result;
75 
76  template<typename QV>
77  static bool cast(QV *qv, valtype_t type) {
78  return qv->getAsBool();
79  }
80  };
81 
83  template<>
84  struct QoreValueCastHelper<double> {
85  typedef double Result;
86 
87  template<typename QV>
88  static double cast(QV *qv, valtype_t type) {
89  return qv->getAsFloat();
90  }
91  };
92 
94  template<>
96  typedef int64 Result;
97 
98  template<typename QV>
99  static double cast(QV *qv, valtype_t type) {
100  return qv->getAsBigInt();
101  }
102  };
103 } // namespace detail
104 
105 struct QoreValue {
106  friend class ValueHolder;
107  friend class ValueEvalRefHolder;
108  template<typename> friend struct detail::QoreValueCastHelper;
109 
110 protected:
111  DLLEXPORT AbstractQoreNode* takeNodeIntern();
112 
113 public:
114  qore_value_u v;
115  valtype_t type;
116 
118  DLLEXPORT QoreValue();
119 
120  DLLEXPORT QoreValue(bool b);
121 
122  DLLEXPORT QoreValue(int i);
123 
124  DLLEXPORT QoreValue(unsigned int i);
125 
126  DLLEXPORT QoreValue(long i);
127 
128  DLLEXPORT QoreValue(unsigned long i);
129 
130  DLLEXPORT QoreValue(unsigned long long i);
131 
132  DLLEXPORT QoreValue(int64 i);
133 
134  DLLEXPORT QoreValue(double f);
135 
136  // the QoreValue object takes the reference of the argument
137  DLLEXPORT QoreValue(AbstractQoreNode* n);
138 
139  // does not reference n for any assignment
140  // sanitizes n (increases the reference of n if necessary) - meaning:
141  // if possible, the value is converted to an immediate value in place
142  // (int, float, or bool)
143  DLLEXPORT QoreValue(const AbstractQoreNode* n);
144 
145  DLLEXPORT QoreValue(const QoreValue& old);
146 
147  DLLEXPORT void swap(QoreValue& val);
148 
149  DLLEXPORT bool getAsBool() const;
150 
151  DLLEXPORT int64 getAsBigInt() const;
152 
153  DLLEXPORT double getAsFloat() const;
154 
155  DLLEXPORT void ref() const;
156 
157  DLLEXPORT QoreValue refSelf() const;
158 
159  DLLEXPORT AbstractQoreNode* getInternalNode();
160 
161  DLLEXPORT const AbstractQoreNode* getInternalNode() const;
162 
163  // the QoreValue object takes the reference of the argument
164  DLLEXPORT AbstractQoreNode* assign(AbstractQoreNode* n);
165 
166  // the QoreValue object will increase the reference of n if necessary
167  //returns 0 or the previously held AbstractQoreNode*
168  // FIXME: remove with new API/ABI
169  DLLEXPORT AbstractQoreNode* assignAndSanitize(const QoreValue n);
170 
171  DLLEXPORT AbstractQoreNode* assign(int64 n);
172 
173  DLLEXPORT AbstractQoreNode* assign(double n);
174 
175  DLLEXPORT AbstractQoreNode* assign(bool n);
176 
177  DLLEXPORT AbstractQoreNode* assignNothing();
178 
179  DLLEXPORT bool isEqualSoft(const QoreValue v, ExceptionSink* xsink) const;
180  DLLEXPORT bool isEqualHard(const QoreValue v) const;
181 
182  // FIXME: remove with new API/ABI
183  // converts pointers to efficient representations
184  DLLEXPORT void sanitize();
185 
186  DLLEXPORT QoreValue& operator=(const QoreValue& n);
187 
188  // dereferences any contained AbstractQoreNode pointer and sets to 0; does not modify other values
189  DLLEXPORT void discard(ExceptionSink* xsink);
190 
192  DLLEXPORT void clear();
193 
194  DLLEXPORT int getAsString(QoreString& str, int format_offset, ExceptionSink *xsink) const;
195 
196  DLLEXPORT QoreString* getAsString(bool& del, int foff, ExceptionSink* xsink) const;
197 
199 
201  template<typename T>
202  DLLLOCAL T* take() {
203  assert(type == QV_Node);
204  assert(dynamic_cast<T*>(v.n));
205  T* rv = reinterpret_cast<T*>(v.n);
206  v.n = 0;
207  return rv;
208  }
209 
210  template<typename T>
211  DLLLOCAL typename detail::QoreValueCastHelper<T>::Result get() {
212  return detail::QoreValueCastHelper<T>::cast(this, type);
213  }
214 
215  template<typename T>
216  DLLLOCAL typename detail::QoreValueCastHelper<const T>::Result get() const {
218  }
219 
221  DLLEXPORT AbstractQoreNode* getReferencedValue() const;
222 
224  DLLEXPORT AbstractQoreNode* takeNode();
225 
227  DLLEXPORT AbstractQoreNode* takeIfNode();
228 
230  DLLEXPORT qore_type_t getType() const;
231 
233  DLLEXPORT const char* getTypeName() const;
234 
236  DLLEXPORT bool hasNode() const;
237 
239  DLLEXPORT bool isNothing() const;
240 
242  DLLEXPORT bool isNull() const;
243 
245  DLLEXPORT bool isNullOrNothing() const;
246 };
247 
248 class ValueHolderBase {
249 protected:
250  QoreValue v;
251  ExceptionSink* xsink;
252 
253 public:
254  DLLLOCAL ValueHolderBase(ExceptionSink* xs) : xsink(xs) {
255  }
256 
257  DLLLOCAL ValueHolderBase(QoreValue n_v, ExceptionSink* xs) : v(n_v), xsink(xs) {
258  }
259 
261  DLLLOCAL QoreValue* operator->() { return &v; }
262 
264  DLLLOCAL QoreValue& operator*() { return v; }
265 };
266 
267 class ValueHolder : public ValueHolderBase {
268 public:
269  DLLLOCAL ValueHolder(ExceptionSink* xs) : ValueHolderBase(xs) {
270  }
271 
272  DLLLOCAL ValueHolder(QoreValue n_v, ExceptionSink* xs) : ValueHolderBase(n_v, xs) {
273  }
274 
275  DLLEXPORT ~ValueHolder();
276 
278  DLLEXPORT AbstractQoreNode* getReferencedValue();
279 
281  DLLEXPORT QoreValue release();
282 
283  DLLLOCAL QoreValue& operator=(QoreValue nv) {
284  v.discard(xsink);
285  v = nv;
286  return v;
287  }
288 
290  DLLLOCAL operator bool() const {
291  return v.type == QV_Node && v.v.n;
292  }
293 };
294 
295 class ValueOptionalRefHolder : public ValueHolderBase {
296 private:
297  // not implemented
298  DLLLOCAL QoreValue& operator=(QoreValue& nv);
299 
300 protected:
301  bool needs_deref;
302 
303  DLLLOCAL ValueOptionalRefHolder(ExceptionSink* xs) : ValueHolderBase(xs), needs_deref(false) {
304  }
305 
306 public:
307  DLLLOCAL ValueOptionalRefHolder(QoreValue n_v, bool nd, ExceptionSink* xs) : ValueHolderBase(n_v, xs), needs_deref(nd) {
308  }
309 
310  DLLEXPORT ~ValueOptionalRefHolder();
311 
313  DLLLOCAL bool isTemp() const { return needs_deref; }
314 
316  DLLLOCAL void setTemp() {
317  assert(needs_deref);
318  needs_deref = false;
319  }
320 
322  DLLLOCAL operator bool() const {
323  return v.type == QV_Node && v.v.n;
324  }
325 
327  DLLLOCAL void setTemp(QoreValue nv) {
328  if (needs_deref)
329  v.discard(xsink);
330  v = nv;
331  }
332 };
333 
334 class ValueEvalRefHolder : public ValueOptionalRefHolder {
335 protected:
336 
337 public:
338  DLLEXPORT ValueEvalRefHolder(const AbstractQoreNode* exp, ExceptionSink* xs);
339 
340  // ensures that the held value is referenced
343  DLLEXPORT void ensureReferencedValue();
344 
345  template<typename T>
346  DLLLOCAL T* takeReferencedNode() {
347  T* rv = v.take<T>();
348  if (needs_deref)
349  needs_deref = false;
350  else
351  rv->ref();
352 
353  return rv;
354  }
355 
356  // leaves the container empty
357  DLLEXPORT AbstractQoreNode* getReferencedValue();
358 
359  DLLLOCAL AbstractQoreNode* takeNode(bool& nd) {
360  if (v.type == QV_Node) {
361  nd = needs_deref;
362  return v.takeNodeIntern();
363  }
364  nd = true;
365  return v.takeNode();
366  }
367 
368  DLLLOCAL QoreValue takeValue(bool& nd) {
369  if (v.type == QV_Node) {
370  nd = needs_deref;
371  return v.takeNodeIntern();
372  }
373  nd = false;
374  return v;
375  }
376 
377  DLLEXPORT QoreValue takeReferencedValue();
378 };
379 
380 #endif
The base class for all value and parse types in Qore expression trees.
Definition: AbstractQoreNode.h:55
static void discard(AbstractQoreNode *n, ExceptionSink *xsink)
to deref an AbstractQoreNode (when the pointer may be 0)
Definition: QoreLib.h:322
Qore&#39;s string type supported by the QoreEncoding class.
Definition: QoreString.h:82
used in QoreValue::get()
Definition: QoreValue.h:60
container for holding Qore-language exception information and also for registering a &quot;thread_exit&quot; ca...
Definition: ExceptionSink.h:43
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:228
int16_t qore_type_t
used to identify unique Qore data and parse types (descendents of AbstractQoreNode) ...
Definition: common.h:68