]> git.lizzy.rs Git - nothing.git/blob - src/stack.h
3ab4454b9b311505cdd2fb972776fa6d9306698c
[nothing.git] / src / stack.h
1 #ifndef STACK_H_
2 #define STACK_H_
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <system/stacktrace.h>
8
9 typedef struct {
10     size_t capacity;
11     size_t size;
12     char *bottom;
13 } Stack;
14
15 static inline
16 void destroy_stack(Stack stack)
17 {
18     free(stack.bottom);
19 }
20
21 static inline
22 void stack_grow(Stack *stack, size_t new_capacity)
23 {
24     trace_assert(stack);
25     trace_assert(stack->capacity < new_capacity);
26
27     stack->bottom = realloc(stack->bottom, new_capacity);
28     stack->capacity = new_capacity;
29 }
30
31 static inline
32 void stack_push(Stack *stack, const void *element, size_t element_size)
33 {
34     trace_assert(stack);
35     trace_assert(element);
36     trace_assert(element_size > 0);
37
38     size_t frame_size = element_size + sizeof(element_size);
39
40     if (frame_size >= (stack->capacity - stack->size)) {
41         stack_grow(stack, stack->capacity * 2 + frame_size);
42     }
43
44     trace_assert(stack->bottom);
45
46     memcpy(stack->bottom + stack->size, element, element_size);
47     stack->size += element_size;
48     memcpy(stack->bottom + stack->size, &element_size, sizeof(element_size));
49     stack->size += sizeof(element_size);
50 }
51
52 static inline
53 size_t stack_top_size(const Stack *stack)
54 {
55     trace_assert(stack);
56     trace_assert(stack->size > 0);
57     trace_assert(stack->bottom);
58     size_t stack_size = 0;
59     memcpy(&stack_size, stack->bottom + stack->size - sizeof(size_t), sizeof(size_t));
60     return stack_size;
61 }
62
63 static inline
64 void *stack_top_element(const Stack *stack)
65 {
66     trace_assert(stack);
67     trace_assert(stack->size > 0);
68     trace_assert(stack->bottom);
69     size_t element_size = stack_top_size(stack);
70     return stack->bottom + stack->size - element_size - sizeof(size_t);
71 }
72
73 static inline
74 void stack_pop(Stack *stack)
75 {
76     trace_assert(stack);
77     trace_assert(stack->size > 0);
78     size_t element_size = stack_top_size(stack);
79     stack->size -= element_size + sizeof(size_t);
80 }
81
82 static inline
83 int stack_empty(Stack *stack)
84 {
85     trace_assert(stack);
86     return stack->size > 0;
87 }
88
89 #endif  // STACK_H_