Qore Programming Language  0.9.2
QoreListNodeEvalOptionalRefHolder.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  QoreListNodeEvalOptionalRefHolder.h
4 
5  Qore Programming Language
6 
7  Copyright (C) 2003 - 2018 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_QORELISTNODEEVALOPTIONALREFHOLDER_H
33 
34 #define _QORE_QORELISTNODEEVALOPTIONALREFHOLDER_H
35 
38 private:
39  QoreListNode* val;
40  ExceptionSink* xsink;
41  bool needs_deref;
42 
43  DLLLOCAL void discardIntern() {
44  if (needs_deref && val) {
45  val->deref(xsink);
46  }
47  }
48 
49  DLLLOCAL void evalIntern(const QoreListNode* exp) {
50  if (exp) {
51  val = exp->evalList(needs_deref, xsink);
52  //printd(0, "QoreListNodeEvalOptionalRefHolder::evalIntern() this: %p exp: %p '%s' (%d) val: %p '%s' (%d)\n", this, exp, exp ? get_full_type_name(exp) : "n/a", exp->size(), val, val ? get_full_type_name(val) : "n/a", val ? val->size() : 0);
53  }
54  else {
55  val = nullptr;
56  needs_deref = false;
57  }
58  }
59 
60  DLLLOCAL void evalIntern(QoreListNode* exp);
61 
62  DLLLOCAL void editIntern() {
63  if (!val) {
64  val = new QoreListNode;
65  needs_deref = true;
66  }
67  else if (!needs_deref || !val->is_unique()) {
68  val = val->copy();
69  needs_deref = true;
70  }
71  }
72 
78  DLLLOCAL void *operator new(size_t);
79 
80 public:
82  DLLLOCAL QoreListNodeEvalOptionalRefHolder(ExceptionSink* n_xsink) : val(nullptr), xsink(n_xsink), needs_deref(false) {
83  }
84 
86  DLLLOCAL QoreListNodeEvalOptionalRefHolder(const QoreListNode* exp, ExceptionSink* n_xsink) : xsink(n_xsink) {
87  evalIntern(exp);
88  }
89 
92  discardIntern();
93  }
94 
96  DLLLOCAL void discard() {
97  discardIntern();
98  needs_deref = false;
99  val = nullptr;
100  }
101 
103  DLLLOCAL void assignEval(const QoreListNode* exp) {
104  discardIntern();
105  evalIntern(exp);
106  }
107 
109  DLLLOCAL void assignEval(QoreListNode* exp) {
110  discardIntern();
111  evalIntern(exp);
112  }
113 
115  DLLLOCAL void assign(bool n_needs_deref, QoreListNode* n_val) {
116  discardIntern();
117  needs_deref = n_needs_deref;
118  val = n_val;
119  }
120 
122  DLLLOCAL bool needsDeref() const {
123  return needs_deref;
124  }
125 
127 
132  if (needs_deref) {
133  needs_deref = false;
134  }
135  else if (val) {
136  val->ref();
137  }
138  return val;
139  }
140 
142  DLLLOCAL void edit() {
143  editIntern();
144  }
145 
146  DLLLOCAL QoreValue& getEntryReference(size_t index);
147 
148  DLLLOCAL size_t size() const {
149  return val ? val->size() : 0;
150  }
151 
153  DLLLOCAL bool canEdit() const {
154  return !val || needs_deref || val->is_unique();
155  }
156 
158 
162  DLLLOCAL const QoreListNode* operator->() const { return val; }
163 
164  DLLLOCAL QoreListNode* operator->() { return val; }
165 
167  DLLLOCAL const QoreListNode* operator*() const { return val; }
168 
169  DLLLOCAL QoreListNode* operator*() { return val; }
170 
172  DLLLOCAL operator bool() const { return val != 0; }
173 };
174 
175 #endif
DLLLOCAL const QoreListNode * operator->() const
returns a pointer to the QoreListNode object being managed
Definition: QoreListNodeEvalOptionalRefHolder.h:162
DLLLOCAL ~QoreListNodeEvalOptionalRefHolder()
clears the object (dereferences the old object if necessary)
Definition: QoreListNodeEvalOptionalRefHolder.h:91
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
DLLLOCAL void discard()
clears the object (dereferences the old object if necessary)
Definition: QoreListNodeEvalOptionalRefHolder.h:96
DLLEXPORT size_t size() const
returns the number of elements in the list
DLLLOCAL void assignEval(const QoreListNode *exp)
assigns a new value by executing the given list and dereference flag to this object, dereferences the old object if necessary
Definition: QoreListNodeEvalOptionalRefHolder.h:103
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:262
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:46
DLLLOCAL const QoreListNode * operator*() const
returns a pointer to the QoreListNode object being managed
Definition: QoreListNodeEvalOptionalRefHolder.h:167
DLLEXPORT QoreListNode * evalList(ExceptionSink *xsink) const
evaluates the list and returns a value (or 0)
DLLEXPORT void deref(ExceptionSink *xsink)
decrements the reference count and calls derefImpl() if there_can_be_only_one is false, otherwise does nothing
DLLEXPORT void ref() const
increments the reference count
DLLEXPORT bool is_unique() const
returns true if the reference count is 1
DLLLOCAL void assign(bool n_needs_deref, QoreListNode *n_val)
assigns a new value and dereference flag to this object, dereferences the old object if necessary ...
Definition: QoreListNodeEvalOptionalRefHolder.h:115
DLLLOCAL void edit()
will create a unique list so the list can be edited
Definition: QoreListNodeEvalOptionalRefHolder.h:142
DLLLOCAL bool canEdit() const
returns true if the value being managed can be edited/updated
Definition: QoreListNodeEvalOptionalRefHolder.h:153
For use on the stack only: manages result of the optional evaluation of a QoreListNode.
Definition: QoreListNodeEvalOptionalRefHolder.h:37
DLLLOCAL QoreListNode * getReferencedValue()
returns a referenced value - the caller will own the reference
Definition: QoreListNodeEvalOptionalRefHolder.h:131
DLLLOCAL bool needsDeref() const
returns true if the object contains a temporary (evaluated) value that needs a dereference ...
Definition: QoreListNodeEvalOptionalRefHolder.h:122
DLLEXPORT QoreListNode * copy() const
performs a deep copy of the list and returns the new list