Qore Programming Language  1.7.0
QoreListNodeEvalOptionalRefHolder.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  QoreListNodeEvalOptionalRefHolder.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_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  } else {
54  val = nullptr;
55  needs_deref = false;
56  }
57  }
58 
59  DLLLOCAL void evalIntern(QoreListNode* exp);
60 
61  DLLLOCAL void editIntern() {
62  if (!val) {
63  val = new QoreListNode(autoTypeInfo);
64  needs_deref = true;
65  }
66  else if (!needs_deref || !val->is_unique()) {
67  val = val->copy();
68  needs_deref = true;
69  }
70  }
71 
77  DLLLOCAL void *operator new(size_t);
78 
79 public:
81  DLLLOCAL QoreListNodeEvalOptionalRefHolder(ExceptionSink* n_xsink) : val(nullptr), xsink(n_xsink), needs_deref(false) {
82  }
83 
85  DLLLOCAL QoreListNodeEvalOptionalRefHolder(const QoreListNode* exp, ExceptionSink* n_xsink) : xsink(n_xsink) {
86  evalIntern(exp);
87  }
88 
91  discardIntern();
92  }
93 
95  DLLLOCAL void discard() {
96  discardIntern();
97  needs_deref = false;
98  val = nullptr;
99  }
100 
102  DLLLOCAL void assignEval(const QoreListNode* exp) {
103  discardIntern();
104  evalIntern(exp);
105  }
106 
108  DLLLOCAL void assignEval(QoreListNode* exp) {
109  discardIntern();
110  evalIntern(exp);
111  }
112 
114  DLLLOCAL void assign(bool n_needs_deref, QoreListNode* n_val) {
115  discardIntern();
116  needs_deref = n_needs_deref;
117  val = n_val;
118  }
119 
121  DLLLOCAL bool needsDeref() const {
122  return needs_deref;
123  }
124 
126 
131  if (needs_deref) {
132  needs_deref = false;
133  }
134  else if (val) {
135  val->ref();
136  }
137  return val;
138  }
139 
141  DLLLOCAL void edit() {
142  editIntern();
143  }
144 
145  DLLLOCAL QoreValue& getEntryReference(size_t index);
146 
147  DLLLOCAL size_t size() const {
148  return val ? val->size() : 0;
149  }
150 
152  DLLLOCAL bool canEdit() const {
153  return !val || needs_deref || val->is_unique();
154  }
155 
157 
161  DLLLOCAL const QoreListNode* operator->() const { return val; }
162 
163  DLLLOCAL QoreListNode* operator->() { return val; }
164 
166  DLLLOCAL const QoreListNode* operator*() const { return val; }
167 
168  DLLLOCAL QoreListNode* operator*() { return val; }
169 
171  DLLLOCAL operator bool() const { return val != 0; }
172 };
173 
174 #endif
DLLEXPORT void ref() const
increments the reference count
DLLEXPORT void deref(ExceptionSink *xsink)
decrements the reference count and calls derefImpl() if there_can_be_only_one is false,...
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:48
For use on the stack only: manages result of the optional evaluation of a QoreListNode.
Definition: QoreListNodeEvalOptionalRefHolder.h:37
DLLLOCAL void assignEval(const QoreListNode *exp)
assigns a new value by executing the given list and dereference flag to this object,...
Definition: QoreListNodeEvalOptionalRefHolder.h:102
DLLLOCAL const QoreListNode * operator*() const
returns a pointer to the QoreListNode object being managed
Definition: QoreListNodeEvalOptionalRefHolder.h:166
DLLLOCAL const QoreListNode * operator->() const
returns a pointer to the QoreListNode object being managed
Definition: QoreListNodeEvalOptionalRefHolder.h:161
DLLLOCAL ~QoreListNodeEvalOptionalRefHolder()
clears the object (dereferences the old object if necessary)
Definition: QoreListNodeEvalOptionalRefHolder.h:90
DLLLOCAL bool canEdit() const
returns true if the value being managed can be edited/updated
Definition: QoreListNodeEvalOptionalRefHolder.h:152
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:114
DLLLOCAL QoreListNode * getReferencedValue()
returns a referenced value - the caller will own the reference
Definition: QoreListNodeEvalOptionalRefHolder.h:130
DLLLOCAL bool needsDeref() const
returns true if the object contains a temporary (evaluated) value that needs a dereference
Definition: QoreListNodeEvalOptionalRefHolder.h:121
DLLLOCAL void edit()
will create a unique list so the list can be edited
Definition: QoreListNodeEvalOptionalRefHolder.h:141
DLLLOCAL void discard()
clears the object (dereferences the old object if necessary)
Definition: QoreListNodeEvalOptionalRefHolder.h:95
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
DLLEXPORT size_t size() const
returns the number of elements in the list
DLLEXPORT QoreListNode * evalList(ExceptionSink *xsink) const
evaluates the list and returns a value (or 0)
DLLEXPORT QoreListNode * copy() const
performs a deep copy of the list and returns the new list
DLLEXPORT bool is_unique() const
returns true if the reference count is 1
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:275