Sierra Toolkit Version of the Day
eabase_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  * eabase.h
00031  *
00032  * Copyright (c) 2002 - 2005 Electronic Arts Inc. All rights reserved.
00033  * Maintained by Paul Pedriana, Maxis
00034  *---------------------------------------------------------------------------*/
00035 
00036 
00037 #ifndef INCLUDED_eabase_H
00038 #define INCLUDED_eabase_H
00039 
00040 
00041 // Identify the compiler and declare the EA_COMPILER_xxxx defines
00042 #ifndef INCLUDED_eacompiler_H
00043     #include <stk_util/util/eacompiler_eastl.h>
00044 #endif
00045 
00046 // Identify traits which this compiler supports, or does not support
00047 #ifndef INCLUDED_eacompilertraits_H
00048     #include <stk_util/util/eacompilertraits_eastl.h>
00049 #endif
00050 
00051 // Identify the platform and declare the EA_xxxx defines
00052 #ifndef INCLUDED_eaplatform_H
00053     #include <stk_util/util/eaplatform_eastl.h>
00054 #endif
00055 
00056 
00057 
00059 // EABASE_VERSION
00060 //
00061 // We more or less follow the conventional EA packaging approach to versioning
00062 // here. A primary distinction here is that minor versions are defined as two
00063 // digit entities (e.g. .03") instead of minimal digit entities ".3"). The logic
00064 // here is that the value is a counter and not a floating point fraction.
00065 // Note that the major version doesn't have leading zeros.
00066 //
00067 // Example version strings:
00068 //      "0.91.00"   // Major version 0, minor version 91, patch version 0.
00069 //      "1.00.00"   // Major version 1, minor and patch version 0.
00070 //      "3.10.02"   // Major version 3, minor version 10, patch version 02.
00071 //     "12.03.01"   // Major version 12, minor version 03, patch version
00072 //
00073 // Example usage:
00074 //     printf("EABASE version: %s", EABASE_VERSION);
00075 //     printf("EABASE version: %d.%d.%d", EABASE_VERSION_N / 10000 % 100, EABASE_VERSION_N / 100 % 100, EABASE_VERSION_N % 100);
00076 //
00078 
00079 #ifndef EABASE_VERSION
00080     #define EABASE_VERSION   "2.00.22"
00081     #define EABASE_VERSION_N  20022
00082 #endif
00083 
00084 
00085 
00086 // ------------------------------------------------------------------------
00087 // The C++ standard defines size_t as a built-in type. Some compilers are
00088 // not standards-compliant in this respect, so we need an additional include.
00089 // The case is similar with wchar_t under C++.
00090 
00091 #if defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_MSVC) || defined(EA_WCHAR_T_NON_NATIVE)
00092     #include <stddef.h>
00093 #endif
00094 
00095 
00096 // ------------------------------------------------------------------------
00097 // Ensure this header file is only processed once (with certain compilers)
00098 // GCC doesn't need such a pragma because it has special recognition for
00099 // include guards (such as that above) and effectively implements the same
00100 // thing without having to resort to non-portable pragmas. It is possible
00101 // that the decision to use pragma once here is ill-advised, perhaps because
00102 // some compilers masquerade as MSVC but don't implement all features.
00103 #if defined(EA_COMPILER_MSVC) || defined(EA_COMPILER_METROWERKS)
00104     #pragma once
00105 #endif
00106 
00107 
00108 // ------------------------------------------------------------------------
00109 // By default, GCC on certain platforms defines NULL as ((void*)0), which is the
00110 // C definition. This causes all sort of problems for C++ code, so it is
00111 // worked around by undefining NULL.
00112 
00113 #if defined(NULL)
00114     #undef NULL
00115 #endif
00116 
00117 
00118 // ------------------------------------------------------------------------
00119 // Define the NULL pointer. This is normally defined in <stddef.h>, but we
00120 // don't want to force a global dependency on that header, so the definition
00121 // is duplicated here.
00122 
00123 #if defined(__cplusplus)
00124     #define NULL 0
00125 #else
00126     #define NULL ((void*)0)
00127 #endif
00128 
00129 
00130 // ------------------------------------------------------------------------
00131 // C98/99 Standard typedefs. From the ANSI ISO/IEC 9899 standards document
00132 // Most recent versions of the gcc-compiler come with these defined in
00133 // inttypes.h or stddef.h. Determining if they are predefined can be
00134 // tricky, so we expect some problems on non-standard compilers
00135 
00136 // ------------------------------------------------------------------------
00137 // We need to test this after we potentially include stddef.h, otherwise we
00138 // would have put this into the compilertraits header.
00139 #if !defined(EA_COMPILER_HAS_INTTYPES) && (!defined(_MSC_VER) || (_MSC_VER > 1500)) && (defined(EA_COMPILER_IS_C99) || defined(INT8_MIN) || defined(EA_COMPILER_HAS_C99_TYPES) || defined(_SN_STDINT_H))
00140     #define EA_COMPILER_HAS_INTTYPES
00141 #endif
00142 
00143 
00144 #ifdef EA_COMPILER_HAS_INTTYPES // If the compiler supports inttypes...
00145     // ------------------------------------------------------------------------
00146     // Include the stdint header to define and derive the required types.
00147     // Additionally include inttypes.h as many compilers, including variations
00148     // of GCC define things in inttypes.h that the C99 standard says goes
00149     // in stdint.h.
00150     //
00151     // The C99 standard specifies that inttypes.h only define printf/scanf
00152     // format macros if __STDC_FORMAT_MACROS is defined before #including
00153     // inttypes.h. For consistency, we do that here.
00154     #ifndef __STDC_FORMAT_MACROS
00155        #define __STDC_FORMAT_MACROS
00156     #endif
00157     #if !defined(__psp__) // The GCC compiler defines standard int types (e.g. uint32_t) but not PRId8, etc.
00158         #include <inttypes.h> // PRId8, SCNd8, etc.
00159     #endif
00160     #include <stdint.h>   // int32_t, INT64_C, UINT8_MAX, etc.
00161     #include <math.h>     // float_t, double_t, etc.
00162     #include <float.h>    // FLT_EVAL_METHOD.
00163 
00164     #if !defined(FLT_EVAL_METHOD) && (defined(__FLT_EVAL_METHOD__) || defined(_FEVAL)) // GCC 3.x defines __FLT_EVAL_METHOD__ instead of the C99 standard FLT_EVAL_METHOD.
00165         #ifdef __FLT_EVAL_METHOD__
00166             #define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
00167         #else
00168             #define FLT_EVAL_METHOD _FEVAL
00169         #endif
00170     #endif
00171 
00172     // MinGW GCC (up to at least v4.3.0-20080502) mistakenly neglects to define float_t and double_t.
00173     // This appears to be an acknowledged bug as of March 2008 and is scheduled to be fixed.
00174     // Similarly, Android uses a mix of custom standard library headers which don't define float_t and double_t.
00175     #if defined(__MINGW32__) || defined(EA_PLATFORM_ANDROID)
00176         #if defined(__FLT_EVAL_METHOD__)
00177             #if(__FLT_EVAL_METHOD__== 0)
00178                 typedef float float_t;
00179                 typedef double double_t;
00180             #elif(__FLT_EVAL_METHOD__ == 1)
00181                 typedef double float_t;
00182                 typedef double double_t;
00183             #elif(__FLT_EVAL_METHOD__ == 2)
00184                 typedef long double float_t;
00185                 typedef long double double_t;
00186             #endif
00187         #else
00188             typedef float  float_t;
00189             typedef double double_t;
00190         #endif
00191     #endif
00192 
00193     // Airplay's pretty broken for these types (at least as of 4.1)
00194     #if defined __S3E__
00195 
00196         typedef float float_t;
00197         typedef double double_t;
00198 
00199         #undef INT32_C
00200         #undef UINT32_C
00201         #undef INT64_C
00202         #undef UINT64_C
00203         #define  INT32_C(x)  x##L
00204         #define UINT32_C(x)  x##UL
00205         #define  INT64_C(x)  x##LL
00206         #define UINT64_C(x)  x##ULL
00207 
00208         #define EA_PRI_64_LENGTH_SPECIFIER "ll"
00209         #define EA_SCN_64_LENGTH_SPECIFIER "ll"
00210 
00211         #define SCNd16        "hd"
00212         #define SCNi16        "hi"
00213         #define SCNo16        "ho"
00214         #define SCNu16        "hu"
00215         #define SCNx16        "hx"
00216 
00217         #define SCNd32        "d" // This works for both 32 bit and 64 bit systems, as we assume LP64 conventions.
00218         #define SCNi32        "i"
00219         #define SCNo32        "o"
00220         #define SCNu32        "u"
00221         #define SCNx32        "x"
00222 
00223         #define SCNd64        EA_SCN_64_LENGTH_SPECIFIER "d"
00224         #define SCNi64        EA_SCN_64_LENGTH_SPECIFIER "i"
00225         #define SCNo64        EA_SCN_64_LENGTH_SPECIFIER "o"
00226         #define SCNu64        EA_SCN_64_LENGTH_SPECIFIER "u"
00227         #define SCNx64        EA_SCN_64_LENGTH_SPECIFIER "x"
00228 
00229         #define PRIdPTR       PRId32 // Usage of pointer values will generate warnings with
00230         #define PRIiPTR       PRIi32 // some compilers because they are defined in terms of
00231         #define PRIoPTR       PRIo32 // integers. However, you can't simply use "p" because
00232         #define PRIuPTR       PRIu32 // 'p' is interpreted in a specific and often different
00233         #define PRIxPTR       PRIx32 // way by the library.
00234         #define PRIXPTR       PRIX32
00235 
00236         #define PRId8     "hhd"
00237         #define PRIi8     "hhi"
00238         #define PRIo8     "hho"
00239         #define PRIu8     "hhu"
00240         #define PRIx8     "hhx"
00241         #define PRIX8     "hhX"
00242 
00243         #define PRId16        "hd"
00244         #define PRIi16        "hi"
00245         #define PRIo16        "ho"
00246         #define PRIu16        "hu"
00247         #define PRIx16        "hx"
00248         #define PRIX16        "hX"
00249 
00250         #define PRId32        "d" // This works for both 32 bit and 64 bit systems, as we assume LP64 conventions.
00251         #define PRIi32        "i"
00252         #define PRIo32        "o"
00253         #define PRIu32        "u"
00254         #define PRIx32        "x"
00255         #define PRIX32        "X"
00256 
00257         #define PRId64        EA_PRI_64_LENGTH_SPECIFIER "d"
00258         #define PRIi64        EA_PRI_64_LENGTH_SPECIFIER "i"
00259         #define PRIo64        EA_PRI_64_LENGTH_SPECIFIER "o"
00260         #define PRIu64        EA_PRI_64_LENGTH_SPECIFIER "u"
00261         #define PRIx64        EA_PRI_64_LENGTH_SPECIFIER "x"
00262         #define PRIX64        EA_PRI_64_LENGTH_SPECIFIER "X"
00263     #endif
00264 
00265     // The CodeSourcery definitions of PRIxPTR and SCNxPTR are broken for 32 bit systems.
00266     #if defined(__SIZEOF_SIZE_T__) && (__SIZEOF_SIZE_T__ == 4) && (defined(__have_long64) || defined(__have_longlong64) || defined(__S3E__))
00267         #undef  PRIdPTR
00268         #define PRIdPTR "d"
00269         #undef  PRIiPTR
00270         #define PRIiPTR "i"
00271         #undef  PRIoPTR
00272         #define PRIoPTR "o"
00273         #undef  PRIuPTR
00274         #define PRIuPTR "u"
00275         #undef  PRIxPTR
00276         #define PRIxPTR "x"
00277         #undef  PRIXPTR
00278         #define PRIXPTR "X"
00279 
00280         #undef  SCNdPTR
00281         #define SCNdPTR "d"
00282         #undef  SCNiPTR
00283         #define SCNiPTR "i"
00284         #undef  SCNoPTR
00285         #define SCNoPTR "o"
00286         #undef  SCNuPTR
00287         #define SCNuPTR "u"
00288         #undef  SCNxPTR
00289         #define SCNxPTR "x"
00290     #endif
00291 #else // else we must implement types ourselves.
00292 
00293     #if !defined(__S3E__)
00294         #if !defined(__BIT_TYPES_DEFINED__) && !defined(__int8_t_defined)
00295             typedef signed char             int8_t;             //< 8 bit signed integer
00296         #endif
00297         #if !defined( __int8_t_defined )
00298             typedef signed short            int16_t;            //< 16 bit signed integer
00299             typedef signed int              int32_t;            //< 32 bit signed integer. This works for both 32 bit and 64 bit platforms, as we assume the LP64 is followed.
00300             #define __int8_t_defined
00301         #endif
00302             typedef unsigned char           uint8_t;            //< 8 bit unsigned integer
00303             typedef unsigned short         uint16_t;            //< 16 bit unsigned integer
00304         #if !defined( __uint32_t_defined )
00305             typedef unsigned int           uint32_t;            //< 32 bit unsigned integer. This works for both 32 bit and 64 bit platforms, as we assume the LP64 is followed.
00306             #define __uint32_t_defined
00307         #endif
00308     #endif
00309 
00310     // According to the C98/99 standard, FLT_EVAL_METHOD defines control the
00311     // width used for floating point _t types.
00312     #if defined(__MWERKS__) && ((defined(_MSL_C99) && (_MSL_C99 == 1)) || (__MWERKS__ < 0x4000))
00313        // Metrowerks defines FLT_EVAL_METHOD and
00314        // float_t/double_t under this condition.
00315     #elif defined(FLT_EVAL_METHOD)
00316         #if (FLT_EVAL_METHOD == 0)
00317             typedef float           float_t;
00318             typedef double          double_t;
00319         #elif (FLT_EVAL_METHOD == 1)
00320             typedef double          float_t;
00321             typedef double          double_t;
00322         #elif (FLT_EVAL_METHOD == 2)
00323             typedef long double     float_t;
00324             typedef long double     double_t;
00325         #endif
00326     #else
00327         #define FLT_EVAL_METHOD 0
00328         typedef float               float_t;
00329         typedef double              double_t;
00330     #endif
00331 
00332    #if defined(EA_PLATFORM_LINUX) || defined(EA_PLATFORM_PS3) || defined(EA_PLATFORM_PS3_SPU)
00333        typedef signed long long    int64_t;
00334        typedef unsigned long long  uint64_t;
00335 
00336    #elif defined(EA_PLATFORM_SUN) || defined(EA_PLATFORM_SGI)
00337        #if (EA_PLATFORM_PTR_SIZE == 4)
00338            typedef signed long long    int64_t;
00339            typedef unsigned long long  uint64_t;
00340        #else
00341            typedef signed long         int64_t;
00342            typedef unsigned long       uint64_t;
00343        #endif
00344 
00345    #elif defined(EA_PLATFORM_WINDOWS) || defined(EA_PLATFORM_XBOX) || defined(EA_PLATFORM_XENON) || defined(EA_PLATFORM_MAC)
00346        #if defined(EA_COMPILER_MSVC) || defined(EA_COMPILER_BORLAND)  || defined(EA_COMPILER_INTEL)
00347            typedef signed __int64      int64_t;
00348            typedef unsigned __int64    uint64_t;
00349        #else // GCC, Metrowerks, etc.
00350            typedef long long           int64_t;
00351            typedef unsigned long long  uint64_t;
00352        #endif
00353    #elif defined(EA_PLATFORM_AIRPLAY)
00354    #else
00355        typedef signed long long    int64_t;
00356        typedef unsigned long long  uint64_t;
00357    #endif
00358 
00359 
00360     // ------------------------------------------------------------------------
00361     // macros for declaring constants in a portable way.
00362     //
00363     // e.g. int64_t  x =  INT64_C(1234567812345678);
00364     // e.g. int64_t  x =  INT64_C(0x1111111122222222);
00365     // e.g. uint64_t x = UINT64_C(0x1111111122222222);
00366 
00367     #ifndef INT8_C_DEFINED // If the user hasn't already defined these...
00368         #define INT8_C_DEFINED
00369 
00370         // VC++ 7.0 and earlier don't handle the LL suffix.
00371         #if defined(EA_COMPILER_MSVC) || defined(EA_COMPILER_BORLAND)
00372             #ifndef INT8_C
00373                 #define   INT8_C(x)    int8_t(x)  // x##i8 doesn't work satisfactorilly because -128i8 generates an out of range warning.
00374             #endif
00375             #ifndef UINT8_C
00376                 #define  UINT8_C(x)   uint8_t(x)
00377             #endif
00378             #ifndef INT16_C
00379                 #define  INT16_C(x)   int16_t(x)  // x##i16 doesn't work satisfactorilly because -32768i8 generates an out of range warning.
00380             #endif
00381             #ifndef UINT16_C
00382                 #define UINT16_C(x)  uint16_t(x)
00383             #endif
00384             #ifndef INT32_C
00385                 #define  INT32_C(x)  x##i32
00386             #endif
00387             #ifndef UINT32_C
00388                 #define UINT32_C(x)  x##ui32
00389             #endif
00390             #ifndef INT64_C
00391                 #define  INT64_C(x)  x##i64
00392             #endif
00393             #ifndef UINT64_C
00394                 #define UINT64_C(x)  x##ui64
00395             #endif
00396 
00397         #elif !defined(__STDC_CONSTANT_MACROS) // __STDC_CONSTANT_MACROS is defined by GCC 3 and later when INT8_C(), etc. are defined.
00398             #define   INT8_C(x)    int8_t(x)   // For the majority of compilers and platforms, long is 32 bits and long long is 64 bits.
00399             #define  UINT8_C(x)   uint8_t(x)
00400             #define  INT16_C(x)   int16_t(x)
00401             #define UINT16_C(x)  uint16_t(x)     // Possibly we should make this be uint16_t(x##u). Let's see how compilers react before changing this.
00402             #if defined(EA_PLATFORM_PS3)         // PS3 defines long as 64 bit, so we cannot use any size suffix.
00403                 #define  INT32_C(x)  int32_t(x)
00404                 #define UINT32_C(x)  uint32_t(x)
00405             #else                                // Else we are working on a platform whereby sizeof(long) == sizeof(int32_t).
00406                 #define  INT32_C(x)  x##L
00407                 #define UINT32_C(x)  x##UL
00408             #endif
00409             #define  INT64_C(x)  x##LL         // The way to deal with this is to compare ULONG_MAX to 0xffffffff and if not equal, then remove the L.
00410             #define UINT64_C(x)  x##ULL        // We need to follow a similar approach for LL.
00411         #endif
00412     #endif
00413 
00414     // ------------------------------------------------------------------------
00415     // type sizes
00416     #ifndef INT8_MAX_DEFINED // If the user hasn't already defined these...
00417         #define INT8_MAX_DEFINED
00418 
00419         // The value must be 2^(n-1)-1
00420         #ifndef INT8_MAX
00421             #define INT8_MAX                127
00422         #endif
00423         #ifndef INT16_MAX
00424             #define INT16_MAX               32767
00425         #endif
00426         #ifndef INT32_MAX
00427             #define INT32_MAX               2147483647
00428         #endif
00429         #ifndef INT64_MAX
00430             #define INT64_MAX               INT64_C(9223372036854775807)
00431         #endif
00432 
00433         // The value must be either -2^(n-1) or 1-2(n-1).
00434         #ifndef INT8_MIN
00435             #define INT8_MIN                -128
00436         #endif
00437         #ifndef INT16_MIN
00438             #define INT16_MIN               -32768
00439         #endif
00440         #ifndef INT32_MIN
00441             #define INT32_MIN               (-INT32_MAX - 1)  // -2147483648
00442         #endif
00443         #ifndef INT64_MIN
00444             #define INT64_MIN               (-INT64_MAX - 1)  // -9223372036854775808
00445         #endif
00446 
00447         // The value must be 2^n-1
00448         #ifndef UINT8_MAX
00449             #define UINT8_MAX               0xffU                        // 255
00450         #endif
00451         #ifndef UINT16_MAX
00452             #define UINT16_MAX              0xffffU                      // 65535
00453         #endif
00454         #ifndef UINT32_MAX
00455             #define UINT32_MAX              UINT32_C(0xffffffff)         // 4294967295
00456         #endif
00457         #ifndef UINT64_MAX
00458             #define UINT64_MAX              UINT64_C(0xffffffffffffffff) // 18446744073709551615
00459         #endif
00460     #endif
00461 
00462     // ------------------------------------------------------------------------
00463     // sized printf and scanf format specifiers
00464     // See the C99 standard, section 7.8.1 -- Macros for format specifiers.
00465     //
00466     // The C99 standard specifies that inttypes.h only define printf/scanf
00467     // format macros if __STDC_FORMAT_MACROS is defined before #including
00468     // inttypes.h. For consistency, we define both __STDC_FORMAT_MACROS and
00469     // the printf format specifiers here. We also skip the "least/most"
00470     // variations of these specifiers, as we've decided to do so with
00471     // basic types.
00472     //
00473     // For 64 bit systems, we assume the LP64 standard is followed
00474     // (as opposed to ILP64, etc.) For 32 bit systems, we assume the
00475     // ILP32 standard is followed. See:
00476     //    http://www.opengroup.org/public/tech/aspen/lp64_wp.htm
00477     // for information about this. Thus, on both 32 and 64 bit platforms,
00478     // %l refers to 32 bit data while %ll refers to 64 bit data.
00479 
00480     #ifndef __STDC_FORMAT_MACROS
00481        #define __STDC_FORMAT_MACROS
00482     #endif
00483 
00484     #if defined(EA_COMPILER_MSVC) || defined(EA_COMPILER_BORLAND) // VC++ 7.1+ understands long long as a data type but doesn't accept %ll as a printf specifier.
00485         #define EA_PRI_64_LENGTH_SPECIFIER "I64"
00486         #define EA_SCN_64_LENGTH_SPECIFIER "I64"
00487     #else
00488         #define EA_PRI_64_LENGTH_SPECIFIER "ll"
00489         #define EA_SCN_64_LENGTH_SPECIFIER "ll"
00490     #endif // It turns out that some platforms use %q to represent a 64 bit value, but these are not relevant to us at this time.
00491 
00492     // Printf format specifiers
00493     #if defined(EA_COMPILER_IS_C99) || defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_METROWERKS) // || defined(EA_COMPILER_INTEL) ?
00494         #define PRId8     "hhd"
00495         #define PRIi8     "hhi"
00496         #define PRIo8     "hho"
00497         #define PRIu8     "hhu"
00498         #define PRIx8     "hhx"
00499         #define PRIX8     "hhX"
00500     #else // VC++, Borland, etc. which have no way to specify 8 bit values other than %c.
00501         #define PRId8     "c"  // This may not work properly but it at least will not crash. Try using 16 bit versions instead.
00502         #define PRIi8     "c"  //  "
00503         #define PRIo8     "o"  //  "
00504         #define PRIu8     "u"  //  "
00505         #define PRIx8     "x"  //  "
00506         #define PRIX8     "X"  //  "
00507     #endif
00508 
00509     #define PRId16        "hd"
00510     #define PRIi16        "hi"
00511     #define PRIo16        "ho"
00512     #define PRIu16        "hu"
00513     #define PRIx16        "hx"
00514     #define PRIX16        "hX"
00515 
00516     #define PRId32        "d" // This works for both 32 bit and 64 bit systems, as we assume LP64 conventions.
00517     #define PRIi32        "i"
00518     #define PRIo32        "o"
00519     #define PRIu32        "u"
00520     #define PRIx32        "x"
00521     #define PRIX32        "X"
00522 
00523     #define PRId64        EA_PRI_64_LENGTH_SPECIFIER "d"
00524     #define PRIi64        EA_PRI_64_LENGTH_SPECIFIER "i"
00525     #define PRIo64        EA_PRI_64_LENGTH_SPECIFIER "o"
00526     #define PRIu64        EA_PRI_64_LENGTH_SPECIFIER "u"
00527     #define PRIx64        EA_PRI_64_LENGTH_SPECIFIER "x"
00528     #define PRIX64        EA_PRI_64_LENGTH_SPECIFIER "X"
00529 
00530     #if (EA_PLATFORM_PTR_SIZE == 4)
00531         #define PRIdPTR       PRId32 // Usage of pointer values will generate warnings with
00532         #define PRIiPTR       PRIi32 // some compilers because they are defined in terms of
00533         #define PRIoPTR       PRIo32 // integers. However, you can't simply use "p" because
00534         #define PRIuPTR       PRIu32 // 'p' is interpreted in a specific and often different
00535         #define PRIxPTR       PRIx32 // way by the library.
00536         #define PRIXPTR       PRIX32
00537     #elif (EA_PLATFORM_PTR_SIZE == 8)
00538         #define PRIdPTR       PRId64
00539         #define PRIiPTR       PRIi64
00540         #define PRIoPTR       PRIo64
00541         #define PRIuPTR       PRIu64
00542         #define PRIxPTR       PRIx64
00543         #define PRIXPTR       PRIX64
00544     #endif
00545 
00546     // Scanf format specifiers
00547     #if defined(EA_COMPILER_IS_C99) || defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_METROWERKS) // || defined(EA_COMPILER_INTEL) ?
00548         #define SCNd8     "hhd"
00549         #define SCNi8     "hhi"
00550         #define SCNo8     "hho"
00551         #define SCNu8     "hhu"
00552         #define SCNx8     "hhx"
00553     #else // VC++, Borland, etc. which have no way to specify 8 bit values other than %c.
00554         #define SCNd8     "c" // This will not work properly but it at least will not crash. Try using 16 bit versions instead.
00555         #define SCNi8     "c" //  "
00556         #define SCNo8     "c" //  "
00557         #define SCNu8     "c" //  "
00558         #define SCNx8     "c" //  "
00559     #endif
00560 
00561     #define SCNd16        "hd"
00562     #define SCNi16        "hi"
00563     #define SCNo16        "ho"
00564     #define SCNu16        "hu"
00565     #define SCNx16        "hx"
00566 
00567     #define SCNd32        "d" // This works for both 32 bit and 64 bit systems, as we assume LP64 conventions.
00568     #define SCNi32        "i"
00569     #define SCNo32        "o"
00570     #define SCNu32        "u"
00571     #define SCNx32        "x"
00572 
00573     #define SCNd64        EA_SCN_64_LENGTH_SPECIFIER "d"
00574     #define SCNi64        EA_SCN_64_LENGTH_SPECIFIER "i"
00575     #define SCNo64        EA_SCN_64_LENGTH_SPECIFIER "o"
00576     #define SCNu64        EA_SCN_64_LENGTH_SPECIFIER "u"
00577     #define SCNx64        EA_SCN_64_LENGTH_SPECIFIER "x"
00578 
00579     #if (EA_PLATFORM_PTR_SIZE == 4)
00580         #define SCNdPTR       SCNd32 // Usage of pointer values will generate warnings with
00581         #define SCNiPTR       SCNi32 // some compilers because they are defined in terms of
00582         #define SCNoPTR       SCNo32 // integers. However, you can't simply use "p" because
00583         #define SCNuPTR       SCNu32 // 'p' is interpreted in a specific and often different
00584         #define SCNxPTR       SCNx32 // way by the library.
00585     #elif (EA_PLATFORM_PTR_SIZE == 8)
00586         #define SCNdPTR       SCNd64
00587         #define SCNiPTR       SCNi64
00588         #define SCNoPTR       SCNo64
00589         #define SCNuPTR       SCNu64
00590         #define SCNxPTR       SCNx64
00591     #endif
00592 
00593 #endif
00594 
00595 
00596 // ------------------------------------------------------------------------
00597 // bool8_t
00598 // The definition of a bool8_t is controversial with some, as it doesn't
00599 // act just like built-in bool. For example, you can assign -100 to it.
00600 //
00601 #ifndef BOOL8_T_DEFINED // If the user hasn't already defined this...
00602     #define BOOL8_T_DEFINED
00603     #if defined(EA_COMPILER_MSVC) || defined(EA_COMPILER_METROWERKS) || (defined(EA_COMPILER_INTEL) && defined(EA_PLATFORM_WINDOWS)) || defined(EA_COMPILER_BORLAND)
00604         #if defined(__cplusplus)
00605             typedef bool bool8_t;
00606         #else
00607             typedef int8_t bool8_t;
00608         #endif
00609     #else // EA_COMPILER_GNUC generally uses 4 bytes per bool.
00610         typedef int8_t bool8_t;
00611     #endif
00612 #endif
00613 
00614 
00615 // ------------------------------------------------------------------------
00616 // intptr_t / uintptr_t
00617 // Integer type guaranteed to be big enough to hold
00618 // a native pointer ( intptr_t is defined in STDDEF.H )
00619 //
00620 #if !defined(_INTPTR_T_DEFINED) && !defined(_intptr_t_defined) && !defined(EA_COMPILER_HAS_C99_TYPES)
00621     #if (EA_PLATFORM_PTR_SIZE == 4)
00622         typedef int32_t            intptr_t;
00623     #elif (EA_PLATFORM_PTR_SIZE == 8)
00624         typedef int64_t            intptr_t;
00625     #endif
00626 
00627     #define _intptr_t_defined
00628     #define _INTPTR_T_DEFINED
00629 #endif
00630 
00631 #if !defined(_UINTPTR_T_DEFINED) && !defined(_uintptr_t_defined) && !defined(EA_COMPILER_HAS_C99_TYPES)
00632     #if (EA_PLATFORM_PTR_SIZE == 4)
00633         typedef uint32_t           uintptr_t;
00634     #elif (EA_PLATFORM_PTR_SIZE == 8)
00635         typedef uint64_t           uintptr_t;
00636     #endif
00637 
00638     #define _uintptr_t_defined
00639     #define _UINTPTR_T_DEFINED
00640 #endif
00641 
00642 #if !defined(EA_COMPILER_HAS_INTTYPES)
00643     #ifndef INTMAX_T_DEFINED
00644         #define INTMAX_T_DEFINED
00645 
00646         // At this time, all supported compilers have int64_t as the max
00647         // integer type. Some compilers support a 128 bit inteter type,
00648         // but in those cases it is not a true int128_t but rather a
00649         // crippled data type.
00650         typedef int64_t            intmax_t;
00651         typedef uint64_t           uintmax_t;
00652     #endif
00653 #endif
00654 
00655 
00656 // ------------------------------------------------------------------------
00657 // ssize_t
00658 // signed equivalent to size_t.
00659 // This is defined by GCC but not by other compilers.
00660 //
00661 #if !defined(__GNUC__)
00662     // As of this writing, all non-GCC compilers significant to us implement
00663     // uintptr_t the same as size_t. However, this isn't guaranteed to be
00664     // so for all compilers, as size_t may be based on int, long, or long long.
00665     #if defined(_MSC_VER) && (EA_PLATFORM_PTR_SIZE == 8)
00666         typedef __int64 ssize_t;
00667     #elif !defined(__S3E__)
00668         typedef long ssize_t;
00669     #endif
00670 #elif defined(EA_PLATFORM_UNIX) || defined(EA_PLATFORM_MINGW) || defined(__APPLE__) || defined(_BSD_SIZE_T_) // _BSD_SIZE_T_ indicates that Unix-like headers are present, even though it may not be a true Unix platform.
00671     #include <sys/types.h>
00672 #endif
00673 
00674 
00675 // ------------------------------------------------------------------------
00676 // Character types
00677 
00678 #if defined(EA_COMPILER_MSVC) || defined(EA_COMPILER_BORLAND)
00679     #if defined(EA_WCHAR_T_NON_NATIVE)
00680        // In this case, wchar_t is not defined unless we include
00681        // wchar.h or if the compiler makes it built-in.
00682        #ifdef EA_COMPILER_MSVC
00683           #pragma warning(push, 3)
00684        #endif
00685        #include <wchar.h>
00686        #ifdef EA_COMPILER_MSVC
00687           #pragma warning(pop)
00688        #endif
00689     #endif
00690 #endif
00691 
00692 
00693 // ------------------------------------------------------------------------
00694 // char8_t  -- Guaranteed to be equal to the compiler's char data type.
00695 //             Some compilers implement char8_t as unsigned, though char
00696 //             is usually set to be signed.
00697 //
00698 // char16_t -- This is set to be an unsigned 16 bit value. If the compiler
00699 //             has wchar_t as an unsigned 16 bit value, then char16_t is
00700 //             set to be the same thing as wchar_t in order to allow the
00701 //             user to use char16_t with standard wchar_t functions.
00702 //
00703 // char32_t -- This is set to be an unsigned 32 bit value. If the compiler
00704 //             has wchar_t as an unsigned 32 bit value, then char32_t is
00705 //             set to be the same thing as wchar_t in order to allow the
00706 //             user to use char32_t with standard wchar_t functions.
00707 //
00708 // VS2010 unilaterally defines char16_t and char32_t in its yvals.h header
00709 // unless _HAS_CHAR16_T_LANGUAGE_SUPPORT or _CHAR16T are defined.
00710 // However, VS2010 does not support the C++0x u"" and U"" string literals,
00711 // which makes its definition of char16_t and char32_t somewhat useless.
00712 // Until VC++ supports string literals, the buildystems should define
00713 // _CHAR16T and let EABase define char16_t and EA_CHAR16.
00714 //
00715 // GCC defines char16_t and char32_t in the C compiler in -std=gnu99 mode,
00716 // as __CHAR16_TYPE__ and __CHAR32_TYPE__, and for the C++ compiler
00717 // in -std=c++0x and -std=gnu++0x modes, as char16_t and char32_t too.
00718 
00719 #if !defined(EA_CHAR16_NATIVE)
00720     #if defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(_HAS_CHAR16_T_LANGUAGE_SUPPORT) && _HAS_CHAR16_T_LANGUAGE_SUPPORT // VS2010+
00721         #define EA_CHAR16_NATIVE 1
00722     #elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 404) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__STDC_VERSION__)) // g++ (C++ compiler) 4.4+ with -std=c++0x or gcc (C compiler) 4.4+ with -std=gnu99
00723         #define EA_CHAR16_NATIVE 1
00724     #else
00725         #define EA_CHAR16_NATIVE 0
00726     #endif
00727 #endif
00728 
00729 #if !defined(EA_CHAR32_NATIVE)
00730     #if defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(_HAS_CHAR16_T_LANGUAGE_SUPPORT) && _HAS_CHAR16_T_LANGUAGE_SUPPORT // VS2010+
00731         #define EA_CHAR32_NATIVE 1
00732     #elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 404) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__STDC_VERSION__)) // g++ (C++ compiler) 4.4+ with -std=c++0x or gcc (C compiler) 4.4+ with -std=gnu99
00733         #define EA_CHAR32_NATIVE 1
00734     #else
00735         #define EA_CHAR32_NATIVE 0
00736     #endif
00737 #endif
00738 
00739 
00740 #ifndef CHAR8_T_DEFINED // If the user hasn't already defined these...
00741     #define CHAR8_T_DEFINED
00742 
00743     #if EA_CHAR16_NATIVE
00744         typedef char char8_t;
00745 
00746         // In C++, char16_t and char32_t are already defined by the compiler.
00747         // In MS C, char16_t and char32_t are already defined by the compiler/standard library.
00748         // In GCC C, __CHAR16_TYPE__ and __CHAR32_TYPE__ are defined instead, and we must define char16_t and char32_t from these.
00749         #if defined(__GNUC__) && !defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(__CHAR16_TYPE__) // If using GCC and compiling in C...
00750             typedef __CHAR16_TYPE__ char16_t;
00751             typedef __CHAR32_TYPE__ char32_t;
00752         #endif
00753     #elif (EA_WCHAR_SIZE == 2)
00754         typedef char      char8_t;
00755         typedef wchar_t   char16_t;
00756         typedef uint32_t  char32_t;
00757     #else
00758         typedef char      char8_t;
00759         typedef uint16_t  char16_t;
00760         typedef wchar_t   char32_t;
00761     #endif
00762 #endif
00763 
00764 
00765 // EA_CHAR16 / EA_CHAR32
00766 //
00767 // Supports usage of portable string constants.
00768 //
00769 // Example usage:
00770 //     const char16_t* str = EA_CHAR16("Hello world");
00771 //     const char32_t* str = EA_CHAR32("Hello world");
00772 //     const char16_t  c   = EA_CHAR16('\x3001');
00773 //     const char32_t  c   = EA_CHAR32('\x3001');
00774 //
00775 #ifndef EA_CHAR16
00776     #if EA_CHAR16_NATIVE && !defined(_MSC_VER) // Microsoft doesn't support char16_t string literals.
00777         #define EA_CHAR16(s) u ## s
00778     #elif (EA_WCHAR_SIZE == 2)
00779         #define EA_CHAR16(s) L ## s
00780     #else
00781       //#define EA_CHAR16(s) // Impossible to implement.
00782     #endif
00783 #endif
00784 
00785 #ifndef EA_CHAR32
00786     #if EA_CHAR32_NATIVE && !defined(_MSC_VER) // Microsoft doesn't support char32_t string literals.
00787         #define EA_CHAR32(s) U ## s
00788     #elif (EA_WCHAR_SIZE == 2)
00789       //#define EA_CHAR32(s) // Impossible to implement.
00790     #else
00791         #define EA_CHAR32(s) L ## s
00792     #endif
00793 #endif
00794 
00795 
00796 // ------------------------------------------------------------------------
00797 // EAArrayCount
00798 //
00799 // Returns the count of items in a built-in C array. This is a common technique
00800 // which is often used to help properly calculate the number of items in an
00801 // array at runtime in order to prevent overruns, etc.
00802 //
00803 // Example usage:
00804 //     int array[75];
00805 //     size_t arrayCount = EAArrayCount(array); // arrayCount is 75.
00806 //
00807 #ifndef EAArrayCount
00808     #define EAArrayCount(x) (sizeof(x) / sizeof(x[0]))
00809 #endif
00810 
00811 
00812 // ------------------------------------------------------------------------
00813 // static_assert
00814 //
00815 // C++0x static_assert (a.k.a. compile-time assert).
00816 //
00817 // Specification:
00818 //     void static_assert(bool const_expression, const char* description);
00819 //
00820 // Example usage:
00821 //     static_assert(sizeof(int) == 4, "int must be 32 bits");
00822 //
00823 #if !defined(EABASE_STATIC_ASSERT_ENABLED)
00824     #if defined(EA_DEBUG) || defined(_DEBUG)
00825         #define EABASE_STATIC_ASSERT_ENABLED 1
00826     #else
00827         #define EABASE_STATIC_ASSERT_ENABLED 0
00828     #endif
00829 #endif
00830 
00831 #ifndef EA_PREPROCESSOR_JOIN
00832     #define EA_PREPROCESSOR_JOIN(a, b)  EA_PREPROCESSOR_JOIN1(a, b)
00833     #define EA_PREPROCESSOR_JOIN1(a, b) EA_PREPROCESSOR_JOIN2(a, b)
00834     #define EA_PREPROCESSOR_JOIN2(a, b) a##b
00835 #endif
00836 
00837 #if defined(_MSC_VER) && (_MSC_VER >= 1600)
00838     // static_assert is defined by the compiler for both C and C++.
00839 #elif defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__)
00840     // static_assert is defined by the compiler.
00841 #else
00842     #if EABASE_STATIC_ASSERT_ENABLED
00843         #if defined(__COUNTER__) // If this VC++ extension is available...
00844             #define static_assert(expression, description) enum { EA_PREPROCESSOR_JOIN(static_assert_, __COUNTER__) = 1 / ((!!(expression)) ? 1 : 0) }
00845         #else
00846             #define static_assert(expression, description) enum { EA_PREPROCESSOR_JOIN(static_assert_, __LINE__) = 1 / ((!!(expression)) ? 1 : 0) }
00847         #endif
00848     #else
00849         #if defined(EA_COMPILER_METROWERKS)
00850             #if defined(__cplusplus)
00851                 #define static_assert(expression, description) struct EA_PREPROCESSOR_JOIN(EACTAssertUnused_, __LINE__){ }
00852             #else
00853                 #define static_assert(expression, description) enum { EA_PREPROCESSOR_JOIN(static_assert_, __LINE__) = 1 / ((!!(expression)) ? 1 : 0) }
00854             #endif
00855         #else
00856             #define static_assert(expression, description)
00857         #endif
00858     #endif
00859 #endif
00860 
00861 
00862 #endif // Header include guard
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends