update
[cgds.git] / src / Stack.h
CommitLineData
a7868768
BA
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 */
16typedef 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 */
24typedef 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 */
33void _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 */
41Stack* _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 */
57Stack* stack_copy(
58 Stack* stack ///< "this" pointer.
59);
60
61/**
62 * @brief Check if the stack is empty.
63 */
64Bool stack_empty(
65 Stack* stack ///< "this" pointer.
66);
67
68/**
69 * @brief Return size of the current stack.
70 */
71UInt stack_size(
72 Stack* stack ///< "this" pointer.
73);
74
75/**
76 * @brief Add something on top of the stack.
77 */
78void _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 */
99void* _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 */
119void stack_pop(
120 Stack* stack ///< "this" pointer.
121);
122
123/**
124 * @brief Clear the entire stack.
125 */
126void stack_clear(
127 Stack* stack ///< "this" pointer.
128);
129
130/**
131 * @brief Destroy the stack: clear it, and free 'stack' pointer.
132 */
133void stack_destroy(
134 Stack* stack ///< "this" pointer.
135);
136
137#endif