Nugget
eacompilertraits.h
1 /*-----------------------------------------------------------------------------
2  * config/eacompilertraits.h
3  *
4  * Copyright (c) Electronic Arts Inc. All rights reserved.
5  *-----------------------------------------------------------------------------
6  * Currently supported defines include:
7  * EA_PREPROCESSOR_JOIN
8  *
9  * EA_COMPILER_IS_ANSIC
10  * EA_COMPILER_IS_C99
11  * EA_COMPILER_IS_C11
12  * EA_COMPILER_HAS_C99_TYPES
13  * EA_COMPILER_IS_CPLUSPLUS
14  * EA_COMPILER_MANAGED_CPP
15  * EA_COMPILER_INTMAX_SIZE
16  * EA_OFFSETOF
17  * EA_SIZEOF_MEMBER
18  *
19  * EA_ALIGN_OF()
20  * EA_ALIGN_MAX_STATIC / EA_ALIGN_MAX_AUTOMATIC
21  * EA_ALIGN() / EA_PREFIX_ALIGN() / EA_POSTFIX_ALIGN()
22  * EA_ALIGNED()
23  * EA_PACKED()
24  *
25  * EA_LIKELY()
26  * EA_UNLIKELY()
27  * EA_INIT_PRIORITY()
28  * EA_MAY_ALIAS()
29  * EA_ASSUME()
30  * EA_ANALYSIS_ASSUME()
31  * EA_PURE
32  * EA_WEAK
33  * EA_UNUSED()
34  * EA_EMPTY()
35  *
36  * EA_WCHAR_T_NON_NATIVE
37  * EA_WCHAR_SIZE = <n bytes>
38  *
39  * EA_RESTRICT
40  * EA_DEPRECATED / EA_PREFIX_DEPRECATED / EA_POSTFIX_DEPRECATED
41  * EA_FORCE_INLINE / EA_PREFIX_FORCE_INLINE / EA_POSTFIX_FORCE_INLINE
42  * EA_NO_INLINE / EA_PREFIX_NO_INLINE / EA_POSTFIX_NO_INLINE
43  * EA_NO_VTABLE / EA_CLASS_NO_VTABLE / EA_STRUCT_NO_VTABLE
44  * EA_PASCAL
45  * EA_PASCAL_FUNC()
46  * EA_SSE = [0 | 1]
47  * EA_IMPORT
48  * EA_EXPORT
49  * EA_PRAGMA_ONCE_SUPPORTED
50  * EA_ONCE
51  * EA_OVERRIDE
52  * EA_INHERITANCE_FINAL
53  * EA_SEALED
54  * EA_ABSTRACT
55  * EA_CONSTEXPR / EA_CONSTEXPR_OR_CONST
56  * EA_CONSTEXPR_IF
57  * EA_EXTERN_TEMPLATE
58  * EA_NOEXCEPT
59  * EA_NORETURN
60  * EA_CARRIES_DEPENDENCY
61  * EA_NON_COPYABLE / struct EANonCopyable
62  * EA_OPTIMIZE_OFF / EA_OPTIMIZE_ON
63  * EA_SIGNED_RIGHT_SHIFT_IS_UNSIGNED
64  *
65  * EA_DISABLE_VC_WARNING / EA_RESTORE_VC_WARNING / EA_DISABLE_ALL_VC_WARNINGS / EA_RESTORE_ALL_VC_WARNINGS
66  * EA_DISABLE_GCC_WARNING / EA_RESTORE_GCC_WARNING
67  * EA_DISABLE_CLANG_WARNING / EA_RESTORE_CLANG_WARNING
68  * EA_DISABLE_SN_WARNING / EA_RESTORE_SN_WARNING / EA_DISABLE_ALL_SN_WARNINGS / EA_RESTORE_ALL_SN_WARNINGS
69  * EA_DISABLE_GHS_WARNING / EA_RESTORE_GHS_WARNING
70  * EA_DISABLE_EDG_WARNING / EA_RESTORE_EDG_WARNING
71  * EA_DISABLE_CW_WARNING / EA_RESTORE_CW_WARNING
72  *
73  * EA_DISABLE_DEFAULT_CTOR
74  * EA_DISABLE_COPY_CTOR
75  * EA_DISABLE_MOVE_CTOR
76  * EA_DISABLE_ASSIGNMENT_OPERATOR
77  * EA_DISABLE_MOVE_OPERATOR
78  *
79  * Todo:
80  * Find a way to reliably detect wchar_t size at preprocessor time and
81  * implement it below for EA_WCHAR_SIZE.
82  *
83  * Todo:
84  * Find out how to support EA_PASCAL and EA_PASCAL_FUNC for systems in
85  * which it hasn't yet been found out for.
86  *---------------------------------------------------------------------------*/
87 
88 
89 #ifndef INCLUDED_eacompilertraits_H
90 #define INCLUDED_eacompilertraits_H
91 
92  #include <EABase/config/eaplatform.h>
93  #include <EABase/config/eacompiler.h>
94 
95 
96  // Metrowerks uses #defines in its core C header files to define
97  // the kind of information we need below (e.g. C99 compatibility)
98 
99 
100 
101  // Determine if this compiler is ANSI C compliant and if it is C99 compliant.
102  #if defined(__STDC__)
103  #define EA_COMPILER_IS_ANSIC 1 // The compiler claims to be ANSI C
104 
105  // Is the compiler a C99 compiler or equivalent?
106  // From ISO/IEC 9899:1999:
107  // 6.10.8 Predefined macro names
108  // __STDC_VERSION__ The integer constant 199901L. (150)
109  //
110  // 150) This macro was not specified in ISO/IEC 9899:1990 and was
111  // specified as 199409L in ISO/IEC 9899/AMD1:1995. The intention
112  // is that this will remain an integer constant of type long int
113  // that is increased with each revision of this International Standard.
114  //
115  #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
116  #define EA_COMPILER_IS_C99 1
117  #endif
118 
119  // Is the compiler a C11 compiler?
120  // From ISO/IEC 9899:2011:
121  // Page 176, 6.10.8.1 (Predefined macro names) :
122  // __STDC_VERSION__ The integer constant 201112L. (178)
123  //
124  #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
125  #define EA_COMPILER_IS_C11 1
126  #endif
127  #endif
128 
129  // Some compilers (e.g. GCC) define __USE_ISOC99 if they are not
130  // strictly C99 compilers (or are simply C++ compilers) but are set
131  // to use C99 functionality. Metrowerks defines _MSL_C99 as 1 in
132  // this case, but 0 otherwise.
133  #if (defined(__USE_ISOC99) || (defined(_MSL_C99) && (_MSL_C99 == 1))) && !defined(EA_COMPILER_IS_C99)
134  #define EA_COMPILER_IS_C99 1
135  #endif
136 
137  // Metrowerks defines C99 types (e.g. intptr_t) instrinsically when in C99 mode (-lang C99 on the command line).
138  #if (defined(_MSL_C99) && (_MSL_C99 == 1))
139  #define EA_COMPILER_HAS_C99_TYPES 1
140  #endif
141 
142  #if defined(__GNUC__)
143  #if (((__GNUC__ * 100) + __GNUC_MINOR__) >= 302) // Also, GCC defines _HAS_C9X.
144  #define EA_COMPILER_HAS_C99_TYPES 1 // The compiler is not necessarily a C99 compiler, but it defines C99 types.
145 
146  #ifndef __STDC_LIMIT_MACROS
147  #define __STDC_LIMIT_MACROS 1
148  #endif
149 
150  #ifndef __STDC_CONSTANT_MACROS
151  #define __STDC_CONSTANT_MACROS 1 // This tells the GCC compiler that we want it to use its native C99 types.
152  #endif
153  #endif
154  #endif
155 
156  #if defined(_MSC_VER) && (_MSC_VER >= 1600)
157  #define EA_COMPILER_HAS_C99_TYPES 1
158  #endif
159 
160  #ifdef __cplusplus
161  #define EA_COMPILER_IS_CPLUSPLUS 1
162  #endif
163 
164 
165  // ------------------------------------------------------------------------
166  // EA_PREPROCESSOR_JOIN
167  //
168  // This macro joins the two arguments together, even when one of
169  // the arguments is itself a macro (see 16.3.1 in C++98 standard).
170  // This is often used to create a unique name with __LINE__.
171  //
172  // For example, this declaration:
173  // char EA_PREPROCESSOR_JOIN(unique_, __LINE__);
174  // expands to this:
175  // char unique_73;
176  //
177  // Note that all versions of MSVC++ up to at least version 7.1
178  // fail to properly compile macros that use __LINE__ in them
179  // when the "program database for edit and continue" option
180  // is enabled. The result is that __LINE__ gets converted to
181  // something like __LINE__(Var+37).
182  //
183  #ifndef EA_PREPROCESSOR_JOIN
184  #define EA_PREPROCESSOR_JOIN(a, b) EA_PREPROCESSOR_JOIN1(a, b)
185  #define EA_PREPROCESSOR_JOIN1(a, b) EA_PREPROCESSOR_JOIN2(a, b)
186  #define EA_PREPROCESSOR_JOIN2(a, b) a##b
187  #endif
188 
189 
190  // ------------------------------------------------------------------------
191  // EA_STRINGIFY
192  //
193  // Example usage:
194  // printf("Line: %s", EA_STRINGIFY(__LINE__));
195  //
196  #ifndef EA_STRINGIFY
197  #define EA_STRINGIFY(x) EA_STRINGIFYIMPL(x)
198  #define EA_STRINGIFYIMPL(x) #x
199  #endif
200 
201 
202  // ------------------------------------------------------------------------
203  // EA_IDENTITY
204  //
205  #ifndef EA_IDENTITY
206  #define EA_IDENTITY(x) x
207  #endif
208 
209 
210  // ------------------------------------------------------------------------
211  // EA_COMPILER_MANAGED_CPP
212  // Defined if this is being compiled with Managed C++ extensions
213  #ifdef EA_COMPILER_MSVC
214  #if EA_COMPILER_VERSION >= 1300
215  #ifdef _MANAGED
216  #define EA_COMPILER_MANAGED_CPP 1
217  #endif
218  #endif
219  #endif
220 
221 
222  // ------------------------------------------------------------------------
223  // EA_COMPILER_INTMAX_SIZE
224  //
225  // This is related to the concept of intmax_t uintmax_t, but is available
226  // in preprocessor form as opposed to compile-time form. At compile-time
227  // you can use intmax_t and uintmax_t to use the actual types.
228  //
229  #if defined(__GNUC__) && defined(__x86_64__)
230  #define EA_COMPILER_INTMAX_SIZE 16 // intmax_t is __int128_t (GCC extension) and is 16 bytes.
231  #else
232  #define EA_COMPILER_INTMAX_SIZE 8 // intmax_t is int64_t and is 8 bytes.
233  #endif
234 
235 
236 
237  // ------------------------------------------------------------------------
238  // EA_LPAREN / EA_RPAREN / EA_COMMA / EA_SEMI
239  //
240  // These are used for using special characters in macro-using expressions.
241  // Note that this macro intentionally uses (), as in some cases it can't
242  // work unless it does.
243  //
244  // Example usage:
245  // int x = SOME_MACRO(SomeTemplate<int EA_COMMA() int EACOMMA() char>);
246  //
247  #ifndef EA_LPAREN
248  #define EA_LPAREN() (
249  #endif
250  #ifndef EA_RPAREN
251  #define EA_RPAREN() )
252  #endif
253  #ifndef EA_COMMA
254  #define EA_COMMA() ,
255  #endif
256  #ifndef EA_SEMI
257  #define EA_SEMI() ;
258  #endif
259 
260 
261 
262 
263  // ------------------------------------------------------------------------
264  // EA_OFFSETOF
265  // Implements a portable version of the non-standard offsetof macro.
266  //
267  // The offsetof macro is guaranteed to only work with POD types. However, we wish to use
268  // it for non-POD types but where we know that offsetof will still work for the cases
269  // in which we use it. GCC unilaterally gives a warning when using offsetof with a non-POD,
270  // even if the given usage happens to work. So we make a workaround version of offsetof
271  // here for GCC which has the same effect but tricks the compiler into not issuing the warning.
272  // The 65536 does the compiler fooling; the reinterpret_cast prevents the possibility of
273  // an overloaded operator& for the class getting in the way.
274  //
275  // Example usage:
276  // struct A{ int x; int y; };
277  // size_t n = EA_OFFSETOF(A, y);
278  //
279  #if defined(__GNUC__) // We can't use GCC 4's __builtin_offsetof because it mistakenly complains about non-PODs that are really PODs.
280  #define EA_OFFSETOF(struct_, member_) ((size_t)(((uintptr_t)&reinterpret_cast<const volatile char&>((((struct_*)65536)->member_))) - 65536))
281  #else
282  #define EA_OFFSETOF(struct_, member_) offsetof(struct_, member_)
283  #endif
284 
285  // ------------------------------------------------------------------------
286  // EA_SIZEOF_MEMBER
287  // Implements a portable way to determine the size of a member.
288  //
289  // The EA_SIZEOF_MEMBER simply returns the size of a member within a class or struct; member
290  // access rules still apply. We offer two approaches depending on the compiler's support for non-static member
291  // initializers although most C++11 compilers support this.
292  //
293  // Example usage:
294  // struct A{ int x; int y; };
295  // size_t n = EA_SIZEOF_MEMBER(A, y);
296  //
297  #ifndef EA_COMPILER_NO_EXTENDED_SIZEOF
298  #define EA_SIZEOF_MEMBER(struct_, member_) (sizeof(struct_::member_))
299  #else
300  #define EA_SIZEOF_MEMBER(struct_, member_) (sizeof(((struct_*)0)->member_))
301  #endif
302 
303  // ------------------------------------------------------------------------
304  // alignment expressions
305  //
306  // Here we define
307  // EA_ALIGN_OF(type) // Returns size_t.
308  // EA_ALIGN_MAX_STATIC // The max align value that the compiler will respect for EA_ALIGN for static data (global and static variables). Some compilers allow high values, some allow no more than 8. EA_ALIGN_MIN is assumed to be 1.
309  // EA_ALIGN_MAX_AUTOMATIC // The max align value for automatic variables (variables declared as local to a function).
310  // EA_ALIGN(n) // Used as a prefix. n is byte alignment, with being a power of two. Most of the time you can use this and avoid using EA_PREFIX_ALIGN/EA_POSTFIX_ALIGN.
311  // EA_ALIGNED(t, v, n) // Type, variable, alignment. Used to align an instance. You should need this only for unusual compilers.
312  // EA_PACKED // Specifies that the given structure be packed (and not have its members aligned).
313  //
314  // Also we define the following for rare cases that it's needed.
315  // EA_PREFIX_ALIGN(n) // n is byte alignment, with being a power of two. You should need this only for unusual compilers.
316  // EA_POSTFIX_ALIGN(n) // Valid values for n are 1, 2, 4, 8, etc. You should need this only for unusual compilers.
317  //
318  // Example usage:
319  // size_t x = EA_ALIGN_OF(int); Non-aligned equivalents. Meaning
320  // EA_PREFIX_ALIGN(8) int x = 5; int x = 5; Align x on 8 for compilers that require prefix attributes. Can just use EA_ALIGN instead.
321  // EA_ALIGN(8) int x; int x; Align x on 8 for compilers that allow prefix attributes.
322  // int x EA_POSTFIX_ALIGN(8); int x; Align x on 8 for compilers that require postfix attributes.
323  // int x EA_POSTFIX_ALIGN(8) = 5; int x = 5; Align x on 8 for compilers that require postfix attributes.
324  // int x EA_POSTFIX_ALIGN(8)(5); int x(5); Align x on 8 for compilers that require postfix attributes.
325  // struct EA_PREFIX_ALIGN(8) X { int x; } EA_POSTFIX_ALIGN(8); struct X { int x; }; Define X as a struct which is aligned on 8 when used.
326  // EA_ALIGNED(int, x, 8) = 5; int x = 5; Align x on 8.
327  // EA_ALIGNED(int, x, 16)(5); int x(5); Align x on 16.
328  // EA_ALIGNED(int, x[3], 16); int x[3]; Align x array on 16.
329  // EA_ALIGNED(int, x[3], 16) = { 1, 2, 3 }; int x[3] = { 1, 2, 3 }; Align x array on 16.
330  // int x[3] EA_PACKED; int x[3]; Pack the 3 ints of the x array. GCC doesn't seem to support packing of int arrays.
331  // struct EA_ALIGN(32) X { int x; int y; }; struct X { int x; }; Define A as a struct which is aligned on 32 when used.
332  // EA_ALIGN(32) struct X { int x; int y; } Z; struct X { int x; } Z; Define A as a struct, and align the instance Z on 32.
333  // struct X { int x EA_PACKED; int y EA_PACKED; }; struct X { int x; int y; }; Pack the x and y members of struct X.
334  // struct X { int x; int y; } EA_PACKED; struct X { int x; int y; }; Pack the members of struct X.
335  // typedef EA_ALIGNED(int, int16, 16); int16 n16; typedef int int16; int16 n16; Define int16 as an int which is aligned on 16.
336  // typedef EA_ALIGNED(X, X16, 16); X16 x16; typedef X X16; X16 x16; Define X16 as an X which is aligned on 16.
337 
338  #if !defined(EA_ALIGN_MAX) // If the user hasn't globally set an alternative value...
339  #if defined(EA_PROCESSOR_ARM) // ARM compilers in general tend to limit automatic variables to 8 or less.
340  #define EA_ALIGN_MAX_STATIC 1048576
341  #define EA_ALIGN_MAX_AUTOMATIC 1 // Typically they support only built-in natural aligment types (both arm-eabi and apple-abi).
342  #elif defined(EA_PLATFORM_APPLE)
343  #define EA_ALIGN_MAX_STATIC 1048576
344  #define EA_ALIGN_MAX_AUTOMATIC 16
345  #else
346  #define EA_ALIGN_MAX_STATIC 1048576 // Arbitrarily high value. What is the actual max?
347  #define EA_ALIGN_MAX_AUTOMATIC 1048576
348  #endif
349  #endif
350 
351  // EDG intends to be compatible with GCC but has a bug whereby it
352  // fails to support calling a constructor in an aligned declaration when
353  // using postfix alignment attributes. Prefix works for alignment, but does not align
354  // the size like postfix does. Prefix also fails on templates. So gcc style post fix
355  // is still used, but the user will need to use EA_POSTFIX_ALIGN before the constructor parameters.
356  #if defined(__GNUC__) && (__GNUC__ < 3)
357  #define EA_ALIGN_OF(type) ((size_t)__alignof__(type))
358  #define EA_ALIGN(n)
359  #define EA_PREFIX_ALIGN(n)
360  #define EA_POSTFIX_ALIGN(n) __attribute__((aligned(n)))
361  #define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n)))
362  #define EA_PACKED __attribute__((packed))
363 
364  // GCC 3.x+, IBM, and clang support prefix attributes.
365  #elif (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__xlC__) || defined(__clang__)
366  #define EA_ALIGN_OF(type) ((size_t)__alignof__(type))
367  #define EA_ALIGN(n) __attribute__((aligned(n)))
368  #define EA_PREFIX_ALIGN(n)
369  #define EA_POSTFIX_ALIGN(n) __attribute__((aligned(n)))
370  #define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n)))
371  #define EA_PACKED __attribute__((packed))
372 
373  // Metrowerks supports prefix attributes.
374  // Metrowerks does not support packed alignment attributes.
375  #elif defined(EA_COMPILER_INTEL) || defined(CS_UNDEFINED_STRING) || (defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1300))
376  #define EA_ALIGN_OF(type) ((size_t)__alignof(type))
377  #define EA_ALIGN(n) __declspec(align(n))
378  #define EA_PREFIX_ALIGN(n) EA_ALIGN(n)
379  #define EA_POSTFIX_ALIGN(n)
380  #define EA_ALIGNED(variable_type, variable, n) EA_ALIGN(n) variable_type variable
381  #define EA_PACKED // See EA_PRAGMA_PACK_VC for an alternative.
382 
383  // Arm brand compiler
384  #elif defined(EA_COMPILER_ARM)
385  #define EA_ALIGN_OF(type) ((size_t)__ALIGNOF__(type))
386  #define EA_ALIGN(n) __align(n)
387  #define EA_PREFIX_ALIGN(n) __align(n)
388  #define EA_POSTFIX_ALIGN(n)
389  #define EA_ALIGNED(variable_type, variable, n) __align(n) variable_type variable
390  #define EA_PACKED __packed
391 
392  #else // Unusual compilers
393  // There is nothing we can do about some of these. This is not as bad a problem as it seems.
394  // If the given platform/compiler doesn't support alignment specifications, then it's somewhat
395  // likely that alignment doesn't matter for that platform. Otherwise they would have defined
396  // functionality to manipulate alignment.
397  #define EA_ALIGN(n)
398  #define EA_PREFIX_ALIGN(n)
399  #define EA_POSTFIX_ALIGN(n)
400  #define EA_ALIGNED(variable_type, variable, n) variable_type variable
401  #define EA_PACKED
402 
403  #ifdef __cplusplus
404  template <typename T> struct EAAlignOf1 { enum { s = sizeof (T), value = s ^ (s & (s - 1)) }; };
405  template <typename T> struct EAAlignOf2;
406  template <int size_diff> struct helper { template <typename T> struct Val { enum { value = size_diff }; }; };
407  template <> struct helper<0> { template <typename T> struct Val { enum { value = EAAlignOf2<T>::value }; }; };
408  template <typename T> struct EAAlignOf2 { struct Big { T x; char c; };
409  enum { diff = sizeof (Big) - sizeof (T), value = helper<diff>::template Val<Big>::value }; };
410  template <typename T> struct EAAlignof3 { enum { x = EAAlignOf2<T>::value, y = EAAlignOf1<T>::value, value = x < y ? x : y }; };
411  #define EA_ALIGN_OF(type) ((size_t)EAAlignof3<type>::value)
412 
413  #else
414  // C implementation of EA_ALIGN_OF
415  // This implementation works for most cases, but doesn't directly work
416  // for types such as function pointer declarations. To work with those
417  // types you need to typedef the type and then use the typedef in EA_ALIGN_OF.
418  #define EA_ALIGN_OF(type) ((size_t)offsetof(struct { char c; type m; }, m))
419  #endif
420  #endif
421 
422  // EA_PRAGMA_PACK_VC
423  //
424  // Wraps #pragma pack in a way that allows for cleaner code.
425  //
426  // Example usage:
427  // EA_PRAGMA_PACK_VC(push, 1)
428  // struct X{ char c; int i; };
429  // EA_PRAGMA_PACK_VC(pop)
430  //
431  #if !defined(EA_PRAGMA_PACK_VC)
432  #if defined(EA_COMPILER_MSVC)
433  #define EA_PRAGMA_PACK_VC(...) __pragma(pack(__VA_ARGS__))
434  #elif !defined(EA_COMPILER_NO_VARIADIC_MACROS)
435  #define EA_PRAGMA_PACK_VC(...)
436  #else
437  // No support. However, all compilers of significance to us support variadic macros.
438  #endif
439  #endif
440 
441 
442  // ------------------------------------------------------------------------
443  // EA_LIKELY / EA_UNLIKELY
444  //
445  // Defined as a macro which gives a hint to the compiler for branch
446  // prediction. GCC gives you the ability to manually give a hint to
447  // the compiler about the result of a comparison, though it's often
448  // best to compile shipping code with profiling feedback under both
449  // GCC (-fprofile-arcs) and VC++ (/LTCG:PGO, etc.). However, there
450  // are times when you feel very sure that a boolean expression will
451  // usually evaluate to either true or false and can help the compiler
452  // by using an explicity directive...
453  //
454  // Example usage:
455  // if(EA_LIKELY(a == 0)) // Tell the compiler that a will usually equal 0.
456  // { ... }
457  //
458  // Example usage:
459  // if(EA_UNLIKELY(a == 0)) // Tell the compiler that a will usually not equal 0.
460  // { ... }
461  //
462  #ifndef EA_LIKELY
463  #if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__clang__)
464  #if defined(__cplusplus)
465  #define EA_LIKELY(x) __builtin_expect(!!(x), true)
466  #define EA_UNLIKELY(x) __builtin_expect(!!(x), false)
467  #else
468  #define EA_LIKELY(x) __builtin_expect(!!(x), 1)
469  #define EA_UNLIKELY(x) __builtin_expect(!!(x), 0)
470  #endif
471  #else
472  #define EA_LIKELY(x) (x)
473  #define EA_UNLIKELY(x) (x)
474  #endif
475  #endif
476 
477  // ------------------------------------------------------------------------
478  // EA_HAS_INCLUDE_AVAILABLE
479  //
480  // Used to guard against the EA_HAS_INCLUDE() macro on compilers that do not
481  // support said feature.
482  //
483  // Example usage:
484  //
485  // #if EA_HAS_INCLUDE_AVAILABLE
486  // #if EA_HAS_INCLUDE("myinclude.h")
487  // #include "myinclude.h"
488  // #endif
489  // #endif
490  #if !defined(EA_HAS_INCLUDE_AVAILABLE)
491  #if EA_COMPILER_CPP17_ENABLED || EA_COMPILER_CLANG || EA_COMPILER_GNUC
492  #define EA_HAS_INCLUDE_AVAILABLE 1
493  #else
494  #define EA_HAS_INCLUDE_AVAILABLE 0
495  #endif
496  #endif
497 
498 
499  // ------------------------------------------------------------------------
500  // EA_HAS_INCLUDE
501  //
502  // May be used in #if and #elif expressions to test for the existence
503  // of the header referenced in the operand. If possible it evaluates to a
504  // non-zero value and zero otherwise. The operand is the same form as the file
505  // in a #include directive.
506  //
507  // Example usage:
508  //
509  // #if EA_HAS_INCLUDE("myinclude.h")
510  // #include "myinclude.h"
511  // #endif
512  //
513  // #if EA_HAS_INCLUDE(<myinclude.h>)
514  // #include <myinclude.h>
515  // #endif
516 
517  #if !defined(EA_HAS_INCLUDE)
518  #if EA_COMPILER_CPP17_ENABLED
519  #define EA_HAS_INCLUDE(x) __has_include(x)
520  #elif EA_COMPILER_CLANG
521  #define EA_HAS_INCLUDE(x) __has_include(x)
522  #elif EA_COMPILER_GNUC
523  #define EA_HAS_INCLUDE(x) __has_include(x)
524  #endif
525  #endif
526 
527 
528  // ------------------------------------------------------------------------
529  // EA_INIT_PRIORITY_AVAILABLE
530  //
531  // This value is either not defined, or defined to 1.
532  // Defines if the GCC attribute init_priority is supported by the compiler.
533  //
534  #if !defined(EA_INIT_PRIORITY_AVAILABLE)
535  #if defined(__GNUC__) && !defined(__EDG__) // EDG typically #defines __GNUC__ but doesn't implement init_priority.
536  #define EA_INIT_PRIORITY_AVAILABLE 1
537  #elif defined(__clang__)
538  #define EA_INIT_PRIORITY_AVAILABLE 1 // Clang implements init_priority
539  #endif
540  #endif
541 
542 
543  // ------------------------------------------------------------------------
544  // EA_INIT_PRIORITY
545  //
546  // This is simply a wrapper for the GCC init_priority attribute that allows
547  // multiplatform code to be easier to read. This attribute doesn't apply
548  // to VC++ because VC++ uses file-level pragmas to control init ordering.
549  //
550  // Example usage:
551  // SomeClass gSomeClass EA_INIT_PRIORITY(2000);
552  //
553  #if !defined(EA_INIT_PRIORITY)
554  #if defined(EA_INIT_PRIORITY_AVAILABLE)
555  #define EA_INIT_PRIORITY(x) __attribute__ ((init_priority (x)))
556  #else
557  #define EA_INIT_PRIORITY(x)
558  #endif
559  #endif
560 
561 
562  // ------------------------------------------------------------------------
563  // EA_INIT_SEG_AVAILABLE
564  //
565  //
566  #if !defined(EA_INIT_SEG_AVAILABLE)
567  #if defined(_MSC_VER)
568  #define EA_INIT_SEG_AVAILABLE 1
569  #endif
570  #endif
571 
572 
573  // ------------------------------------------------------------------------
574  // EA_INIT_SEG
575  //
576  // Specifies a keyword or code section that affects the order in which startup code is executed.
577  //
578  // https://docs.microsoft.com/en-us/cpp/preprocessor/init-seg?view=vs-2019
579  //
580  // Example:
581  // EA_INIT_SEG(compiler) MyType gMyTypeGlobal;
582  // EA_INIT_SEG("my_section") MyOtherType gMyOtherTypeGlobal;
583  //
584  #if !defined(EA_INIT_SEG)
585  #if defined(EA_INIT_SEG_AVAILABLE)
586  #define EA_INIT_SEG(x) \
587  __pragma(warning(push)) __pragma(warning(disable : 4074)) __pragma(warning(disable : 4075)) __pragma(init_seg(x)) \
588  __pragma(warning(pop))
589  #else
590  #define EA_INIT_SEG(x)
591  #endif
592  #endif
593 
594 
595  // ------------------------------------------------------------------------
596  // EA_MAY_ALIAS_AVAILABLE
597  //
598  // Defined as 0, 1, or 2.
599  // Defines if the GCC attribute may_alias is supported by the compiler.
600  // Consists of a value 0 (unsupported, shouldn't be used), 1 (some support),
601  // or 2 (full proper support).
602  //
603  #ifndef EA_MAY_ALIAS_AVAILABLE
604  #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 303)
605  #if !defined(__EDG__) // define it as 1 while defining GCC's support as 2.
606  #define EA_MAY_ALIAS_AVAILABLE 2
607  #else
608  #define EA_MAY_ALIAS_AVAILABLE 0
609  #endif
610  #else
611  #define EA_MAY_ALIAS_AVAILABLE 0
612  #endif
613  #endif
614 
615 
616  // EA_MAY_ALIAS
617  //
618  // Defined as a macro that wraps the GCC may_alias attribute. This attribute
619  // has no significance for VC++ because VC++ doesn't support the concept of
620  // strict aliasing. Users should avoid writing code that breaks strict
621  // aliasing rules; EA_MAY_ALIAS is for cases with no alternative.
622  //
623  // Example usage:
624  // void* EA_MAY_ALIAS gPtr = NULL;
625  //
626  // Example usage:
627  // typedef void* EA_MAY_ALIAS pvoid_may_alias;
628  // pvoid_may_alias gPtr = NULL;
629  //
630  #if EA_MAY_ALIAS_AVAILABLE
631  #define EA_MAY_ALIAS __attribute__((__may_alias__))
632  #else
633  #define EA_MAY_ALIAS
634  #endif
635 
636 
637  // ------------------------------------------------------------------------
638  // EA_ASSUME
639  //
640  // This acts the same as the VC++ __assume directive and is implemented
641  // simply as a wrapper around it to allow portable usage of it and to take
642  // advantage of it if and when it appears in other compilers.
643  //
644  // Example usage:
645  // void Function(int a) {
646  // switch(a) {
647  // case 1:
648  // DoSomething(1);
649  // break;
650  // case 2:
651  // DoSomething(-1);
652  // break;
653  // default:
654  // EA_ASSUME(0); // This tells the optimizer that the default cannot be reached.
655  // }
656  // }
657  //
658  #ifndef EA_ASSUME
659  #if defined(_MSC_VER) && (_MSC_VER >= 1300) // If VC7.0 and later
660  #define EA_ASSUME(x) __assume(x)
661  #else
662  #define EA_ASSUME(x)
663  #endif
664  #endif
665 
666 
667 
668  // ------------------------------------------------------------------------
669  // EA_ANALYSIS_ASSUME
670  //
671  // This acts the same as the VC++ __analysis_assume directive and is implemented
672  // simply as a wrapper around it to allow portable usage of it and to take
673  // advantage of it if and when it appears in other compilers.
674  //
675  // Example usage:
676  // char Function(char* p) {
677  // EA_ANALYSIS_ASSUME(p != NULL);
678  // return *p;
679  // }
680  //
681  #ifndef EA_ANALYSIS_ASSUME
682  #if defined(_MSC_VER) && (_MSC_VER >= 1300) // If VC7.0 and later
683  #define EA_ANALYSIS_ASSUME(x) __analysis_assume(!!(x)) // !! because that allows for convertible-to-bool in addition to bool.
684  #else
685  #define EA_ANALYSIS_ASSUME(x)
686  #endif
687  #endif
688 
689 
690 
691  // ------------------------------------------------------------------------
692  // EA_DISABLE_VC_WARNING / EA_RESTORE_VC_WARNING
693  //
694  // Disable and re-enable warning(s) within code.
695  // This is simply a wrapper for VC++ #pragma warning(disable: nnnn) for the
696  // purpose of making code easier to read due to avoiding nested compiler ifdefs
697  // directly in code.
698  //
699  // Example usage:
700  // EA_DISABLE_VC_WARNING(4127 3244)
701  // <code>
702  // EA_RESTORE_VC_WARNING()
703  //
704  #ifndef EA_DISABLE_VC_WARNING
705  #if defined(_MSC_VER)
706  #define EA_DISABLE_VC_WARNING(w) \
707  __pragma(warning(push)) \
708  __pragma(warning(disable:w))
709  #else
710  #define EA_DISABLE_VC_WARNING(w)
711  #endif
712  #endif
713 
714  #ifndef EA_RESTORE_VC_WARNING
715  #if defined(_MSC_VER)
716  #define EA_RESTORE_VC_WARNING() \
717  __pragma(warning(pop))
718  #else
719  #define EA_RESTORE_VC_WARNING()
720  #endif
721  #endif
722 
723 
724  // ------------------------------------------------------------------------
725  // EA_ENABLE_VC_WARNING_AS_ERROR / EA_DISABLE_VC_WARNING_AS_ERROR
726  //
727  // Disable and re-enable treating a warning as error within code.
728  // This is simply a wrapper for VC++ #pragma warning(error: nnnn) for the
729  // purpose of making code easier to read due to avoiding nested compiler ifdefs
730  // directly in code.
731  //
732  // Example usage:
733  // EA_ENABLE_VC_WARNING_AS_ERROR(4996)
734  // <code>
735  // EA_DISABLE_VC_WARNING_AS_ERROR()
736  //
737  #ifndef EA_ENABLE_VC_WARNING_AS_ERROR
738  #if defined(_MSC_VER)
739  #define EA_ENABLE_VC_WARNING_AS_ERROR(w) \
740  __pragma(warning(push)) \
741  __pragma(warning(error:w))
742  #else
743  #define EA_ENABLE_VC_WARNING_AS_ERROR(w)
744  #endif
745  #endif
746 
747  #ifndef EA_DISABLE_VC_WARNING_AS_ERROR
748  #if defined(_MSC_VER)
749  #define EA_DISABLE_VC_WARNING_AS_ERROR() \
750  __pragma(warning(pop))
751  #else
752  #define EA_DISABLE_VC_WARNING_AS_ERROR()
753  #endif
754  #endif
755 
756 
757  // ------------------------------------------------------------------------
758  // EA_DISABLE_GCC_WARNING / EA_RESTORE_GCC_WARNING
759  //
760  // Example usage:
761  // // Only one warning can be ignored per statement, due to how GCC works.
762  // EA_DISABLE_GCC_WARNING(-Wuninitialized)
763  // EA_DISABLE_GCC_WARNING(-Wunused)
764  // <code>
765  // EA_RESTORE_GCC_WARNING()
766  // EA_RESTORE_GCC_WARNING()
767  //
768  #ifndef EA_DISABLE_GCC_WARNING
769  #if defined(EA_COMPILER_GNUC)
770  #define EAGCCWHELP0(x) #x
771  #define EAGCCWHELP1(x) EAGCCWHELP0(GCC diagnostic ignored x)
772  #define EAGCCWHELP2(x) EAGCCWHELP1(#x)
773  #endif
774 
775  #if defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION >= 4006) // Can't test directly for __GNUC__ because some compilers lie.
776  #define EA_DISABLE_GCC_WARNING(w) \
777  _Pragma("GCC diagnostic push") \
778  _Pragma(EAGCCWHELP2(w))
779  #elif defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION >= 4004)
780  #define EA_DISABLE_GCC_WARNING(w) \
781  _Pragma(EAGCCWHELP2(w))
782  #else
783  #define EA_DISABLE_GCC_WARNING(w)
784  #endif
785  #endif
786 
787  #ifndef EA_RESTORE_GCC_WARNING
788  #if defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION >= 4006)
789  #define EA_RESTORE_GCC_WARNING() \
790  _Pragma("GCC diagnostic pop")
791  #else
792  #define EA_RESTORE_GCC_WARNING()
793  #endif
794  #endif
795 
796 
797  // ------------------------------------------------------------------------
798  // EA_DISABLE_ALL_GCC_WARNINGS / EA_RESTORE_ALL_GCC_WARNINGS
799  //
800  // This isn't possible except via using _Pragma("GCC system_header"), though
801  // that has some limitations in how it works. Another means is to manually
802  // disable individual warnings within a GCC diagnostic push statement.
803  // GCC doesn't have as many warnings as VC++ and EDG and so this may be feasible.
804  // ------------------------------------------------------------------------
805 
806 
807  // ------------------------------------------------------------------------
808  // EA_ENABLE_GCC_WARNING_AS_ERROR / EA_DISABLE_GCC_WARNING_AS_ERROR
809  //
810  // Example usage:
811  // // Only one warning can be treated as an error per statement, due to how GCC works.
812  // EA_ENABLE_GCC_WARNING_AS_ERROR(-Wuninitialized)
813  // EA_ENABLE_GCC_WARNING_AS_ERROR(-Wunused)
814  // <code>
815  // EA_DISABLE_GCC_WARNING_AS_ERROR()
816  // EA_DISABLE_GCC_WARNING_AS_ERROR()
817  //
818  #ifndef EA_ENABLE_GCC_WARNING_AS_ERROR
819  #if defined(EA_COMPILER_GNUC)
820  #define EAGCCWERRORHELP0(x) #x
821  #define EAGCCWERRORHELP1(x) EAGCCWERRORHELP0(GCC diagnostic error x)
822  #define EAGCCWERRORHELP2(x) EAGCCWERRORHELP1(#x)
823  #endif
824 
825  #if defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION >= 4006) // Can't test directly for __GNUC__ because some compilers lie.
826  #define EA_ENABLE_GCC_WARNING_AS_ERROR(w) \
827  _Pragma("GCC diagnostic push") \
828  _Pragma(EAGCCWERRORHELP2(w))
829  #elif defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION >= 4004)
830  #define EA_DISABLE_GCC_WARNING(w) \
831  _Pragma(EAGCCWERRORHELP2(w))
832  #else
833  #define EA_DISABLE_GCC_WARNING(w)
834  #endif
835  #endif
836 
837  #ifndef EA_DISABLE_GCC_WARNING_AS_ERROR
838  #if defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION >= 4006)
839  #define EA_DISABLE_GCC_WARNING_AS_ERROR() \
840  _Pragma("GCC diagnostic pop")
841  #else
842  #define EA_DISABLE_GCC_WARNING_AS_ERROR()
843  #endif
844  #endif
845 
846 
847  // ------------------------------------------------------------------------
848  // EA_DISABLE_CLANG_WARNING / EA_RESTORE_CLANG_WARNING
849  //
850  // Example usage:
851  // // Only one warning can be ignored per statement, due to how clang works.
852  // EA_DISABLE_CLANG_WARNING(-Wuninitialized)
853  // EA_DISABLE_CLANG_WARNING(-Wunused)
854  // <code>
855  // EA_RESTORE_CLANG_WARNING()
856  // EA_RESTORE_CLANG_WARNING()
857  //
858  #ifndef EA_DISABLE_CLANG_WARNING
859  #if defined(EA_COMPILER_CLANG) || defined(EA_COMPILER_CLANG_CL)
860  #define EACLANGWHELP0(x) #x
861  #define EACLANGWHELP1(x) EACLANGWHELP0(clang diagnostic ignored x)
862  #define EACLANGWHELP2(x) EACLANGWHELP1(#x)
863 
864  #define EA_DISABLE_CLANG_WARNING(w) \
865  _Pragma("clang diagnostic push") \
866  _Pragma(EACLANGWHELP2(-Wunknown-warning-option))\
867  _Pragma(EACLANGWHELP2(w))
868  #else
869  #define EA_DISABLE_CLANG_WARNING(w)
870  #endif
871  #endif
872 
873  #ifndef EA_RESTORE_CLANG_WARNING
874  #if defined(EA_COMPILER_CLANG) || defined(EA_COMPILER_CLANG_CL)
875  #define EA_RESTORE_CLANG_WARNING() \
876  _Pragma("clang diagnostic pop")
877  #else
878  #define EA_RESTORE_CLANG_WARNING()
879  #endif
880  #endif
881 
882 
883  // ------------------------------------------------------------------------
884  // EA_DISABLE_ALL_CLANG_WARNINGS / EA_RESTORE_ALL_CLANG_WARNINGS
885  //
886  // The situation for clang is the same as for GCC. See above.
887  // ------------------------------------------------------------------------
888 
889 
890  // ------------------------------------------------------------------------
891  // EA_ENABLE_CLANG_WARNING_AS_ERROR / EA_DISABLE_CLANG_WARNING_AS_ERROR
892  //
893  // Example usage:
894  // // Only one warning can be treated as an error per statement, due to how clang works.
895  // EA_ENABLE_CLANG_WARNING_AS_ERROR(-Wuninitialized)
896  // EA_ENABLE_CLANG_WARNING_AS_ERROR(-Wunused)
897  // <code>
898  // EA_DISABLE_CLANG_WARNING_AS_ERROR()
899  // EA_DISABLE_CLANG_WARNING_AS_ERROR()
900  //
901  #ifndef EA_ENABLE_CLANG_WARNING_AS_ERROR
902  #if defined(EA_COMPILER_CLANG) || defined(EA_COMPILER_CLANG_CL)
903  #define EACLANGWERRORHELP0(x) #x
904  #define EACLANGWERRORHELP1(x) EACLANGWERRORHELP0(clang diagnostic error x)
905  #define EACLANGWERRORHELP2(x) EACLANGWERRORHELP1(#x)
906 
907  #define EA_ENABLE_CLANG_WARNING_AS_ERROR(w) \
908  _Pragma("clang diagnostic push") \
909  _Pragma(EACLANGWERRORHELP2(w))
910  #else
911  #define EA_DISABLE_CLANG_WARNING(w)
912  #endif
913  #endif
914 
915  #ifndef EA_DISABLE_CLANG_WARNING_AS_ERROR
916  #if defined(EA_COMPILER_CLANG) || defined(EA_COMPILER_CLANG_CL)
917  #define EA_DISABLE_CLANG_WARNING_AS_ERROR() \
918  _Pragma("clang diagnostic pop")
919  #else
920  #define EA_DISABLE_CLANG_WARNING_AS_ERROR()
921  #endif
922  #endif
923 
924 
925  // ------------------------------------------------------------------------
926  // EA_DISABLE_SN_WARNING / EA_RESTORE_SN_WARNING
927  //
928  // Note that we define this macro specifically for the SN compiler instead of
929  // having a generic one for EDG-based compilers. The reason for this is that
930  // while SN is indeed based on EDG, SN has different warning value mappings
931  // and thus warning 1234 for SN is not the same as 1234 for all other EDG compilers.
932  //
933  // Example usage:
934  // // Currently we are limited to one warning per line.
935  // EA_DISABLE_SN_WARNING(1787)
936  // EA_DISABLE_SN_WARNING(552)
937  // <code>
938  // EA_RESTORE_SN_WARNING()
939  // EA_RESTORE_SN_WARNING()
940  //
941  #ifndef EA_DISABLE_SN_WARNING
942  #define EA_DISABLE_SN_WARNING(w)
943  #endif
944 
945  #ifndef EA_RESTORE_SN_WARNING
946  #define EA_RESTORE_SN_WARNING()
947  #endif
948 
949 
950  // ------------------------------------------------------------------------
951  // EA_DISABLE_ALL_SN_WARNINGS / EA_RESTORE_ALL_SN_WARNINGS
952  //
953  // Example usage:
954  // EA_DISABLE_ALL_SN_WARNINGS()
955  // <code>
956  // EA_RESTORE_ALL_SN_WARNINGS()
957  //
958  #ifndef EA_DISABLE_ALL_SN_WARNINGS
959  #define EA_DISABLE_ALL_SN_WARNINGS()
960  #endif
961 
962  #ifndef EA_RESTORE_ALL_SN_WARNINGS
963  #define EA_RESTORE_ALL_SN_WARNINGS()
964  #endif
965 
966 
967 
968  // ------------------------------------------------------------------------
969  // EA_DISABLE_GHS_WARNING / EA_RESTORE_GHS_WARNING
970  //
971  // Disable warnings from the Green Hills compiler.
972  //
973  // Example usage:
974  // EA_DISABLE_GHS_WARNING(193)
975  // EA_DISABLE_GHS_WARNING(236, 5323)
976  // <code>
977  // EA_RESTORE_GHS_WARNING()
978  // EA_RESTORE_GHS_WARNING()
979  //
980  #ifndef EA_DISABLE_GHS_WARNING
981  #define EA_DISABLE_GHS_WARNING(w)
982  #endif
983 
984  #ifndef EA_RESTORE_GHS_WARNING
985  #define EA_RESTORE_GHS_WARNING()
986  #endif
987 
988 
989  // ------------------------------------------------------------------------
990  // EA_DISABLE_ALL_GHS_WARNINGS / EA_RESTORE_ALL_GHS_WARNINGS
991  //
992  // #ifndef EA_DISABLE_ALL_GHS_WARNINGS
993  // #if defined(EA_COMPILER_GREEN_HILLS)
994  // #define EA_DISABLE_ALL_GHS_WARNINGS(w) \_
995  // _Pragma("_________")
996  // #else
997  // #define EA_DISABLE_ALL_GHS_WARNINGS(w)
998  // #endif
999  // #endif
1000  //
1001  // #ifndef EA_RESTORE_ALL_GHS_WARNINGS
1002  // #if defined(EA_COMPILER_GREEN_HILLS)
1003  // #define EA_RESTORE_ALL_GHS_WARNINGS() \_
1004  // _Pragma("_________")
1005  // #else
1006  // #define EA_RESTORE_ALL_GHS_WARNINGS()
1007  // #endif
1008  // #endif
1009 
1010 
1011 
1012  // ------------------------------------------------------------------------
1013  // EA_DISABLE_EDG_WARNING / EA_RESTORE_EDG_WARNING
1014  //
1015  // Example usage:
1016  // // Currently we are limited to one warning per line.
1017  // EA_DISABLE_EDG_WARNING(193)
1018  // EA_DISABLE_EDG_WARNING(236)
1019  // <code>
1020  // EA_RESTORE_EDG_WARNING()
1021  // EA_RESTORE_EDG_WARNING()
1022  //
1023  #ifndef EA_DISABLE_EDG_WARNING
1024  // EDG-based compilers are inconsistent in how the implement warning pragmas.
1025  #if defined(EA_COMPILER_EDG) && !defined(EA_COMPILER_INTEL) && !defined(EA_COMPILER_RVCT)
1026  #define EAEDGWHELP0(x) #x
1027  #define EAEDGWHELP1(x) EAEDGWHELP0(diag_suppress x)
1028 
1029  #define EA_DISABLE_EDG_WARNING(w) \
1030  _Pragma("control %push diag") \
1031  _Pragma(EAEDGWHELP1(w))
1032  #else
1033  #define EA_DISABLE_EDG_WARNING(w)
1034  #endif
1035  #endif
1036 
1037  #ifndef EA_RESTORE_EDG_WARNING
1038  #if defined(EA_COMPILER_EDG) && !defined(EA_COMPILER_INTEL) && !defined(EA_COMPILER_RVCT)
1039  #define EA_RESTORE_EDG_WARNING() \
1040  _Pragma("control %pop diag")
1041  #else
1042  #define EA_RESTORE_EDG_WARNING()
1043  #endif
1044  #endif
1045 
1046 
1047  // ------------------------------------------------------------------------
1048  // EA_DISABLE_ALL_EDG_WARNINGS / EA_RESTORE_ALL_EDG_WARNINGS
1049  //
1050  //#ifndef EA_DISABLE_ALL_EDG_WARNINGS
1051  // #if defined(EA_COMPILER_EDG) && !defined(EA_COMPILER_SN)
1052  // #define EA_DISABLE_ALL_EDG_WARNINGS(w) \_
1053  // _Pragma("_________")
1054  // #else
1055  // #define EA_DISABLE_ALL_EDG_WARNINGS(w)
1056  // #endif
1057  //#endif
1058  //
1059  //#ifndef EA_RESTORE_ALL_EDG_WARNINGS
1060  // #if defined(EA_COMPILER_EDG) && !defined(EA_COMPILER_SN)
1061  // #define EA_RESTORE_ALL_EDG_WARNINGS() \_
1062  // _Pragma("_________")
1063  // #else
1064  // #define EA_RESTORE_ALL_EDG_WARNINGS()
1065  // #endif
1066  //#endif
1067 
1068 
1069 
1070  // ------------------------------------------------------------------------
1071  // EA_DISABLE_CW_WARNING / EA_RESTORE_CW_WARNING
1072  //
1073  // Note that this macro can only control warnings via numbers and not by
1074  // names. The reason for this is that the compiler's syntax for such
1075  // warnings is not the same as for numbers.
1076  //
1077  // Example usage:
1078  // // Currently we are limited to one warning per line and must also specify the warning in the restore macro.
1079  // EA_DISABLE_CW_WARNING(10317)
1080  // EA_DISABLE_CW_WARNING(10324)
1081  // <code>
1082  // EA_RESTORE_CW_WARNING(10317)
1083  // EA_RESTORE_CW_WARNING(10324)
1084  //
1085  #ifndef EA_DISABLE_CW_WARNING
1086  #define EA_DISABLE_CW_WARNING(w)
1087  #endif
1088 
1089  #ifndef EA_RESTORE_CW_WARNING
1090 
1091  #define EA_RESTORE_CW_WARNING(w)
1092 
1093  #endif
1094 
1095 
1096  // ------------------------------------------------------------------------
1097  // EA_DISABLE_ALL_CW_WARNINGS / EA_RESTORE_ALL_CW_WARNINGS
1098  //
1099  #ifndef EA_DISABLE_ALL_CW_WARNINGS
1100  #define EA_DISABLE_ALL_CW_WARNINGS()
1101 
1102  #endif
1103 
1104  #ifndef EA_RESTORE_ALL_CW_WARNINGS
1105  #define EA_RESTORE_ALL_CW_WARNINGS()
1106  #endif
1107 
1108 
1109 
1110  // ------------------------------------------------------------------------
1111  // EA_PURE
1112  //
1113  // This acts the same as the GCC __attribute__ ((pure)) directive and is
1114  // implemented simply as a wrapper around it to allow portable usage of
1115  // it and to take advantage of it if and when it appears in other compilers.
1116  //
1117  // A "pure" function is one that has no effects except its return value and
1118  // its return value is a function of only the function's parameters or
1119  // non-volatile global variables. Any parameter or global variable access
1120  // must be read-only. Loop optimization and subexpression elimination can be
1121  // applied to such functions. A common example is strlen(): Given identical
1122  // inputs, the function's return value (its only effect) is invariant across
1123  // multiple invocations and thus can be pulled out of a loop and called but once.
1124  //
1125  // Example usage:
1126  // EA_PURE void Function();
1127  //
1128  #ifndef EA_PURE
1129  #if defined(EA_COMPILER_GNUC)
1130  #define EA_PURE __attribute__((pure))
1131  #elif defined(EA_COMPILER_ARM) // Arm brand compiler for ARM CPU
1132  #define EA_PURE __pure
1133  #else
1134  #define EA_PURE
1135  #endif
1136  #endif
1137 
1138 
1139 
1140  // ------------------------------------------------------------------------
1141  // EA_WEAK
1142  // EA_WEAK_SUPPORTED -- defined as 0 or 1.
1143  //
1144  // GCC
1145  // The weak attribute causes the declaration to be emitted as a weak
1146  // symbol rather than a global. This is primarily useful in defining
1147  // library functions which can be overridden in user code, though it
1148  // can also be used with non-function declarations.
1149  //
1150  // VC++
1151  // At link time, if multiple definitions of a COMDAT are seen, the linker
1152  // picks one and discards the rest. If the linker option /OPT:REF
1153  // is selected, then COMDAT elimination will occur to remove all the
1154  // unreferenced data items in the linker output.
1155  //
1156  // Example usage:
1157  // EA_WEAK void Function();
1158  //
1159  #ifndef EA_WEAK
1160  #if defined(_MSC_VER) && (_MSC_VER >= 1300) // If VC7.0 and later
1161  #define EA_WEAK __declspec(selectany)
1162  #define EA_WEAK_SUPPORTED 1
1163  #elif defined(_MSC_VER) || (defined(__GNUC__) && defined(__CYGWIN__))
1164  #define EA_WEAK
1165  #define EA_WEAK_SUPPORTED 0
1166  #elif defined(EA_COMPILER_ARM) // Arm brand compiler for ARM CPU
1167  #define EA_WEAK __weak
1168  #define EA_WEAK_SUPPORTED 1
1169  #else // GCC and IBM compilers, others.
1170  #define EA_WEAK __attribute__((weak))
1171  #define EA_WEAK_SUPPORTED 1
1172  #endif
1173  #endif
1174 
1175 
1176 
1177  // ------------------------------------------------------------------------
1178  // EA_UNUSED
1179  //
1180  // Makes compiler warnings about unused variables go away.
1181  //
1182  // Example usage:
1183  // void Function(int x)
1184  // {
1185  // int y;
1186  // EA_UNUSED(x);
1187  // EA_UNUSED(y);
1188  // }
1189  //
1190  #ifndef EA_UNUSED
1191  // The EDG solution below is pretty weak and needs to be augmented or replaced.
1192  // It can't handle the C language, is limited to places where template declarations
1193  // can be used, and requires the type x to be usable as a functions reference argument.
1194  #if defined(__cplusplus) && defined(__EDG__)
1195  template <typename T>
1196  inline void EABaseUnused(T const volatile & x) { (void)x; }
1197  #define EA_UNUSED(x) EABaseUnused(x)
1198  #else
1199  #define EA_UNUSED(x) (void)x
1200  #endif
1201  #endif
1202 
1203 
1204 
1205  // ------------------------------------------------------------------------
1206  // EA_EMPTY
1207  //
1208  // Allows for a null statement, usually for the purpose of avoiding compiler warnings.
1209  //
1210  // Example usage:
1211  // #ifdef EA_DEBUG
1212  // #define MyDebugPrintf(x, y) printf(x, y)
1213  // #else
1214  // #define MyDebugPrintf(x, y) EA_EMPTY
1215  // #endif
1216  //
1217  #ifndef EA_EMPTY
1218  #define EA_EMPTY (void)0
1219  #endif
1220 
1221 
1222  // ------------------------------------------------------------------------
1223  // EA_CURRENT_FUNCTION
1224  //
1225  // Provides a consistent way to get the current function name as a macro
1226  // like the __FILE__ and __LINE__ macros work. The C99 standard specifies
1227  // that __func__ be provided by the compiler, but most compilers don't yet
1228  // follow that convention. However, many compilers have an alternative.
1229  //
1230  // We also define EA_CURRENT_FUNCTION_SUPPORTED for when it is not possible
1231  // to have EA_CURRENT_FUNCTION work as expected.
1232  //
1233  // Defined inside a function because otherwise the macro might not be
1234  // defined and code below might not compile. This happens with some
1235  // compilers.
1236  //
1237  #ifndef EA_CURRENT_FUNCTION
1238  #if defined __GNUC__ || (defined __ICC && __ICC >= 600)
1239  #define EA_CURRENT_FUNCTION __PRETTY_FUNCTION__
1240  #elif defined(__FUNCSIG__)
1241  #define EA_CURRENT_FUNCTION __FUNCSIG__
1242  #elif (defined __INTEL_COMPILER && __INTEL_COMPILER >= 600) || (defined __IBMCPP__ && __IBMCPP__ >= 500) || (defined CS_UNDEFINED_STRING && CS_UNDEFINED_STRING >= 0x4200)
1243  #define EA_CURRENT_FUNCTION __FUNCTION__
1244  #elif defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901
1245  #define EA_CURRENT_FUNCTION __func__
1246  #else
1247  #define EA_CURRENT_FUNCTION "(unknown function)"
1248  #endif
1249  #endif
1250 
1251 
1252  // ------------------------------------------------------------------------
1253  // wchar_t
1254  // Here we define:
1255  // EA_WCHAR_T_NON_NATIVE
1256  // EA_WCHAR_SIZE = <sizeof(wchar_t)>
1257  //
1258  #ifndef EA_WCHAR_T_NON_NATIVE
1259  // Compilers that always implement wchar_t as native include:
1260  // COMEAU, new SN, and other EDG-based compilers.
1261  // GCC
1262  // Borland
1263  // SunPro
1264  // IBM Visual Age
1265  #if defined(EA_COMPILER_INTEL)
1266  #if (EA_COMPILER_VERSION < 700)
1267  #define EA_WCHAR_T_NON_NATIVE 1
1268  #else
1269  #if (!defined(_WCHAR_T_DEFINED) && !defined(_WCHAR_T))
1270  #define EA_WCHAR_T_NON_NATIVE 1
1271  #endif
1272  #endif
1273  #elif defined(EA_COMPILER_MSVC) || (defined(EA_COMPILER_CLANG) && defined(EA_PLATFORM_WINDOWS))
1274  #ifndef _NATIVE_WCHAR_T_DEFINED
1275  #define EA_WCHAR_T_NON_NATIVE 1
1276  #endif
1277  #elif defined(__EDG_VERSION__) && (!defined(_WCHAR_T) && (__EDG_VERSION__ < 400)) // EDG prior to v4 uses _WCHAR_T to indicate if wchar_t is native. v4+ may define something else, but we're not currently aware of it.
1278  #define EA_WCHAR_T_NON_NATIVE 1
1279  #endif
1280  #endif
1281 
1282  #ifndef EA_WCHAR_SIZE // If the user hasn't specified that it is a given size...
1283  #if defined(__WCHAR_MAX__) // GCC defines this for most platforms.
1284  #if (__WCHAR_MAX__ == 2147483647) || (__WCHAR_MAX__ == 4294967295)
1285  #define EA_WCHAR_SIZE 4
1286  #elif (__WCHAR_MAX__ == 32767) || (__WCHAR_MAX__ == 65535)
1287  #define EA_WCHAR_SIZE 2
1288  #elif (__WCHAR_MAX__ == 127) || (__WCHAR_MAX__ == 255)
1289  #define EA_WCHAR_SIZE 1
1290  #else
1291  #define EA_WCHAR_SIZE 4
1292  #endif
1293  #elif defined(WCHAR_MAX) // The SN and Arm compilers define this.
1294  #if (WCHAR_MAX == 2147483647) || (WCHAR_MAX == 4294967295)
1295  #define EA_WCHAR_SIZE 4
1296  #elif (WCHAR_MAX == 32767) || (WCHAR_MAX == 65535)
1297  #define EA_WCHAR_SIZE 2
1298  #elif (WCHAR_MAX == 127) || (WCHAR_MAX == 255)
1299  #define EA_WCHAR_SIZE 1
1300  #else
1301  #define EA_WCHAR_SIZE 4
1302  #endif
1303  #elif defined(__WCHAR_BIT) // Green Hills (and other versions of EDG?) uses this.
1304  #if (__WCHAR_BIT == 16)
1305  #define EA_WCHAR_SIZE 2
1306  #elif (__WCHAR_BIT == 32)
1307  #define EA_WCHAR_SIZE 4
1308  #elif (__WCHAR_BIT == 8)
1309  #define EA_WCHAR_SIZE 1
1310  #else
1311  #define EA_WCHAR_SIZE 4
1312  #endif
1313  #elif defined(_WCMAX) // The SN and Arm compilers define this.
1314  #if (_WCMAX == 2147483647) || (_WCMAX == 4294967295)
1315  #define EA_WCHAR_SIZE 4
1316  #elif (_WCMAX == 32767) || (_WCMAX == 65535)
1317  #define EA_WCHAR_SIZE 2
1318  #elif (_WCMAX == 127) || (_WCMAX == 255)
1319  #define EA_WCHAR_SIZE 1
1320  #else
1321  #define EA_WCHAR_SIZE 4
1322  #endif
1323  #elif defined(EA_PLATFORM_UNIX)
1324  // It is standard on Unix to have wchar_t be int32_t or uint32_t.
1325  // All versions of GNUC default to a 32 bit wchar_t, but EA has used
1326  // the -fshort-wchar GCC command line option to force it to 16 bit.
1327  // If you know that the compiler is set to use a wchar_t of other than
1328  // the default, you need to manually define EA_WCHAR_SIZE for the build.
1329  #define EA_WCHAR_SIZE 4
1330  #else
1331  // It is standard on Windows to have wchar_t be uint16_t. GCC
1332  // defines wchar_t as int by default. Electronic Arts has
1333  // standardized on wchar_t being an unsigned 16 bit value on all
1334  // console platforms. Given that there is currently no known way to
1335  // tell at preprocessor time what the size of wchar_t is, we declare
1336  // it to be 2, as this is the Electronic Arts standard. If you have
1337  // EA_WCHAR_SIZE != sizeof(wchar_t), then your code might not be
1338  // broken, but it also won't work with wchar libraries and data from
1339  // other parts of EA. Under GCC, you can force wchar_t to two bytes
1340  // with the -fshort-wchar compiler argument.
1341  #define EA_WCHAR_SIZE 2
1342  #endif
1343  #endif
1344 
1345 
1346  // ------------------------------------------------------------------------
1347  // EA_RESTRICT
1348  //
1349  // The C99 standard defines a new keyword, restrict, which allows for the
1350  // improvement of code generation regarding memory usage. Compilers can
1351  // generate significantly faster code when you are able to use restrict.
1352  //
1353  // Example usage:
1354  // void DoSomething(char* EA_RESTRICT p1, char* EA_RESTRICT p2);
1355  //
1356  #ifndef EA_RESTRICT
1357  #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // If VC8 (VS2005) or later...
1358  #define EA_RESTRICT __restrict
1359  #elif defined(EA_COMPILER_CLANG)
1360  #define EA_RESTRICT __restrict
1361  #elif defined(EA_COMPILER_GNUC) // Includes GCC and other compilers emulating GCC.
1362  #define EA_RESTRICT __restrict // GCC defines 'restrict' (as opposed to __restrict) in C99 mode only.
1363  #elif defined(EA_COMPILER_ARM)
1364  #define EA_RESTRICT __restrict
1365  #elif defined(EA_COMPILER_IS_C99)
1366  #define EA_RESTRICT restrict
1367  #else
1368  // If the compiler didn't support restricted pointers, defining EA_RESTRICT
1369  // away would result in compiling and running fine but you just wouldn't
1370  // the same level of optimization. On the other hand, all the major compilers
1371  // support restricted pointers.
1372  #define EA_RESTRICT
1373  #endif
1374  #endif
1375 
1376 
1377  // ------------------------------------------------------------------------
1378  // EA_DEPRECATED // Used as a prefix.
1379  // EA_PREFIX_DEPRECATED // You should need this only for unusual compilers.
1380  // EA_POSTFIX_DEPRECATED // You should need this only for unusual compilers.
1381  // EA_DEPRECATED_MESSAGE // Used as a prefix and provides a deprecation message.
1382  //
1383  // Example usage:
1384  // EA_DEPRECATED void Function();
1385  // EA_DEPRECATED_MESSAGE("Use 1.0v API instead") void Function();
1386  //
1387  // or for maximum portability:
1388  // EA_PREFIX_DEPRECATED void Function() EA_POSTFIX_DEPRECATED;
1389  //
1390 
1391  #ifndef EA_DEPRECATED
1392  #if defined(EA_COMPILER_CPP14_ENABLED)
1393  #define EA_DEPRECATED [[deprecated]]
1394  #elif defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION > 1300) // If VC7 (VS2003) or later...
1395  #define EA_DEPRECATED __declspec(deprecated)
1396  #elif defined(EA_COMPILER_MSVC)
1397  #define EA_DEPRECATED
1398  #else
1399  #define EA_DEPRECATED __attribute__((deprecated))
1400  #endif
1401  #endif
1402 
1403  #ifndef EA_PREFIX_DEPRECATED
1404  #if defined(EA_COMPILER_CPP14_ENABLED)
1405  #define EA_PREFIX_DEPRECATED [[deprecated]]
1406  #define EA_POSTFIX_DEPRECATED
1407  #elif defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION > 1300) // If VC7 (VS2003) or later...
1408  #define EA_PREFIX_DEPRECATED __declspec(deprecated)
1409  #define EA_POSTFIX_DEPRECATED
1410  #elif defined(EA_COMPILER_MSVC)
1411  #define EA_PREFIX_DEPRECATED
1412  #define EA_POSTFIX_DEPRECATED
1413  #else
1414  #define EA_PREFIX_DEPRECATED
1415  #define EA_POSTFIX_DEPRECATED __attribute__((deprecated))
1416  #endif
1417  #endif
1418 
1419  #ifndef EA_DEPRECATED_MESSAGE
1420  #if defined(EA_COMPILER_CPP14_ENABLED)
1421  #define EA_DEPRECATED_MESSAGE(msg) [[deprecated(#msg)]]
1422  #else
1423  // Compiler does not support depreaction messages, explicitly drop the msg but still mark the function as deprecated
1424  #define EA_DEPRECATED_MESSAGE(msg) EA_DEPRECATED
1425  #endif
1426  #endif
1427 
1428 
1429  // ------------------------------------------------------------------------
1430  // EA_FORCE_INLINE // Used as a prefix.
1431  // EA_PREFIX_FORCE_INLINE // You should need this only for unusual compilers.
1432  // EA_POSTFIX_FORCE_INLINE // You should need this only for unusual compilers.
1433  //
1434  // Example usage:
1435  // EA_FORCE_INLINE void Foo(); // Implementation elsewhere.
1436  // EA_PREFIX_FORCE_INLINE void Foo() EA_POSTFIX_FORCE_INLINE; // Implementation elsewhere.
1437  //
1438  // Note that when the prefix version of this function is used, it replaces
1439  // the regular C++ 'inline' statement. Thus you should not use both the
1440  // C++ inline statement and this macro with the same function declaration.
1441  //
1442  // To force inline usage under GCC 3.1+, you use this:
1443  // inline void Foo() __attribute__((always_inline));
1444  // or
1445  // inline __attribute__((always_inline)) void Foo();
1446  //
1447  // The CodeWarrior compiler doesn't have the concept of forcing inlining per function.
1448  //
1449  #ifndef EA_FORCE_INLINE
1450  #if defined(EA_COMPILER_MSVC)
1451  #define EA_FORCE_INLINE __forceinline
1452  #elif defined(EA_COMPILER_GNUC) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 301) || defined(EA_COMPILER_CLANG)
1453  #if defined(__cplusplus)
1454  #define EA_FORCE_INLINE inline __attribute__((always_inline))
1455  #else
1456  #define EA_FORCE_INLINE __inline__ __attribute__((always_inline))
1457  #endif
1458  #else
1459  #if defined(__cplusplus)
1460  #define EA_FORCE_INLINE inline
1461  #else
1462  #define EA_FORCE_INLINE __inline
1463  #endif
1464  #endif
1465  #endif
1466 
1467  #if defined(EA_COMPILER_GNUC) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 301) || defined(EA_COMPILER_CLANG)
1468  #define EA_PREFIX_FORCE_INLINE inline
1469  #define EA_POSTFIX_FORCE_INLINE __attribute__((always_inline))
1470  #else
1471  #define EA_PREFIX_FORCE_INLINE inline
1472  #define EA_POSTFIX_FORCE_INLINE
1473  #endif
1474 
1475 
1476  // ------------------------------------------------------------------------
1477  // EA_FORCE_INLINE_LAMBDA
1478  //
1479  // EA_FORCE_INLINE_LAMBDA is used to force inline a call to a lambda when possible.
1480  // Force inlining a lambda can be useful to reduce overhead in situations where a lambda may
1481  // may only be called once, or inlining allows the compiler to apply other optimizations that wouldn't
1482  // otherwise be possible.
1483  //
1484  // The ability to force inline a lambda is currently only available on a subset of compilers.
1485  //
1486  // Example usage:
1487  //
1488  // auto lambdaFunction = []() EA_FORCE_INLINE_LAMBDA
1489  // {
1490  // };
1491  //
1492  #ifndef EA_FORCE_INLINE_LAMBDA
1493  #if defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)
1494  #define EA_FORCE_INLINE_LAMBDA __attribute__((always_inline))
1495  #else
1496  #define EA_FORCE_INLINE_LAMBDA
1497  #endif
1498  #endif
1499 
1500 
1501  // ------------------------------------------------------------------------
1502  // EA_NO_INLINE // Used as a prefix.
1503  // EA_PREFIX_NO_INLINE // You should need this only for unusual compilers.
1504  // EA_POSTFIX_NO_INLINE // You should need this only for unusual compilers.
1505  //
1506  // Example usage:
1507  // EA_NO_INLINE void Foo(); // Implementation elsewhere.
1508  // EA_PREFIX_NO_INLINE void Foo() EA_POSTFIX_NO_INLINE; // Implementation elsewhere.
1509  //
1510  // That this declaration is incompatbile with C++ 'inline' and any
1511  // variant of EA_FORCE_INLINE.
1512  //
1513  // To disable inline usage under VC++ priof to VS2005, you need to use this:
1514  // #pragma inline_depth(0) // Disable inlining.
1515  // void Foo() { ... }
1516  // #pragma inline_depth() // Restore to default.
1517  //
1518  // Since there is no easy way to disable inlining on a function-by-function
1519  // basis in VC++ prior to VS2005, the best strategy is to write platform-specific
1520  // #ifdefs in the code or to disable inlining for a given module and enable
1521  // functions individually with EA_FORCE_INLINE.
1522  //
1523  #ifndef EA_NO_INLINE
1524  #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // If VC8 (VS2005) or later...
1525  #define EA_NO_INLINE __declspec(noinline)
1526  #elif defined(EA_COMPILER_MSVC)
1527  #define EA_NO_INLINE
1528  #else
1529  #define EA_NO_INLINE __attribute__((noinline))
1530  #endif
1531  #endif
1532 
1533  #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // If VC8 (VS2005) or later...
1534  #define EA_PREFIX_NO_INLINE __declspec(noinline)
1535  #define EA_POSTFIX_NO_INLINE
1536  #elif defined(EA_COMPILER_MSVC)
1537  #define EA_PREFIX_NO_INLINE
1538  #define EA_POSTFIX_NO_INLINE
1539  #else
1540  #define EA_PREFIX_NO_INLINE
1541  #define EA_POSTFIX_NO_INLINE __attribute__((noinline))
1542  #endif
1543 
1544 
1545  // ------------------------------------------------------------------------
1546  // EA_NO_VTABLE
1547  //
1548  // Example usage:
1549  // class EA_NO_VTABLE X {
1550  // virtual void InterfaceFunction();
1551  // };
1552  //
1553  // EA_CLASS_NO_VTABLE(X) {
1554  // virtual void InterfaceFunction();
1555  // };
1556  //
1557  #ifdef EA_COMPILER_MSVC
1558  #define EA_NO_VTABLE __declspec(novtable)
1559  #define EA_CLASS_NO_VTABLE(x) class __declspec(novtable) x
1560  #define EA_STRUCT_NO_VTABLE(x) struct __declspec(novtable) x
1561  #else
1562  #define EA_NO_VTABLE
1563  #define EA_CLASS_NO_VTABLE(x) class x
1564  #define EA_STRUCT_NO_VTABLE(x) struct x
1565  #endif
1566 
1567 
1568  // ------------------------------------------------------------------------
1569  // EA_PASCAL
1570  //
1571  // Also known on PC platforms as stdcall.
1572  // This convention causes the compiler to assume that the called function
1573  // will pop off the stack space used to pass arguments, unless it takes a
1574  // variable number of arguments.
1575  //
1576  // Example usage:
1577  // this:
1578  // void DoNothing(int x);
1579  // void DoNothing(int x){}
1580  // would be written as this:
1581  // void EA_PASCAL_FUNC(DoNothing(int x));
1582  // void EA_PASCAL_FUNC(DoNothing(int x)){}
1583  //
1584  #ifndef EA_PASCAL
1585  #if defined(EA_COMPILER_MSVC)
1586  #define EA_PASCAL __stdcall
1587  #elif defined(EA_COMPILER_GNUC) && defined(EA_PROCESSOR_X86)
1588  #define EA_PASCAL __attribute__((stdcall))
1589  #else
1590  // Some compilers simply don't support pascal calling convention.
1591  // As a result, there isn't an issue here, since the specification of
1592  // pascal calling convention is for the purpose of disambiguating the
1593  // calling convention that is applied.
1594  #define EA_PASCAL
1595  #endif
1596  #endif
1597 
1598  #ifndef EA_PASCAL_FUNC
1599  #if defined(EA_COMPILER_MSVC)
1600  #define EA_PASCAL_FUNC(funcname_and_paramlist) __stdcall funcname_and_paramlist
1601  #elif defined(EA_COMPILER_GNUC) && defined(EA_PROCESSOR_X86)
1602  #define EA_PASCAL_FUNC(funcname_and_paramlist) __attribute__((stdcall)) funcname_and_paramlist
1603  #else
1604  #define EA_PASCAL_FUNC(funcname_and_paramlist) funcname_and_paramlist
1605  #endif
1606  #endif
1607 
1608 
1609  // ------------------------------------------------------------------------
1610  // EA_SSE
1611  // Visual C Processor Packs define _MSC_FULL_VER and are needed for SSE
1612  // Intel C also has SSE support.
1613  // EA_SSE is used to select FPU or SSE versions in hw_select.inl
1614  //
1615  // EA_SSE defines the level of SSE support:
1616  // 0 indicates no SSE support
1617  // 1 indicates SSE1 is supported
1618  // 2 indicates SSE2 is supported
1619  // 3 indicates SSE3 (or greater) is supported
1620  //
1621  // Note: SSE support beyond SSE3 can't be properly represented as a single
1622  // version number. Instead users should use specific SSE defines (e.g.
1623  // EA_SSE4_2) to detect what specific support is available. EA_SSE being
1624  // equal to 3 really only indicates that SSE3 or greater is supported.
1625  #ifndef EA_SSE
1626  #if defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)
1627  #if defined(__SSE3__)
1628  #define EA_SSE 3
1629  #elif defined(__SSE2__)
1630  #define EA_SSE 2
1631  #elif defined(__SSE__) && __SSE__
1632  #define EA_SSE 1
1633  #else
1634  #define EA_SSE 0
1635  #endif
1636  #elif (defined(EA_SSE3) && EA_SSE3) || defined EA_PLATFORM_XBOXONE || defined CS_UNDEFINED_STRING
1637  #define EA_SSE 3
1638  #elif defined(EA_SSE2) && EA_SSE2
1639  #define EA_SSE 2
1640  #elif defined(EA_PROCESSOR_X86) && defined(_MSC_FULL_VER) && !defined(__NOSSE__) && defined(_M_IX86_FP)
1641  #define EA_SSE _M_IX86_FP
1642  #elif defined(EA_PROCESSOR_X86) && defined(EA_COMPILER_INTEL) && !defined(__NOSSE__)
1643  #define EA_SSE 1
1644  #elif defined(EA_PROCESSOR_X86_64)
1645  // All x64 processors support SSE2 or higher
1646  #define EA_SSE 2
1647  #else
1648  #define EA_SSE 0
1649  #endif
1650  #endif
1651 
1652  // ------------------------------------------------------------------------
1653  // We define separate defines for SSE support beyond SSE1. These defines
1654  // are particularly useful for detecting SSE4.x features since there isn't
1655  // a single concept of SSE4.
1656  //
1657  // The following SSE defines are always defined. 0 indicates the
1658  // feature/level of SSE is not supported, and 1 indicates support is
1659  // available.
1660  #ifndef EA_SSE2
1661  #if EA_SSE >= 2
1662  #define EA_SSE2 1
1663  #else
1664  #define EA_SSE2 0
1665  #endif
1666  #endif
1667  #ifndef EA_SSE3
1668  #if EA_SSE >= 3
1669  #define EA_SSE3 1
1670  #else
1671  #define EA_SSE3 0
1672  #endif
1673  #endif
1674  #ifndef EA_SSSE3
1675  #if defined __SSSE3__ || defined EA_PLATFORM_XBOXONE || defined CS_UNDEFINED_STRING
1676  #define EA_SSSE3 1
1677  #else
1678  #define EA_SSSE3 0
1679  #endif
1680  #endif
1681  #ifndef EA_SSE4_1
1682  #if defined __SSE4_1__ || defined EA_PLATFORM_XBOXONE || defined CS_UNDEFINED_STRING
1683  #define EA_SSE4_1 1
1684  #else
1685  #define EA_SSE4_1 0
1686  #endif
1687  #endif
1688  #ifndef EA_SSE4_2
1689  #if defined __SSE4_2__ || defined EA_PLATFORM_XBOXONE || defined CS_UNDEFINED_STRING
1690  #define EA_SSE4_2 1
1691  #else
1692  #define EA_SSE4_2 0
1693  #endif
1694  #endif
1695  #ifndef EA_SSE4A
1696  #if defined __SSE4A__ || defined EA_PLATFORM_XBOXONE || defined CS_UNDEFINED_STRING
1697  #define EA_SSE4A 1
1698  #else
1699  #define EA_SSE4A 0
1700  #endif
1701  #endif
1702 
1703  // ------------------------------------------------------------------------
1704  // EA_AVX
1705  // EA_AVX may be used to determine if Advanced Vector Extensions are available for the target architecture
1706  //
1707  // EA_AVX defines the level of AVX support:
1708  // 0 indicates no AVX support
1709  // 1 indicates AVX1 is supported
1710  // 2 indicates AVX2 is supported
1711  #ifndef EA_AVX
1712  #if defined __AVX2__
1713  #define EA_AVX 2
1714  #elif defined __AVX__ || defined EA_PLATFORM_XBOXONE || defined CS_UNDEFINED_STRING
1715  #define EA_AVX 1
1716  #else
1717  #define EA_AVX 0
1718  #endif
1719  #endif
1720  #ifndef EA_AVX2
1721  #if EA_AVX >= 2
1722  #define EA_AVX2 1
1723  #else
1724  #define EA_AVX2 0
1725  #endif
1726  #endif
1727 
1728  // EA_FP16C may be used to determine the existence of float <-> half conversion operations on an x86 CPU.
1729  // (For example to determine if _mm_cvtph_ps or _mm_cvtps_ph could be used.)
1730  #ifndef EA_FP16C
1731  #if defined __F16C__ || defined EA_PLATFORM_XBOXONE || defined CS_UNDEFINED_STRING
1732  #define EA_FP16C 1
1733  #else
1734  #define EA_FP16C 0
1735  #endif
1736  #endif
1737 
1738  // EA_FP128 may be used to determine if __float128 is a supported type for use. This type is enabled by a GCC extension (_GLIBCXX_USE_FLOAT128)
1739  // but has support by some implementations of clang (__FLOAT128__)
1740  // PS4 does not support __float128 as of SDK 5.500 https://ps4.siedev.net/resources/documents/SDK/5.500/CPU_Compiler_ABI-Overview/0003.html
1741  #ifndef EA_FP128
1742  #if (defined __FLOAT128__ || defined _GLIBCXX_USE_FLOAT128) && !defined(EA_PLATFORM_SONY)
1743  #define EA_FP128 1
1744  #else
1745  #define EA_FP128 0
1746  #endif
1747  #endif
1748 
1749  // ------------------------------------------------------------------------
1750  // EA_ABM
1751  // EA_ABM may be used to determine if Advanced Bit Manipulation sets are available for the target architecture (POPCNT, LZCNT)
1752  //
1753  #ifndef EA_ABM
1754  #if defined(__ABM__) || defined(EA_PLATFORM_XBOXONE) || defined(EA_PLATFORM_SONY) || defined(CS_UNDEFINED_STRING)
1755  #define EA_ABM 1
1756  #else
1757  #define EA_ABM 0
1758  #endif
1759  #endif
1760 
1761  // ------------------------------------------------------------------------
1762  // EA_NEON
1763  // EA_NEON may be used to determine if NEON is supported.
1764  #ifndef EA_NEON
1765  #if defined(__ARM_NEON__) || defined(__ARM_NEON)
1766  #define EA_NEON 1
1767  #else
1768  #define EA_NEON 0
1769  #endif
1770  #endif
1771 
1772  // ------------------------------------------------------------------------
1773  // EA_BMI
1774  // EA_BMI may be used to determine if Bit Manipulation Instruction sets are available for the target architecture
1775  //
1776  // EA_BMI defines the level of BMI support:
1777  // 0 indicates no BMI support
1778  // 1 indicates BMI1 is supported
1779  // 2 indicates BMI2 is supported
1780  #ifndef EA_BMI
1781  #if defined(__BMI2__)
1782  #define EA_BMI 2
1783  #elif defined(__BMI__) || defined(EA_PLATFORM_XBOXONE) || defined(CS_UNDEFINED_STRING)
1784  #define EA_BMI 1
1785  #else
1786  #define EA_BMI 0
1787  #endif
1788  #endif
1789  #ifndef EA_BMI2
1790  #if EA_BMI >= 2
1791  #define EA_BMI2 1
1792  #else
1793  #define EA_BMI2 0
1794  #endif
1795  #endif
1796 
1797  // ------------------------------------------------------------------------
1798  // EA_FMA3
1799  // EA_FMA3 may be used to determine if Fused Multiply Add operations are available for the target architecture
1800  // __FMA__ is defined only by GCC, Clang, and ICC; MSVC only defines __AVX__ and __AVX2__
1801  // FMA3 was introduced alongside AVX2 on Intel Haswell
1802  // All AMD processors support FMA3 if AVX2 is also supported
1803  //
1804  // EA_FMA3 defines the level of FMA3 support:
1805  // 0 indicates no FMA3 support
1806  // 1 indicates FMA3 is supported
1807  #ifndef EA_FMA3
1808  #if defined(__FMA__) || EA_AVX2 >= 1
1809  #define EA_FMA3 1
1810  #else
1811  #define EA_FMA3 0
1812  #endif
1813  #endif
1814 
1815  // ------------------------------------------------------------------------
1816  // EA_TBM
1817  // EA_TBM may be used to determine if Trailing Bit Manipulation instructions are available for the target architecture
1818  #ifndef EA_TBM
1819  #if defined(__TBM__)
1820  #define EA_TBM 1
1821  #else
1822  #define EA_TBM 0
1823  #endif
1824  #endif
1825 
1826 
1827  // ------------------------------------------------------------------------
1828  // EA_IMPORT
1829  // import declaration specification
1830  // specifies that the declared symbol is imported from another dynamic library.
1831  #ifndef EA_IMPORT
1832  #if defined(EA_COMPILER_MSVC)
1833  #define EA_IMPORT __declspec(dllimport)
1834  #else
1835  #define EA_IMPORT
1836  #endif
1837  #endif
1838 
1839 
1840  // ------------------------------------------------------------------------
1841  // EA_EXPORT
1842  // export declaration specification
1843  // specifies that the declared symbol is exported from the current dynamic library.
1844  // this is not the same as the C++ export keyword. The C++ export keyword has been
1845  // removed from the language as of C++11.
1846  #ifndef EA_EXPORT
1847  #if defined(EA_COMPILER_MSVC)
1848  #define EA_EXPORT __declspec(dllexport)
1849  #else
1850  #define EA_EXPORT
1851  #endif
1852  #endif
1853 
1854 
1855  // ------------------------------------------------------------------------
1856  // EA_PRAGMA_ONCE_SUPPORTED
1857  //
1858  // This is a wrapper for the #pragma once preprocessor directive.
1859  // It allows for some compilers (in particular VC++) to implement signifcantly
1860  // faster include file preprocessing. #pragma once can be used to replace
1861  // header include guards or to augment them. However, #pragma once isn't
1862  // necessarily supported by all compilers and isn't guaranteed to be so in
1863  // the future, so using #pragma once to replace traditional include guards
1864  // is not strictly portable. Note that a direct #define for #pragma once is
1865  // impossible with VC++, due to limitations, but can be done with other
1866  // compilers/preprocessors via _Pragma("once").
1867  //
1868  // Example usage (which includes traditional header guards for portability):
1869  // #ifndef SOMEPACKAGE_SOMEHEADER_H
1870  // #define SOMEPACKAGE_SOMEHEADER_H
1871  //
1872  // #if defined(EA_PRAGMA_ONCE_SUPPORTED)
1873  // #pragma once
1874  // #endif
1875  //
1876  // <user code>
1877  //
1878  // #endif
1879  //
1880  #if defined(_MSC_VER) || defined(__GNUC__) || defined(__EDG__) || defined(__APPLE__)
1881  #define EA_PRAGMA_ONCE_SUPPORTED 1
1882  #endif
1883 
1884 
1885 
1886  // ------------------------------------------------------------------------
1887  // EA_ONCE
1888  //
1889  // Example usage (which includes traditional header guards for portability):
1890  // #ifndef SOMEPACKAGE_SOMEHEADER_H
1891  // #define SOMEPACKAGE_SOMEHEADER_H
1892  //
1893  // EA_ONCE()
1894  //
1895  // <user code>
1896  //
1897  // #endif
1898  //
1899  #if defined(EA_PRAGMA_ONCE_SUPPORTED)
1900  #if defined(_MSC_VER)
1901  #define EA_ONCE() __pragma(once)
1902  #else
1903  #define EA_ONCE() // _Pragma("once") It turns out that _Pragma("once") isn't supported by many compilers.
1904  #endif
1905  #endif
1906 
1907 
1908 
1909  // ------------------------------------------------------------------------
1910  // EA_OVERRIDE
1911  //
1912  // C++11 override
1913  // See http://msdn.microsoft.com/en-us/library/jj678987.aspx for more information.
1914  // You can use EA_FINAL_OVERRIDE to combine usage of EA_OVERRIDE and EA_INHERITANCE_FINAL in a single statement.
1915  //
1916  // Example usage:
1917  // struct B { virtual void f(int); };
1918  // struct D : B { void f(int) EA_OVERRIDE; };
1919  //
1920  #ifndef EA_OVERRIDE
1921  #if defined(EA_COMPILER_NO_OVERRIDE)
1922  #define EA_OVERRIDE
1923  #else
1924  #define EA_OVERRIDE override
1925  #endif
1926  #endif
1927 
1928 
1929  // ------------------------------------------------------------------------
1930  // EA_INHERITANCE_FINAL
1931  //
1932  // Portably wraps the C++11 final specifier.
1933  // See http://msdn.microsoft.com/en-us/library/jj678985.aspx for more information.
1934  // You can use EA_FINAL_OVERRIDE to combine usage of EA_OVERRIDE and EA_INHERITANCE_FINAL in a single statement.
1935  // This is not called EA_FINAL because that term is used within EA to denote debug/release/final builds.
1936  //
1937  // Example usage:
1938  // struct B { virtual void f() EA_INHERITANCE_FINAL; };
1939  //
1940  #ifndef EA_INHERITANCE_FINAL
1941  #if defined(EA_COMPILER_NO_INHERITANCE_FINAL)
1942  #define EA_INHERITANCE_FINAL
1943  #elif (defined(_MSC_VER) && (EA_COMPILER_VERSION < 1700)) // Pre-VS2012
1944  #define EA_INHERITANCE_FINAL sealed
1945  #else
1946  #define EA_INHERITANCE_FINAL final
1947  #endif
1948  #endif
1949 
1950 
1951  // ------------------------------------------------------------------------
1952  // EA_FINAL_OVERRIDE
1953  //
1954  // Portably wraps the C++11 override final specifiers combined.
1955  //
1956  // Example usage:
1957  // struct A { virtual void f(); };
1958  // struct B : public A { virtual void f() EA_FINAL_OVERRIDE; };
1959  //
1960  #ifndef EA_FINAL_OVERRIDE
1961  #define EA_FINAL_OVERRIDE EA_OVERRIDE EA_INHERITANCE_FINAL
1962  #endif
1963 
1964 
1965  // ------------------------------------------------------------------------
1966  // EA_SEALED
1967  //
1968  // This is deprecated, as the C++11 Standard has final (EA_INHERITANCE_FINAL) instead.
1969  // See http://msdn.microsoft.com/en-us/library/0w2w91tf.aspx for more information.
1970  // Example usage:
1971  // struct B { virtual void f() EA_SEALED; };
1972  //
1973  #ifndef EA_SEALED
1974  #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // VS2005 (VC8) and later
1975  #define EA_SEALED sealed
1976  #else
1977  #define EA_SEALED
1978  #endif
1979  #endif
1980 
1981 
1982  // ------------------------------------------------------------------------
1983  // EA_ABSTRACT
1984  //
1985  // This is a Microsoft language extension.
1986  // See http://msdn.microsoft.com/en-us/library/b0z6b513.aspx for more information.
1987  // Example usage:
1988  // struct X EA_ABSTRACT { virtual void f(){} };
1989  //
1990  #ifndef EA_ABSTRACT
1991  #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // VS2005 (VC8) and later
1992  #define EA_ABSTRACT abstract
1993  #else
1994  #define EA_ABSTRACT
1995  #endif
1996  #endif
1997 
1998 
1999  // ------------------------------------------------------------------------
2000  // EA_CONSTEXPR
2001  // EA_CONSTEXPR_OR_CONST
2002  //
2003  // Portable wrapper for C++11's 'constexpr' support.
2004  //
2005  // See http://www.cprogramming.com/c++11/c++11-compile-time-processing-with-constexpr.html for more information.
2006  // Example usage:
2007  // EA_CONSTEXPR int GetValue() { return 37; }
2008  // EA_CONSTEXPR_OR_CONST double gValue = std::sin(kTwoPi);
2009  //
2010  #if !defined(EA_CONSTEXPR)
2011  #if defined(EA_COMPILER_NO_CONSTEXPR)
2012  #define EA_CONSTEXPR
2013  #else
2014  #define EA_CONSTEXPR constexpr
2015  #endif
2016  #endif
2017 
2018  #if !defined(EA_CONSTEXPR_OR_CONST)
2019  #if defined(EA_COMPILER_NO_CONSTEXPR)
2020  #define EA_CONSTEXPR_OR_CONST const
2021  #else
2022  #define EA_CONSTEXPR_OR_CONST constexpr
2023  #endif
2024  #endif
2025 
2026  // ------------------------------------------------------------------------
2027  // EA_CONSTEXPR_IF
2028  //
2029  // Portable wrapper for C++17's 'constexpr if' support.
2030  //
2031  // https://en.cppreference.com/w/cpp/language/if
2032  //
2033  // Example usage:
2034  //
2035  // EA_CONSTEXPR_IF(eastl::is_copy_constructible_v<T>)
2036  // { ... }
2037  //
2038  #if !defined(EA_CONSTEXPR_IF)
2039  #if defined(EA_COMPILER_NO_CONSTEXPR_IF)
2040  #define EA_CONSTEXPR_IF(predicate) if ((predicate))
2041  #else
2042  #define EA_CONSTEXPR_IF(predicate) if constexpr ((predicate))
2043  #endif
2044  #endif
2045 
2046 
2047 
2048  // ------------------------------------------------------------------------
2049  // EA_EXTERN_TEMPLATE
2050  //
2051  // Portable wrapper for C++11's 'extern template' support.
2052  //
2053  // Example usage:
2054  // EA_EXTERN_TEMPLATE(class basic_string<char>);
2055  //
2056  #if !defined(EA_EXTERN_TEMPLATE)
2057  #if defined(EA_COMPILER_NO_EXTERN_TEMPLATE)
2058  #define EA_EXTERN_TEMPLATE(declaration)
2059  #else
2060  #define EA_EXTERN_TEMPLATE(declaration) extern template declaration
2061  #endif
2062  #endif
2063 
2064 
2065  // ------------------------------------------------------------------------
2066  // EA_NOEXCEPT
2067  // EA_NOEXCEPT_IF(predicate)
2068  // EA_NOEXCEPT_EXPR(expression)
2069  //
2070  // Portable wrapper for C++11 noexcept
2071  // http://en.cppreference.com/w/cpp/language/noexcept
2072  // http://en.cppreference.com/w/cpp/language/noexcept_spec
2073  //
2074  // Example usage:
2075  // EA_NOEXCEPT
2076  // EA_NOEXCEPT_IF(predicate)
2077  // EA_NOEXCEPT_EXPR(expression)
2078  //
2079  // This function never throws an exception.
2080  // void DoNothing() EA_NOEXCEPT
2081  // { }
2082  //
2083  // This function throws an exception of T::T() throws an exception.
2084  // template <class T>
2085  // void DoNothing() EA_NOEXCEPT_IF(EA_NOEXCEPT_EXPR(T()))
2086  // { T t; }
2087  //
2088  #if !defined(EA_NOEXCEPT)
2089  #if defined(EA_COMPILER_NO_NOEXCEPT)
2090  #define EA_NOEXCEPT
2091  #define EA_NOEXCEPT_IF(predicate)
2092  #define EA_NOEXCEPT_EXPR(expression) false
2093  #else
2094  #define EA_NOEXCEPT noexcept
2095  #define EA_NOEXCEPT_IF(predicate) noexcept((predicate))
2096  #define EA_NOEXCEPT_EXPR(expression) noexcept((expression))
2097  #endif
2098  #endif
2099 
2100 
2101  // ------------------------------------------------------------------------
2102  // EA_NORETURN
2103  //
2104  // Wraps the C++11 noreturn attribute. See EA_COMPILER_NO_NORETURN
2105  // http://en.cppreference.com/w/cpp/language/attributes
2106  // http://msdn.microsoft.com/en-us/library/k6ktzx3s%28v=vs.80%29.aspx
2107  // http://blog.aaronballman.com/2011/09/understanding-attributes/
2108  //
2109  // Example usage:
2110  // EA_NORETURN void SomeFunction()
2111  // { throw "error"; }
2112  //
2113  #if !defined(EA_NORETURN)
2114  #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1300) // VS2003 (VC7) and later
2115  #define EA_NORETURN __declspec(noreturn)
2116  #elif defined(EA_COMPILER_NO_NORETURN)
2117  #define EA_NORETURN
2118  #else
2119  #define EA_NORETURN [[noreturn]]
2120  #endif
2121  #endif
2122 
2123 
2124  // ------------------------------------------------------------------------
2125  // EA_CARRIES_DEPENDENCY
2126  //
2127  // Wraps the C++11 carries_dependency attribute
2128  // http://en.cppreference.com/w/cpp/language/attributes
2129  // http://blog.aaronballman.com/2011/09/understanding-attributes/
2130  //
2131  // Example usage:
2132  // EA_CARRIES_DEPENDENCY int* SomeFunction()
2133  // { return &mX; }
2134  //
2135  //
2136  #if !defined(EA_CARRIES_DEPENDENCY)
2137  #if defined(EA_COMPILER_NO_CARRIES_DEPENDENCY)
2138  #define EA_CARRIES_DEPENDENCY
2139  #else
2140  #define EA_CARRIES_DEPENDENCY [[carries_dependency]]
2141  #endif
2142  #endif
2143 
2144 
2145  // ------------------------------------------------------------------------
2146  // EA_FALLTHROUGH
2147  //
2148  // [[fallthrough] is a C++17 standard attribute that appears in switch
2149  // statements to indicate that the fallthrough from the previous case in the
2150  // switch statement is intentially and not a bug.
2151  //
2152  // http://en.cppreference.com/w/cpp/language/attributes
2153  //
2154  // Example usage:
2155  // void f(int n)
2156  // {
2157  // switch(n)
2158  // {
2159  // case 1:
2160  // DoCase1();
2161  // // Compiler may generate a warning for fallthrough behaviour
2162  //
2163  // case 2:
2164  // DoCase2();
2165  //
2166  // EA_FALLTHROUGH;
2167  // case 3:
2168  // DoCase3();
2169  // }
2170  // }
2171  //
2172  #if !defined(EA_FALLTHROUGH)
2173  #if defined(EA_COMPILER_NO_FALLTHROUGH)
2174  #define EA_FALLTHROUGH
2175  #else
2176  #define EA_FALLTHROUGH [[fallthrough]]
2177  #endif
2178  #endif
2179 
2180 
2181 
2182  // ------------------------------------------------------------------------
2183  // EA_NODISCARD
2184  //
2185  // [[nodiscard]] is a C++17 standard attribute that can be applied to a
2186  // function declaration, enum, or class declaration. If a any of the list
2187  // previously are returned from a function (without the user explicitly
2188  // casting to void) the addition of the [[nodiscard]] attribute encourages
2189  // the compiler to generate a warning about the user discarding the return
2190  // value. This is a useful practice to encourage client code to check API
2191  // error codes.
2192  //
2193  // http://en.cppreference.com/w/cpp/language/attributes
2194  //
2195  // Example usage:
2196  //
2197  // EA_NODISCARD int baz() { return 42; }
2198  //
2199  // void foo()
2200  // {
2201  // baz(); // warning: ignoring return value of function declared with 'nodiscard' attribute
2202  // }
2203  //
2204  #if !defined(EA_NODISCARD)
2205  #if defined(EA_COMPILER_NO_NODISCARD)
2206  #define EA_NODISCARD
2207  #else
2208  #define EA_NODISCARD [[nodiscard]]
2209  #endif
2210  #endif
2211 
2212 
2213  // ------------------------------------------------------------------------
2214  // EA_MAYBE_UNUSED
2215  //
2216  // [[maybe_unused]] is a C++17 standard attribute that suppresses warnings
2217  // on unused entities that are declared as maybe_unused.
2218  //
2219  // http://en.cppreference.com/w/cpp/language/attributes
2220  //
2221  // Example usage:
2222  // void foo(EA_MAYBE_UNUSED int i)
2223  // {
2224  // assert(i == 42); // warning suppressed when asserts disabled.
2225  // }
2226  //
2227  #if !defined(EA_MAYBE_UNUSED)
2228  #if defined(EA_COMPILER_NO_MAYBE_UNUSED)
2229  #define EA_MAYBE_UNUSED
2230  #else
2231  #define EA_MAYBE_UNUSED [[maybe_unused]]
2232  #endif
2233  #endif
2234 
2235 
2236  // ------------------------------------------------------------------------
2237  // EA_NO_UBSAN
2238  //
2239  // The LLVM/Clang undefined behaviour sanitizer will not analyse a function tagged with the following attribute.
2240  //
2241  // https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#disabling-instrumentation-with-attribute-no-sanitize-undefined
2242  //
2243  // Example usage:
2244  // EA_NO_UBSAN int SomeFunction() { ... }
2245  //
2246  #ifndef EA_NO_UBSAN
2247  #if defined(EA_COMPILER_CLANG)
2248  #define EA_NO_UBSAN __attribute__((no_sanitize("undefined")))
2249  #else
2250  #define EA_NO_UBSAN
2251  #endif
2252  #endif
2253 
2254 
2255  // ------------------------------------------------------------------------
2256  // EA_NO_ASAN
2257  //
2258  // The LLVM/Clang address sanitizer will not analyse a function tagged with the following attribute.
2259  //
2260  // https://clang.llvm.org/docs/AddressSanitizer.html#disabling-instrumentation-with-attribute-no-sanitize-address
2261  //
2262  // Example usage:
2263  // EA_NO_ASAN int SomeFunction() { ... }
2264  //
2265  #ifndef EA_NO_ASAN
2266  #if defined(EA_COMPILER_CLANG)
2267  #define EA_NO_ASAN __attribute__((no_sanitize("address")))
2268  #else
2269  #define EA_NO_ASAN
2270  #endif
2271  #endif
2272 
2273 
2274  // ------------------------------------------------------------------------
2275  // EA_ASAN_ENABLED
2276  //
2277  // Defined as 0 or 1. It's value depends on the compile environment.
2278  // Specifies whether the code is being built with Clang's Address Sanitizer.
2279  //
2280  #if defined(__has_feature)
2281  #if __has_feature(address_sanitizer)
2282  #define EA_ASAN_ENABLED 1
2283  #else
2284  #define EA_ASAN_ENABLED 0
2285  #endif
2286  #else
2287  #define EA_ASAN_ENABLED 0
2288  #endif
2289 
2290 
2291  // ------------------------------------------------------------------------
2292  // EA_NON_COPYABLE
2293  //
2294  // This macro defines as a class as not being copy-constructable
2295  // or assignable. This is useful for preventing class instances
2296  // from being passed to functions by value, is useful for preventing
2297  // compiler warnings by some compilers about the inability to
2298  // auto-generate a copy constructor and assignment, and is useful
2299  // for simply declaring in the interface that copy semantics are
2300  // not supported by the class. Your class needs to have at least a
2301  // default constructor when using this macro.
2302  //
2303  // Beware that this class works by declaring a private: section of
2304  // the class in the case of compilers that don't support C++11 deleted
2305  // functions.
2306  //
2307  // Note: With some pre-C++11 compilers (e.g. Green Hills), you may need
2308  // to manually define an instances of the hidden functions, even
2309  // though they are not used.
2310  //
2311  // Example usage:
2312  // class Widget {
2313  // Widget();
2314  // . . .
2315  // EA_NON_COPYABLE(Widget)
2316  // };
2317  //
2318  #if !defined(EA_NON_COPYABLE)
2319  #if defined(EA_COMPILER_NO_DELETED_FUNCTIONS)
2320  #define EA_NON_COPYABLE(EAClass_) \
2321  private: \
2322  EA_DISABLE_VC_WARNING(4822); /* local class member function does not have a body */ \
2323  EAClass_(const EAClass_&); \
2324  void operator=(const EAClass_&); \
2325  EA_RESTORE_VC_WARNING();
2326  #else
2327  #define EA_NON_COPYABLE(EAClass_) \
2328  EA_DISABLE_VC_WARNING(4822); /* local class member function does not have a body */ \
2329  EAClass_(const EAClass_&) = delete; \
2330  void operator=(const EAClass_&) = delete; \
2331  EA_RESTORE_VC_WARNING();
2332  #endif
2333  #endif
2334 
2335 
2336  // ------------------------------------------------------------------------
2337  // EA_FUNCTION_DELETE
2338  //
2339  // Semi-portable way of specifying a deleted function which allows for
2340  // cleaner code in class declarations.
2341  //
2342  // Example usage:
2343  //
2344  // class Example
2345  // {
2346  // private: // For portability with pre-C++11 compilers, make the function private.
2347  // void foo() EA_FUNCTION_DELETE;
2348  // };
2349  //
2350  // Note: EA_FUNCTION_DELETE'd functions should be private to prevent the
2351  // functions from being called even when the compiler does not support
2352  // deleted functions. Some compilers (e.g. Green Hills) that don't support
2353  // C++11 deleted functions can require that you define the function,
2354  // which you can do in the associated source file for the class.
2355  //
2356  #if defined(EA_COMPILER_NO_DELETED_FUNCTIONS)
2357  #define EA_FUNCTION_DELETE
2358  #else
2359  #define EA_FUNCTION_DELETE = delete
2360  #endif
2361 
2362  // ------------------------------------------------------------------------
2363  // EA_DISABLE_DEFAULT_CTOR
2364  //
2365  // Disables the compiler generated default constructor. This macro is
2366  // provided to improve portability and clarify intent of code.
2367  //
2368  // Example usage:
2369  //
2370  // class Example
2371  // {
2372  // private:
2373  // EA_DISABLE_DEFAULT_CTOR(Example);
2374  // };
2375  //
2376  #define EA_DISABLE_DEFAULT_CTOR(ClassName) ClassName() EA_FUNCTION_DELETE
2377 
2378  // ------------------------------------------------------------------------
2379  // EA_DISABLE_COPY_CTOR
2380  //
2381  // Disables the compiler generated copy constructor. This macro is
2382  // provided to improve portability and clarify intent of code.
2383  //
2384  // Example usage:
2385  //
2386  // class Example
2387  // {
2388  // private:
2389  // EA_DISABLE_COPY_CTOR(Example);
2390  // };
2391  //
2392  #define EA_DISABLE_COPY_CTOR(ClassName) ClassName(const ClassName &) EA_FUNCTION_DELETE
2393 
2394  // ------------------------------------------------------------------------
2395  // EA_DISABLE_MOVE_CTOR
2396  //
2397  // Disables the compiler generated move constructor. This macro is
2398  // provided to improve portability and clarify intent of code.
2399  //
2400  // Example usage:
2401  //
2402  // class Example
2403  // {
2404  // private:
2405  // EA_DISABLE_MOVE_CTOR(Example);
2406  // };
2407  //
2408  #define EA_DISABLE_MOVE_CTOR(ClassName) ClassName(ClassName&&) EA_FUNCTION_DELETE
2409 
2410  // ------------------------------------------------------------------------
2411  // EA_DISABLE_ASSIGNMENT_OPERATOR
2412  //
2413  // Disables the compiler generated assignment operator. This macro is
2414  // provided to improve portability and clarify intent of code.
2415  //
2416  // Example usage:
2417  //
2418  // class Example
2419  // {
2420  // private:
2421  // EA_DISABLE_ASSIGNMENT_OPERATOR(Example);
2422  // };
2423  //
2424  #define EA_DISABLE_ASSIGNMENT_OPERATOR(ClassName) ClassName & operator=(const ClassName &) EA_FUNCTION_DELETE
2425 
2426  // ------------------------------------------------------------------------
2427  // EA_DISABLE_MOVE_OPERATOR
2428  //
2429  // Disables the compiler generated move operator. This macro is
2430  // provided to improve portability and clarify intent of code.
2431  //
2432  // Example usage:
2433  //
2434  // class Example
2435  // {
2436  // private:
2437  // EA_DISABLE_MOVE_OPERATOR(Example);
2438  // };
2439  //
2440  #define EA_DISABLE_MOVE_OPERATOR(ClassName) ClassName & operator=(ClassName&&) EA_FUNCTION_DELETE
2441 
2442  // ------------------------------------------------------------------------
2443  // EANonCopyable
2444  //
2445  // Declares a class as not supporting copy construction or assignment.
2446  // May be more reliable with some situations that EA_NON_COPYABLE alone,
2447  // though it may result in more code generation.
2448  //
2449  // Note that VC++ will generate warning C4625 and C4626 if you use EANonCopyable
2450  // and you are compiling with /W4 and /Wall. There is no resolution but
2451  // to redelare EA_NON_COPYABLE in your subclass or disable the warnings with
2452  // code like this:
2453  // EA_DISABLE_VC_WARNING(4625 4626)
2454  // ...
2455  // EA_RESTORE_VC_WARNING()
2456  //
2457  // Example usage:
2458  // struct Widget : EANonCopyable {
2459  // . . .
2460  // };
2461  //
2462  #ifdef __cplusplus
2463  struct EANonCopyable
2464  {
2465  #if defined(EA_COMPILER_NO_DEFAULTED_FUNCTIONS) || defined(__EDG__)
2466  // EDG doesn't appear to behave properly for the case of defaulted constructors;
2467  // it generates a mistaken warning about missing default constructors.
2468  EANonCopyable() {} // Putting {} here has the downside that it allows a class to create itself,
2469  ~EANonCopyable() {} // but avoids linker errors that can occur with some compilers (e.g. Green Hills).
2470  #else
2471  EANonCopyable() = default;
2472  ~EANonCopyable() = default;
2473  #endif
2474 
2475  EA_NON_COPYABLE(EANonCopyable)
2476  };
2477  #endif
2478 
2479 
2480  // ------------------------------------------------------------------------
2481  // EA_OPTIMIZE_OFF / EA_OPTIMIZE_ON
2482  //
2483  // Implements portable inline optimization enabling/disabling.
2484  // Usage of these macros must be in order OFF then ON. This is
2485  // because the OFF macro pushes a set of settings and the ON
2486  // macro pops them. The nesting of OFF/ON sets (e.g. OFF, OFF, ON, ON)
2487  // is not guaranteed to work on all platforms.
2488  //
2489  // This is often used to allow debugging of some code that's
2490  // otherwise compiled with undebuggable optimizations. It's also
2491  // useful for working around compiler code generation problems
2492  // that occur in optimized builds.
2493  //
2494  // Some compilers (e.g. VC++) don't allow doing this within a function and
2495  // so the usage must be outside a function, as with the example below.
2496  // GCC on x86 appears to have some problem with argument passing when
2497  // using EA_OPTIMIZE_OFF in optimized builds.
2498  //
2499  // Example usage:
2500  // // Disable optimizations for SomeFunction.
2501  // EA_OPTIMIZE_OFF()
2502  // void SomeFunction()
2503  // {
2504  // ...
2505  // }
2506  // EA_OPTIMIZE_ON()
2507  //
2508  #if !defined(EA_OPTIMIZE_OFF)
2509  #if defined(EA_COMPILER_MSVC)
2510  #define EA_OPTIMIZE_OFF() __pragma(optimize("", off))
2511  #elif defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION > 4004) && (defined(__i386__) || defined(__x86_64__)) // GCC 4.4+ - Seems to work only on x86/Linux so far. However, GCC 4.4 itself appears broken and screws up parameter passing conventions.
2512  #define EA_OPTIMIZE_OFF() \
2513  _Pragma("GCC push_options") \
2514  _Pragma("GCC optimize 0")
2515  #elif defined(EA_COMPILER_CLANG) && (!defined(EA_PLATFORM_ANDROID) || (EA_COMPILER_VERSION >= 380))
2516  #define EA_OPTIMIZE_OFF() \
2517  EA_DISABLE_CLANG_WARNING(-Wunknown-pragmas) \
2518  _Pragma("clang optimize off") \
2519  EA_RESTORE_CLANG_WARNING()
2520  #else
2521  #define EA_OPTIMIZE_OFF()
2522  #endif
2523  #endif
2524 
2525  #if !defined(EA_OPTIMIZE_ON)
2526  #if defined(EA_COMPILER_MSVC)
2527  #define EA_OPTIMIZE_ON() __pragma(optimize("", on))
2528  #elif defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION > 4004) && (defined(__i386__) || defined(__x86_64__)) // GCC 4.4+ - Seems to work only on x86/Linux so far. However, GCC 4.4 itself appears broken and screws up parameter passing conventions.
2529  #define EA_OPTIMIZE_ON() _Pragma("GCC pop_options")
2530  #elif defined(EA_COMPILER_CLANG) && (!defined(EA_PLATFORM_ANDROID) || (EA_COMPILER_VERSION >= 380))
2531  #define EA_OPTIMIZE_ON() \
2532  EA_DISABLE_CLANG_WARNING(-Wunknown-pragmas) \
2533  _Pragma("clang optimize on") \
2534  EA_RESTORE_CLANG_WARNING()
2535  #else
2536  #define EA_OPTIMIZE_ON()
2537  #endif
2538  #endif
2539 
2540 
2541 
2542  // ------------------------------------------------------------------------
2543  // EA_SIGNED_RIGHT_SHIFT_IS_UNSIGNED
2544  //
2545  // Defined if right shifts of signed integers (i.e. arithmetic shifts) fail
2546  // to propogate the high bit downward, and thus preserve sign. Most hardware
2547  // and their corresponding compilers do this.
2548  //
2549  // <No current platform fails to propogate sign bits on right signed shifts>
2550 
2551 #endif // Header include guard
2552 
2553 
2554 
2555 
2556 
2557 
2558 
2559 
2560 
2561