Lely core libraries 2.3.4
features.h
Go to the documentation of this file.
1
22#ifndef LELY_FEATURES_H_
23#define LELY_FEATURES_H_
24
25#if defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L
26#error This file requires compiler and library support for the ISO C99 standard.
27#endif
28
29#if defined(__cplusplus) && __cplusplus < 201103L
30#error This file requires compiler and library support for the ISO C++11 standard.
31#endif
32
33#ifdef _MSC_VER
34#if _MSC_VER < 1900
35#error This file requires Microsoft Visual C++ 2015 or later.
36#endif
37// Disable warnings about deprecated POSIX functions.
38#pragma warning(disable : 4996)
39#endif
40
41#if _WIN32
42// Windows 7 is the minimum supported version.
43#if !defined(NTDDI_VERSION) || (NTDDI_VERSION < NTDDI_WIN7)
44#undef NTDDI_VERSION
45#define NTDDI_VERSION NTDDI_WIN7
46#endif
47#if !defined(_WIN32_WINNT) || _WIN32_WINNT < _WIN32_WINNT_WIN7
48#undef _WIN32_WINNT
49#define _WIN32_WINNT _WIN32_WINNT_WIN7
50#endif
51#if !defined(WINVER) || WINVER < _WIN32_WINNT
52#undef WINVER
53#define WINVER _WIN32_WINNT
54#endif
55#ifndef WIN32_LEAN_AND_MEAN
56#define WIN32_LEAN_AND_MEAN
57#endif
58#include <windef.h>
59#endif
60
61// <limits.h> is guaranteed to be present, even in freestanding environments,
62// and will typically include <features.h>, which we need but cannot portably
63// include directly.
64#include <limits.h>
65
66// Include a (platform-specific) header which defines the POSIX feature test
67// macros.
68#ifdef __GLIBC__
69#include <bits/posix_opt.h>
70#elif defined(__NEWLIB__)
71#include <sys/features.h>
72#endif
73
74#ifndef CLANG_PREREQ
75#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
76#define CLANG_PREREQ(major, minor) \
77 ((__clang_major__ << 16) + __clang_minor__ >= ((major) << 16) + (minor))
78#else
79#define CLANG_PREREQ(major, minor) 0
80#endif
81#endif
82
83#ifndef GNUC_PREREQ
84#if defined(__GNUC__) && defined(__GNUC_MINOR__)
85#define GNUC_PREREQ(major, minor) \
86 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((major) << 16) + (minor))
87#else
88#define GNUC_PREREQ(major, minor) 0
89#endif
90#endif
91
92#ifndef __has_attribute
93#define __has_attribute(x) 0
94#endif
95
96#ifndef __has_builtin
97#define __has_builtin(x) 0
98#endif
99
100#ifndef __has_declspec_attribute
101#define __has_declspec_attribute(x) 0
102#endif
103
104#ifndef __has_extension
105#define __has_extension __has_feature
106#endif
107
108#ifndef __has_feature
109#define __has_feature(x) 0
110#endif
111
112#ifndef __has_include
113#define __has_include(x) 1
114#endif
115
116#ifndef __STDC_CONSTANT_MACROS
117#define __STDC_CONSTANT_MACROS 1
118#endif
119
120#ifndef __STDC_LIMIT_MACROS
121#define __STDC_LIMIT_MACROS 1
122#endif
123
124#ifndef __cplusplus
125
126#ifndef __STDC_NO_ATOMICS__
127// GCC versions older than 4.9 do not properly advertise the absence of
128// <stdatomic.h>.
129// clang-format off
130#if defined(_MSC_VER) \
131 || (defined(__GNUC__) && !GNUC_PREREQ(4, 9) \
132 && !defined(__clang__)) \
133 || (defined(__clang__) && !__has_extension(c_atomic))
134// clang-format on
135#define __STDC_NO_ATOMICS__ 1
136#endif
137#endif // !__STDC_NO_ATOMICS__
138
139#ifndef __STDC_NO_THREADS__
140// Although recent versions of Cygwin do provide <threads.h>, it requires
141// <machine/_threads.h>, which is missing.
142#if defined(_MSC_VER) || defined(__CYGWIN__)
143#define __STDC_NO_THREADS__ 1
144#endif
145#endif // !__STDC_NO_THREADS__
146
147#ifndef __STDC_NO_VLA__
148#if defined(_MSC_VER)
149#define __STDC_NO_VLA__ 1
150#endif
151#endif // !__STDC_NO_VLA__
152
153#endif // !__cplusplus
154
155#ifdef __cplusplus
156
157#ifndef __cpp_exceptions
158#if (defined(_MSC_VER) && _HAS_EXCEPTIONS) \
159 || (defined(__GNUC__) && defined(__EXCEPTIONS)) \
160 || (defined(__clang__) && __has_feature(cxx_exceptions))
161#define __cpp_exceptions __cplusplus
162#endif
163#endif
164
165#ifndef __cpp_rtti
166#if (defined(_MSC_VER) && _CPPRTTI) \
167 || (defined(__GNUC__) && defined(__GXX_RTTI)) \
168 || (defined(__clang__) && __has_feature(cxx_rtti))
169#define __cpp_rtti __cplusplus
170#endif
171#endif
172
173#endif // __cplusplus
174
176// clang-format off
177#if !defined(_Alignas) && !(__STDC_VERSION__ >= 201112L \
178 && (GNUC_PREREQ(4, 7) || __has_feature(c_alignas)))
179// clang-format on
180#if __cplusplus >= 201103L && (GNUC_PREREQ(4, 8) || __has_feature(cxx_alignas))
181#define _Alignas alignas
182#elif defined(__GNUC__) || __has_attribute(__aligned__)
183#define _Alignas(x) __attribute__((__aligned__(x)))
184#elif defined(_MSC_VER) || defined(__declspec) \
185 || __has_declspec_attribute(align)
186#define _Alignas(x) __declspec(align(x))
187#else
188#define _Alignas(x)
189#endif
190#endif
191
193// clang-format off
194#if !defined(_Alignof) && !(__STDC_VERSION__ >= 201112L \
195 && (GNUC_PREREQ(4, 7) || __has_feature(c_alignof)))
196// clang-format on
197#if __cplusplus >= 201103L && (GNUC_PREREQ(4, 8) || __has_feature(cxx_alignof))
198#define _Alignof alignof
199#elif defined(__GNUC__)
200#define _Alignof(x) __alignof__(x)
201#elif defined(_MSC_VER)
202#define _Alignof(x) __alignof(x)
203#else
204#include <stddef.h>
205#define _Alignof(type) \
206 (offsetof( \
207 struct { \
208 char c; \
209 type x; \
210 }, \
211 x))
212#endif
213#endif
214
219// clang-format off
220#if !defined(_Noreturn) && !(__STDC_VERSION__ >= 201112L \
221 && (GNUC_PREREQ(4, 7) || CLANG_PREREQ(3, 3)))
222// clang-format on
223#if defined(__GNUC__) || __has_attribute(__noreturn__)
224#define _Noreturn __attribute__((__noreturn__))
225#elif defined(_MSC_VER) || defined(__declspec) \
226 || __has_declspec_attribute(noreturn)
227#define _Noreturn __declspec(noreturn)
228#else
229#define _Noreturn
230#endif
231#endif
232
241// clang-format off
242#if !defined(_Thread_local) && !(__STDC_VERSION__ >= 201112L \
243 && (GNUC_PREREQ(4, 7) || __has_feature(c_thread_local)))
244// clang-format on
245#if __cplusplus >= 201103L \
246 && (GNUC_PREREQ(4, 8) || __has_feature(cxx_thread_local))
247#define _Thread_local thread_local
248#elif defined(__GNUC__)
249#define _Thread_local __thread
250#elif defined(_MSC_VER) || defined(__declspec) \
251 || __has_declspec_attribute(thread)
252#define _Thread_local __declspec(thread)
253#else
254#define _Thread_local
255#endif
256#endif
257
258#ifndef format_printf__
259#if defined(__GNUC__) || __has_attribute(__format__)
260#ifdef __MINGW32__
261#define format_printf__(i, j) \
262 __attribute__((__format__(__gnu_printf__, (i), (j))))
263#else
264#define format_printf__(i, j) __attribute__((__format__(__printf__, (i), (j))))
265#endif
266#else
267#define format_printf__(i, j)
268#endif
269#endif
270
271#ifndef __WORDSIZE
273// clang-format off
274#if !defined(__ILP32__) && (defined(__LP64__) || _WIN64 || defined(_M_AMD64) \
275 || defined(__amd64__) || defined(_M_IA64) || defined(__ia64__) \
276 || defined(_M_X64) || defined(__x86_64__) \
277 || defined(__aarch64__))
278// clang-format on
279#define __WORDSIZE 64
280#else
281#define __WORDSIZE 32
282#endif
283#endif
284
285#ifndef LONG_BIT
287#if _WIN32
288// long remains 32-bits on 64-bit Windows.
289#define LONG_BIT 32
290#else
291#define LONG_BIT __WORDSIZE
292#endif
293#endif
294
295#ifndef LEVEL1_DCACHE_LINESIZE
302#define LEVEL1_DCACHE_LINESIZE 64
303#endif
304
305#if !LELY_NO_THREADS
306#if defined(__cplusplus)
307// <thread> (C++11 thread support library) is available.
308#elif __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__)
309// <threads.h> (C11 thread support library) is available.
310#elif _POSIX_THREADS >= 200112L || defined(__MINGW32__)
311// <pthread.h> (POSIX threads) is available.
312#elif _WIN32
313// Windows threads are available.
314#else
315#define LELY_NO_THREADS 1
316#endif
317#endif // !LELY_NO_THREADS
318
319#if !LELY_NO_ATOMICS
320#if LELY_NO_THREADS
321// Disable atomic operations if threads are disabled.
322#define LELY_NO_ATOMICS 1
323#elif __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
324// <stdatomic.h> (C11 atomic operations library) is available.
325#elif defined(__clang__) && __has_extension(c_atomic)
326// Clang C11 atomic operations are available.
327#elif GNUC_PREREQ(4, 1)
328// GCC __sync or __atomic builtins are available.
329#else
330#define LELY_NO_ATOMICS 1
331#endif
332#endif // !LELY_NO_ATOMICS
333
334#if LELY_NO_ERRNO || LELY_NO_MALLOC
335// Disable standard I/O if errno and/or dynamic memory allocation are disabled.
336#undef LELY_NO_STDIO
337#define LELY_NO_STDIO 1
338#endif
339
340#if _WIN32
341#if LELY_NO_ERRNO
342#error Windows requires errno.
343#endif
344#if LELY_NO_MALLOC
345#error Windows requires dynamic memory allocation.
346#endif
347#endif // _WIN32
348
349#define LELY_INGORE_EMPTY_TRANSLATION_UNIT \
350 typedef int lely_ignore_empty_translation_unit__;
351
352#ifndef LELY_VLA_SIZE_MAX
354#define LELY_VLA_SIZE_MAX 256
355#endif
356
357#endif // LELY_FEATURES_H_
This header file is part of the C11 and POSIX compatibility library; it includes <stddef....