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;
270 else if ((
size_t)offset > length)
276 DLLLOCAL
void checkOffset(ptrdiff_t offset, ptrdiff_t len,
size_t &n_offset,
size_t &n_len) {
277 n_offset = checkOffset(offset);
279 len = length + len - n_offset;
280 n_len = len < 0 ? 0 : len;
287 assert(offset < length);
290 if (needs_scan(rv)) {
294 size_t end = offset + 1;
297 memmove(entry + offset, entry + end,
sizeof(
QoreValue) * (length - end));
299 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;
328 for (
size_t i = offset; i < end; i++) {
329 removeEntry(entry[i], rv);
334 memmove(entry + offset, entry + end,
sizeof(
QoreValue) * (length - end));
336 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();
366 if (checkVal(holder, xsink)) {
373 if (len > (length - offset)) {
375 len = length - offset;
383 for (
size_t i = offset; i < end; i++) {
384 removeEntry(entry[i], rv);
392 resize(length - len + n);
395 memmove(entry + (end - len + n), entry + end,
sizeof(
QoreValue) * (ol - end));
398 memmove(entry + offset + n, entry + offset + len,
sizeof(
QoreValue) * (length - offset - n));
400 zeroEntries(length - (len - n), length);
402 resize(length - (len - n));
407 entry[offset] = holder.
release();
412 qore_list_private* lst = holder->get<
const QoreListNode>()->priv;
413 for (
size_t i = 0; i < n; ++i) {
418 entry[offset + i] = v;
426 DLLLOCAL
QoreValue& getEntryReference(
size_t num) {
433 DLLLOCAL
QoreValue getAndClear(
size_t i) {
440 if (needs_scan(rv)) {
448 if (!l->
priv->complexTypeInfo)
452 return l->
priv->copy(
true);
457 QoreValue& p = getEntryReference((
size_t)offset);
466 QoreValue& p = getEntryReference((
size_t)offset);
468 bool before = needs_scan(p);
469 bool after = needs_scan(val);
484 DLLLOCAL
QoreValue takeExists(
size_t offset) {
485 if (offset >= length) {
492 if (needs_scan(rv)) {
499 DLLLOCAL
void reserve(
size_t num) {
503 if (num >= allocated) {
505 allocated = num + (d < LIST_PAD ? LIST_PAD : d);
510 DLLLOCAL
void resize(
size_t num) {
518 if (num >= allocated) {
520 allocated = num + (d < LIST_PAD ? LIST_PAD : d);
523 zeroEntries(length, num);
528 DLLLOCAL
void zeroEntries(
size_t start,
size_t end) {
529 for (
size_t i = start; i < end; ++i) {
540 rv->
priv->pushIntern(v);
543 DLLLOCAL
int getLValue(
size_t ind, LValueHelper& lvh,
bool for_remove,
ExceptionSink* xsink);
551 DLLLOCAL
void incScanCount(
int dt) {
553 assert(obj_count || (dt > 0));
565 DLLLOCAL
static int parseInitComplexListInitialization(
const QoreProgramLocation* loc, LocalVar *oflag,
int pflag, QoreParseListNode* args,
QoreValue& new_args,
const QoreTypeInfo* vti);
567 DLLLOCAL
static int parseInitListInitialization(
const QoreProgramLocation* loc, LocalVar *oflag,
int pflag,
int& lvids, QoreParseListNode* args,
QoreValue& new_args,
const QoreTypeInfo*& argTypeInfo);
569 DLLLOCAL
static void parseCheckComplexListInitialization(
const QoreProgramLocation* loc,
const QoreTypeInfo* typeInfo,
const QoreTypeInfo* expTypeInfo,
const QoreValue exp,
const char* context_action,
bool strict_check =
true);
571 DLLLOCAL
static void parseCheckTypedAssignment(
const QoreProgramLocation* loc,
const QoreValue arg,
const QoreTypeInfo* vti,
const char* context_action,
bool strict_check =
true);
578 DLLLOCAL
static const qore_list_private* get(
const QoreListNode& l) {
582 DLLLOCAL
static qore_list_private* get(
QoreListNode& l) {
586 DLLLOCAL
static unsigned getScanCount(
const QoreListNode& l) {
587 return l.
priv->obj_count;
590 DLLLOCAL
static void incScanCount(
const QoreListNode& l,
int dt) {
591 l.
priv->incScanCount(dt);