|
Sierra Toolkit
Version of the Day
|
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