Sierra Toolkit  Version of the Day
eacompilertraits_eastl.h
1 /*
2 Copyright (C) 2009 Electronic Arts, Inc. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7 
8 1. Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in the
12  documentation and/or other materials provided with the distribution.
13 3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of
14  its contributors may be used to endorse or promote products derived
15  from this software without specific prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY
18 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
29 /*-----------------------------------------------------------------------------
30  * config/eacompilertraits.h
31  *
32  * Copyright (c) 2002 - 2005 Electronic Arts Inc. All rights reserved.
33  * Maintained by Paul Pedriana, Maxis
34  *
35  *-----------------------------------------------------------------------------
36  * Currently supported defines include:
37  * EA_COMPILER_IS_ANSIC
38  * EA_COMPILER_IS_C99
39  * EA_COMPILER_HAS_C99_TYPES
40  * EA_COMPILER_IS_CPLUSPLUS
41  * EA_COMPILER_MANAGED_CPP
42  *
43  * EA_ALIGN_OF()
44  * EA_ALIGN() / EA_PREFIX_ALIGN() / EA_POSTFIX_ALIGN()
45  * EA_ALIGNED()
46  * EA_PACKED()
47  *
48  * EA_LIKELY()
49  * EA_UNLIKELY()
50  * EA_INIT_PRIORITY()
51  * EA_MAY_ALIAS()
52  * EA_ASSUME()
53  * EA_PURE
54  * EA_WEAK
55  *
56  * EA_WCHAR_T_NON_NATIVE
57  * EA_WCHAR_SIZE = <n bytes>
58  *
59  * EA_RESTRICT
60  * EA_DEPRECATED / EA_PREFIX_DEPRECATED / EA_POSTFIX_DEPRECATED
61  * EA_FORCE_INLINE / EA_PREFIX_FORCE_INLINE / EA_POSTFIX_FORCE_INLINE
62  * EA_NO_INLINE / EA_PREFIX_NO_INLINE / EA_POSTFIX_NO_INLINE
63  * EA_NO_VTABLE / EA_CLASS_NO_VTABLE / EA_STRUCT_NO_VTABLE
64  * EA_PASCAL
65  * EA_PASCAL_FUNC()
66  * EA_SSE = [0 | 1]
67  * EA_IMPORT
68  * EA_EXPORT
69  * EA_PRAGMA_ONCE_SUPPORTED
70  * EA_OVERRIDE
71  * EA_SEALED
72  * EA_ABSTRACT
73  *
74  * Todo:
75  * Find a way to reliably detect wchar_t size at preprocessor time and
76  * implement it below for EA_WCHAR_SIZE.
77  *
78  * Todo:
79  * Find out how to support EA_PASCAL and EA_PASCAL_FUNC for systems in
80  * which it hasn't yet been found out for.
81  *---------------------------------------------------------------------------*/
82 
83 
84 #ifndef INCLUDED_eacompilertraits_H
85 #define INCLUDED_eacompilertraits_H
86 
87  #ifndef INCLUDED_eaplatform_H
88  #include <stk_util/util/eaplatform.h>
89  #endif
90 
91  #ifndef INCLUDED_eacompiler_H
92  #include <stk_util/util/eacompiler.h>
93  #endif
94 
95  // Metrowerks uses #defines in its core C header files to define
96  // the kind of information we need below (e.g. C99 compatibility)
97  #if defined(__MWERKS__)
98  // Defining the following causes C99 compilers to enable the macros
99  // associated with the defines. The C99 standard specifies that you
100  // should define these as such.
101  #ifndef __STDC_LIMIT_MACROS
102  #define __STDC_LIMIT_MACROS
103  #endif
104 
105  #ifndef __STDC_CONSTANT_MACROS
106  #define __STDC_CONSTANT_MACROS
107  #endif
108 
109  #include <stddef.h>
110  #endif
111 
112  #if defined(__SNC__) || defined(EA_PLATFORM_PS3) || defined(__S3E__)
113  #ifndef __STDC_LIMIT_MACROS
114  #define __STDC_LIMIT_MACROS
115  #endif
116 
117  #ifndef __STDC_CONSTANT_MACROS
118  #define __STDC_CONSTANT_MACROS
119  #endif
120 
121  #include <stdint.h>
122 
123  #if !defined(EA_COMPILER_HAS_INTTYPES)
124  #if !defined(__S3E__)
125  #define EA_COMPILER_HAS_INTTYPES
126  #endif
127  #endif
128  #endif
129 
130  // Determine if this compiler is ANSI C compliant and if it is C99 compliant.
131  #if defined(__STDC__)
132  #define EA_COMPILER_IS_ANSIC // The compiler claims to be ANSI C
133 
134  // Is the compiler a C99 compiler or equivalent?
135  // From ISO/IEC 9899:1999:
136  // 6.10.8 Predefined macro names
137  // __STDC_VERSION__ The integer constant 199901L. (150)
138  //
139  // 150) This macro was not specified in ISO/IEC 9899:1990 and was
140  // specified as 199409L in ISO/IEC 9899/AMD1:1995. The intention
141  // is that this will remain an integer constant of type long int
142  // that is increased with each revision of this International Standard.
143  //
144  #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
145  #define EA_COMPILER_IS_C99
146  #endif
147  #endif
148 
149  // Some compilers (e.g. GCC) define __USE_ISOC99 if they are not
150  // strictly C99 compilers (or are simply C++ compilers) but are set
151  // to use C99 functionality. Metrowerks defines _MSL_C99 as 1 in
152  // this case, but 0 otherwise.
153  #if (defined(__USE_ISOC99) || (defined(_MSL_C99) && (_MSL_C99 == 1))) && !defined(EA_COMPILER_IS_C99)
154  #define EA_COMPILER_IS_C99
155  #endif
156 
157  // Metrowerks defines C99 types (e.g. intptr_t) instrinsically when in C99 mode (-lang C99 on the command line).
158  #if (defined(_MSL_C99) && (_MSL_C99 == 1))
159  #define EA_COMPILER_HAS_C99_TYPES
160  #endif
161 
162  #if defined(__GNUC__)
163  #if (((__GNUC__ * 100) + __GNUC_MINOR__) >= 302) // Also, GCC defines _HAS_C9X.
164  #define EA_COMPILER_HAS_C99_TYPES // The compiler is not necessarily a C99 compiler, but it defines C99 types.
165 
166  #ifndef __STDC_LIMIT_MACROS
167  #define __STDC_LIMIT_MACROS
168  #endif
169 
170  #ifndef __STDC_CONSTANT_MACROS
171  #define __STDC_CONSTANT_MACROS // This tells the GCC compiler that we want it to use its native C99 types.
172  #endif
173  #endif
174  #endif
175 
176  #ifdef __cplusplus
177  #define EA_COMPILER_IS_CPLUSPLUS
178  #endif
179 
180 
181  // ------------------------------------------------------------------------
182  // EA_COMPILER_MANAGED_CPP
183  // Defined if this is being compiled with Managed C++ extensions
184  #ifdef EA_COMPILER_MSVC
185  #if EA_COMPILER_VERSION >= 1300
186  #ifdef _MANAGED
187  #define EA_COMPILER_MANAGED_CPP
188  #endif
189  #endif
190  #endif
191 
192 
193  // ------------------------------------------------------------------------
194  // alignment expressions
195  //
196  // Here we define
197  // EA_ALIGN_OF(type) // Returns size_t.
198  // 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.
199  // EA_PREFIX_ALIGN(n) // n is byte alignment, with being a power of two. You should need this only for unusual compilers.
200  // EA_POSTFIX_ALIGN(n) // Valid values for n are 1, 2, 4, 8, etc. You should need this only for unusual compilers.
201  // EA_ALIGNED(t, v, n) // Type, variable, alignment. Used to align an instance. You should need this only for unusual compilers.
202  // EA_PACKED // Specifies that the given structure be packed (and not have its members aligned).
203  //
204  // Example usage:
205  // size_t x = EA_ALIGN_OF(int); Non-aligned equivalents. Meaning
206  // 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.
207  // EA_ALIGN(8) int x; int x; Align x on 8 for compilers that allow prefix attributes.
208  // int x EA_POSTFIX_ALIGN(8); int x; Align x on 8 for compilers that require postfix attributes.
209  // int x EA_POSTFIX_ALIGN(8) = 5; int x = 5; Align x on 8 for compilers that require postfix attributes.
210  // int x EA_POSTFIX_ALIGN(8)(5); int x(5); Align x on 8 for compilers that require postfix attributes.
211  // 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.
212  // EA_ALIGNED(int, x, 8) = 5; int x = 5; Align x on 8.
213  // EA_ALIGNED(int, x, 16)(5); int x(5); Align x on 16.
214  // EA_ALIGNED(int, x[3], 16); int x[3]; Align x array on 16.
215  // EA_ALIGNED(int, x[3], 16) = { 1, 2, 3 }; int x[3] = { 1, 2, 3 }; Align x array on 16.
216  // 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.
217  // 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.
218  // 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.
219  // 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.
220  // struct X { int x; int y; } EA_PACKED; struct X { int x; int y; }; Pack the members of struct X.
221  // typedef EA_ALIGNED(int, int16, 16); int16 n16; typedef int int16; int16 n16; Define int16 as an int which is aligned on 16.
222  // typedef EA_ALIGNED(X, X16, 16); X16 x16; typedef X X16; X16 x16; Define X16 as an X which is aligned on 16.
223 
224  // SNC (EDG) intends to be compatible with GCC but has a bug whereby it
225  // fails to support calling a constructor in an aligned declaration when
226  // using postfix alignment attributes. Prefix works for alignment, but does not align
227  // the size like postfix does. Prefix also fails on templates. So gcc style post fix
228  // is still used, but the user will need to use EA_POSTFIX_ALIGN before the constructor parameters.
229  // this note by Paul and Frank
230  #if defined(EA_COMPILER_SN) && defined(__GNUC__) // If using the SN compiler in GCC compatibility mode...
231  #define EA_ALIGN_OF(type) ((size_t)__alignof__(type))
232  #define EA_ALIGN(n) __attribute__((aligned(n)))
233  #define EA_PREFIX_ALIGN(n)
234  #define EA_POSTFIX_ALIGN(n) __attribute__((aligned(n)))
235  #define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n)))
236  #define EA_PACKED __attribute__((packed))
237 
238  // GCC 2.x doesn't support prefix attributes.
239  #elif defined(__GNUC__) && (__GNUC__ < 3)
240  #define EA_ALIGN_OF(type) ((size_t)__alignof__(type))
241  #define EA_ALIGN(n)
242  #define EA_PREFIX_ALIGN(n)
243  #define EA_POSTFIX_ALIGN(n) __attribute__((aligned(n)))
244  #define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n)))
245  #define EA_PACKED __attribute__((packed))
246 
247  // GCC 3.x+ and IBM C support prefix attributes.
248  #elif (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__xlC__)
249  #define EA_ALIGN_OF(type) ((size_t)__alignof__(type))
250  #define EA_ALIGN(n) __attribute__((aligned(n)))
251  #define EA_PREFIX_ALIGN(n)
252  #define EA_POSTFIX_ALIGN(n) __attribute__((aligned(n)))
253  #define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n)))
254  #define EA_PACKED __attribute__((packed))
255 
256  // Metrowerks supports prefix attributes.
257  // Metrowerks does not support packed alignment attributes.
258  #elif defined(EA_COMPILER_METROWERKS)
259  #define EA_ALIGN_OF(type) ((size_t)__alignof__(type))
260  #define EA_ALIGN(n) __attribute__((aligned(n)))
261  #define EA_PREFIX_ALIGN(n)
262  #define EA_POSTFIX_ALIGN(n) __attribute__((aligned(n)))
263  #define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n)))
264  #define EA_PACKED
265 
266  // Microsoft supports prefix alignment via __declspec, but the alignment value must be a literal number, not just a constant expression.
267  // Contrary to VC7.x and earlier documentation, __declspec(align) works on stack variables. VC8+ (VS2005+) documents correctly.
268  // Microsoft does not support packed alignment attributes; you must use #pragma pack.
269  #elif defined(EA_COMPILER_INTEL) || defined(EA_PLATFORM_XBOX) || (defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1300))
270  #define EA_ALIGN_OF(type) ((size_t)__alignof(type))
271  #define EA_ALIGN(n) __declspec(align(n))
272  #define EA_PREFIX_ALIGN(n) __declspec(align(n))
273  #define EA_POSTFIX_ALIGN(n)
274  #define EA_ALIGNED(variable_type, variable, n) __declspec(align(n)) variable_type variable
275  #define EA_PACKED
276 
277  // Arm brand compiler
278  #elif defined(__ARMCC_VERSION)
279  #define EA_ALIGN_OF(type) ((size_t)__ALIGNOF__(type))
280  #define EA_ALIGN(n) __align(n)
281  #define EA_PREFIX_ALIGN(n) __align(n)
282  #define EA_POSTFIX_ALIGN(n)
283  #define EA_ALIGNED(variable_type, variable, n) __align(n) variable_type variable
284  #define EA_PACKED __packed
285 
286  #else // Unusual compilers
287  // There is nothing we can do about some of these. This is not as bad a problem as it seems.
288  // If the given platform/compiler doesn't support alignment specifications, then it's somewhat
289  // likely that alignment doesn't matter for that platform. Otherwise they would have defined
290  // functionality to manipulate alignment.
291  #define EA_ALIGN(n)
292  #define EA_PREFIX_ALIGN(n)
293  #define EA_POSTFIX_ALIGN(n)
294  #define EA_ALIGNED(variable_type, variable, n) variable_type variable
295  #define EA_PACKED
296 
297  #ifdef __cplusplus
298  template <typename T> struct EAAlignOf1 { enum { s = sizeof (T), value = s ^ (s & (s - 1)) }; };
299  template <typename T> struct EAAlignOf2;
300  template <int size_diff> struct helper { template <typename T> struct Val { enum { value = size_diff }; }; };
301  template <> struct helper<0> { template <typename T> struct Val { enum { value = EAAlignOf2<T>::value }; }; };
302  template <typename T> struct EAAlignOf2 { struct Big { T x; char c; };
303  enum { diff = sizeof (Big) - sizeof (T), value = helper<diff>::template Val<Big>::value }; };
304  template <typename T> struct EAAlignof3 { enum { x = EAAlignOf2<T>::value, y = EAAlignOf1<T>::value, value = x < y ? x : y }; };
305  #define EA_ALIGN_OF(type) ((size_t)EAAlignof3<type>::value)
306 
307  #else
308  // C implementation of EA_ALIGN_OF
309  // This implementation works for most cases, but doesn't directly work
310  // for types such as function pointer declarations. To work with those
311  // types you need to typedef the type and then use the typedef in EA_ALIGN_OF.
312  #define EA_ALIGN_OF(type) ((size_t)offsetof(struct { char c; type m; }, m))
313  #endif
314  #endif
315 
316 
317  // ------------------------------------------------------------------------
318  // EA_LIKELY / EA_UNLIKELY
319  //
320  // Defined as a macro which gives a hint to the compiler for branch
321  // prediction. GCC gives you the ability to manually give a hint to
322  // the compiler about the result of a comparison, though it's often
323  // best to compile shipping code with profiling feedback under both
324  // GCC (-fprofile-arcs) and VC++ (/LTCG:PGO, etc.). However, there
325  // are times when you feel very sure that a boolean expression will
326  // usually evaluate to either true or false and can help the compiler
327  // by using an explicity directive...
328  //
329  // Example usage:
330  // if(EA_LIKELY(a == 0)) // Tell the compiler that a will usually equal 0.
331  // { ... }
332  //
333  // Example usage:
334  // if(EA_UNLIKELY(a == 0)) // Tell the compiler that a will usually not equal 0.
335  // { ... }
336  //
337  #ifndef EA_LIKELY
338  #if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__MWERKS__) // Metrowerks supports __builtin_expect, but with some platforms (e.g. Wii) it appears to ignore it.
339  #if defined(__cplusplus)
340  #define EA_LIKELY(x) __builtin_expect(!!(x), true)
341  #define EA_UNLIKELY(x) __builtin_expect(!!(x), false)
342  #else
343  #define EA_LIKELY(x) __builtin_expect(!!(x), 1)
344  #define EA_UNLIKELY(x) __builtin_expect(!!(x), 0)
345  #endif
346  #else
347  #define EA_LIKELY(x) (x)
348  #define EA_UNLIKELY(x) (x)
349  #endif
350  #endif
351 
352 
353  // ------------------------------------------------------------------------
354  // EA_INIT_PRIORITY
355  //
356  // This is simply a wrapper for the GCC init_priority attribute that allows
357  // multiplatform code to be easier to read. This attribute doesn't apply
358  // to VC++ because VC++ uses file-level pragmas to control init ordering.
359  //
360  // Example usage:
361  // SomeClass gSomeClass EA_INIT_PRIORITY(2000);
362  //
363  #if !defined(EA_INIT_PRIORITY)
364  #if defined(__GNUC__)
365  #define EA_INIT_PRIORITY(x) __attribute__ ((init_priority (x)))
366  #else
367  #define EA_INIT_PRIORITY(x)
368  #endif
369  #endif
370 
371 
372  // ------------------------------------------------------------------------
373  // EA_MAY_ALIAS
374  //
375  // Defined as a macro that wraps the GCC may_alias attribute. This attribute
376  // has no significance for VC++ because VC++ doesn't support the concept of
377  // strict aliasing. Users should avoid writing code that breaks strict
378  // aliasing rules; EA_MAY_ALIAS is for cases with no alternative.
379  //
380  // Example usage:
381  // void* EA_MAY_ALIAS gPtr = NULL;
382  //
383  // Example usage:
384  // typedef void* EA_MAY_ALIAS pvoid_may_alias;
385  // pvoid_may_alias gPtr = NULL;
386  //
387  #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 303)
388  #define EA_MAY_ALIAS __attribute__((__may_alias__))
389  #else
390  #define EA_MAY_ALIAS
391  #endif
392 
393 
394  // ------------------------------------------------------------------------
395  // EA_ASSUME
396  //
397  // This acts the same as the VC++ __assume directive and is implemented
398  // simply as a wrapper around it to allow portable usage of it and to take
399  // advantage of it if and when it appears in other compilers.
400  //
401  // Example usage:
402  // void Function(int a) {
403  // switch(a) {
404  // case 1:
405  // DoSomething(1);
406  // break;
407  // case 2:
408  // DoSomething(-1);
409  // break;
410  // default:
411  // EA_ASSUME(0); // This tells the optimizer that the default cannot be reached.
412  // }
413  // }
414  //
415  #ifndef EA_ASSUME
416  #if defined(_MSC_VER) && (_MSC_VER >= 1300) // If VC7.0 and later (including XBox, and XBox 360)...
417  #define EA_ASSUME(x) __assume(x)
418  #else
419  #define EA_ASSUME(x)
420  #endif
421  #endif
422 
423 
424 
425  // ------------------------------------------------------------------------
426  // EA_PURE
427  //
428  // This acts the same as the GCC __attribute__ ((pure)) directive and is
429  // implemented simply as a wrapper around it to allow portable usage of
430  // it and to take advantage of it if and when it appears in other compilers.
431  //
432  // A "pure" function is one that has no effects except its return value and
433  // its return value is a function of only the function's parameters or
434  // non-volatile global variables. Any parameter or global variable access
435  // must be read-only. Loop optimization and subexpression elimination can be
436  // applied to such functions. A common example is strlen(): Given identical
437  // inputs, the function's return value (its only effect) is invariant across
438  // multiple invocations and thus can be pulled out of a loop and called but once.
439  //
440  // Example usage:
441  // EA_PURE void Function();
442  //
443  #ifndef EA_PURE
444  #if defined(EA_COMPILER_GNUC)
445  #define EA_PURE __attribute__((pure))
446  #elif defined(__ARMCC_VERSION) // Arm brand compiler for ARM CPU
447  #define EA_PURE __pure
448  #else
449  #define EA_PURE
450  #endif
451  #endif
452 
453 
454 
455  // ------------------------------------------------------------------------
456  // EA_WEAK
457  // EA_WEAK_SUPPORTED -- defined as 0 or 1.
458  //
459  // GCC
460  // The weak attribute causes the declaration to be emitted as a weak
461  // symbol rather than a global. This is primarily useful in defining
462  // library functions which can be overridden in user code, though it
463  // can also be used with non-function declarations.
464  //
465  // VC++
466  // At link time, if multiple definitions of a COMDAT are seen, the linker
467  // picks one and discards the rest. If the linker option /OPT:REF
468  // is selected, then COMDAT elimination will occur to remove all the
469  // unreferenced data items in the linker output.
470  //
471  // Example usage:
472  // EA_WEAK void Function();
473  //
474  #ifndef EA_WEAK
475  #if defined(_MSC_VER) && (_MSC_VER >= 1300) // If VC7.0 and later (including XBox)...
476  #define EA_WEAK __declspec(selectany)
477  #define EA_WEAK_SUPPORTED 1
478  #elif defined(_MSC_VER) || (defined(__GNUC__) && defined(__CYGWIN__))
479  #define EA_WEAK
480  #define EA_WEAK_SUPPORTED 0
481  #elif defined(__ARMCC_VERSION) // Arm brand compiler for ARM CPU
482  #define EA_WEAK __weak
483  #define EA_WEAK_SUPPORTED 1
484  #else // GCC and IBM compilers, others.
485  #define EA_WEAK __attribute__((weak))
486  #define EA_WEAK_SUPPORTED 1
487  #endif
488  #endif
489 
490 
491 
492  // ------------------------------------------------------------------------
493  // wchar_t
494  // Here we define:
495  // EA_WCHAR_T_NON_NATIVE
496  // EA_WCHAR_SIZE = <sizeof(wchar_t)>
497  //
498  #ifndef EA_WCHAR_T_NON_NATIVE
499  // Compilers that always implement wchar_t as native include:
500  // COMEAU, new SN, and other EDG-based compilers.
501  // GCC
502  // Borland
503  // SunPro
504  // IBM Visual Age
505  #if defined(EA_COMPILER_INTEL)
506  #if (EA_COMPILER_VERSION < 700)
507  #define EA_WCHAR_T_NON_NATIVE 1
508  #else
509  #if (!defined(_WCHAR_T_DEFINED) && !defined(_WCHAR_T))
510  #define EA_WCHAR_T_NON_NATIVE 1
511  #endif
512  #endif
513  #elif defined(EA_COMPILER_MSVC) || defined(EA_COMPILER_BORLAND)
514  #ifndef _NATIVE_WCHAR_T_DEFINED
515  #define EA_WCHAR_T_NON_NATIVE 1
516  #endif
517  #elif defined(EA_COMPILER_METROWERKS)
518  #if !__option(wchar_type)
519  #define EA_WCHAR_T_NON_NATIVE 1
520  #endif
521  #elif defined(__SNC__) && !defined(__cplusplus) // If compiling C under SNC...
522  #define EA_WCHAR_T_NON_NATIVE 1
523  #endif
524  #endif
525 
526  #ifndef EA_WCHAR_SIZE // If the user hasn't specified that it is a given size...
527  #if defined(__WCHAR_MAX__) // GCC defines this for most platforms.
528  #if (__WCHAR_MAX__ == 2147483647) || (__WCHAR_MAX__ == 4294967295)
529  #define EA_WCHAR_SIZE 4
530  #elif (__WCHAR_MAX__ == 32767) || (__WCHAR_MAX__ == 65535)
531  #define EA_WCHAR_SIZE 2
532  #elif (__WCHAR_MAX__ == 127) || (__WCHAR_MAX__ == 255)
533  #define EA_WCHAR_SIZE 1
534  #else
535  #define EA_WCHAR_SIZE 4
536  #endif
537  #elif defined(WCHAR_MAX) // The SN and Arm compilers define this.
538  #if (WCHAR_MAX == 2147483647) || (WCHAR_MAX == 4294967295)
539  #define EA_WCHAR_SIZE 4
540  #elif (WCHAR_MAX == 32767) || (WCHAR_MAX == 65535)
541  #define EA_WCHAR_SIZE 2
542  #elif (WCHAR_MAX == 127) || (WCHAR_MAX == 255)
543  #define EA_WCHAR_SIZE 1
544  #else
545  #define EA_WCHAR_SIZE 4
546  #endif
547  #elif defined(_WCMAX) // The SN and Arm compilers define this.
548  #if (_WCMAX == 2147483647) || (_WCMAX == 4294967295)
549  #define EA_WCHAR_SIZE 4
550  #elif (_WCMAX == 32767) || (_WCMAX == 65535)
551  #define EA_WCHAR_SIZE 2
552  #elif (_WCMAX == 127) || (_WCMAX == 255)
553  #define EA_WCHAR_SIZE 1
554  #else
555  #define EA_WCHAR_SIZE 4
556  #endif
557  #elif defined(EA_PLATFORM_UNIX) || defined(EA_PLATFORM_PS3) || defined(EA_PLATFORM_PS3_SPU)
558  // It is standard on Unix to have wchar_t be int32_t or uint32_t.
559  // All versions of GNUC default to a 32 bit wchar_t, but has been used
560  // with the -fshort-wchar GCC command line option to force it to 16 bit.
561  // If you know that the compiler is set to use a wchar_t of other than
562  // the default, you need to manually define EA_WCHAR_SIZE for the build.
563  #define EA_WCHAR_SIZE 4
564  #else
565  // It is standard on Windows to have wchar_t be uint16_t.
566  // Metrowerks and the new EDG-based SN compilers define wchar_t
567  // as uint16_t. Given that there is currently no known way to tell at preprocessor
568  // time what the size of wchar_t is, we declare it to be 2.
569  // If you have EA_WCHAR_SIZE != sizeof(wchar_t), then your
570  // code might not be broken, but it also won't work with wchar libraries
571  // and data from other parts of EA. Under GCC, you can force wchar_t
572  // to two bytes with the -fshort-wchar compiler argument.
573  #define EA_WCHAR_SIZE 2
574  #endif
575  #endif
576 
577 
578  // ------------------------------------------------------------------------
579  // EA_RESTRICT
580  //
581  // The C99 standard defines a new keyword, restrict, which allows for the
582  // improvement of code generation regarding memory usage. Compilers can
583  // generate significantly faster code when you are able to use restrict.
584  //
585  // Example usage:
586  // void DoSomething(char* EA_RESTRICT p1, char* EA_RESTRICT p2);
587  //
588  #ifndef EA_RESTRICT
589  #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // If VC8 (VS2005) or later...
590  #define EA_RESTRICT __restrict
591  #elif defined(EA_COMPILER_GNUC)
592  #define EA_RESTRICT __restrict // GCC defines 'restrict' (as opposed to __restrict) in C99 mode only.
593  #elif defined(__ARMCC_VERSION)
594  #define EA_RESTRICT __restrict
595  #elif defined(__MWERKS__)
596  #if __option(c99)
597  #define EA_RESTRICT restrict
598  #else
599  #define EA_RESTRICT
600  #endif
601  #elif defined(EA_COMPILER_IS_C99)
602  #define EA_RESTRICT restrict
603  #else
604  // If the compiler didn't support restricted pointers, defining EA_RESTRICT
605  // away would result in compiling and running fine but you just wouldn't
606  // the same level of optimization. On the other hand, all the major compilers
607  // support restricted pointers.
608  #define EA_RESTRICT
609  #endif
610  #endif
611 
612 
613  // ------------------------------------------------------------------------
614  // EA_DEPRECATED // Used as a prefix.
615  // EA_PREFIX_DEPRECATED // You should need this only for unusual compilers.
616  // EA_POSTFIX_DEPRECATED // You should need this only for unusual compilers.
617  //
618  // Example usage:
619  // EA_DEPRECATED void Function();
620  //
621  // or for maximum portability:
622  // EA_PREFIX_DEPRECATED void Function() EA_POSTFIX_DEPRECATED;
623  //
624  #ifndef EA_DEPRECATED
625  #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION > 1300) // If VC7 (VS2003) or later...
626  #define EA_DEPRECATED __declspec(deprecated)
627  #elif defined(EA_COMPILER_MSVC)
628  #define EA_DEPRECATED
629  #else
630  #define EA_DEPRECATED __attribute__((deprecated))
631  #endif
632  #endif
633 
634  #ifndef EA_PREFIX_DEPRECATED
635  #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION > 1300) // If VC7 (VS2003) or later...
636  #define EA_PREFIX_DEPRECATED __declspec(deprecated)
637  #define EA_POSTFIX_DEPRECATED
638  #elif defined(EA_COMPILER_MSVC)
639  #define EA_PREFIX_DEPRECATED
640  #define EA_POSTFIX_DEPRECATED
641  #else
642  #define EA_PREFIX_DEPRECATED
643  #define EA_POSTFIX_DEPRECATED __attribute__((deprecated))
644  #endif
645  #endif
646 
647 
648  // ------------------------------------------------------------------------
649  // EA_FORCE_INLINE // Used as a prefix.
650  // EA_PREFIX_FORCE_INLINE // You should need this only for unusual compilers.
651  // EA_POSTFIX_FORCE_INLINE // You should need this only for unusual compilers.
652  //
653  // Example usage:
654  // EA_FORCE_INLINE void Foo(); // Implementation elsewhere.
655  // EA_PREFIX_FORCE_INLINE void Foo() EA_POSTFIX_FORCE_INLINE; // Implementation elsewhere.
656  //
657  // Note that when the prefix version of this function is used, it replaces
658  // the regular C++ 'inline' statement. Thus you should not use both the
659  // C++ inline statement and this macro with the same function declaration.
660  //
661  // To force inline usage under GCC 3.1+, you use this:
662  // inline void Foo() __attribute__((always_inline));
663  // or
664  // inline __attribute__((always_inline)) void Foo();
665  //
666  // The CodeWarrior compiler doesn't have the concept of forcing inlining per function.
667  //
668  #ifndef EA_FORCE_INLINE
669  #if defined(EA_COMPILER_MSVC)
670  #define EA_FORCE_INLINE __forceinline
671  #elif defined(EA_COMPILER_GNUC) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 301)
672  #if defined(__cplusplus)
673  #define EA_FORCE_INLINE inline __attribute__((always_inline))
674  #else
675  #define EA_FORCE_INLINE __inline__ __attribute__((always_inline))
676  #endif
677  #else
678  #if defined(__cplusplus)
679  #define EA_FORCE_INLINE inline
680  #else
681  #define EA_FORCE_INLINE __inline
682  #endif
683  #endif
684  #endif
685 
686  #if defined(EA_COMPILER_SN) && defined(EA_PLATFORM_PS3) // SN's implementation of always_inline is broken and sometimes fails to link the function.
687  #define EA_PREFIX_FORCE_INLINE inline
688  #define EA_POSTFIX_FORCE_INLINE
689  #elif defined(EA_COMPILER_GNUC) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 301)
690  #define EA_PREFIX_FORCE_INLINE inline
691  #define EA_POSTFIX_FORCE_INLINE __attribute__((always_inline))
692  #else
693  #define EA_PREFIX_FORCE_INLINE inline
694  #define EA_POSTFIX_FORCE_INLINE
695  #endif
696 
697 
698  // ------------------------------------------------------------------------
699  // EA_NO_INLINE // Used as a prefix.
700  // EA_PREFIX_NO_INLINE // You should need this only for unusual compilers.
701  // EA_POSTFIX_NO_INLINE // You should need this only for unusual compilers.
702  //
703  // Example usage:
704  // EA_NO_INLINE void Foo(); // Implementation elsewhere.
705  // EA_PREFIX_NO_INLINE void Foo() EA_POSTFIX_NO_INLINE; // Implementation elsewhere.
706  //
707  // That this declaration is incompatbile with C++ 'inline' and any
708  // variant of EA_FORCE_INLINE.
709  //
710  // To disable inline usage under VC++ priof to VS2005, you need to use this:
711  // #pragma inline_depth(0) // Disable inlining.
712  // void Foo() { ... }
713  // #pragma inline_depth() // Restore to default.
714  //
715  // Since there is no easy way to disable inlining on a function-by-function
716  // basis in VC++ prior to VS2005, the best strategy is to write platform-specific
717  // #ifdefs in the code or to disable inlining for a given module and enable
718  // functions individually with EA_FORCE_INLINE.
719  //
720  #ifndef EA_NO_INLINE
721  #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // If VC8 (VS2005) or later...
722  #define EA_NO_INLINE __declspec(noinline)
723  #elif defined(EA_COMPILER_MSVC)
724  #define EA_NO_INLINE
725  #else
726  #define EA_NO_INLINE __attribute__((noinline))
727  #endif
728  #endif
729 
730  #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // If VC8 (VS2005) or later...
731  #define EA_PREFIX_NO_INLINE __declspec(noinline)
732  #define EA_POSTFIX_NO_INLINE
733  #elif defined(EA_COMPILER_MSVC)
734  #define EA_PREFIX_NO_INLINE
735  #define EA_POSTFIX_NO_INLINE
736  #else
737  #define EA_PREFIX_NO_INLINE
738  #define EA_POSTFIX_NO_INLINE __attribute__((noinline))
739  #endif
740 
741 
742  // ------------------------------------------------------------------------
743  // EA_NO_VTABLE
744  //
745  // Example usage:
746  // class EA_NO_VTABLE X {
747  // virtual void InterfaceFunction();
748  // };
749  //
750  // EA_CLASS_NO_VTABLE(X) {
751  // virtual void InterfaceFunction();
752  // };
753  //
754  #ifdef EA_COMPILER_MSVC
755  #define EA_NO_VTABLE __declspec(novtable)
756  #define EA_CLASS_NO_VTABLE(x) class __declspec(novtable) x
757  #define EA_STRUCT_NO_VTABLE(x) struct __declspec(novtable) x
758  #else
759  #define EA_NO_VTABLE
760  #define EA_CLASS_NO_VTABLE(x) class x
761  #define EA_STRUCT_NO_VTABLE(x) struct x
762  #endif
763 
764 
765  // ------------------------------------------------------------------------
766  // EA_PASCAL
767  //
768  // Also known on PC platforms as stdcall.
769  // This convention causes the compiler to assume that the called function
770  // will pop off the stack space used to pass arguments, unless it takes a
771  // variable number of arguments.
772  //
773  // Example usage:
774  // this:
775  // void DoNothing(int x);
776  // void DoNothing(int x){}
777  // would be written as this:
778  // void EA_PASCAL_FUNC(DoNothing(int x));
779  // void EA_PASCAL_FUNC(DoNothing(int x)){}
780  //
781  #ifndef EA_PASCAL
782  #if defined(EA_COMPILER_MSVC)
783  #define EA_PASCAL __stdcall
784  #elif defined(EA_COMPILER_GNUC) && defined(EA_PROCESSOR_X86)
785  #define EA_PASCAL __attribute__((stdcall))
786  #elif defined(EA_COMPILER_METROWERKS) && defined(EA_PLATFORM_WINDOWS)
787  // You need to make sure you have the Metrowerks "ANSI keywords only'
788  // compilation option disabled for the pascal keyword to work.
789  #define EA_PASCAL pascal
790  #else
791  // Some compilers simply don't support pascal calling convention.
792  // As a result, there isn't an issue here, since the specification of
793  // pascal calling convention is for the purpose of disambiguating the
794  // calling convention that is applied.
795  #define EA_PASCAL
796  #endif
797  #endif
798 
799  #ifndef EA_PASCAL_FUNC
800  #if defined(EA_COMPILER_MSVC)
801  #define EA_PASCAL_FUNC(funcname_and_paramlist) __stdcall funcname_and_paramlist
802  #elif defined(EA_COMPILER_GNUC) && defined(EA_PROCESSOR_X86)
803  #define EA_PASCAL_FUNC(funcname_and_paramlist) __attribute__((stdcall)) funcname_and_paramlist
804  #elif defined(EA_COMPILER_METROWERKS) && defined(EA_PLATFORM_WINDOWS)
805  #define EA_PASCAL_FUNC(funcname_and_paramlist) pascal funcname_and_paramlist
806  #else
807  #define EA_PASCAL_FUNC(funcname_and_paramlist) funcname_and_paramlist
808  #endif
809  #endif
810 
811 
812  // ------------------------------------------------------------------------
813  // EA_SSE
814  // Visual C Processor Packs define _MSC_FULL_VER and are needed for SSE
815  // Intel C also has SSE support.
816  // EA_SSE is used to select FPU or SSE versions in hw_select.inl
817  #ifndef EA_SSE
818  #if defined(EA_COMPILER_GNUC)
819  #if defined(__SSE2__)
820  #define EA_SSE 2
821  #elif defined(__SSE__) && __SSE__
822  #define EA_SSE 1
823  #else
824  #define EA_SSE 0
825  #endif
826  #elif defined(EA_PROCESSOR_X86) && defined(_MSC_FULL_VER) && !defined(__NOSSE__) && defined(_M_IX86_FP)
827  #define EA_SSE _M_IX86_FP
828  #elif defined(EA_PROCESSOR_X86) && defined(EA_COMPILER_INTEL) && !defined(__NOSSE__)
829  #define EA_SSE 1
830  #else
831  #define EA_SSE 0
832  #endif
833  #endif
834 
835 
836  // ------------------------------------------------------------------------
837  // EA_IMPORT
838  // import declaration specification
839  // specifies that the declared symbol is imported from another dynamic library.
840  #ifndef EA_IMPORT
841  #if defined(EA_COMPILER_MSVC)
842  #define EA_IMPORT __declspec(dllimport)
843  #else
844  #define EA_IMPORT
845  #endif
846  #endif
847 
848 
849  // ------------------------------------------------------------------------
850  // EA_EXPORT
851  // export declaration specification
852  // specifies that the declared symbol is exported from the current dynamic library.
853  // this is not the same as the C++ export keyword.
854  #ifndef EA_EXPORT
855  #if defined(EA_COMPILER_MSVC)
856  #define EA_EXPORT __declspec(dllexport)
857  #else
858  #define EA_EXPORT
859  #endif
860  #endif
861 
862 
863  // ------------------------------------------------------------------------
864  // EA_PRAGMA_ONCE_SUPPORTED
865  //
866  // This is a wrapper for the #pragma once preprocessor directive.
867  // It allows for some compilers (in particular VC++) to implement signifcantly
868  // faster include file preprocessing. #pragma once can be used to replace
869  // header include guards or to augment them. However, #pragma once isn't
870  // necessarily supported by all compilers and isn't guaranteed to be so in
871  // the future, so using #pragma once to replace traditional include guards
872  // is not strictly portable. Note that a direct #define for #pragma once is
873  // impossible with VC++, due to limitations, but can be done with other
874  // compilers/preprocessors via _Pragma("once").
875  //
876  // Example usage (which includes traditional header guards for portability):
877  // #ifndef SOMEPACKAGE_SOMEHEADER_H
878  // #define SOMEPACKAGE_SOMEHEADER_H
879  //
880  // #if defined(EA_PRAGMA_ONCE_SUPPORTED)
881  // #pragma once
882  // #endif
883  //
884  // <user code>
885  //
886  // #endif
887  //
888  #if defined(_MSC_VER) || defined(__MWERKS__) || defined(__GNUC__) || defined(__SNC__) || defined(__ICC) || defined(__ICL)
889  #define EA_PRAGMA_ONCE_SUPPORTED 1
890  #endif
891 
892 
893  // ------------------------------------------------------------------------
894  // EA_OVERRIDE
895  //
896  // See http://msdn.microsoft.com/en-us/library/41w3sh1c.aspx for more information.
897  //
898  #ifndef EA_OVERRIDE
899  #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // VS2005 (VC8) and later
900  #define EA_OVERRIDE override
901  #else
902  #define EA_OVERRIDE
903  #endif
904  #endif
905 
906 
907  // ------------------------------------------------------------------------
908  // EA_SEALED
909  //
910  // See http://msdn.microsoft.com/en-us/library/49k3w2fx%28VS.71%29.aspx for more information.
911  //
912  #ifndef EA_SEALED
913  #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // VS2005 (VC8) and later
914  #define EA_SEALED sealed
915  #else
916  #define EA_SEALED
917  #endif
918  #endif
919 
920 
921  // ------------------------------------------------------------------------
922  // EA_ABSTRACT
923  //
924  // See http://msdn.microsoft.com/en-us/library/49k3w2fx%28VS.71%29.aspx for more information.
925  //
926  #ifndef EA_ABSTRACT
927  #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // VS2005 (VC8) and later
928  #define EA_ABSTRACT abstract
929  #else
930  #define EA_ABSTRACT
931  #endif
932  #endif
933 
934 
935 #endif // Header include guard