Sierra Toolkit Version of the Day
eacompilertraits_eastl.h
00001 /*
00002 Copyright (C) 2009 Electronic Arts, Inc.  All rights reserved.
00003 
00004 Redistribution and use in source and binary forms, with or without
00005 modification, are permitted provided that the following conditions
00006 are met:
00007 
00008 1.  Redistributions of source code must retain the above copyright
00009     notice, this list of conditions and the following disclaimer.
00010 2.  Redistributions in binary form must reproduce the above copyright
00011     notice, this list of conditions and the following disclaimer in the
00012     documentation and/or other materials provided with the distribution.
00013 3.  Neither the name of Electronic Arts, Inc. ("EA") nor the names of
00014     its contributors may be used to endorse or promote products derived
00015     from this software without specific prior written permission.
00016 
00017 THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY
00018 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00019 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00020 DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY
00021 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 */
00028 
00029 /*-----------------------------------------------------------------------------
00030  * config/eacompilertraits.h
00031  *
00032  * Copyright (c) 2002 - 2005 Electronic Arts Inc. All rights reserved.
00033  * Maintained by Paul Pedriana, Maxis
00034  *
00035  *-----------------------------------------------------------------------------
00036  * Currently supported defines include:
00037  *    EA_COMPILER_IS_ANSIC
00038  *    EA_COMPILER_IS_C99
00039  *    EA_COMPILER_HAS_C99_TYPES
00040  *    EA_COMPILER_IS_CPLUSPLUS
00041  *    EA_COMPILER_MANAGED_CPP
00042  *
00043  *    EA_ALIGN_OF()
00044  *    EA_ALIGN() / EA_PREFIX_ALIGN() / EA_POSTFIX_ALIGN()
00045  *    EA_ALIGNED()
00046  *    EA_PACKED()
00047  *
00048  *    EA_LIKELY()
00049  *    EA_UNLIKELY()
00050  *    EA_INIT_PRIORITY()
00051  *    EA_MAY_ALIAS()
00052  *    EA_ASSUME()
00053  *    EA_PURE
00054  *    EA_WEAK
00055  *
00056  *    EA_WCHAR_T_NON_NATIVE
00057  *    EA_WCHAR_SIZE = <n bytes>
00058  *
00059  *    EA_RESTRICT
00060  *    EA_DEPRECATED   / EA_PREFIX_DEPRECATED   / EA_POSTFIX_DEPRECATED
00061  *    EA_FORCE_INLINE / EA_PREFIX_FORCE_INLINE / EA_POSTFIX_FORCE_INLINE
00062  *    EA_NO_INLINE    / EA_PREFIX_NO_INLINE    / EA_POSTFIX_NO_INLINE
00063  *    EA_NO_VTABLE    / EA_CLASS_NO_VTABLE     / EA_STRUCT_NO_VTABLE
00064  *    EA_PASCAL
00065  *    EA_PASCAL_FUNC()
00066  *    EA_SSE = [0 | 1]
00067  *    EA_IMPORT
00068  *    EA_EXPORT
00069  *    EA_PRAGMA_ONCE_SUPPORTED
00070  *    EA_OVERRIDE
00071  *    EA_SEALED
00072  *    EA_ABSTRACT
00073  *
00074  *  Todo:
00075  *    Find a way to reliably detect wchar_t size at preprocessor time and
00076  *    implement it below for EA_WCHAR_SIZE.
00077  *
00078  *  Todo:
00079  *    Find out how to support EA_PASCAL and EA_PASCAL_FUNC for systems in
00080  *    which it hasn't yet been found out for.
00081  *---------------------------------------------------------------------------*/
00082 
00083 
00084 #ifndef INCLUDED_eacompilertraits_H
00085 #define INCLUDED_eacompilertraits_H
00086 
00087     #ifndef INCLUDED_eaplatform_H
00088         #include <stk_util/util/eaplatform.h>
00089     #endif
00090 
00091     #ifndef INCLUDED_eacompiler_H
00092         #include <stk_util/util/eacompiler.h>
00093     #endif
00094 
00095     // Metrowerks uses #defines in its core C header files to define
00096     // the kind of information we need below (e.g. C99 compatibility)
00097     #if defined(__MWERKS__)
00098         // Defining the following causes C99 compilers to enable the macros
00099         // associated with the defines. The C99 standard specifies that you
00100         // should define these as such.
00101         #ifndef __STDC_LIMIT_MACROS
00102             #define __STDC_LIMIT_MACROS
00103         #endif
00104 
00105         #ifndef __STDC_CONSTANT_MACROS
00106             #define __STDC_CONSTANT_MACROS
00107         #endif
00108 
00109         #include <stddef.h>
00110     #endif
00111 
00112     #if defined(__SNC__) || defined(EA_PLATFORM_PS3) || defined(__S3E__)
00113         #ifndef __STDC_LIMIT_MACROS
00114             #define __STDC_LIMIT_MACROS
00115         #endif
00116 
00117         #ifndef __STDC_CONSTANT_MACROS
00118             #define __STDC_CONSTANT_MACROS
00119         #endif
00120 
00121         #include <stdint.h>
00122 
00123         #if !defined(EA_COMPILER_HAS_INTTYPES)
00124             #if !defined(__S3E__)
00125                 #define EA_COMPILER_HAS_INTTYPES
00126             #endif
00127         #endif
00128     #endif
00129 
00130     // Determine if this compiler is ANSI C compliant and if it is C99 compliant.
00131     #if defined(__STDC__)
00132         #define EA_COMPILER_IS_ANSIC    // The compiler claims to be ANSI C
00133 
00134         // Is the compiler a C99 compiler or equivalent?
00135         // From ISO/IEC 9899:1999:
00136         //    6.10.8 Predefined macro names
00137         //    __STDC_VERSION__ The integer constant 199901L. (150)
00138         //
00139         //    150) This macro was not specified in ISO/IEC 9899:1990 and was
00140         //    specified as 199409L in ISO/IEC 9899/AMD1:1995. The intention
00141         //    is that this will remain an integer constant of type long int
00142         //    that is increased with each revision of this International Standard.
00143         //
00144         #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
00145             #define EA_COMPILER_IS_C99
00146         #endif
00147     #endif
00148 
00149     // Some compilers (e.g. GCC) define __USE_ISOC99 if they are not
00150     // strictly C99 compilers (or are simply C++ compilers) but are set
00151     // to use C99 functionality. Metrowerks defines _MSL_C99 as 1 in
00152     // this case, but 0 otherwise.
00153     #if (defined(__USE_ISOC99) || (defined(_MSL_C99) && (_MSL_C99 == 1))) && !defined(EA_COMPILER_IS_C99)
00154         #define EA_COMPILER_IS_C99
00155     #endif
00156 
00157     // Metrowerks defines C99 types (e.g. intptr_t) instrinsically when in C99 mode (-lang C99 on the command line).
00158     #if (defined(_MSL_C99) && (_MSL_C99 == 1))
00159         #define EA_COMPILER_HAS_C99_TYPES
00160     #endif
00161 
00162     #if defined(__GNUC__)
00163         #if (((__GNUC__ * 100) + __GNUC_MINOR__) >= 302) // Also, GCC defines _HAS_C9X.
00164             #define EA_COMPILER_HAS_C99_TYPES // The compiler is not necessarily a C99 compiler, but it defines C99 types.
00165 
00166             #ifndef __STDC_LIMIT_MACROS
00167                 #define __STDC_LIMIT_MACROS
00168             #endif
00169 
00170             #ifndef __STDC_CONSTANT_MACROS
00171                 #define __STDC_CONSTANT_MACROS    // This tells the GCC compiler that we want it to use its native C99 types.
00172             #endif
00173         #endif
00174     #endif
00175 
00176     #ifdef  __cplusplus
00177         #define EA_COMPILER_IS_CPLUSPLUS
00178     #endif
00179 
00180 
00181     // ------------------------------------------------------------------------
00182     // EA_COMPILER_MANAGED_CPP
00183     // Defined if this is being compiled with Managed C++ extensions
00184     #ifdef EA_COMPILER_MSVC
00185         #if EA_COMPILER_VERSION >= 1300
00186             #ifdef _MANAGED
00187                 #define EA_COMPILER_MANAGED_CPP
00188             #endif
00189         #endif
00190     #endif
00191 
00192 
00193     // ------------------------------------------------------------------------
00194     // alignment expressions
00195     //
00196     // Here we define
00197     //    EA_ALIGN_OF(type)         // Returns size_t.
00198     //    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.
00199     //    EA_PREFIX_ALIGN(n)        // n is byte alignment, with being a power of two. You should need this only for unusual compilers.
00200     //    EA_POSTFIX_ALIGN(n)       // Valid values for n are 1, 2, 4, 8, etc. You should need this only for unusual compilers.
00201     //    EA_ALIGNED(t, v, n)       // Type, variable, alignment. Used to align an instance. You should need this only for unusual compilers.
00202     //    EA_PACKED                 // Specifies that the given structure be packed (and not have its members aligned).
00203     //
00204     // Example usage:
00205     //    size_t x = EA_ALIGN_OF(int);                                  Non-aligned equivalents.        Meaning
00206     //    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.
00207     //    EA_ALIGN(8) int x;                                            int x;                          Align x on 8 for compilers that allow prefix attributes.
00208     //    int x EA_POSTFIX_ALIGN(8);                                    int x;                          Align x on 8 for compilers that require postfix attributes.
00209     //    int x EA_POSTFIX_ALIGN(8) = 5;                                int x = 5;                      Align x on 8 for compilers that require postfix attributes.
00210     //    int x EA_POSTFIX_ALIGN(8)(5);                                 int x(5);                       Align x on 8 for compilers that require postfix attributes.
00211     //    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.
00212     //    EA_ALIGNED(int, x, 8) = 5;                                    int x = 5;                      Align x on 8.
00213     //    EA_ALIGNED(int, x, 16)(5);                                    int x(5);                       Align x on 16.
00214     //    EA_ALIGNED(int, x[3], 16);                                    int x[3];                       Align x array on 16.
00215     //    EA_ALIGNED(int, x[3], 16) = { 1, 2, 3 };                      int x[3] = { 1, 2, 3 };         Align x array on 16.
00216     //    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.
00217     //    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.
00218     //    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.
00219     //    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.
00220     //    struct X { int x; int y; } EA_PACKED;                         struct X { int x; int y; };     Pack the members of struct X.
00221     //    typedef EA_ALIGNED(int, int16, 16); int16 n16;                typedef int int16; int16 n16;   Define int16 as an int which is aligned on 16.
00222     //    typedef EA_ALIGNED(X, X16, 16); X16 x16;                      typedef X X16; X16 x16;         Define X16 as an X which is aligned on 16.
00223 
00224     // SNC (EDG) intends to be compatible with GCC but has a bug whereby it
00225     // fails to support calling a constructor in an aligned declaration when
00226     // using postfix alignment attributes. Prefix works for alignment, but does not align
00227     // the size like postfix does.  Prefix also fails on templates.  So gcc style post fix
00228     // is still used, but the user will need to use EA_POSTFIX_ALIGN before the constructor parameters.
00229     // this note by Paul and Frank
00230     #if defined(EA_COMPILER_SN) && defined(__GNUC__)  // If using the SN compiler in GCC compatibility mode...
00231         #define EA_ALIGN_OF(type) ((size_t)__alignof__(type))
00232         #define EA_ALIGN(n) __attribute__((aligned(n)))
00233         #define EA_PREFIX_ALIGN(n)
00234         #define EA_POSTFIX_ALIGN(n) __attribute__((aligned(n)))
00235         #define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n)))
00236         #define EA_PACKED __attribute__((packed))
00237 
00238     // GCC 2.x doesn't support prefix attributes.
00239     #elif defined(__GNUC__) && (__GNUC__ < 3)
00240         #define EA_ALIGN_OF(type) ((size_t)__alignof__(type))
00241         #define EA_ALIGN(n)
00242         #define EA_PREFIX_ALIGN(n)
00243         #define EA_POSTFIX_ALIGN(n) __attribute__((aligned(n)))
00244         #define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n)))
00245         #define EA_PACKED __attribute__((packed))
00246 
00247     // GCC 3.x+ and IBM C support prefix attributes.
00248     #elif (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__xlC__)
00249         #define EA_ALIGN_OF(type) ((size_t)__alignof__(type))
00250         #define EA_ALIGN(n) __attribute__((aligned(n)))
00251         #define EA_PREFIX_ALIGN(n)
00252         #define EA_POSTFIX_ALIGN(n) __attribute__((aligned(n)))
00253         #define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n)))
00254         #define EA_PACKED __attribute__((packed))
00255 
00256     // Metrowerks supports prefix attributes.
00257     // Metrowerks does not support packed alignment attributes.
00258     #elif defined(EA_COMPILER_METROWERKS)
00259         #define EA_ALIGN_OF(type) ((size_t)__alignof__(type))
00260         #define EA_ALIGN(n) __attribute__((aligned(n)))
00261         #define EA_PREFIX_ALIGN(n)
00262         #define EA_POSTFIX_ALIGN(n) __attribute__((aligned(n)))
00263         #define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n)))
00264         #define EA_PACKED
00265 
00266     // Microsoft supports prefix alignment via __declspec, but the alignment value must be a literal number, not just a constant expression.
00267     // Contrary to VC7.x and earlier documentation, __declspec(align) works on stack variables. VC8+ (VS2005+) documents correctly.
00268     // Microsoft does not support packed alignment attributes; you must use #pragma pack.
00269     #elif defined(EA_COMPILER_INTEL) || defined(EA_PLATFORM_XBOX) || (defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1300))
00270         #define EA_ALIGN_OF(type) ((size_t)__alignof(type))
00271         #define EA_ALIGN(n) __declspec(align(n))
00272         #define EA_PREFIX_ALIGN(n) __declspec(align(n))
00273         #define EA_POSTFIX_ALIGN(n)
00274         #define EA_ALIGNED(variable_type, variable, n) __declspec(align(n)) variable_type variable
00275         #define EA_PACKED
00276 
00277     // Arm brand compiler
00278     #elif defined(__ARMCC_VERSION)
00279         #define EA_ALIGN_OF(type) ((size_t)__ALIGNOF__(type))
00280         #define EA_ALIGN(n) __align(n)
00281         #define EA_PREFIX_ALIGN(n) __align(n)
00282         #define EA_POSTFIX_ALIGN(n)
00283         #define EA_ALIGNED(variable_type, variable, n) __align(n) variable_type variable
00284         #define EA_PACKED __packed
00285 
00286     #else // Unusual compilers
00287         // There is nothing we can do about some of these. This is not as bad a problem as it seems.
00288         // If the given platform/compiler doesn't support alignment specifications, then it's somewhat
00289         // likely that alignment doesn't matter for that platform. Otherwise they would have defined
00290         // functionality to manipulate alignment.
00291         #define EA_ALIGN(n)
00292         #define EA_PREFIX_ALIGN(n)
00293         #define EA_POSTFIX_ALIGN(n)
00294         #define EA_ALIGNED(variable_type, variable, n) variable_type variable
00295         #define EA_PACKED
00296 
00297         #ifdef __cplusplus
00298             template <typename T> struct EAAlignOf1 { enum { s = sizeof (T), value = s ^ (s & (s - 1)) }; };
00299             template <typename T> struct EAAlignOf2;
00300             template <int size_diff> struct helper { template <typename T> struct Val { enum { value = size_diff }; }; };
00301             template <> struct helper<0> { template <typename T> struct Val { enum { value = EAAlignOf2<T>::value }; }; };
00302             template <typename T> struct EAAlignOf2 { struct Big { T x; char c; };
00303             enum { diff = sizeof (Big) - sizeof (T), value = helper<diff>::template Val<Big>::value }; };
00304             template <typename T> struct EAAlignof3 { enum { x = EAAlignOf2<T>::value, y = EAAlignOf1<T>::value, value = x < y ? x : y }; };
00305             #define EA_ALIGN_OF(type) ((size_t)EAAlignof3<type>::value)
00306 
00307         #else
00308             // C implementation of EA_ALIGN_OF
00309             // This implementation works for most cases, but doesn't directly work
00310             // for types such as function pointer declarations. To work with those
00311             // types you need to typedef the type and then use the typedef in EA_ALIGN_OF.
00312             #define EA_ALIGN_OF(type) ((size_t)offsetof(struct { char c; type m; }, m))
00313         #endif
00314     #endif
00315 
00316 
00317     // ------------------------------------------------------------------------
00318     // EA_LIKELY / EA_UNLIKELY
00319     //
00320     // Defined as a macro which gives a hint to the compiler for branch
00321     // prediction. GCC gives you the ability to manually give a hint to
00322     // the compiler about the result of a comparison, though it's often
00323     // best to compile shipping code with profiling feedback under both
00324     // GCC (-fprofile-arcs) and VC++ (/LTCG:PGO, etc.). However, there
00325     // are times when you feel very sure that a boolean expression will
00326     // usually evaluate to either true or false and can help the compiler
00327     // by using an explicity directive...
00328     //
00329     // Example usage:
00330     //    if(EA_LIKELY(a == 0)) // Tell the compiler that a will usually equal 0.
00331     //       { ... }
00332     //
00333     // Example usage:
00334     //    if(EA_UNLIKELY(a == 0)) // Tell the compiler that a will usually not equal 0.
00335     //       { ... }
00336     //
00337     #ifndef EA_LIKELY
00338         #if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__MWERKS__) // Metrowerks supports __builtin_expect, but with some platforms (e.g. Wii) it appears to ignore it.
00339             #if defined(__cplusplus)
00340                 #define EA_LIKELY(x)   __builtin_expect(!!(x), true)
00341                 #define EA_UNLIKELY(x) __builtin_expect(!!(x), false)
00342             #else
00343                 #define EA_LIKELY(x)   __builtin_expect(!!(x), 1)
00344                 #define EA_UNLIKELY(x) __builtin_expect(!!(x), 0)
00345             #endif
00346         #else
00347             #define EA_LIKELY(x)   (x)
00348             #define EA_UNLIKELY(x) (x)
00349         #endif
00350     #endif
00351 
00352 
00353     // ------------------------------------------------------------------------
00354     // EA_INIT_PRIORITY
00355     //
00356     // This is simply a wrapper for the GCC init_priority attribute that allows
00357     // multiplatform code to be easier to read. This attribute doesn't apply
00358     // to VC++ because VC++ uses file-level pragmas to control init ordering.
00359     //
00360     // Example usage:
00361     //     SomeClass gSomeClass EA_INIT_PRIORITY(2000);
00362     //
00363     #if !defined(EA_INIT_PRIORITY)
00364         #if defined(__GNUC__)
00365             #define EA_INIT_PRIORITY(x)  __attribute__ ((init_priority (x)))
00366         #else
00367             #define EA_INIT_PRIORITY(x)
00368         #endif
00369     #endif
00370 
00371 
00372     // ------------------------------------------------------------------------
00373     // EA_MAY_ALIAS
00374     //
00375     // Defined as a macro that wraps the GCC may_alias attribute. This attribute
00376     // has no significance for VC++ because VC++ doesn't support the concept of
00377     // strict aliasing. Users should avoid writing code that breaks strict
00378     // aliasing rules; EA_MAY_ALIAS is for cases with no alternative.
00379     //
00380     // Example usage:
00381     //    void* EA_MAY_ALIAS gPtr = NULL;
00382     //
00383     // Example usage:
00384     //    typedef void* EA_MAY_ALIAS pvoid_may_alias;
00385     //    pvoid_may_alias gPtr = NULL;
00386     //
00387     #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 303)
00388         #define EA_MAY_ALIAS __attribute__((__may_alias__))
00389     #else
00390         #define EA_MAY_ALIAS
00391     #endif
00392 
00393 
00394     // ------------------------------------------------------------------------
00395     // EA_ASSUME
00396     //
00397     // This acts the same as the VC++ __assume directive and is implemented
00398     // simply as a wrapper around it to allow portable usage of it and to take
00399     // advantage of it if and when it appears in other compilers.
00400     //
00401     // Example usage:
00402     //    void Function(int a) {
00403     //       switch(a) {
00404     //          case 1:
00405     //             DoSomething(1);
00406     //             break;
00407     //          case 2:
00408     //             DoSomething(-1);
00409     //             break;
00410     //          default:
00411     //             EA_ASSUME(0); // This tells the optimizer that the default cannot be reached.
00412     //       }
00413     //    }
00414     //
00415     #ifndef EA_ASSUME
00416         #if defined(_MSC_VER) && (_MSC_VER >= 1300) // If VC7.0 and later (including XBox, and XBox 360)...
00417             #define EA_ASSUME(x) __assume(x)
00418         #else
00419             #define EA_ASSUME(x)
00420         #endif
00421     #endif
00422 
00423 
00424 
00425     // ------------------------------------------------------------------------
00426     // EA_PURE
00427     //
00428     // This acts the same as the GCC __attribute__ ((pure)) directive and is
00429     // implemented simply as a wrapper around it to allow portable usage of
00430     // it and to take advantage of it if and when it appears in other compilers.
00431     //
00432     // A "pure" function is one that has no effects except its return value and
00433     // its return value is a function of only the function's parameters or
00434     // non-volatile global variables. Any parameter or global variable access
00435     // must be read-only. Loop optimization and subexpression elimination can be
00436     // applied to such functions. A common example is strlen(): Given identical
00437     // inputs, the function's return value (its only effect) is invariant across
00438     // multiple invocations and thus can be pulled out of a loop and called but once.
00439     //
00440     // Example usage:
00441     //    EA_PURE void Function();
00442     //
00443     #ifndef EA_PURE
00444         #if defined(EA_COMPILER_GNUC)
00445             #define EA_PURE __attribute__((pure))
00446         #elif defined(__ARMCC_VERSION)  // Arm brand compiler for ARM CPU
00447             #define EA_PURE __pure
00448         #else
00449             #define EA_PURE
00450         #endif
00451     #endif
00452 
00453 
00454 
00455     // ------------------------------------------------------------------------
00456     // EA_WEAK
00457     // EA_WEAK_SUPPORTED -- defined as 0 or 1.
00458     //
00459     // GCC
00460     // The weak attribute causes the declaration to be emitted as a weak
00461     // symbol rather than a global. This is primarily useful in defining
00462     // library functions which can be overridden in user code, though it
00463     // can also be used with non-function declarations.
00464     //
00465     // VC++
00466     // At link time, if multiple definitions of a COMDAT are seen, the linker
00467     // picks one and discards the rest. If the linker option /OPT:REF
00468     // is selected, then COMDAT elimination will occur to remove all the
00469     // unreferenced data items in the linker output.
00470     //
00471     // Example usage:
00472     //    EA_WEAK void Function();
00473     //
00474     #ifndef EA_WEAK
00475         #if defined(_MSC_VER) && (_MSC_VER >= 1300) // If VC7.0 and later (including XBox)...
00476             #define EA_WEAK __declspec(selectany)
00477             #define EA_WEAK_SUPPORTED 1
00478         #elif defined(_MSC_VER) || (defined(__GNUC__) && defined(__CYGWIN__))
00479             #define EA_WEAK
00480             #define EA_WEAK_SUPPORTED 0
00481         #elif defined(__ARMCC_VERSION)  // Arm brand compiler for ARM CPU
00482             #define EA_WEAK __weak
00483             #define EA_WEAK_SUPPORTED 1
00484         #else                           // GCC and IBM compilers, others.
00485             #define EA_WEAK __attribute__((weak))
00486             #define EA_WEAK_SUPPORTED 1
00487         #endif
00488     #endif
00489 
00490 
00491 
00492     // ------------------------------------------------------------------------
00493     // wchar_t
00494     // Here we define:
00495     //    EA_WCHAR_T_NON_NATIVE
00496     //    EA_WCHAR_SIZE = <sizeof(wchar_t)>
00497     //
00498     #ifndef EA_WCHAR_T_NON_NATIVE
00499         // Compilers that always implement wchar_t as native include:
00500         //     COMEAU, new SN, and other EDG-based compilers.
00501         //     GCC
00502         //     Borland
00503         //     SunPro
00504         //     IBM Visual Age
00505         #if defined(EA_COMPILER_INTEL)
00506             #if (EA_COMPILER_VERSION < 700)
00507                 #define EA_WCHAR_T_NON_NATIVE 1
00508             #else
00509                 #if (!defined(_WCHAR_T_DEFINED) && !defined(_WCHAR_T))
00510                     #define EA_WCHAR_T_NON_NATIVE 1
00511                 #endif
00512             #endif
00513         #elif defined(EA_COMPILER_MSVC) || defined(EA_COMPILER_BORLAND)
00514             #ifndef _NATIVE_WCHAR_T_DEFINED
00515                 #define EA_WCHAR_T_NON_NATIVE 1
00516             #endif
00517         #elif defined(EA_COMPILER_METROWERKS)
00518             #if !__option(wchar_type)
00519                 #define EA_WCHAR_T_NON_NATIVE 1
00520             #endif
00521         #elif defined(__SNC__) && !defined(__cplusplus) // If compiling C under SNC...
00522             #define EA_WCHAR_T_NON_NATIVE 1
00523         #endif
00524     #endif
00525 
00526     #ifndef EA_WCHAR_SIZE // If the user hasn't specified that it is a given size...
00527         #if defined(__WCHAR_MAX__) // GCC defines this for most platforms.
00528             #if (__WCHAR_MAX__ == 2147483647) || (__WCHAR_MAX__ == 4294967295)
00529                 #define EA_WCHAR_SIZE 4
00530             #elif (__WCHAR_MAX__ == 32767) || (__WCHAR_MAX__ == 65535)
00531                 #define EA_WCHAR_SIZE 2
00532             #elif (__WCHAR_MAX__ == 127) || (__WCHAR_MAX__ == 255)
00533                 #define EA_WCHAR_SIZE 1
00534             #else
00535                 #define EA_WCHAR_SIZE 4
00536             #endif
00537         #elif defined(WCHAR_MAX) // The SN and Arm compilers define this.
00538             #if (WCHAR_MAX == 2147483647) || (WCHAR_MAX == 4294967295)
00539                 #define EA_WCHAR_SIZE 4
00540             #elif (WCHAR_MAX == 32767) || (WCHAR_MAX == 65535)
00541                 #define EA_WCHAR_SIZE 2
00542             #elif (WCHAR_MAX == 127) || (WCHAR_MAX == 255)
00543                 #define EA_WCHAR_SIZE 1
00544             #else
00545                 #define EA_WCHAR_SIZE 4
00546             #endif
00547         #elif defined(_WCMAX) // The SN and Arm compilers define this.
00548             #if (_WCMAX == 2147483647) || (_WCMAX == 4294967295)
00549                 #define EA_WCHAR_SIZE 4
00550             #elif (_WCMAX == 32767) || (_WCMAX == 65535)
00551                 #define EA_WCHAR_SIZE 2
00552             #elif (_WCMAX == 127) || (_WCMAX == 255)
00553                 #define EA_WCHAR_SIZE 1
00554             #else
00555                 #define EA_WCHAR_SIZE 4
00556             #endif
00557         #elif defined(EA_PLATFORM_UNIX) || defined(EA_PLATFORM_PS3) || defined(EA_PLATFORM_PS3_SPU)
00558             // It is standard on Unix to have wchar_t be int32_t or uint32_t.
00559             // All versions of GNUC default to a 32 bit wchar_t, but has been used
00560             // with the -fshort-wchar GCC command line option to force it to 16 bit.
00561             // If you know that the compiler is set to use a wchar_t of other than
00562             // the default, you need to manually define EA_WCHAR_SIZE for the build.
00563             #define EA_WCHAR_SIZE 4
00564         #else
00565             // It is standard on Windows to have wchar_t be uint16_t.
00566             // Metrowerks and the new EDG-based SN compilers define wchar_t
00567             // as uint16_t. Given that there is currently no known way to tell at preprocessor
00568             // time what the size of wchar_t is, we declare it to be 2.
00569             // If you have EA_WCHAR_SIZE != sizeof(wchar_t), then your
00570             // code might not be broken, but it also won't work with wchar libraries
00571             // and data from other parts of EA. Under GCC, you can force wchar_t
00572             // to two bytes with the -fshort-wchar compiler argument.
00573             #define EA_WCHAR_SIZE 2
00574         #endif
00575     #endif
00576 
00577 
00578     // ------------------------------------------------------------------------
00579     // EA_RESTRICT
00580     //
00581     // The C99 standard defines a new keyword, restrict, which allows for the
00582     // improvement of code generation regarding memory usage. Compilers can
00583     // generate significantly faster code when you are able to use restrict.
00584     //
00585     // Example usage:
00586     //    void DoSomething(char* EA_RESTRICT p1, char* EA_RESTRICT p2);
00587     //
00588     #ifndef EA_RESTRICT
00589         #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // If VC8 (VS2005) or later...
00590             #define EA_RESTRICT __restrict
00591         #elif defined(EA_COMPILER_GNUC)
00592             #define EA_RESTRICT __restrict // GCC defines 'restrict' (as opposed to __restrict) in C99 mode only.
00593         #elif defined(__ARMCC_VERSION)
00594             #define EA_RESTRICT __restrict
00595         #elif defined(__MWERKS__)
00596             #if __option(c99)
00597                 #define EA_RESTRICT restrict
00598             #else
00599                 #define EA_RESTRICT
00600             #endif
00601         #elif defined(EA_COMPILER_IS_C99)
00602             #define EA_RESTRICT restrict
00603         #else
00604             // If the compiler didn't support restricted pointers, defining EA_RESTRICT
00605             // away would result in compiling and running fine but you just wouldn't
00606             // the same level of optimization. On the other hand, all the major compilers
00607             // support restricted pointers.
00608             #define EA_RESTRICT
00609         #endif
00610     #endif
00611 
00612 
00613     // ------------------------------------------------------------------------
00614     // EA_DEPRECATED            // Used as a prefix.
00615     // EA_PREFIX_DEPRECATED     // You should need this only for unusual compilers.
00616     // EA_POSTFIX_DEPRECATED    // You should need this only for unusual compilers.
00617     //
00618     // Example usage:
00619     //    EA_DEPRECATED void Function();
00620     //
00621     // or for maximum portability:
00622     //    EA_PREFIX_DEPRECATED void Function() EA_POSTFIX_DEPRECATED;
00623     //
00624     #ifndef EA_DEPRECATED
00625         #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION > 1300) // If VC7 (VS2003) or later...
00626             #define EA_DEPRECATED __declspec(deprecated)
00627         #elif defined(EA_COMPILER_MSVC)
00628             #define EA_DEPRECATED
00629         #else
00630             #define EA_DEPRECATED __attribute__((deprecated))
00631         #endif
00632     #endif
00633 
00634     #ifndef EA_PREFIX_DEPRECATED
00635         #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION > 1300) // If VC7 (VS2003) or later...
00636             #define EA_PREFIX_DEPRECATED __declspec(deprecated)
00637             #define EA_POSTFIX_DEPRECATED
00638         #elif defined(EA_COMPILER_MSVC)
00639             #define EA_PREFIX_DEPRECATED
00640             #define EA_POSTFIX_DEPRECATED
00641         #else
00642             #define EA_PREFIX_DEPRECATED
00643             #define EA_POSTFIX_DEPRECATED __attribute__((deprecated))
00644         #endif
00645     #endif
00646 
00647 
00648     // ------------------------------------------------------------------------
00649     // EA_FORCE_INLINE              // Used as a prefix.
00650     // EA_PREFIX_FORCE_INLINE       // You should need this only for unusual compilers.
00651     // EA_POSTFIX_FORCE_INLINE      // You should need this only for unusual compilers.
00652     //
00653     // Example usage:
00654     //     EA_FORCE_INLINE void Foo();                                // Implementation elsewhere.
00655     //     EA_PREFIX_FORCE_INLINE void Foo() EA_POSTFIX_FORCE_INLINE; // Implementation elsewhere.
00656     //
00657     // Note that when the prefix version of this function is used, it replaces
00658     // the regular C++ 'inline' statement. Thus you should not use both the
00659     // C++ inline statement and this macro with the same function declaration.
00660     //
00661     // To force inline usage under GCC 3.1+, you use this:
00662     //    inline void Foo() __attribute__((always_inline));
00663     //       or
00664     //    inline __attribute__((always_inline)) void Foo();
00665     //
00666     // The CodeWarrior compiler doesn't have the concept of forcing inlining per function.
00667     //
00668     #ifndef EA_FORCE_INLINE
00669         #if defined(EA_COMPILER_MSVC)
00670             #define EA_FORCE_INLINE __forceinline
00671         #elif defined(EA_COMPILER_GNUC) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 301)
00672             #if defined(__cplusplus)
00673                 #define EA_FORCE_INLINE inline __attribute__((always_inline))
00674             #else
00675                 #define EA_FORCE_INLINE __inline__ __attribute__((always_inline))
00676             #endif
00677         #else
00678             #if defined(__cplusplus)
00679                 #define EA_FORCE_INLINE inline
00680             #else
00681                 #define EA_FORCE_INLINE __inline
00682             #endif
00683         #endif
00684     #endif
00685 
00686     #if defined(EA_COMPILER_SN) && defined(EA_PLATFORM_PS3) // SN's implementation of always_inline is broken and sometimes fails to link the function.
00687         #define EA_PREFIX_FORCE_INLINE  inline
00688         #define EA_POSTFIX_FORCE_INLINE
00689     #elif defined(EA_COMPILER_GNUC) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 301)
00690         #define EA_PREFIX_FORCE_INLINE  inline
00691         #define EA_POSTFIX_FORCE_INLINE __attribute__((always_inline))
00692     #else
00693         #define EA_PREFIX_FORCE_INLINE  inline
00694         #define EA_POSTFIX_FORCE_INLINE
00695     #endif
00696 
00697 
00698     // ------------------------------------------------------------------------
00699     // EA_NO_INLINE             // Used as a prefix.
00700     // EA_PREFIX_NO_INLINE      // You should need this only for unusual compilers.
00701     // EA_POSTFIX_NO_INLINE     // You should need this only for unusual compilers.
00702     //
00703     // Example usage:
00704     //     EA_NO_INLINE        void Foo();                       // Implementation elsewhere.
00705     //     EA_PREFIX_NO_INLINE void Foo() EA_POSTFIX_NO_INLINE;  // Implementation elsewhere.
00706     //
00707     // That this declaration is incompatbile with C++ 'inline' and any
00708     // variant of EA_FORCE_INLINE.
00709     //
00710     // To disable inline usage under VC++ priof to VS2005, you need to use this:
00711     //    #pragma inline_depth(0) // Disable inlining.
00712     //    void Foo() { ... }
00713     //    #pragma inline_depth()  // Restore to default.
00714     //
00715     // Since there is no easy way to disable inlining on a function-by-function
00716     // basis in VC++ prior to VS2005, the best strategy is to write platform-specific
00717     // #ifdefs in the code or to disable inlining for a given module and enable
00718     // functions individually with EA_FORCE_INLINE.
00719     //
00720     #ifndef EA_NO_INLINE
00721         #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // If VC8 (VS2005) or later...
00722             #define EA_NO_INLINE __declspec(noinline)
00723         #elif defined(EA_COMPILER_MSVC)
00724             #define EA_NO_INLINE
00725         #else
00726             #define EA_NO_INLINE __attribute__((noinline))
00727         #endif
00728     #endif
00729 
00730     #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // If VC8 (VS2005) or later...
00731         #define EA_PREFIX_NO_INLINE  __declspec(noinline)
00732         #define EA_POSTFIX_NO_INLINE
00733     #elif defined(EA_COMPILER_MSVC)
00734         #define EA_PREFIX_NO_INLINE
00735         #define EA_POSTFIX_NO_INLINE
00736     #else
00737         #define EA_PREFIX_NO_INLINE
00738         #define EA_POSTFIX_NO_INLINE __attribute__((noinline))
00739     #endif
00740 
00741 
00742     // ------------------------------------------------------------------------
00743     // EA_NO_VTABLE
00744     //
00745     // Example usage:
00746     //     class EA_NO_VTABLE X {
00747     //        virtual void InterfaceFunction();
00748     //     };
00749     //
00750     //     EA_CLASS_NO_VTABLE(X) {
00751     //        virtual void InterfaceFunction();
00752     //     };
00753     //
00754     #ifdef EA_COMPILER_MSVC
00755         #define EA_NO_VTABLE           __declspec(novtable)
00756         #define EA_CLASS_NO_VTABLE(x)  class __declspec(novtable) x
00757         #define EA_STRUCT_NO_VTABLE(x) struct __declspec(novtable) x
00758     #else
00759         #define EA_NO_VTABLE
00760         #define EA_CLASS_NO_VTABLE(x)  class x
00761         #define EA_STRUCT_NO_VTABLE(x) struct x
00762     #endif
00763 
00764 
00765     // ------------------------------------------------------------------------
00766     // EA_PASCAL
00767     //
00768     // Also known on PC platforms as stdcall.
00769     // This convention causes the compiler to assume that the called function
00770     // will pop off the stack space used to pass arguments, unless it takes a
00771     // variable number of arguments.
00772     //
00773     // Example usage:
00774     //    this:
00775     //       void DoNothing(int x);
00776     //       void DoNothing(int x){}
00777     //    would be written as this:
00778     //       void EA_PASCAL_FUNC(DoNothing(int x));
00779     //       void EA_PASCAL_FUNC(DoNothing(int x)){}
00780     //
00781     #ifndef EA_PASCAL
00782         #if defined(EA_COMPILER_MSVC)
00783             #define EA_PASCAL __stdcall
00784         #elif defined(EA_COMPILER_GNUC) && defined(EA_PROCESSOR_X86)
00785             #define EA_PASCAL __attribute__((stdcall))
00786         #elif defined(EA_COMPILER_METROWERKS) && defined(EA_PLATFORM_WINDOWS)
00787             // You need to make sure you have the Metrowerks "ANSI keywords only'
00788             // compilation option disabled for the pascal keyword to work.
00789             #define EA_PASCAL   pascal
00790         #else
00791             // Some compilers simply don't support pascal calling convention.
00792             // As a result, there isn't an issue here, since the specification of
00793             // pascal calling convention is for the purpose of disambiguating the
00794             // calling convention that is applied.
00795             #define EA_PASCAL
00796         #endif
00797     #endif
00798 
00799     #ifndef EA_PASCAL_FUNC
00800         #if defined(EA_COMPILER_MSVC)
00801             #define EA_PASCAL_FUNC(funcname_and_paramlist)    __stdcall funcname_and_paramlist
00802         #elif defined(EA_COMPILER_GNUC) && defined(EA_PROCESSOR_X86)
00803             #define EA_PASCAL_FUNC(funcname_and_paramlist)    __attribute__((stdcall)) funcname_and_paramlist
00804         #elif defined(EA_COMPILER_METROWERKS) && defined(EA_PLATFORM_WINDOWS)
00805             #define EA_PASCAL_FUNC(funcname_and_paramlist)    pascal funcname_and_paramlist
00806         #else
00807             #define EA_PASCAL_FUNC(funcname_and_paramlist)    funcname_and_paramlist
00808         #endif
00809     #endif
00810 
00811 
00812     // ------------------------------------------------------------------------
00813     // EA_SSE
00814     // Visual C Processor Packs define _MSC_FULL_VER and are needed for SSE
00815     // Intel C also has SSE support.
00816     // EA_SSE is used to select FPU or SSE versions in hw_select.inl
00817     #ifndef EA_SSE
00818         #if defined(EA_COMPILER_GNUC)
00819             #if defined(__SSE2__)
00820                 #define EA_SSE 2
00821             #elif defined(__SSE__) && __SSE__
00822                 #define EA_SSE 1
00823             #else
00824                 #define EA_SSE 0
00825             #endif
00826         #elif defined(EA_PROCESSOR_X86) && defined(_MSC_FULL_VER) && !defined(__NOSSE__) && defined(_M_IX86_FP)
00827             #define EA_SSE _M_IX86_FP
00828         #elif defined(EA_PROCESSOR_X86) && defined(EA_COMPILER_INTEL) && !defined(__NOSSE__)
00829             #define EA_SSE 1
00830         #else
00831             #define EA_SSE 0
00832         #endif
00833     #endif
00834 
00835 
00836     // ------------------------------------------------------------------------
00837     // EA_IMPORT
00838     // import declaration specification
00839     // specifies that the declared symbol is imported from another dynamic library.
00840     #ifndef EA_IMPORT
00841         #if defined(EA_COMPILER_MSVC)
00842             #define EA_IMPORT __declspec(dllimport)
00843         #else
00844             #define EA_IMPORT
00845         #endif
00846     #endif
00847 
00848 
00849     // ------------------------------------------------------------------------
00850     // EA_EXPORT
00851     // export declaration specification
00852     // specifies that the declared symbol is exported from the current dynamic library.
00853     // this is not the same as the C++ export keyword.
00854     #ifndef EA_EXPORT
00855         #if defined(EA_COMPILER_MSVC)
00856             #define EA_EXPORT __declspec(dllexport)
00857         #else
00858             #define EA_EXPORT
00859         #endif
00860     #endif
00861 
00862 
00863     // ------------------------------------------------------------------------
00864     // EA_PRAGMA_ONCE_SUPPORTED
00865     //
00866     // This is a wrapper for the #pragma once preprocessor directive.
00867     // It allows for some compilers (in particular VC++) to implement signifcantly
00868     // faster include file preprocessing. #pragma once can be used to replace
00869     // header include guards or to augment them. However, #pragma once isn't
00870     // necessarily supported by all compilers and isn't guaranteed to be so in
00871     // the future, so using #pragma once to replace traditional include guards
00872     // is not strictly portable. Note that a direct #define for #pragma once is
00873     // impossible with VC++, due to limitations, but can be done with other
00874     // compilers/preprocessors via _Pragma("once").
00875     //
00876     // Example usage (which includes traditional header guards for portability):
00877     //    #ifndef SOMEPACKAGE_SOMEHEADER_H
00878     //    #define SOMEPACKAGE_SOMEHEADER_H
00879     //
00880     //    #if defined(EA_PRAGMA_ONCE_SUPPORTED)
00881     //        #pragma once
00882     //    #endif
00883     //
00884     //    <user code>
00885     //
00886     //    #endif
00887     //
00888     #if defined(_MSC_VER) || defined(__MWERKS__) || defined(__GNUC__) || defined(__SNC__) || defined(__ICC) || defined(__ICL)
00889         #define EA_PRAGMA_ONCE_SUPPORTED 1
00890     #endif
00891 
00892 
00893     // ------------------------------------------------------------------------
00894     // EA_OVERRIDE
00895     //
00896     //  See http://msdn.microsoft.com/en-us/library/41w3sh1c.aspx for more information.
00897     //
00898     #ifndef EA_OVERRIDE
00899         #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // VS2005 (VC8) and later
00900             #define EA_OVERRIDE override
00901         #else
00902             #define EA_OVERRIDE
00903         #endif
00904     #endif
00905 
00906 
00907     // ------------------------------------------------------------------------
00908     // EA_SEALED
00909     //
00910     // See http://msdn.microsoft.com/en-us/library/49k3w2fx%28VS.71%29.aspx for more information.
00911     //
00912     #ifndef EA_SEALED
00913         #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // VS2005 (VC8) and later
00914             #define EA_SEALED sealed
00915         #else
00916             #define EA_SEALED
00917         #endif
00918     #endif
00919 
00920 
00921     // ------------------------------------------------------------------------
00922     // EA_ABSTRACT
00923     //
00924     // See http://msdn.microsoft.com/en-us/library/49k3w2fx%28VS.71%29.aspx for more information.
00925     //
00926     #ifndef EA_ABSTRACT
00927         #if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // VS2005 (VC8) and later
00928             #define EA_ABSTRACT abstract
00929         #else
00930             #define EA_ABSTRACT
00931         #endif
00932     #endif
00933 
00934 
00935 #endif // Header include guard
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends