clean up linked lists
This commit is contained in:
parent
91e83eea1d
commit
e5f91cae6d
57
alloc.d
57
alloc.d
@ -25,19 +25,20 @@ struct ArenaPool
|
||||
u8* mem;
|
||||
u64 pos;
|
||||
u64 length;
|
||||
ArenaPool* next;
|
||||
}
|
||||
|
||||
struct Arena
|
||||
{
|
||||
SLList!(ArenaPool) pools;
|
||||
ArenaPool* first, last;
|
||||
u64 def_size;
|
||||
}
|
||||
|
||||
struct TempArena
|
||||
{
|
||||
Arena* arena;
|
||||
Node!(ArenaPool)* start_node;
|
||||
u64 start_pos;
|
||||
ArenaPool* start_pool;
|
||||
}
|
||||
|
||||
T*
|
||||
@ -160,13 +161,13 @@ BeginTempArena(Arena* arena)
|
||||
arena: arena,
|
||||
};
|
||||
|
||||
auto n = arena.pools.first;
|
||||
auto n = arena.first;
|
||||
for(;;)
|
||||
{
|
||||
if(n.next == null)
|
||||
{
|
||||
t.start_node = n;
|
||||
t.start_pos = n.value.pos;
|
||||
t.start_pool = n;
|
||||
t.start_pos = n.pos;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -180,16 +181,16 @@ void
|
||||
End(TempArena* t)
|
||||
{
|
||||
bool resetting = false;
|
||||
for(auto n = t.arena.pools.first; n != null; n = n.next)
|
||||
for(auto n = t.arena.first; n != null; n = n.next)
|
||||
{
|
||||
if(t.start_node == n)
|
||||
if(t.start_pool == n)
|
||||
{
|
||||
n.value.pos = t.start_pos;
|
||||
n.pos = t.start_pos;
|
||||
resetting = true;
|
||||
}
|
||||
else if(resetting)
|
||||
{
|
||||
n.value.pos = 0;
|
||||
n.pos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -233,17 +234,17 @@ Alloc(T)(TempArena* t)
|
||||
void
|
||||
AddArenaPool(Arena* arena, u64 size)
|
||||
{
|
||||
u8* mem = Alloc!(u8)(size + Node!(ArenaPool).sizeof).ptr;
|
||||
u8* mem = Alloc!(u8)(size + ArenaPool.sizeof).ptr;
|
||||
|
||||
Node!(ArenaPool)* node = cast(Node!(ArenaPool)*)mem;
|
||||
ArenaPool* node = cast(ArenaPool*)mem;
|
||||
|
||||
node.value.mem = (cast(u8*)mem) + Node!(ArenaPool).sizeof;
|
||||
node.value.pos = 0;
|
||||
node.value.length = size;
|
||||
node.mem = (cast(u8*)mem) + ArenaPool.sizeof;
|
||||
node.pos = 0;
|
||||
node.length = size;
|
||||
|
||||
assert(node.value.mem != null, "Unable to allocate memory for arena");
|
||||
assert(node.mem != null, "Unable to allocate memory for arena");
|
||||
|
||||
SLLPushFront(&arena.pools, node, null);
|
||||
SLLPushFront(arena, node, null);
|
||||
}
|
||||
|
||||
T[]
|
||||
@ -308,7 +309,7 @@ AllocAlign(Arena* arena, u64 size, u64 alignment)
|
||||
void* ptr = null;
|
||||
|
||||
uintptr mem_pos, current, offset;
|
||||
Node!(ArenaPool)* node = arena.pools.first;
|
||||
ArenaPool* node = arena.first;
|
||||
while (true)
|
||||
{
|
||||
if(node == null)
|
||||
@ -319,14 +320,14 @@ AllocAlign(Arena* arena, u64 size, u64 alignment)
|
||||
}
|
||||
|
||||
AddArenaPool(arena, Max(size, arena.def_size));
|
||||
node = arena.pools.first;
|
||||
node = arena.first;
|
||||
}
|
||||
|
||||
mem_pos = cast(uintptr)node.value.mem;
|
||||
current = mem_pos + node.value.pos;
|
||||
mem_pos = cast(uintptr)node.mem;
|
||||
current = mem_pos + node.pos;
|
||||
offset = AlignPow2(current, alignment) - mem_pos;
|
||||
|
||||
if(offset+size <= node.value.length)
|
||||
if(offset+size <= node.length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -334,8 +335,8 @@ AllocAlign(Arena* arena, u64 size, u64 alignment)
|
||||
node = node.next;
|
||||
}
|
||||
|
||||
ptr = &node.value.mem[offset];
|
||||
node.value.pos = offset+size;
|
||||
ptr = &node.mem[offset];
|
||||
node.pos = offset+size;
|
||||
|
||||
return ptr;
|
||||
};
|
||||
@ -343,10 +344,10 @@ AllocAlign(Arena* arena, u64 size, u64 alignment)
|
||||
void
|
||||
Reset(Arena* arena)
|
||||
{
|
||||
Node!(ArenaPool)* node = arena.pools.first;
|
||||
ArenaPool* node = arena.first;
|
||||
while (node != null)
|
||||
{
|
||||
node.value.pos = 0;
|
||||
node.pos = 0;
|
||||
node = node.next;
|
||||
}
|
||||
}
|
||||
@ -354,11 +355,13 @@ Reset(Arena* arena)
|
||||
void
|
||||
Free(Arena* arena)
|
||||
{
|
||||
Node!(ArenaPool)* node = arena.pools.first;
|
||||
ArenaPool* node = arena.first;
|
||||
ArenaPool* next;
|
||||
while (node != null)
|
||||
{
|
||||
next = node.next;
|
||||
Free(node);
|
||||
node = node.next;
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
76
platform.d
76
platform.d
@ -160,6 +160,7 @@ struct InputEvent
|
||||
i32 y;
|
||||
i32 rel_x;
|
||||
i32 rel_y;
|
||||
InputEvent* next, prev;
|
||||
}
|
||||
|
||||
enum ClipboardMode
|
||||
@ -175,7 +176,7 @@ alias CBM = ClipboardMode;
|
||||
|
||||
struct Inputs
|
||||
{
|
||||
DLList!(InputEvent) list;
|
||||
InputEvent* first, last;
|
||||
Arena arena;
|
||||
}
|
||||
|
||||
@ -287,20 +288,21 @@ Unlock(TicketMut* mut)
|
||||
return atomicFetchAdd!(MemoryOrder.rel, u64)(mut.next_ticket, 1);
|
||||
}
|
||||
|
||||
__gshared const DNode!(SysMessage) g_sys_message;
|
||||
__gshared DNode!(SysMessage)* g_NIL_MSG;
|
||||
__gshared const SysMessage g_sys_message;
|
||||
__gshared SysMessage* g_NIL_MSG;
|
||||
|
||||
struct SysMessage
|
||||
{
|
||||
SysMessageType type;
|
||||
SysMessage* next, prev;
|
||||
}
|
||||
|
||||
struct MessageQueue
|
||||
{
|
||||
DLList!(SysMessage) list;
|
||||
DLList!(SysMessage) free_list;
|
||||
TicketMut mut;
|
||||
Arena arena;
|
||||
SysMessage* first, last;
|
||||
LinkedList!(SysMessage) free_list;
|
||||
}
|
||||
|
||||
MessageQueue
|
||||
@ -308,37 +310,35 @@ CreateMessageQueue()
|
||||
{
|
||||
if(g_NIL_MSG == null)
|
||||
{
|
||||
g_NIL_MSG = cast(DNode!(SysMessage)*)&g_sys_message;
|
||||
g_NIL_MSG = cast(SysMessage*)&g_sys_message;
|
||||
}
|
||||
|
||||
MessageQueue queue = {
|
||||
list: {
|
||||
first: g_NIL_MSG,
|
||||
last: g_NIL_MSG,
|
||||
},
|
||||
mut: CreateTicketMut(),
|
||||
arena: CreateArena(MB(1)),
|
||||
free_list: {
|
||||
first: g_NIL_MSG,
|
||||
last: g_NIL_MSG,
|
||||
},
|
||||
mut: CreateTicketMut(),
|
||||
arena: CreateArena(MB(1)),
|
||||
};
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
||||
pragma(inline) bool
|
||||
Nil(DNode!(SysMessage)* msg)
|
||||
Nil(SysMessage* msg)
|
||||
{
|
||||
return msg == null || msg == g_NIL_MSG;
|
||||
}
|
||||
|
||||
DNode!(SysMessage)*
|
||||
SysMessage*
|
||||
Pop(MessageQueue* queue)
|
||||
{
|
||||
Lock(&queue.mut);
|
||||
|
||||
DNode!(SysMessage)* node = DLLPop(&queue.list, g_NIL_MSG);
|
||||
SysMessage* node = DLLPop(queue, g_NIL_MSG);
|
||||
|
||||
Unlock(&queue.mut);
|
||||
|
||||
@ -350,26 +350,26 @@ Push(PlatformWindow* w, SysMessageType msg)
|
||||
{
|
||||
Lock(&w.msg_queue.mut);
|
||||
|
||||
DNode!(SysMessage)* node = g_NIL_MSG;
|
||||
SysMessage* node = g_NIL_MSG;
|
||||
if(Nil(w.msg_queue.free_list.first))
|
||||
{
|
||||
node = Alloc!(DNode!(SysMessage))(&w.msg_queue.arena);
|
||||
node = Alloc!(SysMessage)(&w.msg_queue.arena);
|
||||
}
|
||||
else
|
||||
{
|
||||
node = DLLPop(&w.msg_queue.free_list, g_NIL_MSG);
|
||||
}
|
||||
|
||||
node.value.type = msg;
|
||||
DLLPush(&w.msg_queue.list, node, g_NIL_MSG);
|
||||
node.type = msg;
|
||||
DLLPush(&w.msg_queue, node, g_NIL_MSG);
|
||||
|
||||
Unlock(&w.msg_queue.mut);
|
||||
}
|
||||
|
||||
void
|
||||
PushFree(PlatformWindow* w, DNode!(SysMessage)* node)
|
||||
PushFree(PlatformWindow* w, SysMessage* node)
|
||||
{
|
||||
DLLPush(&w.msg_queue.list, node, g_NIL_MSG);
|
||||
DLLPush(&w.msg_queue, node, g_NIL_MSG);
|
||||
}
|
||||
|
||||
version(linux)
|
||||
@ -548,35 +548,35 @@ Kill()
|
||||
void
|
||||
ResetInputs(Inputs* inputs)
|
||||
{
|
||||
inputs.list.first = inputs.list.last = null;
|
||||
inputs.first = inputs.last = null;
|
||||
Reset(&inputs.arena);
|
||||
}
|
||||
|
||||
void
|
||||
Push(Inputs* inputs, Input input, i32 x, i32 y, bool pressed, Modifier md)
|
||||
{
|
||||
DNode!(InputEvent)* node = Alloc!(DNode!(InputEvent))(&inputs.arena);
|
||||
node.value.key = input;
|
||||
node.value.pressed = pressed;
|
||||
node.value.x = x;
|
||||
node.value.y = y;
|
||||
node.value.md = md;
|
||||
InputEvent* node = Alloc!(InputEvent)(&inputs.arena);
|
||||
node.key = input;
|
||||
node.pressed = pressed;
|
||||
node.x = x;
|
||||
node.y = y;
|
||||
node.md = md;
|
||||
|
||||
DLLPushFront(&inputs.list, node, null);
|
||||
DLLPushFront(inputs, node, null);
|
||||
}
|
||||
|
||||
void
|
||||
PushMotion(Inputs* inputs, i32 rel_x, i32 rel_y, i32 x, i32 y)
|
||||
{
|
||||
DNode!(InputEvent)* node = Alloc!(DNode!(InputEvent))(&inputs.arena);
|
||||
node.value.key = Input.MouseMotion;
|
||||
node.value.rel_x = rel_x;
|
||||
node.value.rel_y = rel_y;
|
||||
node.value.x = x;
|
||||
node.value.y = y;
|
||||
node.value.pressed = false;
|
||||
InputEvent* node = Alloc!(InputEvent)(&inputs.arena);
|
||||
node.key = Input.MouseMotion;
|
||||
node.rel_x = rel_x;
|
||||
node.rel_y = rel_y;
|
||||
node.x = x;
|
||||
node.y = y;
|
||||
node.pressed = false;
|
||||
|
||||
DLLPushFront(&inputs.list, node, null);
|
||||
DLLPushFront(inputs, node, null);
|
||||
}
|
||||
|
||||
struct PlatformWindow
|
||||
@ -1156,7 +1156,7 @@ HandleEvents(void* window_ptr)
|
||||
{
|
||||
PlatformWindow* w = cast(PlatformWindow*)window_ptr;
|
||||
|
||||
DNode!(SysMessage)* sys_msg = g_NIL_MSG;
|
||||
SysMessage* sys_msg = g_NIL_MSG;
|
||||
XEvent e;
|
||||
|
||||
bool ignore_mouse_events = false;
|
||||
@ -1173,9 +1173,7 @@ HandleEvents(void* window_ptr)
|
||||
|
||||
if(!Nil(sys_msg))
|
||||
{
|
||||
SysMessage msg = sys_msg.value;
|
||||
|
||||
switch (msg.type)
|
||||
switch (sys_msg.type)
|
||||
{
|
||||
case SMT.Quit:
|
||||
{
|
||||
|
||||
2
test.sh
2
test.sh
@ -4,7 +4,7 @@ name="Test_Runner"
|
||||
|
||||
/bin/bash ./build.sh build
|
||||
|
||||
ldc2 platform.d aliases.d math.d util.d alloc.d assets.d external/xxhash/xxhash.d build/libcglm.a -d-version=DLIB_TEST -Xcc=-mno-sse -P-I/usr/include/freetype2 -L-lfreetype --main --unittest -g --of=$name
|
||||
ldc2 platform.d aliases.d math.d util.d alloc.d assets.d external/xxhash/xxhash.d build/libcglm.a -d-version=DLIB_TEST -Xcc=-mno-sse -P-I/usr/include/freetype2 -L-lfreetype --main --unittest -g --of=$name -verrors=8
|
||||
|
||||
rm $name.o
|
||||
./$name
|
||||
|
||||
186
util.d
186
util.d
@ -205,17 +205,21 @@ BitEq(u64 l, u64 r)
|
||||
return (l & r) == r;
|
||||
}
|
||||
|
||||
struct DNode(T)
|
||||
struct ListBox(T, bool doubly_linked)
|
||||
{
|
||||
DNode!(T)* next;
|
||||
DNode!(T)* prev;
|
||||
alias U = ListBox!(T, doubly_linked);
|
||||
|
||||
U* next;
|
||||
static if(doubly_linked)
|
||||
{
|
||||
U* prev;
|
||||
}
|
||||
T value;
|
||||
}
|
||||
|
||||
struct DLList(T)
|
||||
struct LinkedList(T)
|
||||
{
|
||||
DNode!(T)* first;
|
||||
DNode!(T)* last;
|
||||
T* first, last;
|
||||
}
|
||||
|
||||
void
|
||||
@ -320,100 +324,38 @@ DLLPush(T, U)(T* list, U* node, U* nil)
|
||||
}
|
||||
|
||||
void
|
||||
DLLInsert(T, U)(T* list, U* node, U* prev, U* nil)
|
||||
DLLInsert(T, U)(T* list, U* node, U* prev, U* nil) if(hasMember!(T, "last") && hasMember!(U, "prev"))
|
||||
{
|
||||
node.next = node.prev = nil;
|
||||
|
||||
if(CheckNil(nil, list.first) && CheckNil(nil, list.last))
|
||||
{
|
||||
assert(CheckNil(nil, prev));
|
||||
list.first = list.last = node;
|
||||
node.next = node.prev = nil;
|
||||
}
|
||||
else if(list.first == prev && list.last == prev)
|
||||
else if(!CheckNil(nil, prev))
|
||||
{
|
||||
list.last = node;
|
||||
node.prev = prev;
|
||||
prev.next = node;
|
||||
node.next = list.first;
|
||||
list.first.prev = node;
|
||||
list.first = node;
|
||||
node.prev = nil;
|
||||
}
|
||||
else if(list.last == prev)
|
||||
{
|
||||
prev.next = node;
|
||||
node.prev = prev;
|
||||
list.last.next = node;
|
||||
node.prev = list.last;
|
||||
list.last = node;
|
||||
node.next = nil;
|
||||
}
|
||||
else if(!CheckNil(nil, prev) && CheckNil(nil, prev.next))
|
||||
{}
|
||||
else
|
||||
{
|
||||
node.next = prev.next;
|
||||
node.prev = prev;
|
||||
node.next = prev.next;
|
||||
node.next.prev = node;
|
||||
prev.next = node;
|
||||
}
|
||||
}
|
||||
|
||||
struct Stack(T)
|
||||
{
|
||||
Node!(T)* top;
|
||||
Node!(T)* free;
|
||||
Node!(T)* nil;
|
||||
}
|
||||
|
||||
void
|
||||
SPush(T)(Arena* arena, Stack!(T)* stack, T value)
|
||||
{
|
||||
Node!(T)* node;
|
||||
if(!CheckNil(stack.nil, stack.free))
|
||||
{
|
||||
node = stack.free;
|
||||
stack.free = node.next;
|
||||
}
|
||||
else
|
||||
{
|
||||
node = Alloc!(Node!(T))(arena);
|
||||
}
|
||||
|
||||
node.value = value;
|
||||
|
||||
if(CheckNil(stack.nil, stack.top))
|
||||
{
|
||||
stack.top = node;
|
||||
node.next = stack.nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
node.next = stack.top;
|
||||
stack.top = node;
|
||||
}
|
||||
}
|
||||
|
||||
T
|
||||
SPop(T)(Stack!(T)* stack)
|
||||
{
|
||||
T result;
|
||||
|
||||
if(!CheckNil(stack.nil, stack.top))
|
||||
{
|
||||
result = stack.top.value;
|
||||
|
||||
Node!(T)* free_node = stack.top;
|
||||
stack.top = free_node.next;
|
||||
free_node.next = stack.free;
|
||||
stack.free = free_node;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct Node(T)
|
||||
{
|
||||
Node!(T)* next;
|
||||
T value;
|
||||
}
|
||||
|
||||
struct SLList(T)
|
||||
{
|
||||
Node!(T)* first;
|
||||
Node!(T)* last;
|
||||
}
|
||||
|
||||
pragma(inline) bool
|
||||
CheckNil(T)(T* nil, T* node)
|
||||
{
|
||||
@ -496,6 +438,7 @@ struct KVPair(K, V)
|
||||
{
|
||||
K key;
|
||||
V value;
|
||||
KVPair!(K, V)* next;
|
||||
}
|
||||
|
||||
struct Result(V)
|
||||
@ -508,9 +451,9 @@ struct HashTable(K, V)
|
||||
{
|
||||
alias P = KVPair!(K, V);
|
||||
|
||||
SLList!(P) free_lists;
|
||||
SLList!(P)[] lists;
|
||||
Node!(P)* nil;
|
||||
LinkedList!(P) free_lists;
|
||||
LinkedList!(P)[] lists;
|
||||
P* nil;
|
||||
Arena arena;
|
||||
u64 node_count;
|
||||
u64 list_count;
|
||||
@ -539,8 +482,8 @@ HashTable!(K, V)
|
||||
CreateHashTable(K, V)(u64 size)
|
||||
{
|
||||
Arena arena = CreateArena(MB(4));
|
||||
auto nil = Alloc!(Node!(KVPair!(K, V)))(&arena);
|
||||
auto lists = Alloc!(SLList!(KVPair!(K, V)))(&arena, size);
|
||||
auto nil = Alloc!(KVPair!(K, V))(&arena);
|
||||
auto lists = Alloc!(LinkedList!(KVPair!(K, V)))(&arena, size);
|
||||
|
||||
HashTable!(K, V) table = {
|
||||
arena: arena,
|
||||
@ -572,13 +515,12 @@ Clear(K, V)(HashTable!(K, V)* ht)
|
||||
}
|
||||
}
|
||||
|
||||
pragma(inline) Node!(KVPair!(K, V))*
|
||||
pragma(inline) KVPair!(K, V)*
|
||||
Push(K, V)(HashTable!(K, V)* ht, K key, V value)
|
||||
{
|
||||
alias P = KVPair!(K, V);
|
||||
alias N = Node!(P);
|
||||
|
||||
N* node = ht.nil;
|
||||
P* node = ht.nil;
|
||||
|
||||
if(!CheckNil(ht.nil, ht.free_lists.first))
|
||||
{
|
||||
@ -586,12 +528,12 @@ Push(K, V)(HashTable!(K, V)* ht, K key, V value)
|
||||
}
|
||||
else
|
||||
{
|
||||
node = Alloc!(N)(&ht.arena);
|
||||
node = Alloc!(P)(&ht.arena);
|
||||
}
|
||||
|
||||
node.next = ht.nil;
|
||||
node.value.key = key;
|
||||
node.value.value = value;
|
||||
node.key = key;
|
||||
node.value = value;
|
||||
|
||||
SLLPush(GetList(ht, key), node, ht.nil);
|
||||
|
||||
@ -608,9 +550,9 @@ Search(K, V)(HashTable!(K, V)* ht, K key)
|
||||
auto list = GetList(ht, key);
|
||||
for(auto node = list.first; !CheckNil(ht.nil, node); node = node.next)
|
||||
{
|
||||
if(node.value.key == key)
|
||||
if(node.key == key)
|
||||
{
|
||||
result = &node.value;
|
||||
result = node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -618,7 +560,7 @@ Search(K, V)(HashTable!(K, V)* ht, K key)
|
||||
return result;
|
||||
}
|
||||
|
||||
pragma(inline) SLList!(KVPair!(K, V))*
|
||||
pragma(inline) LinkedList!(KVPair!(K, V))*
|
||||
GetList(K, V)(HashTable!(K, V)* ht, K key)
|
||||
{
|
||||
u64 hash = Hash(&key);
|
||||
@ -1000,8 +942,9 @@ Embed(string file_name)
|
||||
version(DLIB_TEST) unittest
|
||||
{
|
||||
{ // Singly Linked List
|
||||
SLList!(u32) list;
|
||||
Node!(u32)[5] nodes;
|
||||
alias LT = ListBox!(u32, false);
|
||||
LinkedList!(LT) list;
|
||||
LT[5] nodes;
|
||||
foreach(u32 i, n; nodes)
|
||||
{
|
||||
nodes[i].value = i;
|
||||
@ -1014,15 +957,15 @@ version(DLIB_TEST) unittest
|
||||
SLLRemove(&list, &nodes[1], &nodes[0], null);
|
||||
SLLRemove(&list, &nodes[3], &nodes[2], null);
|
||||
|
||||
Node!(u32)* n = list.first;
|
||||
LT* n = list.first;
|
||||
|
||||
assert(list.first != null && list.last != null);
|
||||
assert(n != null);
|
||||
assert(n.next != null);
|
||||
|
||||
void TestSLList(SLList!(u32)* list, u32[] result)
|
||||
void TestSLList(LinkedList!(LT)* list, u32[] result)
|
||||
{
|
||||
Node!(u32)* n = list.first;
|
||||
LT* n = list.first;
|
||||
foreach(i, v; result)
|
||||
{
|
||||
assert(n != null);
|
||||
@ -1057,9 +1000,11 @@ version(DLIB_TEST) unittest
|
||||
}
|
||||
|
||||
{ // Doubly Linked List
|
||||
void TestDLList(DLList!(u32)* list, u32[] result)
|
||||
alias LT = ListBox!(u32, true);
|
||||
|
||||
void TestDLList(T)(T* list, u32[] result)
|
||||
{
|
||||
DNode!(u32)* n = list.first;
|
||||
LT* n = list.first;
|
||||
foreach(i, v; result)
|
||||
{
|
||||
assert(n != null);
|
||||
@ -1100,8 +1045,8 @@ version(DLIB_TEST) unittest
|
||||
}
|
||||
}
|
||||
|
||||
DLList!(u32) list;
|
||||
DNode!(u32)[5] nodes;
|
||||
LinkedList!(LT) list;
|
||||
LT[5] nodes;
|
||||
foreach(u32 i, n; nodes)
|
||||
{
|
||||
nodes[i].value = i;
|
||||
@ -1223,37 +1168,6 @@ version(DLIB_TEST) unittest
|
||||
assert(v3 > 0);
|
||||
}
|
||||
|
||||
{ // Stack
|
||||
Stack!(u32) stack;
|
||||
Arena arena = CreateArena(MB(1));
|
||||
|
||||
u32 v1 = 1;
|
||||
u32 v2 = 2;
|
||||
u32 v3 = 3;
|
||||
|
||||
Node!(u32) nil;
|
||||
|
||||
stack.nil = &nil;
|
||||
|
||||
SPush(&arena, &stack, v1);
|
||||
SPush(&arena, &stack, v2);
|
||||
SPush(&arena, &stack, v3);
|
||||
|
||||
u32 count = 3;
|
||||
for (auto n = stack.top; !CheckNil(null, n); n = n.next, count -= 1)
|
||||
{
|
||||
assert(n.value == count);
|
||||
}
|
||||
|
||||
count = 3;
|
||||
for (u32 n = SPop(&stack); n != 0; n = SPop(&stack), count -= 1)
|
||||
{
|
||||
assert(n == count);
|
||||
}
|
||||
|
||||
assert(stack.top == &nil);
|
||||
}
|
||||
|
||||
{ // Casts
|
||||
u8[] arr = CastStr!(u8)("Test");
|
||||
char[] char_arr = ['a', 'b'];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user