Startle
Useful and efficient algorithms and facilities
macros.h
Go to the documentation of this file.
1 /* Copyright 2012-2018 Dustin M. DeWeese
2 
3  This file is part of the Startle library.
4 
5  Licensed under the Apache License, Version 2.0 (the "License");
6  you may not use this file except in compliance with the License.
7  You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11  Unless required by applicable law or agreed to in writing, software
12  distributed under the License is distributed on an "AS IS" BASIS,
13  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  See the License for the specific language governing permissions and
15  limitations under the License.
16 */
17 
18 #ifndef __STARTLE_MACROS__
19 #define __STARTLE_MACROS__
20 
21 #include "startle/dispatch.h"
22 
27 // MAKE COMPILERS HAPPY ________________________________________
28 
29 #ifdef __clang__
30 #pragma clang diagnostic ignored "-Wgnu-statement-expression"
31 #endif
32 
33 
34 
35 // MACRO UTILITIES ________________________________________
36 
38 #define _CONCAT(x, y) x##y
39 #define CONCAT(x, y) _CONCAT(x, y)
40 
41 #define _CONCAT_UNDERSCORE(x, y) x##_##y
42 #define CONCAT_UNDERSCORE(x, y) _CONCAT_UNDERSCORE(x, y)
43 
45 #define UNIQUE CONCAT(__unique_, __LINE__)
46 
48 #define _STRINGIFY(x) #x
49 #define STRINGIFY(x) _STRINGIFY(x)
50 
51 
52 
53 // SIZES & OFFSETS ________________________________________
54 
56 #define sizeof_field(s, f) sizeof(((s *)0)->f)
57 
59 #if !defined(offsetof)
60 #define offsetof(s, f) ((uintptr_t)&(((s *)0)->f))
61 #endif
62 
64 #define WIDTH(a) (sizeof((a)[0]))
65 
67 #define LENGTH(a) (sizeof(a) / WIDTH(a))
68 
69 
70 
71 // ITERATION MACROS ________________________________________
72 
74 #define RANGEUP(i, lower, upper) for(size_t i = (lower), __upper = (upper); i < __upper; i++)
75 
77 #define RANGEDOWN(i, lower, upper) for(size_t i = (upper), __lower = (lower); i-- > __lower; )
78 
82 #define COUNTDOWN(i, n) RANGEDOWN(i, 0, n)
83 
85 #define COUNTUP(i, n) RANGEUP(i, 0, n)
86 
88 #define LOOP(n) COUNTDOWN(UNIQUE, n)
89 
91 #define FOREACH(i, a) COUNTUP(i, LENGTH(a))
92 
94 #define FORMAP(i, m) for(size_t i = 1; i <= *map_cnt(m); i++)
95 
96 // DATA STRUCTURES ________________________________________
97 
99 #define BITSET(name, size) uint8_t name[((size)+7)/8] = {0}
100 
102 #define BITSET_INDEX(name, array) BITSET(name, LENGTH(array))
103 
104 #if !defined(static_assert)
105 #define static_assert(expr, msg) _Static_assert(expr, msg)
106 #endif
107 
111 #define SEG(x) {(x), sizeof(x) - 1}
112 
118 #define printseg(pre, seg, fmt, ...) \
119  do { \
120  seg_t __seg = seg; \
121  printf(pre "%.*s" fmt, (int)__seg.n, __seg.s , ##__VA_ARGS__); \
122  } while(0)
123 
124 // building embedded lists
125 
131 #define LIST_ADD(f, l, v) \
132  ({ \
133  __typeof__(v) __v = (v); \
134  *(l) = __v; \
135  (l) = &__v->f; \
136  })
137 
143 #define CONS(f, l, v) \
144  ({ \
145  __typeof__(l) __l = (l); \
146  __typeof__(v) __v = (v); \
147  __v->f = *__l; \
148  *__l = __v; \
149  })
150 
151 
152 
153 // MATH ________________________________________
154 
155 #define min(a, b) \
156  ({ \
157  __typeof__(a) __a = (a); \
158  __typeof__(b) __b = (b); \
159  __a <= __b ? __a : __b; \
160  })
161 
162 #define max(a, b) \
163  ({ \
164  __typeof__(a) __a = (a); \
165  __typeof__(b) __b = (b); \
166  __a >= __b ? __a : __b; \
167  })
168 
170 #define csub(a, b) \
171  ({ \
172  __typeof__(a) _a = (a); \
173  __typeof__(b) _b = (b); \
174  _b > _a ? 0 : _a - _b; \
175  })
176 
177 
178 // UM... OTHER STUFF ________________________________________
179 
181 #define zero(a) memset(&(a), 0, sizeof(a))
182 
186 #define show(x) printf(#x " = %d\n", (int)(x))
187 
189 #define FLAG(s, flag) (((s).flags & (flag)) != 0)
190 
192 #define NOT_FLAG(s, flag) (((s).flags & (flag)) == 0)
193 
194 #define FLAG_SET(s, flag) ((s).flags |= (flag))
195 #define FLAG_CLEAR(s, flag) ((s).flags &= ~(flag))
196 #define FLAG_SET_TO(s, flag, val) ((val) ? FLAG_SET(s, flag) : FLAG_CLEAR(s, flag))
197 
199 #define ARRAY_SHIFTR(array, offset, length) memmove(&(array) + (offset), &(array), (length) * sizeof(array))
200 
202 #define ARRAY_SHIFTL(array, offset, length) memmove(&(array), &(array) + (offset), (length) * sizeof(array))
203 
204 #define ARRAY_COPY(dst, src, length) memcpy(&(dst), &(src), (length) * sizeof(dst))
205 
206 #if !defined(EMSCRIPTEN)
207 #define COLOR(c, str) "\x1b[" CONCAT(COLOR_, c) "m" str "\x1b[0m"
208 #define COLORs(str) "\x1b[%sm" str "\x1b[0m"
209 #define COLOR_red "37;41"
210 #define COLOR_blue "37;44"
211 #define COLOR_gray "38;5;8"
212 #define COLOR_normal "0"
213 #else
214 #define COLOR(c, str) "[[;" CONCAT(COLOR_, c) ";]" str "]"
215 #define COLORs(str) "[[;%s;]" str "]"
216 #define COLOR_red "#fff;#f00"
217 #define COLOR_blue "#fff;#00f"
218 #define COLOR_gray "#999;#000"
219 #define COLOR_normal ";"
220 #endif
221 
222 #define MARK(x) COLOR(red, x)
223 #define NOTE(x) COLOR(blue, x)
224 #define FADE(x) COLOR(gray, x)
225 #define TODO MARK("TODO")
226 #define HACK MARK("HACK")
227 
228 #define DISABLE(...) \
229  do { \
230  LOG(MARK("DISABLED") " %s", __func__); \
231  return __VA_ARGS__; \
232  } while(0) \
233 
234 
237 #define unlikely(c) (__builtin_expect((c), 0))
238 
242 #define likely(c) (__builtin_expect((c), 1))
243 
245 #define TEST(name) int test_##name()
246 
248 #define FORMAT(name, c) void format_##name(intptr_t i)
249 
250 #endif
Function dispatch for variable arguments.