-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathStack.c
96 lines (83 loc) · 1.82 KB
/
Stack.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include "Prototypes.h"
#include <stdbool.h>
#include <stdlib.h>
/*{
struct StackItem_ {
void* data;
StackItem* next;
};
struct Stack_ {
ObjectClass* type;
StackItem* head;
bool owner;
int size;
};
}*/
Stack* Stack_new(ObjectClass* type, bool owner) {
Stack* this = (Stack*) malloc(sizeof(Stack));
this->type = type;
this->head = NULL;
this->owner = owner;
this->size = 0;
return this;
}
void Stack_empty(Stack* this) {
StackItem* item = this->head;
while (item) {
StackItem* saved = item;
if (this->owner) {
if (this->type) {
Object* obj = (Object*)item->data;
Msg0(Object, delete, obj);
} else {
if (item->data)
free(item->data);
}
}
item = item->next;
free(saved);
}
this->head = NULL;
this->size = 0;
}
void Stack_delete(Stack* this) {
Stack_empty(this);
free(this);
}
void Stack_push(Stack* this, void* data) {
assert( !this->type || Call(Object, instanceOf, data, this->type) );
assert( data );
StackItem* item = (StackItem*) malloc(sizeof(StackItem));
item->data = data;
item->next = this->head;
this->head = item;
this->size++;
}
void* Stack_pop(Stack* this) {
if (!this->head)
return NULL;
void* result = this->head->data;
StackItem* headNext = this->head->next;
free(this->head);
this->head = headNext;
assert( !this->type || Call(Object, instanceOf, result, this->type) );
this->size--;
return result;
}
void* Stack_peek(Stack* this) {
if (!this->head) {
return NULL;
}
return this->head->data;
}
void* Stack_peekAt(Stack* this, int n) {
StackItem* at = this->head;
for (int i = 0; i < n; i++) {
if (at)
at = at->next;
}
if (!at) {
return NULL;
}
return at->data;
}