Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/rapidyaml/include/c4/language.hpp
4261 views
1
#ifndef _C4_LANGUAGE_HPP_
2
#define _C4_LANGUAGE_HPP_
3
4
/** @file language.hpp Provides language standard information macros and
5
* compiler agnostic utility macros: namespace facilities, function attributes,
6
* variable attributes, etc.
7
* @ingroup basic_headers */
8
9
#include "c4/preprocessor.hpp"
10
#include "c4/compiler.hpp"
11
12
/* Detect C++ standard.
13
* @see http://stackoverflow.com/a/7132549/5875572 */
14
#ifndef C4_CPP
15
# if defined(_MSC_VER) && !defined(__clang__)
16
# if _MSC_VER >= 1910 // >VS2015: VS2017, VS2019
17
# if (!defined(_MSVC_LANG))
18
# error _MSVC not defined
19
# endif
20
# if _MSVC_LANG >= 201705L
21
# define C4_CPP 20
22
# define C4_CPP20
23
# elif _MSVC_LANG == 201703L
24
# define C4_CPP 17
25
# define C4_CPP17
26
# elif _MSVC_LANG >= 201402L
27
# define C4_CPP 14
28
# define C4_CPP14
29
# elif _MSVC_LANG >= 201103L
30
# define C4_CPP 11
31
# define C4_CPP11
32
# else
33
# error C++ lesser than C++11 not supported
34
# endif
35
# else
36
# if _MSC_VER == 1900
37
# define C4_CPP 14 // VS2015 is c++14 https://devblogs.microsoft.com/cppblog/c111417-features-in-vs-2015-rtm/
38
# define C4_CPP14
39
# elif _MSC_VER == 1800 // VS2013
40
# define C4_CPP 11
41
# define C4_CPP11
42
# else
43
# error C++ lesser than C++11 not supported
44
# endif
45
# endif
46
# elif defined(__INTEL_COMPILER) // https://software.intel.com/en-us/node/524490
47
# ifdef __INTEL_CXX20_MODE__ // not sure about this
48
# define C4_CPP 20
49
# define C4_CPP20
50
# elif defined __INTEL_CXX17_MODE__ // not sure about this
51
# define C4_CPP 17
52
# define C4_CPP17
53
# elif defined __INTEL_CXX14_MODE__ // not sure about this
54
# define C4_CPP 14
55
# define C4_CPP14
56
# elif defined __INTEL_CXX11_MODE__
57
# define C4_CPP 11
58
# define C4_CPP11
59
# else
60
# error C++ lesser than C++11 not supported
61
# endif
62
# else
63
# ifndef __cplusplus
64
# error __cplusplus is not defined?
65
# endif
66
# if __cplusplus == 1
67
# error cannot handle __cplusplus==1
68
# elif __cplusplus >= 201709L
69
# define C4_CPP 20
70
# define C4_CPP20
71
# elif __cplusplus >= 201703L
72
# define C4_CPP 17
73
# define C4_CPP17
74
# elif __cplusplus >= 201402L
75
# define C4_CPP 14
76
# define C4_CPP14
77
# elif __cplusplus >= 201103L
78
# define C4_CPP 11
79
# define C4_CPP11
80
# elif __cplusplus >= 199711L
81
# error C++ lesser than C++11 not supported
82
# endif
83
# endif
84
#else
85
# ifdef C4_CPP == 20
86
# define C4_CPP20
87
# elif C4_CPP == 17
88
# define C4_CPP17
89
# elif C4_CPP == 14
90
# define C4_CPP14
91
# elif C4_CPP == 11
92
# define C4_CPP11
93
# elif C4_CPP == 98
94
# define C4_CPP98
95
# error C++ lesser than C++11 not supported
96
# else
97
# error C4_CPP must be one of 20, 17, 14, 11, 98
98
# endif
99
#endif
100
101
#ifdef C4_CPP20
102
# define C4_CPP17
103
# define C4_CPP14
104
# define C4_CPP11
105
#elif defined(C4_CPP17)
106
# define C4_CPP14
107
# define C4_CPP11
108
#elif defined(C4_CPP14)
109
# define C4_CPP11
110
#endif
111
112
/** lifted from this answer: http://stackoverflow.com/a/20170989/5875572 */
113
#if defined(_MSC_VER) && !defined(__clang__)
114
# if _MSC_VER < 1900
115
# define C4_CONSTEXPR11
116
# define C4_CONSTEXPR14
117
# elif _MSC_VER < 2000
118
# define C4_CONSTEXPR11 constexpr
119
# define C4_CONSTEXPR14
120
# else
121
# define C4_CONSTEXPR11 constexpr
122
# define C4_CONSTEXPR14 constexpr
123
# endif
124
#else
125
# if __cplusplus < 201103
126
# define C4_CONSTEXPR11
127
# define C4_CONSTEXPR14
128
# elif __cplusplus == 201103
129
# define C4_CONSTEXPR11 constexpr
130
# define C4_CONSTEXPR14
131
# else
132
# define C4_CONSTEXPR11 constexpr
133
# define C4_CONSTEXPR14 constexpr
134
# endif
135
#endif // _MSC_VER
136
137
138
#if C4_CPP < 17
139
#define C4_IF_CONSTEXPR
140
#define C4_INLINE_CONSTEXPR constexpr
141
#else
142
#define C4_IF_CONSTEXPR constexpr
143
#define C4_INLINE_CONSTEXPR inline constexpr
144
#endif
145
146
#if defined(_MSC_VER) && !defined(__clang__)
147
# if (defined(_CPPUNWIND) && (_CPPUNWIND == 1))
148
# define C4_EXCEPTIONS
149
# endif
150
#else
151
# if defined(__EXCEPTIONS) || defined(__cpp_exceptions)
152
# define C4_EXCEPTIONS
153
# endif
154
#endif
155
156
#ifdef C4_EXCEPTIONS
157
# define C4_IF_EXCEPTIONS_(exc_code, setjmp_code) exc_code
158
# define C4_IF_EXCEPTIONS(exc_code, setjmp_code) do { exc_code } while(0)
159
#else
160
# define C4_IF_EXCEPTIONS_(exc_code, setjmp_code) setjmp_code
161
# define C4_IF_EXCEPTIONS(exc_code, setjmp_code) do { setjmp_code } while(0)
162
#endif
163
164
#if defined(_MSC_VER) && !defined(__clang__)
165
# if defined(_CPPRTTI)
166
# define C4_RTTI
167
# endif
168
#else
169
# if defined(__GXX_RTTI)
170
# define C4_RTTI
171
# endif
172
#endif
173
174
#ifdef C4_RTTI
175
# define C4_IF_RTTI_(code_rtti, code_no_rtti) code_rtti
176
# define C4_IF_RTTI(code_rtti, code_no_rtti) do { code_rtti } while(0)
177
#else
178
# define C4_IF_RTTI_(code_rtti, code_no_rtti) code_no_rtti
179
# define C4_IF_RTTI(code_rtti, code_no_rtti) do { code_no_rtti } while(0)
180
#endif
181
182
183
//------------------------------------------------------------
184
185
#define _C4_BEGIN_NAMESPACE(ns) namespace ns {
186
#define _C4_END_NAMESPACE(ns) }
187
188
// MSVC cant handle the C4_FOR_EACH macro... need to fix this
189
//#define C4_BEGIN_NAMESPACE(...) C4_FOR_EACH_SEP(_C4_BEGIN_NAMESPACE, , __VA_ARGS__)
190
//#define C4_END_NAMESPACE(...) C4_FOR_EACH_SEP(_C4_END_NAMESPACE, , __VA_ARGS__)
191
#define C4_BEGIN_NAMESPACE(ns) namespace ns {
192
#define C4_END_NAMESPACE(ns) }
193
194
#define C4_BEGIN_HIDDEN_NAMESPACE namespace /*hidden*/ {
195
#define C4_END_HIDDEN_NAMESPACE } /* namespace hidden */
196
197
//------------------------------------------------------------
198
199
#ifndef C4_API
200
# if defined(_MSC_VER) && !defined(__clang__)
201
# if defined(C4_EXPORT)
202
# define C4_API __declspec(dllexport)
203
# elif defined(C4_IMPORT)
204
# define C4_API __declspec(dllimport)
205
# else
206
# define C4_API
207
# endif
208
# else
209
# define C4_API
210
# endif
211
#endif
212
213
#if defined(_MSC_VER) && !defined(__clang__)
214
# define C4_RESTRICT __restrict
215
# define C4_RESTRICT_FN __declspec(restrict)
216
# define C4_NO_INLINE __declspec(noinline)
217
# define C4_ALWAYS_INLINE inline __forceinline
218
/** these are not available in VS AFAIK */
219
# define C4_CONST
220
# define C4_PURE
221
# define C4_FLATTEN
222
# define C4_HOT /** @todo */
223
# define C4_COLD /** @todo */
224
# define C4_EXPECT(x, y) x /** @todo */
225
# define C4_LIKELY(x) x /** @todo */
226
# define C4_UNLIKELY(x) x /** @todo */
227
# define C4_UNREACHABLE() /** @todo */
228
# define C4_ATTR_FORMAT(...) /** */
229
# define C4_NORETURN /** @todo */
230
#else
231
///< @todo assuming gcc-like compiler. check it is actually so.
232
/** for function attributes in GCC,
233
* @see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes */
234
/** for __builtin functions in GCC,
235
* @see https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html */
236
# define C4_RESTRICT __restrict__
237
# define C4_RESTRICT_FN __attribute__((restrict))
238
# define C4_NO_INLINE __attribute__((noinline))
239
# define C4_ALWAYS_INLINE inline __attribute__((always_inline))
240
# define C4_CONST __attribute__((const))
241
# define C4_PURE __attribute__((pure))
242
/** force inlining of every callee function */
243
# define C4_FLATTEN __atribute__((flatten))
244
/** mark a function as hot, ie as having a visible impact in CPU time
245
* thus making it more likely to inline, etc
246
* @see http://stackoverflow.com/questions/15028990/semantics-of-gcc-hot-attribute */
247
# define C4_HOT __attribute__((hot))
248
/** mark a function as cold, ie as NOT having a visible impact in CPU time
249
* @see http://stackoverflow.com/questions/15028990/semantics-of-gcc-hot-attribute */
250
# define C4_COLD __attribute__((cold))
251
# define C4_EXPECT(x, y) __builtin_expect(x, y) ///< @see https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
252
# define C4_LIKELY(x) __builtin_expect(x, 1)
253
# define C4_UNLIKELY(x) __builtin_expect(x, 0)
254
# define C4_UNREACHABLE() __builtin_unreachable()
255
# define C4_ATTR_FORMAT(...) //__attribute__((format (__VA_ARGS__))) ///< @see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes
256
# define C4_NORETURN __attribute__((noreturn))
257
#endif
258
259
#ifdef _MSC_VER
260
# define C4_FUNC __FUNCTION__
261
# define C4_PRETTY_FUNC __FUNCSIG__
262
#else /// @todo assuming gcc-like compiler. check it is actually so.
263
# define C4_FUNC __FUNCTION__
264
# define C4_PRETTY_FUNC __PRETTY_FUNCTION__
265
#endif
266
267
/** prevent compiler warnings about a specific var being unused */
268
#define C4_UNUSED(var) (void)var
269
270
#if C4_CPP >= 17
271
#define C4_STATIC_ASSERT(cond) static_assert(cond)
272
#else
273
#define C4_STATIC_ASSERT(cond) static_assert((cond), #cond)
274
#endif
275
#define C4_STATIC_ASSERT_MSG(cond, msg) static_assert((cond), #cond ": " msg)
276
277
/** @def C4_DONT_OPTIMIZE idea lifted from GoogleBenchmark.
278
* @see https://github.com/google/benchmark/blob/master/include/benchmark/benchmark_api.h */
279
namespace c4 {
280
namespace detail {
281
#ifdef __GNUC__
282
# define C4_DONT_OPTIMIZE(var) c4::detail::dont_optimize(var)
283
template< class T >
284
C4_ALWAYS_INLINE void dont_optimize(T const& value) { asm volatile("" : : "g"(value) : "memory"); }
285
#else
286
# define C4_DONT_OPTIMIZE(var) c4::detail::use_char_pointer(reinterpret_cast< const char* >(&var))
287
void use_char_pointer(char const volatile*);
288
#endif
289
} // namespace detail
290
} // namespace c4
291
292
/** @def C4_KEEP_EMPTY_LOOP prevent an empty loop from being optimized out.
293
* @see http://stackoverflow.com/a/7084193/5875572 */
294
#if defined(_MSC_VER) && !defined(__clang__)
295
# define C4_KEEP_EMPTY_LOOP { char c; C4_DONT_OPTIMIZE(c); }
296
#else
297
# define C4_KEEP_EMPTY_LOOP { asm(""); }
298
#endif
299
300
/** @def C4_VA_LIST_REUSE_MUST_COPY
301
* @todo <jpmag> I strongly suspect that this is actually only in UNIX platforms. revisit this. */
302
#ifdef __GNUC__
303
# define C4_VA_LIST_REUSE_MUST_COPY
304
#endif
305
306
#endif /* _C4_LANGUAGE_HPP_ */
307
308