CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
Macros.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
11
12#include <cassert>
13
14//
15// Operating system platform macro definitions.
16//
17// These conditionals specify in which Operating System the generated code will
18// run. Indention is used to show which conditionals are evolutionary subclasses.
19//
20// CE_PLATFORM_WINDOWS - Generated code will run under Windows.
21// CE_PLATFORM_WIN32 - Generated code will run under WIN32 API.
22// CE_PLATFORM_POSIX - Generated code will run under some POSIX-compliant OS (including macOS).
23// CE_PLATFORM_LINUX - Generated code will run under Linux.
24// CE_PLATFORM_ANDROID - Generated code will run under Android.
25// CE_PLATFORM_BSD - Generated code will run under a BSD system.
26// CE_PLATFORM_FREEBSD - Generated code will run under a FreeBSD system.
27// CE_PLATFORM_APPLE - Generated code will run under an Apple operating system.
28// CE_PLATFORM_MAC - Generated code will run under macOS.
29// CE_PLATFORM_IOS - Generated code will run under iOS.
30// CE_PLATFORM_WEB - Generated code will run on the web.
31// CE_PLATFORM_EMSCRIPTEN - Generated code will run on the web with Emscripten.
32// CE_PLATFORM_WASI - Generated code will run on the web with WASI.
33// CE_PLATFORM_CHEERP - Generated code will run on the web with Cheerp.
34//
35
36#define CE_PLATFORM_WINDOWS 0
37#define CE_PLATFORM_WIN32 0
38#define CE_PLATFORM_POSIX 0
39#define CE_PLATFORM_LINUX 0
40#define CE_PLATFORM_ANDROID 0
41#define CE_PLATFORM_BSD 0
42#define CE_PLATFORM_FREEBSD 0
43#define CE_PLATFORM_APPLE 0
44#define CE_PLATFORM_MAC 0
45#define CE_PLATFORM_IOS 0
46#define CE_PLATFORM_WEB 0
47#define CE_PLATFORM_EMSCRIPTEN 0
48#define CE_PLATFORM_WASI 0
49#define CE_PLATFORM_CHEERP 0
50
51#if defined(__WIN32__) || defined(_WIN32)
52#undef CE_PLATFORM_WINDOWS
53#define CE_PLATFORM_WINDOWS 1
54
55#undef CE_PLATFORM_WIN32
56#define CE_PLATFORM_WIN32 1
57#elif defined(__APPLE__)
58#undef CE_PLATFORM_POSIX
59#define CE_PLATFORM_POSIX 1
60
61#undef CE_PLATFORM_APPLE
62#define CE_PLATFORM_APPLE 1
63
64#include <TargetConditionals.h>
65#if TARGET_OS_OSX
66#undef CE_PLATFORM_MAC
67#define CE_PLATFORM_MAC 1
68#elif TARGET_OS_IPHONE
69#undef CE_PLATFORM_IOS
70#define CE_PLATFORM_IOS 1
71#endif
72#elif defined(__EMSCRIPTEN__)
73#undef CE_PLATFORM_POSIX
74#define CE_PLATFORM_POSIX 1
75
76#undef CE_PLATFORM_WEB
77#define CE_PLATFORM_WEB 1
78
79#undef CE_PLATFORM_EMSCRIPTEN
80#define CE_PLATFORM_EMSCRIPTEN 1
81#elif defined(__wasi__)
82#undef CE_PLATFORM_WEB
83#define CE_PLATFORM_WEB 1
84
85#undef CE_PLATFORM_WASI
86#define CE_PLATFORM_WASI 1
87#elif defined(__linux__)
88#undef CE_PLATFORM_POSIX
89#define CE_PLATFORM_POSIX 1
90
91#undef CE_PLATFORM_LINUX
92#define CE_PLATFORM_LINUX 1
93#else
94#pragma error "Unknown platform."
95#endif
96
97//
98// Compiler macro definitions.
99// CE_COMPILER_CLANG - Code will be compiled with Clang.
100// CE_COMPILER_MSVC - Code will be compiled with MSVC.
101// CE_COMPILER_CLANGCL - Code will be compiled with Clang (with ClangCL).
102// CE_COMPILER_GNUC - Code will be compiled with GCC.
103// CE_COMPILER_INTEL - Code will be compiled with Intel compiler.
104//
105
106#define CE_COMPILER_CLANG 0
107#define CE_COMPILER_MSVC 0
108#define CE_COMPILER_CLANGCL 0
109#define CE_COMPILER_GNUC 0
110#define CE_COMPILER_INTEL 0
111
112#if defined(__clang__)
113#undef CE_COMPILER_CLANG
114#define CE_COMPILER_CLANG 1
115
116// clang-cl defines _MSC_VER
117#if defined(_MSC_VER)
118#undef CE_COMPILER_CLANGCL
119#define CE_COMPILER_CLANGCL 1
120
121#undef CE_COMPILER_MSVC
122#define CE_COMPILER_MSVC 1
123#endif
124#elif defined(__GNUC__) // Check after Clang, as Clang defines this too
125#undef CE_COMPILER_GNUC
126#define CE_COMPILER_GNUC 1
127#elif defined(__INTEL_COMPILER)
128#undef CE_COMPILER_INTEL
129#define CE_COMPILER_INTEL 1
130#elif defined(_MSC_VER) // Check after Clang and Intel, since we could be building with either within VS
131#undef CE_COMPILER_MSVC
132#define CE_COMPILER_MSVC 1
133#else
134#pragma error "Unknown compiler."
135#endif
136
137//
138// CPU architecture macro definitions.
139//
140// These conditionals specify which microprocessor instruction set is being
141// generated. At most one of these is true, the rest are false.
142//
143//
144// CE_ARCHITECTURE_X86 - Compiler is generating x86 instructions.
145// CE_ARCHITECTURE_X86_32 - Compiler is generating x86 instructions for 32-bit mode
146// CE_ARCHITECTURE_X86_64 - Compiler is generating x86 instructions for 64-bit mode
147// CE_ARCHITECTURE_ARM - Compiler is generating ARM instructions.
148// CE_ARCHITECTURE_ARM32 - Compiler is generating ARM instructions for 32-bit mode
149// CE_ARCHITECTURE_ARM64 - Compiler is generating ARM instructions for 64-bit mode
150// CE_ARCHITECTURE_WASM - Compiler is generating WebAssembly instructions.
151// CE_ARCHITECTURE_WASM32 - Compiler is generating WebAssembly instructions for 32-bit mode
152// CE_ARCHITECTURE_WASM64 - Compiler is generating WebAssembly instructions for 64-bit mode
153//
154
155#define CE_ARCHITECTURE_X86 0
156#define CE_ARCHITECTURE_X86_32 0
157#define CE_ARCHITECTURE_X86_64 0
158#define CE_ARCHITECTURE_ARM 0
159#define CE_ARCHITECTURE_ARM32 0
160#define CE_ARCHITECTURE_ARM64 0
161#define CE_ARCHITECTURE_WASM 0
162#define CE_ARCHITECTURE_WASM32 0
163#define CE_ARCHITECTURE_WASM64 0
164
165#define CE_ARCHITECTURE_IS_32BIT CE_ARCHITECTURE_X86_32 || CE_ARCHITECTURE_ARM32 || CE_ARCHITECTURE_WASM32
166#define CE_ARCHITECTURE_IS_64BIT CE_ARCHITECTURE_X86_64 || CE_ARCHITECTURE_ARM64 || CE_ARCHITECTURE_WASM64
167
168// Find the architecture type
169#if defined(__x86_64__) || defined(_M_X64)
170#undef CE_ARCHITECTURE_X86
171#define CE_ARCHITECTURE_X86 1
172
173#undef CE_ARCHITECTURE_X86_64
174#define CE_ARCHITECTURE_X86_64 1
175#elif defined(i386) || defined(__i386__) || defined(__i386) || defined(_M_IX86)
176#undef CE_ARCHITECTURE_X86
177#define CE_ARCHITECTURE_X86 1
178
179#undef CE_ARCHITECTURE_X86_32
180#define CE_ARCHITECTURE_X86_32 1
181#elif defined(__aarch64__) || defined(_M_ARM64)
182#undef CE_ARCHITECTURE_ARM
183#define CE_ARCHITECTURE_ARM 1
184
185#undef CE_ARCHITECTURE_ARM64
186#define CE_ARCHITECTURE_ARM64 1
187#elif defined(__arm__) || defined(_M_ARM)
188#undef CE_ARCHITECTURE_ARM
189#define CE_ARCHITECTURE_ARM 1
190
191#undef CE_ARCHITECTURE_ARM32
192#define CE_ARCHITECTURE_ARM32 1
193#elif defined(__wasm32__)
194#undef CE_ARCHITECTURE_WASM
195#define CE_ARCHITECTURE_WASM 1
196
197#undef CE_ARCHITECTURE_WASM32
198#define CE_ARCHITECTURE_WASM32 1
199#elif defined(__wasm64__)
200#undef CE_ARCHITECTURE_WASM
201#define CE_ARCHITECTURE_WASM 1
202
203#undef CE_ARCHITECTURE_WASM64
204#define CE_ARCHITECTURE_WASM64 1
205#else
206#pragma error "Unknown architecture."
207#endif
208
209// DLL export, import and symbol hiding.
210
211#if CE_PLATFORM_WIN32
212#define CE_DLL_EXPORT __declspec(dllexport)
213#define CE_DLL_IMPORT __declspec(dllimport)
214#define CE_HIDDEN
215#else
216#define CE_VISIBLE __attribute__((visibility("default")))
217#define CE_HIDDEN __attribute__((visibility("hidden")))
218#define CE_DLL_EXPORT CE_VISIBLE
219#define CE_DLL_IMPORT CE_VISIBLE
220#endif
221
222#if defined(CE_SHARED_LIB)
223#if defined(CE_EXPORTS)
224#define CE_EXPORT CE_DLL_EXPORT
225#else
226#define CE_EXPORT CE_DLL_IMPORT
227#endif
228#else
229#define CE_EXPORT
230#endif
231
240#if defined(__has_attribute)
241#if __has_attribute(annotate)
242#define CE_SCRIPT_EXPORT(...) __attribute__((annotate("ce-scriptable:" #__VA_ARGS__)))
243#else
244#define CE_SCRIPT_EXPORT(...)
245#endif
246#else
247#define CE_SCRIPT_EXPORT(...)
248#endif
249
258#if defined(__has_attribute)
259#if __has_attribute(annotate)
260#define CEReflectable(...) clang::annotate("ce-reflectable:" #__VA_ARGS__)
261#else
262#define CEReflectable(...)
263#endif
264#else
265#define CEReflectable(...)
266#endif
267
270#define CE_BIND_THIS(function) \
271 [this](auto&&... args) -> decltype(auto) { \
272 return this->function(std::forward<decltype(args)>(args)...); \
273 }
274
275#define CE_DEPRECATED [[deprecated]]
276#define CE_DEPRECATED_MSG(Message) [[deprecated(Message)]]
277
278// -- Nullability Attributes
279//
280// Whether a particular pointer may be “null” is an important concern when
281// working with pointers in the C family of languages. The various nullability
282// attributes indicate whether a particular pointer can be null or not, which
283// makes APIs more expressive and can help static analysis tools identify bugs
284// involving null pointers.
285//
286// The nullability (type) qualifiers express whether a value of a given pointer
287// type can be null (the `CE_NULLABLE` qualifier), doesn't have a defined
288// meaning for null (the `CE_NON_NULL` qualifier), or for which the purpose of
289// null is unclear (the `CE_NULL_UNSPECIFIED` qualifier). Nullability
290// qualifiers are written to the right of the pointer to which they apply.
291//
292
293#if CE_COMPILER_CLANG
294#define CE_NON_NULL _Nonnull
295#define CE_NULLABLE _Nullable
296#define CE_NULL_UNSPECIFIED \
297 _Null_unspecified
298#else
299#define CE_NON_NULL
300#define CE_NULLABLE
301#define CE_NULL_UNSPECIFIED
302#endif
303
304#if defined(__has_attribute)
305#if __has_attribute(expects)
306#define CE_EXPECTS(...) [[expects:__VA_ARGS__]]
307#else
308#define CE_EXPECTS(...)
309#endif
310#if __has_attribute(ensures)
311#define CE_ENSURES(...) [[ensures:__VA_ARGS__]]
312#else
313#define CE_ENSURES(...)
314#endif
315#if __has_attribute(assert)
316#define CE_ASSERT(...) [[assert:__VA_ARGS__]]
317#else
318#define CE_ASSERT(x) assert(x)
319#endif
320#else
321#define CE_EXPECTS(...)
322#define CE_ENSURES(...)
323#define CE_ASSERT(...) assert(__VA_ARGS__)
324#endif
325
326#define CE_ASSERT_UNDEFINED() \
327 CE_ASSERT(false && "Undefined Behavior"); \
328 std::terminate();
329#define CE_ASSERT_UNIMPLEMENTED() \
330 CE_ASSERT(false && "Not Implemented"); \
331 std::terminate();
332
333#if !defined(NDEBUG)
334#define CE_ASSERT_DEBUG(...) CE_ASSERT(__VA_ARGS__)
335#else
336#define CE_ASSERT_DEBUG(...)
337#endif
338
339#if defined(__cpp_concepts)
340#define CE_CONCEPT_REQUIRES(...) requires __VA_ARGS__
341#else
342#define CE_CONCEPT(Name) typename
343#define CE_CONCEPT_REQUIRES(...)
344#endif
345
346#if CE_COMPILER_MSVC
347#define CE_NOINLINE __declspec(noinline)
348#elif CE_COMPILER_CLANG || CE_COMPILER_GNUC
349#define CE_NOINLINE [[gnu::noinline]]
350#else
351#define CE_NOINLINE
352#endif
353
354#if CE_COMPILER_MSVC
355#define CE_UNREACHABLE __assume(false)
356#elif CE_COMPILER_CLANG || CE_COMPILER_GNUC
357#define CE_UNREACHABLE __builtin_unreachable()
358#else
359#define CE_UNREACHABLE std::abort()
360#endif
361
362#if CE_COMPILER_MSVC
363#define CE_FORCE_INLINE __forceinline
364#elif CE_COMPILER_CLANG || CE_COMPILER_GNUC
365#define CE_FORCE_INLINE __attribute__((always_inline))
366#else
367#define CE_FORCE_INLINE
368#endif
369
370#if CE_COMPILER_MSVC
371#define CE_FLATTEN_INLINE __forceinline
372#elif CE_COMPILER_CLANG || CE_COMPILER_GNUC
373#define CE_FLATTEN_INLINE [[gnu::flatten]]
374#else
375#define CE_FORCE_INLINE
376#endif
377
378#if CE_COMPILER_CLANG || CE_COMPILER_GNUC
379#define CE_COLD [[gnu::cold]]
380#else
381#define CE_COLD
382#endif
383
384#if defined(__has_cpp_attribute)
385#if __has_cpp_attribute(likely)
386#define CE_LIKELY [[likely]]
387#else
388#define CE_LIKELY
389#endif
390#if __has_cpp_attribute(unlikely)
391#define CE_UNLIKELY [[unlikely]]
392#else
393#define CE_UNLIKELY
394#endif
395#else
396#define CE_LIKELY
397#define CE_UNLIKELY
398#endif
399
400#if defined(__has_cpp_attribute)
401#if __has_cpp_attribute(no_unique_address)
402#define CE_NO_UNIQUE_ADDRESS [[no_unique_address]]
403#else
404#define CE_NO_UNIQUE_ADDRESS
405#endif
406#else
407#define CE_NO_UNIQUE_ADDRESS
408#endif
409
410#if defined(__cpp_conditional_explicit)
411#define CE_EXPLICIT(EXPR) explicit(EXPR)
412#else
413#define CE_EXPLICIT(EXPR)
414#endif
415
416#define CE_EXPLICIT_FALSE CE_EXPLICIT(false)
417
418// clang-format off
419
420#if CE_COMPILER_MSVC
421# define CE_DISABLE_WARNING_PUSH __pragma(warning(push))
422# define CE_DISABLE_WARNING_POP __pragma(warning(pop))
423# define CE_DISABLE_WARNING(warningNumber) __pragma(warning(disable : warningNumber))
424# define CE_DISABLE_ALL_WARNINGS __pragma(warning(push, 0))
425
426# define CE_DISABLE_WARNING_UNREFERENCED_FORMAL_PARAMETER CE_DISABLE_WARNING(4100)
427# define CE_DISABLE_WARNING_UNREFERENCED_FUNCTION CE_DISABLE_WARNING(4505)
428# define CE_DISABLE_WARNING_TAUTOLOGICAL_COMPARE
429# define CE_DISABLE_WARNING_REORDER CE_DISABLE_WARNING(5038)
430# define CE_DISABLE_WARNING_UNUSED_VARIABLE CE_DISABLE_WARNING(4189)
431# define CE_DISABLE_WARNING_UNINITIALIZED_VARIABLE CE_DISABLE_WARNING(4701) CE_DISABLE_WARNING(4703)
432# define CE_DISABLE_WARNING_MISSING_FIELD_INITIALIZERS
433# define CE_DISABLE_WARNING_UNUSED_PRIVATE_FIELD
434# define CE_DISABLE_WARNING_TYPE_LIMITS
435# define CE_DISABLE_WARNING_DEPRECATED_VOLATILE
436# define CE_DISABLE_WARNING_DEPRECATED_DECLARATIONS CE_DISABLE_WARNING(4996)
437# define CE_DISABLE_WARNING_UNSIGNED_UNARY_MINUS CE_DISABLE_WARNING(4146)
438# define CE_DISABLE_WARNING_IMPLICIT_LOSSY_CONVERSION CE_DISABLE_WARNING(4244)
439# define CE_DISABLE_WARNING_MISSING_OVERRIDE
440# define CE_DISABLE_WARNING_INHERITS_VIA_DOMINANCE CE_DISABLE_WARNING(4250)
441# define CE_DISABLE_WARNING_DESTRUCTOR_IMPLICITLY_DELETED CE_DISABLE_WARNING(4624)
442
443#elif CE_COMPILER_CLANG || CE_COMPILER_GNUC
444# define CE_DO_PRAGMA(X) _Pragma(#X)
445# define CE_DISABLE_WARNING_STRINGIFY(x) #x
446# if CE_COMPILER_CLANG
447# define CE_DISABLE_WARNING_PUSH CE_DO_PRAGMA(clang diagnostic push)
448# define CE_DISABLE_WARNING_POP CE_DO_PRAGMA(clang diagnostic pop)
449# define CE_DISABLE_WARNING(name) CE_DO_PRAGMA(clang diagnostic ignored #name)
450# define CE_DISABLE_ALL_WARNINGS CE_DO_PRAGMA(clang diagnostic ignored "-Weverything")
451# elif CE_COMPILER_GNUC
452# define CE_DISABLE_WARNING_PUSH CE_DO_PRAGMA(GCC diagnostic push)
453# define CE_DISABLE_WARNING_POP CE_DO_PRAGMA(GCC diagnostic pop)
454# define CE_DISABLE_WARNING(name) CE_DO_PRAGMA(GCC diagnostic ignored #name)
455# define CE_DISABLE_ALL_WARNINGS
456# else
457# error Unsupported compiler!
458# endif
459# define CE_DISABLE_WARNING_UNREFERENCED_FORMAL_PARAMETER CE_DISABLE_WARNING(-Wunused-parameter)
460# define CE_DISABLE_WARNING_UNREFERENCED_FUNCTION CE_DISABLE_WARNING(-Wunused-function)
461# define CE_DISABLE_WARNING_TAUTOLOGICAL_COMPARE CE_DISABLE_WARNING(-Wtautological-compare)
462# define CE_DISABLE_WARNING_REORDER CE_DISABLE_WARNING(-Wreorder)
463# define CE_DISABLE_WARNING_UNUSED_VARIABLE CE_DISABLE_WARNING(-Wunused-variable)
464# define CE_DISABLE_WARNING_UNINITIALIZED_VARIABLE CE_DISABLE_WARNING(-Wuninitialized)
465# define CE_DISABLE_WARNING_MISSING_FIELD_INITIALIZERS CE_DISABLE_WARNING(-Wmissing-field-initializers)
466# define CE_DISABLE_WARNING_UNUSED_PRIVATE_FIELD CE_DISABLE_WARNING(-Wunused-private-field)
467# define CE_DISABLE_WARNING_TYPE_LIMITS CE_DISABLE_WARNING(-Wtype-limits)
468#if CE_COMPILER_CLANG
469# define CE_DISABLE_WARNING_DEPRECATED_VOLATILE CE_DISABLE_WARNING(-Wdeprecated-volatile)
470#else
471# define CE_DISABLE_WARNING_DEPRECATED_VOLATILE /* no-op */
472#endif
473# define CE_DISABLE_WARNING_DEPRECATED_DECLARATIONS CE_DISABLE_WARNING(-Wdeprecated-declarations)
474# define CE_DISABLE_WARNING_UNSIGNED_UNARY_MINUS /* no-op */
475# define CE_DISABLE_WARNING_IMPLICIT_LOSSY_CONVERSION /* no-op */
476#if CE_COMPILER_CLANG
477# define CE_DISABLE_WARNING_MISSING_OVERRIDE CE_DISABLE_WARNING(-Winconsistent-missing-override)
478#else
479# define CE_DISABLE_WARNING_MISSING_OVERRIDE /* no-op */
480#endif
481# define CE_DISABLE_WARNING_INHERITS_VIA_DOMINANCE /* no-op */
482# define CE_DISABLE_WARNING_DESTRUCTOR_IMPLICITLY_DELETED /* no-op */
483#else
484# define CE_DISABLE_WARNING_PUSH
485# define CE_DISABLE_WARNING_POP
486# define CE_DISABLE_ALL_WARNINGS
487
488# define CE_DISABLE_WARNING_UNREFERENCED_FORMAL_PARAMETER
489# define CE_DISABLE_WARNING_UNREFERENCED_FUNCTION
490# define CE_DISABLE_WARNING_TAUTOLOGICAL_COMPARE
491# define CE_DISABLE_WARNING_REORDER
492# define CE_DISABLE_WARNING_UNUSED_VARIABLE
493# define CE_DISABLE_WARNING_UNINITIALIZED_VARIABLE
494# define CE_DISABLE_WARNING_MISSING_FIELD_INITIALIZERS
495# define CE_DISABLE_WARNING_UNUSED_PRIVATE_FIELD
496# define CE_DISABLE_WARNING_TYPE_LIMITS
497# define CE_DISABLE_WARNING_DEPRECATED_VOLATILE
498# define CE_DISABLE_WARNING_DEPRECATED_DECLARATIONS
499# define CE_DISABLE_WARNING_UNSIGNED_UNARY_MINUS
500# define CE_DISABLE_WARNING_UNSIGNED_UNARY_MINUS
501# define CE_DISABLE_WARNING_INHERITS_VIA_DOMINANCE
502# define CE_DISABLE_WARNING_DESTRUCTOR_IMPLICITLY_DELETED
503#endif
504
505// ---------------------------------------------------------------------------------------------
506
507#if CE_COMPILER_MSVC
508#define CE_ASSUME(X) __assume(X)
509#else
510#define CE_ASSUME(X)
511#endif
512
513#if CE_COMPILER_MSVC
514#define CE_CPU_CACHE_LINE std::hardware_destructive_interference_size
515#else
516// On most architectures we can assume a 64-byte cache line.
517#define CE_CPU_CACHE_LINE 64
518#endif
519
520// ---------------------------------------------------------------------------------------------
521
522// clang-format on
523
524#define CE_TOKENPASTE2_(x, y) x##y
525#define CE_TOKENPASTE2(x, y) CE_TOKENPASTE2_(x, y)
526
527#define CE_TOKENPASTE3_(x, y, z) x##y##z
528#define CE_TOKENPASTE3(x, y, z) CE_TOKENPASTE3_(x, y, z)
529
530#define CE_USES_ALLOCATOR(T) \
531 template<typename Alloc> struct std::uses_allocator<T, Alloc> : std::true_type {}
532
533#define FMT_CONSTEVAL
534
535#define GLM_FORCE_RADIANS
536#define GLM_FORCE_DEPTH_ZERO_TO_ONE
537#define GLM_ENABLE_EXPERIMENTAL
538
539// -------------------------------------------------------------------------------------------------
540
541#define CE_REFL_DATA(N) RTTI.template data<&std::decay_t<decltype(RTTI)>::ReflectedType::N>(#N)
542#define CE_REFL_DATA_NAMED(N, M) RTTI.template data<&std::decay_t<decltype(RTTI)>::ReflectedType::M>(#N)
543
544#if CE_COMPILER_MSVC
545#define CE_REFL_DATA_GET(N, G) RTTI.data(#N, [](const typename std::decay_t<decltype(RTTI)>::ReflectedType* obj) { return obj->G(); })
546#define CE_REFL_DATA_GETSET(N, G, S) RTTI.template data<&std::decay_t<decltype(RTTI)>::ReflectedType::G, &std::decay_t<decltype(RTTI)>::ReflectedType::S>(#N)
547#else
548#define CE_REFL_DATA_GET(N, G) RTTI.template data(#N, [](const typename std::decay_t<decltype(RTTI)>::ReflectedType* obj) { return obj->G(); })
549#define CE_REFL_DATA_GETSET(N, G, S) RTTI.template data<&std::decay_t<decltype(RTTI)>::ReflectedType::G, &std::decay_t<decltype(RTTI)>::ReflectedType::S>(#N)
550#endif
551
552#define CE_REFL_FUNC(N) RTTI.template func<&std::decay_t<decltype(RTTI)>::ReflectedType::N>(#N)
553#define CE_REFL_CTOR(...) RTTI.template ctor<__VA_ARGS__>()
554#define CE_REFL_VAL(N) RTTI.template value<std::decay_t<decltype(RTTI)>::ReflectedType::N>(#N)
555#define CE_REFL_BASE(T) RTTI.template base<T>()
556
557// ---------------------------------------------------------------------------------------------
558
559#ifdef __has_attribute
560#if __has_attribute(swift_attr)
561// clang-format off
562#define CE_SWIFT_SELF_CONTAINED __attribute__((swift_attr("import_owned")))
563#define CE_SWIFT_SAFE_TO_IMPORT __attribute__((swift_attr("import_unsafe")))
564
565#define _CXX_INTEROP_STRINGIFY(_x) #_x
566#define CE_SWIFT_REFERENCE_TYPE(_retain, _release) \
567 __attribute__((swift_attr("import_reference"))) \
568 __attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(retain:_retain)))) \
569 __attribute__((swift_attr(_CXX_INTEROP_STRINGIFY(release:_release))))
570// clang-format on
571#else
572#define CE_SWIFT_SELF_CONTAINED
573#define CE_SWIFT_SAFE_TO_IMPORT
574#define CE_SWIFT_REFERENCE_TYPE(_retain, _release)
575#endif
576
577#if defined(__has_attribute) && __has_attribute(swift_name)
578#define CE_SWIFT_NAME(_name) __attribute__((swift_name(#_name)))
579#else
580#define CE_SWIFT_NAME(_name)
581#endif
582#else
583#define CE_SWIFT_SELF_CONTAINED
584#define CE_SWIFT_SAFE_TO_IMPORT
585#define CE_SWIFT_REFERENCE_TYPE(_retain, _release)
586#define CE_SWIFT_NAME(_name)
587#endif