Blender  V2.93
BLI_utildefines_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 
17 #pragma once
18 
26 /* only validate array-bounds in debug mode */
27 #ifdef DEBUG
28 # define STACK_DECLARE(stack) unsigned int _##stack##_index, _##stack##_totalloc
29 # define STACK_INIT(stack, tot) \
30  ((void)stack, (void)((_##stack##_index) = 0), (void)((_##stack##_totalloc) = (tot)))
31 # define _STACK_SIZETEST(stack, off) \
32  (BLI_assert((_##stack##_index) + (off) <= _##stack##_totalloc))
33 # define _STACK_SWAP_TOTALLOC(stack_a, stack_b) \
34  SWAP(unsigned int, _##stack_a##_totalloc, _##stack_b##_totalloc)
35 #else
36 # define STACK_DECLARE(stack) unsigned int _##stack##_index
37 # define STACK_INIT(stack, tot) \
38  ((void)stack, (void)((_##stack##_index) = 0), (void)(0 ? (tot) : 0))
39 # define _STACK_SIZETEST(stack, off) (void)(stack), (void)(off)
40 # define _STACK_SWAP_TOTALLOC(stack_a, stack_b) (void)(stack_a), (void)(stack_b)
41 #endif
42 #define _STACK_BOUNDSTEST(stack, index) \
43  ((void)stack, BLI_assert((unsigned int)(index) < _##stack##_index))
44 
45 #define STACK_SIZE(stack) ((void)stack, (_##stack##_index))
46 #define STACK_CLEAR(stack) \
47  { \
48  (void)stack; \
49  _##stack##_index = 0; \
50  } \
51  ((void)0)
53 #define STACK_PUSH(stack, val) \
54  ((void)stack, _STACK_SIZETEST(stack, 1), ((stack)[(_##stack##_index)++] = (val)))
55 #define STACK_PUSH_RET(stack) \
56  ((void)stack, _STACK_SIZETEST(stack, 1), ((stack)[(_##stack##_index)++]))
57 #define STACK_PUSH_RET_PTR(stack) \
58  ((void)stack, _STACK_SIZETEST(stack, 1), &((stack)[(_##stack##_index)++]))
60 #define STACK_POP(stack) ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : NULL)
61 #define STACK_POP_PTR(stack) ((_##stack##_index) ? &((stack)[--(_##stack##_index)]) : NULL)
62 #define STACK_POP_DEFAULT(stack, r) ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : (r))
64 #define STACK_PEEK(stack) (BLI_assert(_##stack##_index), ((stack)[_##stack##_index - 1]))
65 #define STACK_PEEK_PTR(stack) (BLI_assert(_##stack##_index), &((stack)[_##stack##_index - 1]))
67 #define STACK_REMOVE(stack, i) \
68  { \
69  const unsigned int _i = i; \
70  _STACK_BOUNDSTEST(stack, _i); \
71  if (--_##stack##_index != _i) { \
72  stack[_i] = stack[_##stack##_index]; \
73  } \
74  } \
75  ((void)0)
76 #define STACK_DISCARD(stack, n) \
77  { \
78  const unsigned int _n = n; \
79  BLI_assert(_##stack##_index >= _n); \
80  (void)stack; \
81  _##stack##_index -= _n; \
82  } \
83  ((void)0)
84 #ifdef __GNUC__
85 # define STACK_SWAP(stack_a, stack_b) \
86  { \
87  SWAP(typeof(stack_a), stack_a, stack_b); \
88  SWAP(unsigned int, _##stack_a##_index, _##stack_b##_index); \
89  _STACK_SWAP_TOTALLOC(stack_a, stack_b); \
90  } \
91  ((void)0)
92 #else
93 # define STACK_SWAP(stack_a, stack_b) \
94  { \
95  SWAP(void *, stack_a, stack_b); \
96  SWAP(unsigned int, _##stack_a##_index, _##stack_b##_index); \
97  _STACK_SWAP_TOTALLOC(stack_a, stack_b); \
98  } \
99  ((void)0)
100 #endif