]> gerrit.simantics Code Review - simantics/fmil.git/blob - org.simantics.fmil/native/FMUSimulator/include/FMIL/Util/JM/jm_stack.h
Mavenized FMIL projects.
[simantics/fmil.git] / org.simantics.fmil / native / FMUSimulator / include / FMIL / Util / JM / jm_stack.h
1 /*
2     Copyright (C) 2012 Modelon AB
3
4     This program is free software: you can redistribute it and/or modify
5     it under the terms of the BSD style license.
6
7      This program is distributed in the hope that it will be useful,
8     but WITHOUT ANY WARRANTY; without even the implied warranty of
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10     FMILIB_License.txt file for more details.
11
12     You should have received a copy of the FMILIB_License.txt file
13     along with this program. If not, contact Modelon AB <http://www.modelon.com>.
14 */
15
16 #ifndef jm_stack_h_
17 #define jm_stack_h_
18
19 #include "jm_vector.h"
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
24 /** \file jm_named_ptr.h Definition of ::jm_named_ptr and supporting functions
25         *
26         * \addtogroup jm_utils
27         * @{
28         *    \defgroup jm_stack_grp  A basic stack
29         * @}
30         */
31
32         /** \addtogroup jm_stack_grp
33          @{
34         */
35 /** 
36         \brief A basic stack of items.
37         
38         Stack is implemented on top of jm_vector right now. There is a couple of extra methonds that are convenient.
39
40   */
41 #define jm_stack(T) jm_mangle(jm_stack, T)
42
43 /**
44 *  \brief  Allocates a stack with the given reserved memory
45 *  \code
46 *  jm_stack(T)* jm_stack_alloc(T)(size_t capacity,jm_callbacks*c );
47 *  \endcode
48 *  @param capacity - initial stack capacity, can be 0
49 *  @param c - jm_callbacks callbacks, can be zero
50 *  @return Newly allocated stack
51 */
52 #define jm_stack_alloc(T) jm_mangle(jm_stack_alloc, T)
53
54 /** 
55 *  \brief Release memory allocated for a stack.
56 \code
57 extern void jm_stack_free(T)(jm_stack(T)* a); 
58 \endcode
59 */
60 #define jm_stack_free(T) jm_mangle(jm_stack_free, T)
61
62 /**
63 *  \brief Initializes a #jm_stack allocated on stack.
64 *  \param a - pointer to the stack to be initialized;
65 *  \param c - ::jm_callbacks callbacks, can be zero
66 *
67 *  \code
68 void jm_stack_init(T)(jm_stack(T)* a, jm_callbacks* c)
69   \endcode
70 */
71 #define jm_stack_init(T) jm_mangle(jm_stack_init, T)
72
73 /**
74 *  \brief  Releases memory allocated for stack data.
75 *
76 *  This only needs to be called both for stack allocated #jm_stack structs.
77 *\code
78 inline void jm_stack_free_data(T)(jm_stack(T)* a)
79 \endcode
80 *\param a - pointer to the stack.
81 *
82 */
83 #define jm_stack_free_data(T) jm_mangle(jm_stack_free_data, T)
84
85 /**
86 \brief  Get the number of elements in the stack.
87
88 \code
89 inline size_t jm_stack_get_size(T)(jm_stack(T)* a)
90 \endcode
91 */
92 #define jm_stack_get_size(T) jm_mangle(jm_stack_get_size, T)
93
94 /**
95 *  \brief Preallocate memory for the stack (to speed up consequent push).
96 *
97 *  \return The actually reserved space. Can be smaller than "capacity" if memory allocation failed.
98 *  Can be larger than "capacity" if more memory was previously allocated.
99 *  size_t jm_stack_reserve(T)(jm_stack(T)* a, size_t capacity)
100 */
101 #define jm_stack_reserve(T) jm_mangle(jm_stack_reserve, T)
102
103 /**
104 *  \brief Put an element on the stack.
105 *  \return A pointer to the inserted element or zero pointer if failed.
106 *
107 \code
108 T* jm_stack_push_back(jm_stack(T)* a, T item);
109 \endcode
110 */
111 #define jm_stack_push(T) jm_mangle(jm_stack_push, T)
112
113 /**
114   jm_stack_is_empty returns 1 if the stack is empty and 0 otherwize.
115   int jm_stack_is_empty(jm_stack(T)*)
116   */
117 #define jm_stack_is_empty(T) jm_mangle(jm_stack_is_empty, T)
118
119 /**
120 *  jm_stack_pop gets the stack head and moves to the next element. Popping an empty stack gives assertion failure.
121 *  T jm_stack_pop(jm_stack(T)* a)
122 */
123 #define jm_stack_pop(T) jm_mangle(jm_stack_pop, T)
124
125 /**
126 *  jm_stack_top gets the stack top. Call on an empty stack gives assertion failure.
127 *  T jm_stack_top(jm_stack(T)* a)
128 */
129 #define jm_stack_top(T) jm_mangle(jm_stack_top, T)
130
131 /**
132 *  jm_stack_foreach calls f for each element in the stack. "data" parameter
133 *  is forwarded to the function as the second argument.
134 *  void jm_stack_foreach(T)(jm_stack(T)* a, void (*f)(T, void*), void * data)
135 */
136 #define jm_stack_foreach(T) jm_mangle(jm_stack_foreach, T)
137
138
139 /** minimal number of items always allocated for the stack */
140 #define JM_STACK_MINIMAL_CAPACITY JM_VECTOR_MINIMAL_CAPACITY
141
142 /** maximum memory chunk (in items) to be allocated in push. */
143 #define JM_STACK_MAX_MEMORY_CHUNK JM_VECTOR_MAX_MEMORY_CHUNK
144
145 /** Declare stack for the specific type. */
146 #define jm_stack_declare_template(T)            \
147 typedef jm_vector(T) jm_stack(T);                                       \
148  \
149 static jm_stack(T)* jm_stack_alloc(T)(size_t capacity,jm_callbacks* c) { return jm_vector_alloc(T)(0, capacity, c); }   \
150     \
151 static void jm_stack_free(T)(jm_stack(T) * a) { jm_vector_free(T)(a); } \
152     \
153 static void jm_stack_init(T)(jm_stack(T)* a, jm_callbacks* c) { jm_vector_init(T)(a,0,c); }     \
154 \
155 static void jm_stack_free_data(T)(jm_stack(T)* a) { jm_vector_free_data(T)(a); } \
156 \
157 static size_t jm_stack_get_size(T)(jm_stack(T)* a) { return jm_vector_get_size(T)(a); } \
158 \
159 static size_t jm_stack_reserve(T)(jm_stack(T)* a, size_t capacity) { return jm_vector_reserve(T)(a, capacity);  } \
160     \
161 static T* jm_stack_push(T)(jm_stack(T)* a, T item) { return jm_vector_push_back(T)(a, item); }\
162     \
163 static int jm_stack_is_empty(T)(jm_stack(T)* a) { return ((jm_stack_get_size(T)(a) > 0)? 0:1); } \
164     \
165 static T jm_stack_top(T)(jm_stack(T)* a) { \
166     assert(!jm_stack_is_empty(T)(a)); \
167     return jm_vector_get_item(T)(a,jm_vector_get_size(T)(a)-1) ; \
168 } \
169             \
170 static T jm_stack_pop(T)(jm_stack(T)* a) { \
171     T ret; \
172     ret = jm_stack_top(T)(a); \
173     jm_vector_resize(T)(a, jm_vector_get_size(T)(a) - 1); \
174     return ret; \
175 } \
176 \
177 static void jm_stack_foreach(T)(jm_stack(T)* a, void (*f)(T, void*), void * data) { jm_vector_foreach_c(T)(a,f,data); }
178
179 /** @} */
180
181 jm_stack_declare_template(char)
182 jm_stack_declare_template(int)
183 jm_stack_declare_template(double)
184 jm_stack_declare_template(jm_voidp)
185 jm_stack_declare_template(size_t)
186 jm_stack_declare_template(jm_string)
187
188 #ifdef __cplusplus
189 }
190 #endif
191
192 #endif