Blender  V2.93
BLI_linklist_stack.h
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
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  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
20 #pragma once
21 
34 /* -------------------------------------------------------------------- */
40 #define BLI_LINKSTACK_DECLARE(var, type) \
41  LinkNode *var; \
42  BLI_mempool *var##_pool_; \
43  type var##_type_
44 
45 #define BLI_LINKSTACK_INIT(var) \
46  { \
47  var = NULL; \
48  var##_pool_ = BLI_mempool_create(sizeof(LinkNode), 0, 64, BLI_MEMPOOL_NOP); \
49  } \
50  (void)0
51 
52 #define BLI_LINKSTACK_SIZE(var) BLI_mempool_len(var##_pool_)
53 
54 /* check for typeof() */
55 #ifdef __GNUC__
56 # define BLI_LINKSTACK_PUSH(var, ptr) \
57  (CHECK_TYPE_INLINE(ptr, typeof(var##_type_)), \
58  BLI_linklist_prepend_pool(&(var), ptr, var##_pool_))
59 # define BLI_LINKSTACK_POP(var) \
60  (var ? (typeof(var##_type_))BLI_linklist_pop_pool(&(var), var##_pool_) : NULL)
61 # define BLI_LINKSTACK_POP_DEFAULT(var, r) \
62  (var ? (typeof(var##_type_))BLI_linklist_pop_pool(&(var), var##_pool_) : r)
63 #else /* non gcc */
64 # define BLI_LINKSTACK_PUSH(var, ptr) (BLI_linklist_prepend_pool(&(var), ptr, var##_pool_))
65 # define BLI_LINKSTACK_POP(var) (var ? BLI_linklist_pop_pool(&(var), var##_pool_) : NULL)
66 # define BLI_LINKSTACK_POP_DEFAULT(var, r) (var ? BLI_linklist_pop_pool(&(var), var##_pool_) : r)
67 #endif /* gcc check */
68 
69 #define BLI_LINKSTACK_SWAP(var_a, var_b) \
70  { \
71  CHECK_TYPE_PAIR(var_a##_type_, var_b##_type_); \
72  SWAP(LinkNode *, var_a, var_b); \
73  SWAP(BLI_mempool *, var_a##_pool_, var_b##_pool_); \
74  } \
75  (void)0
76 
77 #define BLI_LINKSTACK_FREE(var) \
78  { \
79  BLI_mempool_destroy(var##_pool_); \
80  var##_pool_ = NULL; \
81  (void)var##_pool_; \
82  var = NULL; \
83  (void)var; \
84  (void)&(var##_type_); \
85  } \
86  (void)0
87 
88 #include "BLI_linklist.h"
89 #include "BLI_mempool.h"
90 
93 /* -------------------------------------------------------------------- */
102 #ifdef __GNUC__
103 # define _BLI_SMALLSTACK_CAST(var) (typeof(_##var##_type))
104 #else
105 # define _BLI_SMALLSTACK_CAST(var)
106 #endif
107 
108 #define _BLI_SMALLSTACK_FAKEUSER(var) (void)(&(_##var##_type))
109 
110 #define BLI_SMALLSTACK_DECLARE(var, type) \
111  LinkNode *_##var##_stack = NULL, *_##var##_free = NULL, *_##var##_temp = NULL; \
112  type _##var##_type
113 
114 #define BLI_SMALLSTACK_PUSH(var, data) \
115  { \
116  CHECK_TYPE_PAIR(data, _##var##_type); \
117  if (_##var##_free) { \
118  _##var##_temp = _##var##_free; \
119  _##var##_free = _##var##_free->next; \
120  } \
121  else { \
122  _##var##_temp = alloca(sizeof(LinkNode)); \
123  } \
124  _##var##_temp->next = _##var##_stack; \
125  _##var##_temp->link = data; \
126  _##var##_stack = _##var##_temp; \
127  _BLI_SMALLSTACK_FAKEUSER(var); \
128  } \
129  (void)0
130 
131 /* internal use, no null check */
132 #define _BLI_SMALLSTACK_DEL_EX(var_src, var_dst) \
133  (void)(_BLI_SMALLSTACK_FAKEUSER(var_src), \
134  _BLI_SMALLSTACK_FAKEUSER(var_dst), \
135  (_##var_src##_temp = _##var_src##_stack->next), \
136  (_##var_src##_stack->next = _##var_dst##_free), \
137  (_##var_dst##_free = _##var_src##_stack), \
138  (_##var_src##_stack = _##var_src##_temp))
139 
140 #define _BLI_SMALLSTACK_DEL(var) _BLI_SMALLSTACK_DEL_EX(var, var)
141 
142 /* check for typeof() */
143 #define BLI_SMALLSTACK_POP(var) \
144  (_BLI_SMALLSTACK_CAST(var)( \
145  (_##var##_stack) ? (_BLI_SMALLSTACK_DEL(var), (_##var##_free->link)) : NULL))
146 
147 /* support to put the free-node into another stack */
148 #define BLI_SMALLSTACK_POP_EX(var_src, var_dst) \
149  (_BLI_SMALLSTACK_CAST(var_src)( \
150  (_##var_src##_stack) ? \
151  (_BLI_SMALLSTACK_DEL_EX(var_src, var_dst), (_##var_dst##_free->link)) : \
152  NULL))
153 
154 #define BLI_SMALLSTACK_PEEK(var) \
155  (_BLI_SMALLSTACK_CAST(var)((_##var##_stack) ? _##var##_stack->link : NULL))
156 
157 #define BLI_SMALLSTACK_IS_EMPTY(var) ((_BLI_SMALLSTACK_CAST(var) _##var##_stack) == NULL)
158 
159 /* fill in a lookup table */
160 #define BLI_SMALLSTACK_AS_TABLE(var, data) \
161  { \
162  LinkNode *_##var##_iter; \
163  unsigned int i; \
164  for (_##var##_iter = _##var##_stack, i = 0; _##var##_iter; \
165  _##var##_iter = _##var##_iter->next, i++) { \
166  (data)[i] = _BLI_SMALLSTACK_CAST(var)(_##var##_iter->link); \
167  } \
168  } \
169  ((void)0)
170 
171 /* loop over stack members last-added-first */
172 #define BLI_SMALLSTACK_ITER_BEGIN(var, item) \
173  { \
174  LinkNode *_##var##_iter; \
175  for (_##var##_iter = _##var##_stack; _##var##_iter; _##var##_iter = _##var##_iter->next) { \
176  item = _BLI_SMALLSTACK_CAST(var)(_##var##_iter->link);
177 
178 #define BLI_SMALLSTACK_ITER_END \
179  } \
180  } \
181  (void)0
182 
183 #define BLI_SMALLSTACK_SWAP(var_a, var_b) \
184  { \
185  CHECK_TYPE_PAIR(_##var_a##_type, _##var_b##_type); \
186  SWAP(LinkNode *, _##var_a##_stack, _##var_b##_stack); \
187  SWAP(LinkNode *, _##var_a##_free, _##var_b##_free); \
188  } \
189  (void)0
190