Files
Viper_VRTE/_list.vp
T
TermiNexus bb05e112ec refactor(_list): 元素地址运算去掉 uint64 往返,改用 i8* 指针加法
rawptr 即 i8*,指针加法按 pointee(1 字节) 缩放,与 uint64(ptr)+n 再强转回指针逐字等价。
元素步长仍显式由 __elem_size__ 给出,故不能改成下标访问(list[int](pool,8) / list[str](tp,64) 依赖显式步长)。
承接 0f92426 中遗留的裸指针 uint64 手动计算待重新处理。
2026-10-01 18:00:57 +08:00

100 lines
3.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import t, c
import memhub
import string
import stdio
from stdint import *
class list[T]:
"""Heap-allocated dynamic list container backed by memhub.MemManager polymorphic allocator.
Usage:
pool: memhub.MemManager = memhub.MemBuddy(arena, arena_size)
nums: list[int] = list[int](pool)
nums.append(42)
x: int = nums.get(0)
For pointer types (e.g. AST*), pass elem_size=8 to avoid object slicing:
lst: list[AST*] = list[AST*](pool, 8)
"""
__data__: rawptr
__count__: sizet
__capacity__: sizet
__pool__: memhub.MemManager*
__elem_size__: sizet
__iter_index__: sizet
def __new__(self, pool: memhub.MemManager*, elem_size: sizet = 0):
ret = pool.alloc(48)
return ret
def __init__(self, pool: memhub.MemManager*, elem_size: sizet = 0):
self.__pool__ = pool
self.__count__ = 0
self.__capacity__ = 8
if elem_size == 0:
self.__elem_size__ = T.__sizeof__()
else:
self.__elem_size__ = elem_size
self.__data__ = memhub.MemAllocTagged(pool, self.__capacity__ * self.__elem_size__, memhub.DETSITE_LIST_43)
self.__iter_index__ = 0
def __len__(self) -> sizet:
return self.__count__
def append(self, item: T):
if self.__count__ >= self.__capacity__:
new_cap: sizet = self.__capacity__ * 2
new_data: t.CPtr = self.__pool__.alloc(new_cap * self.__elem_size__)
if new_data == None: return
string.memcpy(new_data, self.__data__, self.__count__ * self.__elem_size__)
self.__data__ = new_data
self.__capacity__ = new_cap
# 元素地址:`T*(self.__data__ + i * elem_size)`。
# · rawptr 就是 i8*,i8* 上的 `+` 按 **1 字节**缩放(ExprGenOps 的指针算术分流
# → ExprGenBase.translate_ptr_arith 按 pointee 大小缩放)⇒ 与原先
# `uint64(ptr) + n` 再强转回指针**逐字等价**,故去掉整数往返。
# · 步长仍由 __elem_size__ **显式**给出,不能改成下标访问(`__data__[i]` 会按
# sizeof(T) 缩放):list[int](pool, 8) / list[str](pool, 64) 这类"按显式步长
# 当字节缓冲"的用法依赖它。
# 下面 get/set/__getitem__/__setitem__/pop/__next__ 同此式,不再重复注释。
elem_ptr: T* = T*(self.__data__ + self.__count__ * self.__elem_size__)
elem_ptr[0] = item
self.__count__ += 1
def get(self, index: sizet) -> T:
elem_ptr: T* = T*(self.__data__ + index * self.__elem_size__)
return elem_ptr[0]
def __getitem__(self, index: sizet) -> T:
elem_ptr: T* = T*(self.__data__ + index * self.__elem_size__)
return elem_ptr[0]
def set(self, index: sizet, value: T):
elem_ptr: T* = T*(self.__data__ + index * self.__elem_size__)
elem_ptr[0] = value
def __setitem__(self, index: sizet, value: T):
elem_ptr: T* = T*(self.__data__ + index * self.__elem_size__)
elem_ptr[0] = value
def pop(self) -> T:
self.__count__ -= 1
elem_ptr: T* = T*(self.__data__ + self.__count__ * self.__elem_size__)
return elem_ptr[0]
def clear(self):
self.__count__ = 0
def __iter__(self) -> list[T]*:
self.__iter_index__ = 0
return self
def __next__(self) -> T:
if self.__iter_index__ >= self.__count__:
raise StopIteration
idx: sizet = self.__iter_index__
self.__iter_index__ = idx + 1
elem_ptr: T* = T*(self.__data__ + idx * self.__elem_size__)
return elem_ptr[0]