32 #ifndef _QORE_QORELISTPRIVATE_H
33 #define _QORE_QORELISTPRIVATE_H
41 hashdecl qore_list_private {
45 unsigned obj_count = 0;
46 const QoreTypeInfo* complexTypeInfo =
nullptr;
50 DLLLOCAL qore_list_private() : finalized(false), vlist(false) {
53 DLLLOCAL ~qore_list_private() {
61 DLLLOCAL
const QoreTypeInfo* getValueTypeInfo()
const {
62 return complexTypeInfo ? QoreTypeInfo::getComplexListValueType(complexTypeInfo) : nullptr;
65 DLLLOCAL
const QoreTypeInfo* getTypeInfo()
const {
66 return complexTypeInfo ? complexTypeInfo : listTypeInfo;
69 DLLLOCAL
void getTypeName(
QoreString& str)
const {
71 str.
concat(QoreTypeInfo::getName(complexTypeInfo));
78 if (complexTypeInfo) {
79 l->
priv->complexTypeInfo = complexTypeInfo;
84 DLLLOCAL
QoreListNode* getEmptyCopy(
bool is_value)
const {
86 if (complexTypeInfo) {
87 l->
priv->complexTypeInfo = complexTypeInfo;
92 DLLLOCAL
QoreListNode* copyCheckNewElementType(
const QoreTypeInfo* newElementType)
const {
94 rv->
priv->setListTypeFromNewElementType(newElementType);
98 DLLLOCAL
void setListTypeFromNewElementType(
const QoreTypeInfo* newElementType) {
99 const QoreTypeInfo* orig_ctype, * ctype;
100 orig_ctype = ctype = QoreTypeInfo::getUniqueReturnComplexList(complexTypeInfo);
101 if ((!ctype || ctype == anyTypeInfo) && (!newElementType || newElementType == anyTypeInfo)) {
102 complexTypeInfo =
nullptr;
103 }
else if (QoreTypeInfo::matchCommonType(ctype, newElementType)) {
104 if (ctype != orig_ctype) {
105 complexTypeInfo = qore_get_complex_list_type(ctype);
108 complexTypeInfo = autoListTypeInfo;
112 DLLLOCAL
QoreListNode* copy(
const QoreTypeInfo* newComplexTypeInfo)
const {
114 l->
priv->complexTypeInfo = newComplexTypeInfo;
115 copyIntern(*l->
priv);
122 if (!strip || !complexTypeInfo) {
124 copyIntern(*l->
priv);
128 l->
priv->reserve(length);
129 for (
size_t i = 0; i < length; ++i) {
130 l->
priv->pushIntern(copy_strip_complex_types(entry[i]));
135 DLLLOCAL
void copyIntern(qore_list_private& l)
const {
137 for (
size_t i = 0; i < length; ++i) {
138 l.pushIntern(entry[i].refSelf());
145 return mergeWithoutTypeConversion(rv, *l->
priv);
151 if (rv->
priv->pushWithoutTypeConversion(e, xsink)) {
162 if (rv->
priv->pushWithoutTypeConversion(e, xsink)) {
166 return mergeWithoutTypeConversion(rv, *
this);
170 if (complexTypeInfo) {
171 const QoreTypeInfo* vti = QoreTypeInfo::getUniqueReturnComplexList(complexTypeInfo);
172 if (QoreTypeInfo::hasType(vti) && !QoreTypeInfo::superSetOf(vti, holder->getTypeInfo())) {
174 QoreTypeInfo::acceptAssignment(vti,
"<list element assignment>", v, xsink);
176 if (xsink && *xsink) {
178 QoreTypeInfo::getName(vti));
185 return stripVal(holder, xsink);
191 switch (holder->getType()) {
196 holder = copy_strip_complex_types(*v);
198 return xsink && *xsink ? -1 : 0;
208 if (!complexTypeInfo) {
209 return pushStrip(val, xsink);
217 if (stripVal(holder, xsink)) {
226 if (checkVal(holder, xsink)) {
234 reserve(length + list->
size());
237 if (push(i.getReferencedValue(), xsink))
245 for (
size_t i = 0; i < list.length; ++i) {
247 if (!rv->
priv->complexTypeInfo) {
248 v = copy_strip_complex_types(v);
252 rv->
priv->pushIntern(v);
258 DLLLOCAL
void pushIntern(
QoreValue val) {
259 getEntryReference(length) = val;
260 if (needs_scan(val)) {
265 DLLLOCAL
size_t checkOffset(ptrdiff_t offset) {
267 offset = length + offset;
268 return offset < 0 ? 0 : offset;
269 }
else if ((
size_t)offset > length)
275 DLLLOCAL
void checkOffset(ptrdiff_t offset, ptrdiff_t len,
size_t &n_offset,
size_t &n_len) {
276 n_offset = checkOffset(offset);
278 len = length + len - n_offset;
279 n_len = len < 0 ? 0 : len;
286 assert(offset < length);
289 if (needs_scan(rv)) {
293 size_t end = offset + 1;
296 #pragma GCC diagnostic ignored "-Wclass-memaccess"
297 memmove(entry + offset, entry + end,
sizeof(
QoreValue) * (length - end));
298 #pragma GCC diagnostic pop
300 zeroEntries(length - 1, length);
315 DLLLOCAL
QoreListNode* spliceIntern(
size_t offset,
size_t len,
bool extract) {
318 if (len > (length - offset)) {
320 len = length - offset;
327 for (
size_t i = offset; i < end; i++) {
328 removeEntry(entry[i], rv);
333 #pragma GCC diagnostic ignored "-Wclass-memaccess"
334 memmove(entry + offset, entry + end,
sizeof(
QoreValue) * (length - end));
335 #pragma GCC diagnostic pop
337 zeroEntries(length - len, length);
341 resize(length - len);
351 const qore_list_private* sl = l.get<
QoreListNode>()->priv;
353 holder = tmp = sl->getCopy();
354 tmp->priv->reserve(sl->length);
355 for (
size_t i = 0; i < sl->length; ++i) {
357 if (checkVal(eh, xsink)) {
360 tmp->priv->entry[i] = eh.release();
365 if (checkVal(holder, xsink)) {
372 if (len > (length - offset)) {
374 len = length - offset;
381 for (
size_t i = offset; i < end; i++) {
382 removeEntry(entry[i], rv);
390 resize(length - len + n);
393 #pragma GCC diagnostic ignored "-Wclass-memaccess"
394 memmove(entry + (end - len + n), entry + end,
sizeof(
QoreValue) * (ol - end));
395 #pragma GCC diagnostic pop
396 }
else if (len > n) {
397 #pragma GCC diagnostic ignored "-Wclass-memaccess"
398 memmove(entry + offset + n, entry + offset + len,
sizeof(
QoreValue) * (length - offset - n));
399 #pragma GCC diagnostic pop
401 zeroEntries(length - (len - n), length);
403 resize(length - (len - n));
408 entry[offset] = holder.
release();
413 qore_list_private* lst = holder->get<
const QoreListNode>()->priv;
414 for (
size_t i = 0; i < n; ++i) {
419 entry[offset + i] = v;
427 DLLLOCAL
QoreValue& getEntryReference(
size_t num) {
434 DLLLOCAL
QoreValue getAndClear(
size_t i) {
441 if (needs_scan(rv)) {
449 if (!l->
priv->complexTypeInfo)
453 return l->
priv->copy(
true);
458 QoreValue& p = getEntryReference((
size_t)offset);
467 QoreValue& p = getEntryReference((
size_t)offset);
469 bool before = needs_scan(p);
470 bool after = needs_scan(val);
485 DLLLOCAL
QoreValue takeExists(
size_t offset) {
486 if (offset >= length) {
493 if (needs_scan(rv)) {
500 DLLLOCAL
void reserve(
size_t num) {
504 if (num >= allocated) {
506 allocated = num + (d < LIST_PAD ? LIST_PAD : d);
507 #pragma GCC diagnostic ignored "-Wclass-memaccess"
509 #pragma GCC diagnostic pop
513 DLLLOCAL
void resize(
size_t num) {
521 if (num >= allocated) {
523 allocated = num + (d < LIST_PAD ? LIST_PAD : d);
524 #pragma GCC diagnostic ignored "-Wclass-memaccess"
526 #pragma GCC diagnostic pop
528 zeroEntries(length, num);
533 DLLLOCAL
void zeroEntries(
size_t start,
size_t end) {
534 for (
size_t i = start; i < end; ++i) {
545 rv->
priv->pushIntern(v);
548 DLLLOCAL
int getLValue(
size_t ind, LValueHelper& lvh,
bool for_remove,
ExceptionSink* xsink);
557 DLLLOCAL
void incScanCount(
int dt) {
559 assert(obj_count || (dt > 0));
571 DLLLOCAL
static int parseInitComplexListInitialization(
const QoreProgramLocation* loc,
572 QoreParseContext& parse_context, QoreParseListNode* args,
QoreValue& new_args);
574 DLLLOCAL
static int parseInitListInitialization(
const QoreProgramLocation* loc, QoreParseContext& parse_context,
575 QoreParseListNode* args,
QoreValue& new_args,
int& err);
577 DLLLOCAL
static int parseCheckComplexListInitialization(
const QoreProgramLocation* loc,
578 const QoreTypeInfo* typeInfo,
const QoreTypeInfo* expTypeInfo,
const QoreValue exp,
579 const char* context_action,
bool strict_check =
true);
581 DLLLOCAL
static int parseCheckTypedAssignment(
const QoreProgramLocation* loc,
const QoreValue arg,
582 const QoreTypeInfo* vti,
const char* context_action,
bool strict_check =
true);
591 DLLLOCAL
static const qore_list_private* get(
const QoreListNode& l) {
595 DLLLOCAL
static qore_list_private* get(
QoreListNode& l) {
599 DLLLOCAL
static unsigned getScanCount(
const QoreListNode& l) {
600 return l.
priv->obj_count;
603 DLLLOCAL
static void incScanCount(
const QoreListNode& l,
int dt) {
604 l.
priv->incScanCount(dt);
bool value
this is true for values, if false then either the type needs evaluation to produce a value or is a pa...
Definition: AbstractQoreNode.h:330
bool needs_eval_flag
if this is true then the type can be evaluated
Definition: AbstractQoreNode.h:333
For use on the stack only: iterates through elements of a const QoreListNode.
Definition: QoreListNode.h:563
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:48
DLLEXPORT int appendLastDescription(const char *fmt,...)
appends a formatted string to the top exception description if the desc value is a string
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
hashdecl qore_list_private * priv
this structure holds the private implementation for the type
Definition: QoreListNode.h:67
DLLEXPORT size_t size() const
returns the number of elements in the list
Qore's string type supported by the QoreEncoding class.
Definition: QoreString.h:93
DLLEXPORT void concat(const QoreString *str, ExceptionSink *xsink)
concatenates a string and converts encodings if necessary
DLLLOCAL T * release()
releases the pointer to the caller
Definition: ReferenceHolder.h:83
base class for resolved call references
Definition: CallReferenceNode.h:109
holds an object and dereferences it in the destructor
Definition: QoreValue.h:476
DLLEXPORT QoreValue release()
returns a QoreValue object and leaves the current object empty; the caller owns any reference contain...
intptr_t qore_offset_t
used for offsets that could be negative
Definition: common.h:76
const qore_type_t NT_LIST
type value for QoreListNode
Definition: node_types.h:50
const qore_type_t NT_HASH
type value for QoreHashNode
Definition: node_types.h:51
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:275
DLLEXPORT const QoreTypeInfo * getTypeInfo() const
returns the type of the value
DLLEXPORT AbstractQoreNode * assignNothing()
sets the value of the object to QoreNothingNode and returns any node value held previously
DLLEXPORT QoreValue refSelf() const
references the contained value if type == QV_Node, returns itself