initial commit
[cgds.git] / src / Stack.h
1 /**
2 * @file Stack.h
3 */
4
5 #ifndef CGDS_STACK_H
6 #define CGDS_STACK_H
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include "cgds/types.h"
11 #include "cgds/safe_alloc.h"
12
13 /**
14 * @brief Generic internal stack cell.
15 */
16 typedef struct StackCell {
17 void* data; ///< Generic data contained in the cell.
18 struct StackCell* previous; ///< Previous cell in the internal single-linked list.
19 } StackCell;
20
21 /**
22 * @brief Stack containing generic data.
23 */
24 typedef struct Stack {
25 UInt size; ///< Count elements in the stack.
26 size_t dataSize; ///< Size in bytes of a stack element.
27 StackCell* top; ///< Last added element, on top of the stack.
28 } Stack;
29
30 /**
31 * @brief Initialize an empty stack.
32 */
33 void _stack_init(
34 Stack* stack, ///< "this" pointer.
35 size_t dataSize ///< Size in bytes of a stack element.
36 );
37
38 /**
39 * @brief Return an allocated and initialized stack.
40 */
41 Stack* _stack_new(
42 size_t dataSize ///< Size in bytes of a stack element.
43 );
44
45 /**
46 * @brief Return an allocated and initialized stack.
47 * @param type Type of a stack element (int, char*, ...).
48 *
49 * Usage: Stack* stack_new(<Type> type)
50 */
51 #define stack_new(type) \
52 _stack_new(sizeof(type))
53
54 /**
55 * @brief Copy constructor (works well if items do not have allocated sub-pointers).
56 */
57 Stack* stack_copy(
58 Stack* stack ///< "this" pointer.
59 );
60
61 /**
62 * @brief Check if the stack is empty.
63 */
64 Bool stack_empty(
65 Stack* stack ///< "this" pointer.
66 );
67
68 /**
69 * @brief Return size of the current stack.
70 */
71 UInt stack_size(
72 Stack* stack ///< "this" pointer.
73 );
74
75 /**
76 * @brief Add something on top of the stack.
77 */
78 void _stack_push(
79 Stack* stack, ///< "this" pointer.
80 void* data ///< Data to be added.
81 );
82
83 /**
84 * @brief Add something on top of the stack.
85 * @param stack "this" pointer.
86 * @param data Data to be added.
87 *
88 * Usage: void stack_push(Stack* stack, void data)
89 */
90 #define stack_push(stack, data) \
91 { \
92 typeof((data)) tmp = data; \
93 _stack_push(stack,&tmp); \
94 }
95
96 /**
97 * @brief Return what is on top of the stack.
98 */
99 void* _stack_top(
100 Stack* stack ///< "this" pointer.
101 );
102
103 /**
104 * @brief Return what is on top of the stack.
105 * @param stack "this" pointer.
106 * @param data Data to be assigned.
107 *
108 * Usage: void stack_top(Stack* stack, void data)
109 */
110 #define stack_top(stack, data) \
111 { \
112 void* pData = _stack_top(stack); \
113 data = *((typeof(&data))pData); \
114 }
115
116 /**
117 * @brief Remove the top of the stack.
118 */
119 void stack_pop(
120 Stack* stack ///< "this" pointer.
121 );
122
123 /**
124 * @brief Clear the entire stack.
125 */
126 void stack_clear(
127 Stack* stack ///< "this" pointer.
128 );
129
130 /**
131 * @brief Destroy the stack: clear it, and free 'stack' pointer.
132 */
133 void stack_destroy(
134 Stack* stack ///< "this" pointer.
135 );
136
137 #endif