Files
TransPyC/includes/_list.py

86 lines
2.9 KiB
Python
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 mbuddy
import string
from stdint import *
class list[T]:
"""堆上动态列表容器,基于 mbuddy 分配器。
用法:
mb: mbuddy.MBuddy = mbuddy.MBuddy(arena, arena_size)
nums: list[int] = list[int](mb)
nums.append(42)
x: int = nums.get(0)
"""
__data__: t.CVoid | t.CPtr
__count__: t.CSizeT
__capacity__: t.CSizeT
__mbuddy__: mbuddy.MBuddy | t.CPtr
__iter_index__: t.CSizeT
def __new__(self, mb: mbuddy.MBuddy | t.CPtr):
# 堆分配 list[T] 对象 (5 字段 × 8 字节 = 40 字节)
# 避免栈上分配导致返回后 use-after-free
buf: t.CVoid | t.CPtr = mb.alloc(40)
return buf
def __init__(self, mb: mbuddy.MBuddy | t.CPtr):
self.__mbuddy__ = mb
self.__count__ = 0
self.__capacity__ = 8
self.__data__ = mb.alloc(self.__capacity__ * T.__sizeof__())
self.__iter_index__ = 0
def __len__(self) -> t.CSizeT:
return self.__count__
def append(self, item: T):
if self.__count__ >= self.__capacity__:
new_cap: t.CSizeT = self.__capacity__ * 2
new_data: t.CVoid | t.CPtr = self.__mbuddy__.alloc(new_cap * T.__sizeof__())
if new_data == None:
return
string.memcpy(new_data, self.__data__, self.__count__ * T.__sizeof__())
self.__data__ = new_data
self.__capacity__ = new_cap
elem_ptr: T | t.CPtr = t.CVoid(t.CUInt64T(self.__data__) + self.__count__ * T.__sizeof__(), t.CPtr)
elem_ptr[0] = item
self.__count__ += 1
def get(self, index: t.CSizeT) -> T:
elem_ptr: T | t.CPtr = t.CVoid(t.CUInt64T(self.__data__) + index * T.__sizeof__(), t.CPtr)
return elem_ptr[0]
def __getitem__(self, index: t.CSizeT) -> T:
elem_ptr: T | t.CPtr = t.CVoid(t.CUInt64T(self.__data__) + index * T.__sizeof__(), t.CPtr)
return elem_ptr[0]
def set(self, index: t.CSizeT, value: T):
elem_ptr: T | t.CPtr = t.CVoid(t.CUInt64T(self.__data__) + index * T.__sizeof__(), t.CPtr)
elem_ptr[0] = value
def __setitem__(self, index: t.CSizeT, value: T):
elem_ptr: T | t.CPtr = t.CVoid(t.CUInt64T(self.__data__) + index * T.__sizeof__(), t.CPtr)
elem_ptr[0] = value
def pop(self) -> T:
self.__count__ -= 1
elem_ptr: T | t.CPtr = t.CVoid(t.CUInt64T(self.__data__) + self.__count__ * T.__sizeof__(), t.CPtr)
return elem_ptr[0]
def clear(self):
self.__count__ = 0
def __iter__(self):
self.__iter_index__ = 0
return self
def __next__(self) -> T:
if self.__iter_index__ >= self.__count__:
raise StopIteration
idx: t.CSizeT = self.__iter_index__
self.__iter_index__ = idx + 1
elem_ptr: T | t.CPtr = t.CVoid(t.CUInt64T(self.__data__) + idx * T.__sizeof__(), t.CPtr)
return elem_ptr[0]