Qore Programming Language  0.8.12
QoreValue.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  QoreValue.h
4 
5  Qore Programming Language
6 
7  Copyright (C) 2003 - 2015 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 
58 namespace detail {
59 
60 template<typename Type>
61 struct QoreValueCastHelper {
62  typedef Type * Result;
63 
64  template<typename QV>
65  static Result cast(QV *qv, valtype_t type) {
66  assert(type == QV_Node);
67  assert(dynamic_cast<Result>(qv->v.n));
68  return reinterpret_cast<Result>(qv->v.n);
69  }
70 };
71 
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 
82 template<>
83 struct QoreValueCastHelper<double> {
84  typedef double Result;
85 
86  template<typename QV>
87  static double cast(QV *qv, valtype_t type) {
88  return qv->getAsFloat();
89  }
90 };
91 
92 template<>
93 struct QoreValueCastHelper<int64> {
94  typedef int64 Result;
95 
96  template<typename QV>
97  static double cast(QV *qv, valtype_t type) {
98  return qv->getAsBigInt();
99  }
100 };
101 
102 template<>
103 struct QoreValueCastHelper<int> {
104  typedef int Result;
105 
106  template<typename QV>
107  static int cast(QV *qv, valtype_t type) {
108  return qv->getAsBigInt();
109  }
110 };
111 
112 } // namespace detail
113 
114 
115 struct QoreValue {
116  friend class ValueEvalRefHolder;
117  template<typename> friend struct detail::QoreValueCastHelper;
118 
119 protected:
120  DLLEXPORT AbstractQoreNode* takeNodeIntern();
121 
122 public:
123  qore_value_u v;
124  valtype_t type;
125 
127  DLLEXPORT QoreValue();
128 
129  DLLEXPORT QoreValue(bool b);
130 
131  DLLEXPORT QoreValue(int64 i);
132 
133  DLLEXPORT QoreValue(double f);
134 
135  DLLEXPORT QoreValue(AbstractQoreNode* n);
136 
137  DLLEXPORT QoreValue(const AbstractQoreNode* n);
138 
139  DLLEXPORT QoreValue(const QoreValue& old);
140 
141  DLLEXPORT void swap(QoreValue& val);
142 
143  DLLEXPORT bool getAsBool() const;
144 
145  DLLEXPORT int64 getAsBigInt() const;
146 
147  DLLEXPORT double getAsFloat() const;
148 
149  DLLEXPORT QoreValue refSelf() const;
150 
151  DLLEXPORT AbstractQoreNode* getInternalNode();
152 
153  DLLEXPORT const AbstractQoreNode* getInternalNode() const;
154 
155  DLLEXPORT AbstractQoreNode* assign(AbstractQoreNode* n);
156 
157  DLLEXPORT AbstractQoreNode* assign(int64 n);
158 
159  DLLEXPORT AbstractQoreNode* assign(double n);
160 
161  DLLEXPORT AbstractQoreNode* assign(bool n);
162 
163  DLLEXPORT AbstractQoreNode* assignNothing();
164 
165  DLLEXPORT bool isEqualSoft(const QoreValue v, ExceptionSink* xsink) const;
166  DLLEXPORT bool isEqualHard(const QoreValue v) const;
167 
168  // FIXME: remove with new API/ABI
169  // converts pointers to efficient reprensentations
170  DLLEXPORT void sanitize();
171 
172  DLLEXPORT QoreValue& operator=(const QoreValue& n);
173 
174  DLLEXPORT void clearNode();
175 
176  DLLEXPORT void discard(ExceptionSink* xsink);
177 
178  DLLEXPORT int getAsString(QoreString& str, int format_offset, ExceptionSink *xsink) const;
179 
180  DLLEXPORT QoreString* getAsString(bool& del, int foff, ExceptionSink* xsink) const;
181 
182  template<typename T>
183  DLLLOCAL T* take() {
184  assert(type == QV_Node);
185  assert(dynamic_cast<T*>(v.n));
186  T* rv = reinterpret_cast<T*>(v.n);
187  v.n = 0;
188  return rv;
189  }
190 
191  template<typename T>
192  DLLLOCAL typename detail::QoreValueCastHelper<T>::Result get() {
193  return detail::QoreValueCastHelper<T>::cast(this, type);
194  }
195 
196  template<typename T>
197  DLLLOCAL typename detail::QoreValueCastHelper<const T>::Result get() const {
198  return detail::QoreValueCastHelper<const T>::cast(this, type);
199  }
200 
201 
202 
203  DLLEXPORT AbstractQoreNode* getReferencedValue() const;
204 
205  DLLEXPORT AbstractQoreNode* takeNode();
206 
207  DLLEXPORT AbstractQoreNode* takeIfNode();
208 
209  DLLEXPORT qore_type_t getType() const;
210 
211  DLLEXPORT const char* getTypeName() const;
212 
213  DLLEXPORT bool hasNode() const;
214 
215  DLLEXPORT bool isNothing() const;
216 
217  DLLEXPORT bool isNull() const;
218 
219  DLLEXPORT bool isNullOrNothing() const;
220 };
221 
222 class ValueHolderBase {
223 protected:
224  QoreValue v;
225  ExceptionSink* xsink;
226 
227 public:
228  DLLLOCAL ValueHolderBase(ExceptionSink* xs) : xsink(xs) {
229  }
230 
231  DLLLOCAL ValueHolderBase(QoreValue n_v, ExceptionSink* xs) : v(n_v), xsink(xs) {
232  }
233 
235  DLLLOCAL QoreValue* operator->() { return &v; }
236 
238  DLLLOCAL QoreValue& operator*() { return v; }
239 };
240 
241 class ValueHolder : public ValueHolderBase {
242 public:
243  DLLLOCAL ValueHolder(ExceptionSink* xs) : ValueHolderBase(xs) {
244  }
245 
246  DLLLOCAL ValueHolder(QoreValue n_v, ExceptionSink* xs) : ValueHolderBase(n_v, xs) {
247  }
248 
249  DLLEXPORT ~ValueHolder();
250 
251  DLLEXPORT AbstractQoreNode* getReferencedValue();
252 
253  DLLLOCAL QoreValue& operator=(QoreValue nv) {
254  v.discard(xsink);
255  v = nv;
256  return v;
257  }
258 
260  DLLLOCAL operator bool() const {
261  return v.type == QV_Node && v.v.n;
262  }
263 };
264 
265 class ValueOptionalRefHolder : public ValueHolderBase {
266 protected:
267  bool needs_deref;
268 
269  DLLLOCAL ValueOptionalRefHolder(ExceptionSink* xs) : ValueHolderBase(xs), needs_deref(false) {
270  }
271 
272  // not implemented
273  DLLLOCAL QoreValue& operator=(QoreValue& nv);
274 
275 public:
276  DLLLOCAL ValueOptionalRefHolder(QoreValue n_v, bool nd, ExceptionSink* xs) : ValueHolderBase(n_v, xs), needs_deref(nd) {
277  }
278 
279  DLLEXPORT ~ValueOptionalRefHolder();
280 
282  DLLLOCAL bool isTemp() const { return needs_deref; }
283 };
284 
285 class ValueEvalRefHolder : public ValueOptionalRefHolder {
286 protected:
287 
288 public:
289  DLLEXPORT ValueEvalRefHolder(const AbstractQoreNode* exp, ExceptionSink* xs);
290 
291  template<typename T>
292  DLLLOCAL T* takeReferencedNode() {
293  T* rv = v.take<T>();
294  if (needs_deref)
295  needs_deref = false;
296  else
297  rv->ref();
298 
299  return rv;
300  }
301 
302  // leaves the container empty
303  DLLEXPORT AbstractQoreNode* getReferencedValue();
304 
305  DLLLOCAL AbstractQoreNode* takeNode(bool& nd) {
306  if (v.type == QV_Node) {
307  nd = needs_deref;
308  return v.takeNodeIntern();
309  }
310  nd = true;
311  return v.takeNode();
312  }
313 
314  DLLLOCAL QoreValue takeValue(bool& nd) {
315  if (v.type == QV_Node) {
316  nd = needs_deref;
317  return v.takeNodeIntern();
318  }
319  nd = false;
320  return v;
321  }
322 
323  DLLEXPORT QoreValue takeReferencedValue();
324 };
325 
326 #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:312
Qore's string type supported by the QoreEncoding class.
Definition: QoreString.h:50
Definition: QoreValue.h:58
container for holding Qore-language exception information and also for registering a "thread_exit" 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:225
int16_t qore_type_t
used to identify unique Qore data and parse types (descendents of AbstractQoreNode) ...
Definition: common.h:68