Warning: This file is not a C or C++ file. It does not have highlighting.
1 | // -*- C++ -*- |
---|---|
2 | //===----------------------------------------------------------------------===// |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #ifndef SUPPORT_TEST_MACROS_HPP |
11 | #define SUPPORT_TEST_MACROS_HPP |
12 | |
13 | #ifdef __has_include |
14 | # if __has_include("<version>") |
15 | # include <version> |
16 | # else |
17 | # include <ciso646> |
18 | # endif |
19 | #else |
20 | # include <ciso646> |
21 | #endif |
22 | |
23 | #define TEST_STRINGIZE_IMPL(...) #__VA_ARGS__ |
24 | #define TEST_STRINGIZE(...) TEST_STRINGIZE_IMPL(__VA_ARGS__) |
25 | |
26 | #define TEST_CONCAT1(X, Y) X##Y |
27 | #define TEST_CONCAT(X, Y) TEST_CONCAT1(X, Y) |
28 | |
29 | #ifdef __has_feature |
30 | #define TEST_HAS_FEATURE(X) __has_feature(X) |
31 | #else |
32 | #define TEST_HAS_FEATURE(X) 0 |
33 | #endif |
34 | |
35 | #ifndef __has_include |
36 | #define __has_include(...) 0 |
37 | #endif |
38 | |
39 | #ifdef __has_extension |
40 | #define TEST_HAS_EXTENSION(X) __has_extension(X) |
41 | #else |
42 | #define TEST_HAS_EXTENSION(X) 0 |
43 | #endif |
44 | |
45 | #ifdef __has_warning |
46 | #define TEST_HAS_WARNING(X) __has_warning(X) |
47 | #else |
48 | #define TEST_HAS_WARNING(X) 0 |
49 | #endif |
50 | |
51 | #ifdef __has_builtin |
52 | #define TEST_HAS_BUILTIN(X) __has_builtin(X) |
53 | #else |
54 | #define TEST_HAS_BUILTIN(X) 0 |
55 | #endif |
56 | #ifdef __is_identifier |
57 | // '__is_identifier' returns '0' if '__x' is a reserved identifier provided by |
58 | // the compiler and '1' otherwise. |
59 | #define TEST_HAS_BUILTIN_IDENTIFIER(X) !__is_identifier(X) |
60 | #else |
61 | #define TEST_HAS_BUILTIN_IDENTIFIER(X) 0 |
62 | #endif |
63 | |
64 | #if defined(__EDG__) |
65 | # define TEST_COMPILER_EDG |
66 | #elif defined(__clang__) |
67 | # define TEST_COMPILER_CLANG |
68 | # if defined(__apple_build_version__) |
69 | # define TEST_COMPILER_APPLE_CLANG |
70 | # endif |
71 | #elif defined(_MSC_VER) |
72 | # define TEST_COMPILER_MSVC |
73 | #elif defined(__GNUC__) |
74 | # define TEST_COMPILER_GCC |
75 | #endif |
76 | |
77 | #if defined(__apple_build_version__) |
78 | // Given AppleClang XX.Y.Z, TEST_APPLE_CLANG_VER is XXYZ (e.g. AppleClang 14.0.3 => 1403) |
79 | #define TEST_APPLE_CLANG_VER (__apple_build_version__ / 10000) |
80 | #elif defined(__clang_major__) |
81 | #define TEST_CLANG_VER (__clang_major__ * 100) + __clang_minor__ |
82 | #elif defined(__GNUC__) |
83 | // Given GCC XX.YY.ZZ, TEST_GCC_VER is XXYYZZ |
84 | #define TEST_GCC_VER ((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100) + __GNUC_PATCHLEVEL__) |
85 | #endif |
86 | |
87 | /* Make a nice name for the standard version */ |
88 | #ifndef TEST_STD_VER |
89 | #if __cplusplus <= 199711L |
90 | # define TEST_STD_VER 3 |
91 | #elif __cplusplus <= 201103L |
92 | # define TEST_STD_VER 11 |
93 | #elif __cplusplus <= 201402L |
94 | # define TEST_STD_VER 14 |
95 | #elif __cplusplus <= 201703L |
96 | # define TEST_STD_VER 17 |
97 | #elif __cplusplus <= 202002L |
98 | # define TEST_STD_VER 20 |
99 | #elif __cplusplus <= 202302L |
100 | # define TEST_STD_VER 23 |
101 | #else |
102 | # define TEST_STD_VER 99 // greater than current standard |
103 | // This is deliberately different than _LIBCPP_STD_VER to discourage matching them up. |
104 | #endif |
105 | #endif |
106 | |
107 | // Attempt to deduce the GLIBC version |
108 | #if (defined(__has_include) && __has_include(<features.h>)) || \ |
109 | defined(__linux__) |
110 | #include <features.h> |
111 | #if defined(__GLIBC_PREREQ) |
112 | #define TEST_HAS_GLIBC |
113 | #define TEST_GLIBC_PREREQ(major, minor) __GLIBC_PREREQ(major, minor) |
114 | #endif |
115 | #endif |
116 | |
117 | #if TEST_STD_VER >= 11 |
118 | # define TEST_ALIGNOF(...) alignof(__VA_ARGS__) |
119 | # define TEST_ALIGNAS(...) alignas(__VA_ARGS__) |
120 | # define TEST_CONSTEXPR constexpr |
121 | # define TEST_NOEXCEPT noexcept |
122 | # define TEST_NOEXCEPT_FALSE noexcept(false) |
123 | # define TEST_NOEXCEPT_COND(...) noexcept(__VA_ARGS__) |
124 | #else |
125 | # if defined(TEST_COMPILER_CLANG) |
126 | # define TEST_ALIGNOF(...) _Alignof(__VA_ARGS__) |
127 | # else |
128 | # define TEST_ALIGNOF(...) __alignof(__VA_ARGS__) |
129 | # endif |
130 | # define TEST_ALIGNAS(...) __attribute__((__aligned__(__VA_ARGS__))) |
131 | # define TEST_CONSTEXPR |
132 | # define TEST_NOEXCEPT throw() |
133 | # define TEST_NOEXCEPT_FALSE |
134 | # define TEST_NOEXCEPT_COND(...) |
135 | #endif |
136 | |
137 | #if TEST_STD_VER >= 11 |
138 | # define TEST_THROW_SPEC(...) |
139 | #else |
140 | # define TEST_THROW_SPEC(...) throw(__VA_ARGS__) |
141 | #endif |
142 | |
143 | #if defined(__cpp_lib_is_constant_evaluated) && __cpp_lib_is_constant_evaluated >= 201811L |
144 | # define TEST_IS_CONSTANT_EVALUATED std::is_constant_evaluated() |
145 | #elif TEST_HAS_BUILTIN(__builtin_is_constant_evaluated) |
146 | # define TEST_IS_CONSTANT_EVALUATED __builtin_is_constant_evaluated() |
147 | #else |
148 | # define TEST_IS_CONSTANT_EVALUATED false |
149 | #endif |
150 | |
151 | #if TEST_STD_VER >= 23 |
152 | # define TEST_STD_AT_LEAST_23_OR_RUNTIME_EVALUATED true |
153 | #else |
154 | # define TEST_STD_AT_LEAST_23_OR_RUNTIME_EVALUATED (!TEST_IS_CONSTANT_EVALUATED) |
155 | #endif |
156 | |
157 | #if TEST_STD_VER >= 20 |
158 | # define TEST_STD_AT_LEAST_20_OR_RUNTIME_EVALUATED true |
159 | #else |
160 | # define TEST_STD_AT_LEAST_20_OR_RUNTIME_EVALUATED (!TEST_IS_CONSTANT_EVALUATED) |
161 | #endif |
162 | |
163 | #if TEST_STD_VER >= 14 |
164 | # define TEST_CONSTEXPR_CXX14 constexpr |
165 | #else |
166 | # define TEST_CONSTEXPR_CXX14 |
167 | #endif |
168 | |
169 | #if TEST_STD_VER >= 17 |
170 | # define TEST_CONSTEXPR_CXX17 constexpr |
171 | #else |
172 | # define TEST_CONSTEXPR_CXX17 |
173 | #endif |
174 | |
175 | #if TEST_STD_VER >= 20 |
176 | # define TEST_CONSTEXPR_CXX20 constexpr |
177 | #else |
178 | # define TEST_CONSTEXPR_CXX20 |
179 | #endif |
180 | |
181 | #if TEST_STD_VER >= 23 |
182 | # define TEST_CONSTEXPR_CXX23 constexpr |
183 | #else |
184 | # define TEST_CONSTEXPR_CXX23 |
185 | #endif |
186 | |
187 | #define TEST_ALIGNAS_TYPE(...) TEST_ALIGNAS(TEST_ALIGNOF(__VA_ARGS__)) |
188 | |
189 | #if !TEST_HAS_FEATURE(cxx_rtti) && !defined(__cpp_rtti) \ |
190 | && !defined(__GXX_RTTI) |
191 | #define TEST_HAS_NO_RTTI |
192 | #endif |
193 | |
194 | #if !defined(TEST_HAS_NO_RTTI) |
195 | # define RTTI_ASSERT(X) assert(X) |
196 | #else |
197 | # define RTTI_ASSERT(X) |
198 | #endif |
199 | |
200 | #if !TEST_HAS_FEATURE(cxx_exceptions) && !defined(__cpp_exceptions) \ |
201 | && !defined(__EXCEPTIONS) |
202 | #define TEST_HAS_NO_EXCEPTIONS |
203 | #endif |
204 | |
205 | #if TEST_HAS_FEATURE(address_sanitizer) || TEST_HAS_FEATURE(hwaddress_sanitizer) || \ |
206 | TEST_HAS_FEATURE(memory_sanitizer) || TEST_HAS_FEATURE(thread_sanitizer) |
207 | #define TEST_HAS_SANITIZERS |
208 | #define TEST_IS_EXECUTED_IN_A_SLOW_ENVIRONMENT |
209 | #endif |
210 | |
211 | #if defined(_LIBCPP_NORETURN) |
212 | #define TEST_NORETURN _LIBCPP_NORETURN |
213 | #else |
214 | #define TEST_NORETURN [[noreturn]] |
215 | #endif |
216 | |
217 | #if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) || \ |
218 | (!(TEST_STD_VER > 14 || \ |
219 | (defined(__cpp_aligned_new) && __cpp_aligned_new >= 201606L))) |
220 | #define TEST_HAS_NO_ALIGNED_ALLOCATION |
221 | #endif |
222 | |
223 | #if TEST_STD_VER > 17 |
224 | #define TEST_CONSTINIT constinit |
225 | #else |
226 | #define TEST_CONSTINIT |
227 | #endif |
228 | |
229 | #if TEST_STD_VER < 11 |
230 | #define ASSERT_NOEXCEPT(...) |
231 | #define ASSERT_NOT_NOEXCEPT(...) |
232 | #else |
233 | #define ASSERT_NOEXCEPT(...) \ |
234 | static_assert(noexcept(__VA_ARGS__), "Operation must be noexcept") |
235 | |
236 | #define ASSERT_NOT_NOEXCEPT(...) \ |
237 | static_assert(!noexcept(__VA_ARGS__), "Operation must NOT be noexcept") |
238 | #endif |
239 | |
240 | /* Macros for testing libc++ specific behavior and extensions */ |
241 | #if defined(_LIBCPP_VERSION) |
242 | #define LIBCPP_ASSERT(...) assert(__VA_ARGS__) |
243 | #define LIBCPP_STATIC_ASSERT(...) static_assert(__VA_ARGS__) |
244 | #define LIBCPP_ASSERT_NOEXCEPT(...) ASSERT_NOEXCEPT(__VA_ARGS__) |
245 | #define LIBCPP_ASSERT_NOT_NOEXCEPT(...) ASSERT_NOT_NOEXCEPT(__VA_ARGS__) |
246 | #define LIBCPP_ONLY(...) __VA_ARGS__ |
247 | #else |
248 | #define LIBCPP_ASSERT(...) static_assert(true, "") |
249 | #define LIBCPP_STATIC_ASSERT(...) static_assert(true, "") |
250 | #define LIBCPP_ASSERT_NOEXCEPT(...) static_assert(true, "") |
251 | #define LIBCPP_ASSERT_NOT_NOEXCEPT(...) static_assert(true, "") |
252 | #define LIBCPP_ONLY(...) static_assert(true, "") |
253 | #endif |
254 | |
255 | #if __has_cpp_attribute(nodiscard) |
256 | # define TEST_NODISCARD [[nodiscard]] |
257 | #else |
258 | # define TEST_NODISCARD |
259 | #endif |
260 | |
261 | #define TEST_IGNORE_NODISCARD (void) |
262 | |
263 | namespace test_macros_detail { |
264 | template <class T, class U> |
265 | struct is_same { enum { value = 0};} ; |
266 | template <class T> |
267 | struct is_same<T, T> { enum {value = 1}; }; |
268 | } // namespace test_macros_detail |
269 | |
270 | #define ASSERT_SAME_TYPE(...) \ |
271 | static_assert((test_macros_detail::is_same<__VA_ARGS__>::value), \ |
272 | "Types differ unexpectedly") |
273 | |
274 | #ifndef TEST_HAS_NO_EXCEPTIONS |
275 | #define TEST_THROW(...) throw __VA_ARGS__ |
276 | #else |
277 | #if defined(__GNUC__) |
278 | #define TEST_THROW(...) __builtin_abort() |
279 | #else |
280 | #include <stdlib.h> |
281 | #define TEST_THROW(...) ::abort() |
282 | #endif |
283 | #endif |
284 | |
285 | #if defined(__GNUC__) || defined(__clang__) |
286 | // This function can be used to hide some objects from compiler optimizations. |
287 | // |
288 | // For example, this is useful to hide the result of a call to `new` and ensure |
289 | // that the compiler doesn't elide the call to new/delete. Otherwise, elliding |
290 | // calls to new/delete is allowed by the Standard and compilers actually do it |
291 | // when optimizations are enabled. |
292 | template <class Tp> |
293 | inline Tp const& DoNotOptimize(Tp const& value) { |
294 | asm volatile("" : : "r,m"(value) : "memory"); |
295 | return value; |
296 | } |
297 | |
298 | template <class Tp> |
299 | inline Tp& DoNotOptimize(Tp& value) { |
300 | #if defined(__clang__) |
301 | asm volatile("" : "+r,m"(value) : : "memory"); |
302 | #else |
303 | asm volatile("" : "+m,r"(value) : : "memory"); |
304 | #endif |
305 | return value; |
306 | } |
307 | #else |
308 | #include <intrin.h> |
309 | template <class Tp> |
310 | inline Tp const& DoNotOptimize(Tp const& value) { |
311 | const volatile void* volatile unused = __builtin_addressof(value); |
312 | static_cast<void>(unused); |
313 | _ReadWriteBarrier(); |
314 | return value; |
315 | } |
316 | #endif |
317 | |
318 | #if defined(__GNUC__) |
319 | #define TEST_ALWAYS_INLINE __attribute__((always_inline)) |
320 | #define TEST_NOINLINE __attribute__((noinline)) |
321 | #elif defined(_MSC_VER) |
322 | #define TEST_ALWAYS_INLINE __forceinline |
323 | #define TEST_NOINLINE __declspec(noinline) |
324 | #else |
325 | #define TEST_ALWAYS_INLINE |
326 | #define TEST_NOINLINE |
327 | #endif |
328 | |
329 | #ifdef _WIN32 |
330 | #define TEST_NOT_WIN32(...) ((void)0) |
331 | #else |
332 | #define TEST_NOT_WIN32(...) __VA_ARGS__ |
333 | #endif |
334 | |
335 | #if defined(TEST_WINDOWS_DLL) ||defined(__MVS__) || defined(_AIX) |
336 | // Macros for waiving cases when we can't count allocations done within |
337 | // the library implementation. |
338 | // |
339 | // On Windows, when libc++ is built as a DLL, references to operator new/delete |
340 | // within the DLL are bound at link time to the operator new/delete within |
341 | // the library; replacing them in the user executable doesn't override the |
342 | // calls within the library. |
343 | // |
344 | // The same goes on IBM zOS. |
345 | // The same goes on AIX. |
346 | #define ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(...) ((void)(__VA_ARGS__)) |
347 | #define TEST_SUPPORTS_LIBRARY_INTERNAL_ALLOCATIONS 0 |
348 | #else |
349 | #define ASSERT_WITH_LIBRARY_INTERNAL_ALLOCATIONS(...) assert(__VA_ARGS__) |
350 | #define TEST_SUPPORTS_LIBRARY_INTERNAL_ALLOCATIONS 1 |
351 | #endif |
352 | |
353 | #if (defined(TEST_WINDOWS_DLL) && !defined(_MSC_VER)) || \ |
354 | defined(__MVS__) |
355 | // Normally, a replaced e.g. 'operator new' ends up used if the user code |
356 | // does a call to e.g. 'operator new[]'; it's enough to replace the base |
357 | // versions and have it override all of them. |
358 | // |
359 | // When the fallback operators are located within the libc++ library and we |
360 | // can't override the calls within it (see above), this fallback mechanism |
361 | // doesn't work either. |
362 | // |
363 | // On Windows, when using the MSVC vcruntime, the operator new/delete fallbacks |
364 | // are linked separately from the libc++ library, linked statically into |
365 | // the end user executable, and these fallbacks work even in DLL configurations. |
366 | // In MinGW configurations when built as a DLL, and on zOS, these fallbacks |
367 | // don't work though. |
368 | #define ASSERT_WITH_OPERATOR_NEW_FALLBACKS(...) ((void)(__VA_ARGS__)) |
369 | #else |
370 | #define ASSERT_WITH_OPERATOR_NEW_FALLBACKS(...) assert(__VA_ARGS__) |
371 | #endif |
372 | |
373 | #ifdef _WIN32 |
374 | #define TEST_WIN_NO_FILESYSTEM_PERMS_NONE |
375 | #endif |
376 | |
377 | // Support for carving out parts of the test suite, like removing wide characters, etc. |
378 | #if defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) |
379 | # define TEST_HAS_NO_WIDE_CHARACTERS |
380 | #endif |
381 | |
382 | #if defined(_LIBCPP_HAS_NO_UNICODE) |
383 | # define TEST_HAS_NO_UNICODE |
384 | #elif defined(_MSVC_EXECUTION_CHARACTER_SET) && _MSVC_EXECUTION_CHARACTER_SET != 65001 |
385 | # define TEST_HAS_NO_UNICODE |
386 | #endif |
387 | |
388 | #if defined(_LIBCPP_HAS_OPEN_WITH_WCHAR) |
389 | # define TEST_HAS_OPEN_WITH_WCHAR |
390 | #endif |
391 | |
392 | #if defined(_LIBCPP_HAS_NO_INT128) || defined(_MSVC_STL_VERSION) |
393 | # define TEST_HAS_NO_INT128 |
394 | #endif |
395 | |
396 | #if defined(_LIBCPP_HAS_NO_LOCALIZATION) |
397 | # define TEST_HAS_NO_LOCALIZATION |
398 | #endif |
399 | |
400 | #if TEST_STD_VER <= 17 || !defined(__cpp_char8_t) |
401 | # define TEST_HAS_NO_CHAR8_T |
402 | #endif |
403 | |
404 | #if defined(_LIBCPP_HAS_NO_THREADS) |
405 | # define TEST_HAS_NO_THREADS |
406 | #endif |
407 | |
408 | #if defined(_LIBCPP_HAS_NO_FILESYSTEM) |
409 | # define TEST_HAS_NO_FILESYSTEM |
410 | #endif |
411 | |
412 | #if defined(_LIBCPP_HAS_NO_C8RTOMB_MBRTOC8) |
413 | # define TEST_HAS_NO_C8RTOMB_MBRTOC8 |
414 | #endif |
415 | |
416 | #if defined(_LIBCPP_HAS_NO_RANDOM_DEVICE) |
417 | # define TEST_HAS_NO_RANDOM_DEVICE |
418 | #endif |
419 | |
420 | #if defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) |
421 | # define TEST_HAS_NO_EXPERIMENTAL_TZDB |
422 | #endif |
423 | |
424 | #if defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) |
425 | # define TEST_HAS_NO_TIME_ZONE_DATABASE |
426 | #endif |
427 | |
428 | #if defined(TEST_COMPILER_CLANG) |
429 | # define TEST_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") |
430 | # define TEST_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") |
431 | # define TEST_CLANG_DIAGNOSTIC_IGNORED(str) _Pragma(TEST_STRINGIZE(clang diagnostic ignored str)) |
432 | # define TEST_GCC_DIAGNOSTIC_IGNORED(str) |
433 | # define TEST_MSVC_DIAGNOSTIC_IGNORED(num) |
434 | #elif defined(TEST_COMPILER_GCC) |
435 | # define TEST_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") |
436 | # define TEST_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") |
437 | # define TEST_CLANG_DIAGNOSTIC_IGNORED(str) |
438 | # define TEST_GCC_DIAGNOSTIC_IGNORED(str) _Pragma(TEST_STRINGIZE(GCC diagnostic ignored str)) |
439 | # define TEST_MSVC_DIAGNOSTIC_IGNORED(num) |
440 | #elif defined(TEST_COMPILER_MSVC) |
441 | # define TEST_DIAGNOSTIC_PUSH _Pragma("warning(push)") |
442 | # define TEST_DIAGNOSTIC_POP _Pragma("warning(pop)") |
443 | # define TEST_CLANG_DIAGNOSTIC_IGNORED(str) |
444 | # define TEST_GCC_DIAGNOSTIC_IGNORED(str) |
445 | # define TEST_MSVC_DIAGNOSTIC_IGNORED(num) _Pragma(TEST_STRINGIZE(warning(disable: num))) |
446 | #else |
447 | # define TEST_DIAGNOSTIC_PUSH |
448 | # define TEST_DIAGNOSTIC_POP |
449 | # define TEST_CLANG_DIAGNOSTIC_IGNORED(str) |
450 | # define TEST_GCC_DIAGNOSTIC_IGNORED(str) |
451 | # define TEST_MSVC_DIAGNOSTIC_IGNORED(num) |
452 | #endif |
453 | |
454 | #if __has_cpp_attribute(msvc::no_unique_address) |
455 | #define TEST_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] |
456 | #elif __has_cpp_attribute(no_unique_address) |
457 | #define TEST_NO_UNIQUE_ADDRESS [[no_unique_address]] |
458 | #else |
459 | #define TEST_NO_UNIQUE_ADDRESS |
460 | #endif |
461 | |
462 | #ifdef _LIBCPP_SHORT_WCHAR |
463 | # define TEST_SHORT_WCHAR |
464 | #endif |
465 | |
466 | #ifdef _LIBCPP_ABI_MICROSOFT |
467 | # define TEST_ABI_MICROSOFT |
468 | #endif |
469 | |
470 | // This is a temporary workaround for user-defined `operator new` definitions |
471 | // not being picked up on Apple platforms in some circumstances. This is under |
472 | // investigation and should be short-lived. |
473 | #ifdef __APPLE__ |
474 | # define TEST_WORKAROUND_BUG_109234844_WEAK __attribute__((weak)) |
475 | #else |
476 | # define TEST_WORKAROUND_BUG_109234844_WEAK /* nothing */ |
477 | #endif |
478 | |
479 | #ifdef _AIX |
480 | # define TEST_IF_AIX(arg_true, arg_false) arg_true |
481 | #else |
482 | # define TEST_IF_AIX(arg_true, arg_false) arg_false |
483 | #endif |
484 | |
485 | // Clang-18 has support for deducing this, but it does not set the FTM. |
486 | #ifdef _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER |
487 | # define TEST_HAS_EXPLICIT_THIS_PARAMETER |
488 | #endif |
489 | |
490 | #endif // SUPPORT_TEST_MACROS_HPP |
491 |
Warning: This file is not a C or C++ file. It does not have highlighting.