rlib
Convenience library for useful things
Loading...
Searching...
No Matches
rmacros.h
Go to the documentation of this file.
1/* RLIB - Convenience library for useful things
2 * Copyright (C) 2015-2016 Haakon Sporsheim <haakon.sporsheim@gmail.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 3.0 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library.
16 * See the COPYING file at the root of the source repository.
17 */
18#ifndef __R_MACROS_H__
19#define __R_MACROS_H__
20
21#if !defined(__RLIB_H_INCLUDE_GUARD__) && !defined(RLIB_COMPILATION)
22#error "#include <rlib.h> only please."
23#endif
24
47#if defined(__GNUC__) && __GNUC__ < 4
48#error Please use a modern GNU compatible compiler
49#endif
50
51#include <stddef.h>
52
54#ifdef __GNUC__
55#define R_GNUC_PREREQ(x, y) \
56 ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || (__GNUC__ > (x)))
57#else
58#define R_GNUC_PREREQ(x, y) 0
59#endif
60
71#if defined(_MSC_VER)
73#define R_CC_MSVC 1
74#endif
75#if defined(__MINGW32__) /* also set under __MINGW64__ */
77#define R_CC_MINGW 1
78#endif
79#if defined(__clang__)
81#define R_CC_CLANG 1
82#endif
83#if defined(__GNUC__)
85#define R_CC_GNUC 1
86#endif
91#if defined(_WIN32) || defined(__CYGWIN__)
93#define R_API_EXPORT __declspec(dllexport)
95#define R_API_IMPORT __declspec(dllimport)
97#define R_API_HIDDEN
98#elif defined(__GNUC__)
99#define R_API_EXPORT __attribute__ ((visibility ("default")))
100#define R_API_IMPORT __attribute__ ((visibility ("default")))
101#define R_API_HIDDEN __attribute__ ((visibility ("hidden")))
102#else
103#define R_API_EXPORT
104#define R_API_IMPORT
105#define R_API_HIDDEN
106#endif
107
112#if defined(RLIB_COMPILATION)
113#define R_API R_API_EXPORT
114#else
115#define R_API R_API_IMPORT
116#endif
122#ifndef NULL
123#ifdef __cplusplus
124#define NULL (0L)
125#else
126#define NULL ((void*) 0)
127#endif
128#endif
129
131#ifndef FALSE
132#define FALSE (0)
133#endif
135#ifndef TRUE
136#define TRUE (!FALSE)
137#endif
140#undef MAX
141#undef MIN
142#undef ABS
143#undef CLAMP
144
151#define MAX(a, b) (((a) > (b)) ? (a) : (b))
153#define MIN(a, b) (((a) < (b)) ? (a) : (b))
155#define ABS(a) (((a) < 0) ? -(a) : (a))
157#define CLAMP(x, l, h) (((x) > (h)) ? (h) : (((x) < (l)) ? (l) : (x)))
158
160#define R_N_ELEMENTS(a) (sizeof (a) / sizeof ((a)[0]))
166#define R_STRINGIFY_ARG(str) #str
168#define R_STRINGIFY(str) R_STRINGIFY_ARG (str)
170#define R_PASTE_ARGS(a1, a2) a1 ## a2
172#define R_PASTE(a1, a2) R_PASTE_ARGS (a1, a2)
173
175#define R_STRLOC __FILE__ ":" R_STRINGIFY (__LINE__)
177#if defined (__GNUC__) && defined (__cplusplus)
178#define R_STRFUNC ((const char*) (__PRETTY_FUNCTION__))
179#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
180#define R_STRFUNC ((const char*) (__func__))
181#elif defined (__GNUC__) || defined(_MSC_VER)
182#define R_STRFUNC ((const char*) (__FUNCTION__))
183#else
184#define R_STRFUNC ((const char*) ("???"))
185#endif
191#ifdef __cplusplus
192#define R_BEGIN_DECLS extern "C" {
194#define R_END_DECLS }
195#else
196#define R_BEGIN_DECLS
197#define R_END_DECLS
198#endif
199
201#define R_STMT_START do
203#ifndef _MSC_VER
204#define R_STMT_END while (0)
205#else
206#define R_STMT_END \
207 __pragma(warning(push)) \
208 __pragma(warning(disable:4127)) \
209 while(0) \
210 __pragma(warning(pop))
211#endif
216#if defined(__GNUC__)
218#define R_INITIALIZER(f) static void __attribute__((constructor)) f (void)
220#define R_DEINITIALIZER(f) static void __attribute__((destructor)) f (void)
221#elif defined(_MSC_VER)
222#define R_INITIALIZER(f) \
223 static void __cdecl f (void); \
224 __pragma(section(".CRT$XCU",read)) \
225 __declspec(allocate(".CRT$XCU")) void (__cdecl*f##_)(void) = f; \
226 static void __cdecl f (void)
227#define R_DEINITIALIZER(f) \
228 static void __cdecl f (void); \
229 static void __cdecl f##_atexit (void) { atexit (f); } \
230 __pragma(section(".CRT$XCU",read)) \
231 __declspec(allocate(".CRT$XCU")) void (__cdecl*f##_)(void) = f##_atexit; \
232 static void __cdecl f (void)
233#else
234#error Your compiler does not support initializers/deinitializers
235#endif
236
238#if defined(__GNUC__) && defined(__OPTIMIZE__)
239#define R_LIKELY(expr) __builtin_expect(!!(expr), 1)
241#define R_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
242#else
243#define R_LIKELY(expr) (expr)
244#define R_UNLIKELY(expr) (expr)
245#endif
253#if defined(__GNUC__)
254#if __MACH__
256#define R_ATTR_DATA_SECTION(sec) __attribute__((section("__DATA," sec)))
258#define R_ATTR_CODE_SECTION(sec) __attribute__((section("__TEXT," sec)))
259#else
260#define R_ATTR_DATA_SECTION(sec) __attribute__((section(sec)))
261#define R_ATTR_CODE_SECTION(sec) __attribute__((section(sec)))
262#endif
263#elif defined(_MSC_VER)
264#define R_ATTR_DATA_SECTION(sec) \
265 __pragma(section(sec,read,write)) \
266 __declspec(allocate(sec))
267#define R_ATTR_CODE_SECTION(sec) __declspec(code_seg(sec))
268#else
269#error Your compiler does not support data/code/text section attributes
270#endif
271
273#if defined(__GNUC__)
274#define R_ATTR_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
275#elif defined(_MSC_VER) && (_MSC_VER >= 1700)
276#define R_ATTR_WARN_UNUSED_RESULT _Check_return_
277#else
278#define R_ATTR_WARN_UNUSED_RESULT
279#endif
280
282#if defined(__GNUC__)
283#define R_ATTR_NORETURN __attribute__((__noreturn__))
285#define R_ATTR_WEAK __attribute__((weak))
287#define R_ATTR_ALIGN(a) __attribute__((aligned(a)))
288#elif defined(_MSC_VER)
289#define R_ATTR_NORETURN __declspec(noreturn)
290#define R_ATTR_WEAK __declspec(selectany)
291#define R_ATTR_ALIGN(a) __declspec(align(a))
292#else
293#define R_ATTR_NORETURN
294#define R_ATTR_WEAK
295#define R_ATTR_ALIGN(a)
296#endif
297
299#if defined(__clang__) || R_GNUC_PREREQ(7, 0)
300#define R_ATTR_FALLTHROUGH __attribute__((fallthrough))
301#else
302#define R_ATTR_FALLTHROUGH ((void)0)
303#endif
304
306#if defined(__GNUC__)
307#define R_ATTR_NULL_TERMINATED __attribute__((__sentinel__))
309#define R_ATTR_UNUSED __attribute__((__unused__))
311#define R_ATTR_CONST __attribute__((__const__))
313#define R_ATTR_PURE __attribute__((__pure__))
315#define R_ATTR_MALLOC __attribute__((__malloc__))
317#define R_ATTR_FORMAT_ARG(arg_idx) __attribute__((__format_arg__ (arg_idx)))
318/* On mingw the default __printf__/__scanf__ archetypes map to the MS C
319 * runtime checker, which rejects the C99 hh/ll length modifiers our format
320 * macros emit. The gnu_printf/gnu_scanf archetypes check against the C99
321 * conversions; pair with __USE_MINGW_ANSI_STDIO so the linked runtime agrees. */
322#if defined(R_CC_MINGW)
323#define R_PRINTF_ARCHETYPE __gnu_printf__
324#define R_SCANF_ARCHETYPE __gnu_scanf__
325#else
326#define R_PRINTF_ARCHETYPE __printf__
327#define R_SCANF_ARCHETYPE __scanf__
328#endif
330#define R_ATTR_PRINTF(fmt_idx, arg_idx) \
331 __attribute__((__format__ (R_PRINTF_ARCHETYPE, fmt_idx, arg_idx)))
333#define R_ATTR_SCANF(fmt_idx, arg_idx) \
334 __attribute__((__format__ (R_SCANF_ARCHETYPE, fmt_idx, arg_idx)))
335#else
336#define R_ATTR_NULL_TERMINATED
337#define R_ATTR_UNUSED
338#define R_ATTR_CONST
339#define R_ATTR_PURE
340#define R_ATTR_MALLOC
341#define R_ATTR_FORMAT_ARG(arg_idx)
342#define R_ATTR_PRINTF(fmt_idx, arg_idx)
343#define R_ATTR_SCANF(fmt_idx, arg_idx)
344#endif
345
347#if defined(__clang__)
348#define R_ATTR_RESTRICT __restrict__
349#elif defined(__GNUC__)
350#define R_ATTR_RESTRICT __restrict__
351#elif defined(_MSC_VER)
352#define R_ATTR_RESTRICT __restrict
353#else
354#define R_ATTR_RESTRICT
355#endif
361#ifndef __has_feature
362#define __has_feature(x) 0
363#endif
364#ifndef __has_builtin
365#define __has_builtin(x) 0
366#endif
367#ifndef __has_extension
368#define __has_extension __has_feature
369#endif
370
371#if (defined(__clang__) && __has_feature(__alloc_size__)) || \
372 (!defined(__clang__) && R_GNUC_PREREQ(4, 3))
374#define R_ATTR_ALLOC_SIZE_ARG(x) __attribute__((__alloc_size__(x)))
376#define R_ATTR_ALLOC_SIZE_ARGS(x,y) __attribute__((__alloc_size__(x,y)))
377#else
378#define R_ATTR_ALLOC_SIZE_ARG(x)
379#define R_ATTR_ALLOC_SIZE_ARGS(x,y)
380#endif
/* r_macros */
384
385#endif /* __R_MACROS_H__ */