/* * Minimal bootstrap RTL (runtime library) - List class * * Copyright © 2026 Samuel Lidén Borell * * SPDX-License-Identifier: EUPL-1.2+ OR LGPL-2.1-or-later */ #include #include #include "rtl.h" #include "internal.h" struct List { SlulInt capacity; SlulInt append, prepend; union Slul__Generic *elems; }; struct List *List_new(void) { struct List *list = malloc(sizeof(struct List)); OOM_CHECK(list); list->capacity = 0; list->append = 0; list->prepend = 0; list->elems = NULL; return list; } SlulInt List_count(const struct List *const this) { return this->append + this->prepend; } static void grow(struct List *const this) { union Slul__Generic *realloced; SlulInt oldcapa, newcapa; SlulInt count; count = this->append + this->prepend; CHECK(count < 0x7FFFFFF-1U, "Oversized List"); oldcapa = this->capacity; if (!oldcapa) { newcapa = 8; } else { assert(oldcapa <= count); CHECK(oldcapa+1 < ((size_t)-1)/2/sizeof(void *), "Oversized list capacity"); newcapa = 2*oldcapa; } realloced = realloc(this->elems, sizeof(void *) * newcapa); OOM_CHECK(realloced); if (this->prepend) { memcpy(&realloced[newcapa - this->prepend], &realloced[oldcapa - this->prepend], sizeof(void *) * this->prepend); } this->capacity = newcapa; this->elems = realloced; } void List_add( struct List *const this, const union Slul__Generic elem) { if (this->append + this->prepend == this->capacity) { grow(this); } this->elems[this->append++] = elem; } void List_insert_first( struct List *const this, const union Slul__Generic elem) { if (this->append + this->prepend == this->capacity) { grow(this); } this->elems[this->prepend++] = elem; }