1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
|
/** @file
*
* Miscellaneous macros.
*/
#ifndef GU_DEFS_H_
#define GU_DEFS_H_
// MSVC requires explicit export/import of
// symbols in DLLs. CMake takes care of this
// for functions, but not for data/variables.
#if defined(_MSC_VER)
#if defined(COMPILING_GU)
#define GU_API_DECL __declspec(dllexport)
#define GU_API __declspec(dllexport)
#else
#define GU_API_DECL __declspec(dllimport)
#define GU_API ERROR_NOT_COMPILING_LIBGU
#endif
#define GU_INTERNAL_DECL
#define GU_INTERNAL
#define restrict __restrict
#else
#define GU_API_DECL
#define GU_API
#define GU_INTERNAL_DECL __attribute__ ((visibility ("hidden")))
#define GU_INTERNAL __attribute__ ((visibility ("hidden")))
#endif
// end MSVC workaround
#include <stddef.h>
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <limits.h>
#include <stdarg.h>
#include <gu/sysdeps.h>
#define gu_container(mem_p, container_type, member) \
((container_type*)(((uint8_t*) (mem_p)) - offsetof(container_type, member)))
/**< Find the address of a containing structure.
*
* If @c s has type @c t*, where @c t is a struct or union type with a
* member @m, then <tt>GU_CONTAINER_P(&s->m, t, m) == s</tt>.
*
* @param mem_p Pointer to the member of a structure.
* @param container_type The type of the containing structure.
* @param member The name of the member of @a container_type
* @return The address of the containing structure.
*
* @hideinitializer */
#define gu_member_p(struct_p_, offset_) \
((void*)&((uint8_t*)(struct_p_))[offset_])
#define gu_member(t_, struct_p_, offset_) \
(*(t_*)gu_member_p(struct_p_, offset_))
#ifdef GU_ALIGNOF
# define gu_alignof GU_ALIGNOF
#else
# define gu_alignof(t_) \
((size_t)(offsetof(struct { char c_; t_ e_; }, e_)))
#endif
#define GU_PLIT(type, expr) \
((type[1]){ expr })
#define GU_LVALUE(type, expr) \
(*((type[1]){ expr }))
#define GU_COMMA ,
#define GU_ARRAY_LEN(t,a) (sizeof((const t[])a) / sizeof(t))
#define GU_ID(...) __VA_ARGS__
// This trick is by Laurent Deniau <laurent.deniau@cern.ch>
#define GU_N_ARGS(...) \
GU_N_ARGS_(__VA_ARGS__, \
31,30,29,28,27,26,25,24, \
23,22,21,20,19,18,17,16, \
15,14,13,12,11,10,9,8, \
7,6,5,4,3,2,1,0)
#define GU_N_ARGS_(...) GU_N_ARGS__(__VA_ARGS__)
#define GU_N_ARGS__(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p, \
q,r,s,t,u,v,w,x,y,z,aa,ab,ac,ad,ae,N,...) \
N
#define GU_ARG1(a1, ...) a1
#define GU_ARG2(a1, a2, ...) a2
#define GU_BEGIN do {
#define GU_END } while (false)
#define GU_NOP GU_BEGIN (void) 0; GU_END
/**< @hideinitializer */
//
// Assert
//
#define GU_MAX(a_, b_) ((a_) > (b_) ? (a_) : (b_))
#define GU_MIN(a_, b_) ((a_) < (b_) ? (a_) : (b_))
static inline int
gu_max(int a, int b) {
return GU_MAX(a, b);
}
static inline int
gu_min(int a, int b) {
return GU_MIN(a, b);
}
#ifdef GU_ALIGNOF
#define gu_flex_alignof gu_alignof
#else
#define gu_flex_alignof(t) 0
#endif
static inline size_t
gu_flex_size(size_t ssize, size_t offset, int n_elems, size_t e_size)
{
return GU_MAX(ssize, offset + n_elems * e_size);
}
#define GU_FLEX_SIZE(type, flex_member, n_elems) \
gu_flex_size(sizeof(type), offsetof(type, flex_member), \
n_elems, sizeof(((type*)NULL)->flex_member[0]))
// The following are directly from gmacros.h in GLib
#define GU_PASTE_ARGS(id1_,id2_) \
id1_ ## id2_
#define GU_PASTE(id1_, id2_) \
GU_PASTE_ARGS(id1_, id2_)
#define GU_STATIC_ASSERT(expr_) \
typedef struct { \
char static_assert[(expr_) ? 1 : -1]; \
} GU_PASTE(GuStaticAssert_, __LINE__)
#define GU_ENSURE_TYPE(T, EXPR) \
((void)(sizeof(*(T*)NULL=(EXPR))),(EXPR))
#define GU_END_DECLS \
extern void gu_dummy_(void)
extern void* const gu_null;
// Dummy struct used for generic struct pointers
typedef struct GuStruct GuStruct;
GU_API_DECL extern GuStruct* const gu_null_struct;
typedef uintptr_t GuWord;
#define GU_WORD_MAX UINTPTR_MAX
// TODO: use max_align_t once C1X is supported
typedef union {
char c;
short s;
int i;
long l;
long long ll;
intmax_t im;
float f;
double d;
long double ld;
void* p;
void (*fp)();
} GuMaxAlign;
#define gu_alloca(N) \
(((union { GuMaxAlign align_; uint8_t buf_[N]; }){{0}}).buf_)
// For Doxygen
#define GU_PRIVATE /** @private */
#ifdef GU_GNUC
# define GU_LIKELY(EXPR) __builtin_expect(EXPR, 1)
# define GU_UNLIKELY(EXPR) __builtin_expect(EXPR, 0)
# define GU_IS_CONSTANT(EXPR) __builtin_constant_p(EXPR)
#else
# define GU_LIKELY(EXPR) (EXPR)
# define GU_UNLIKELY(EXPR) (EXPR)
# ifdef GU_OPTIMIZE_SIZE
# define GU_IS_CONSTANT(EXPR) false
# else
# define GU_IS_CONSTANT(EXPR) true
# endif
#endif
// Splint annotations
#define GU_ONLY GU_SPLINT(only)
#define GU_NULL GU_SPLINT(null)
#define GU_NOTNULL GU_SPLINT(notnull)
#define GU_RETURNED GU_SPLINT(returned)
#define GU_ABSTRACT GU_SPLINT(abstract)
#define GU_IMMUTABLE GU_SPLINT(immutable)
#define GU_NOTREACHED GU_SPLINT(notreached)
#define GU_UNUSED GU_SPLINT(unused) GU_GNUC_ATTR(unused)
#define GU_OUT GU_SPLINT(out)
#define GU_IN GU_SPLINT(in)
#define GU_NORETURN GU_SPLINT(noreturn) GU_GNUC_ATTR(noreturn)
#define GU_MODIFIES(x) GU_SPLINT(modifies x)
#endif // GU_DEFS_H_
|