From 48e7789645cbf93102738f0da0f4181919d102a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomi=20Korpip=C3=A4=C3=A4?= Date: Fri, 5 Jun 2020 08:12:03 +0300 Subject: Update EABase for EASTL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for missing mips64 architecture. Task-number: QT3DS-4129 Change-Id: I03f306bf842a43fc686093fc0df693189b8a1452 Reviewed-by: Miikka Heikkinen Reviewed-by: Antti Määttä --- UnknownVersion/include/EABase/config/eacompiler.h | 1934 +++++++++-- .../include/EABase/config/eacompilertraits.h | 3399 ++++++++++++++------ UnknownVersion/include/EABase/config/eaplatform.h | 1165 ++++--- UnknownVersion/include/EABase/eabase.h | 1524 +++++---- UnknownVersion/include/EABase/earesult.h | 70 +- UnknownVersion/include/EABase/eaunits.h | 54 + UnknownVersion/include/EABase/int128.h | 1268 ++++++++ UnknownVersion/include/EABase/version.h | 36 + 8 files changed, 6915 insertions(+), 2535 deletions(-) create mode 100644 UnknownVersion/include/EABase/eaunits.h create mode 100644 UnknownVersion/include/EABase/int128.h create mode 100644 UnknownVersion/include/EABase/version.h diff --git a/UnknownVersion/include/EABase/config/eacompiler.h b/UnknownVersion/include/EABase/config/eacompiler.h index 97b65ef..4b388dd 100644 --- a/UnknownVersion/include/EABase/config/eacompiler.h +++ b/UnknownVersion/include/EABase/config/eacompiler.h @@ -1,43 +1,10 @@ -/* -Copyright (C) 2009 Electronic Arts, Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of - its contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - /*----------------------------------------------------------------------------- * config/eacompiler.h * - * Copyright (c) 2002 - 2005 Electronic Arts Inc. All rights reserved. - * Maintained by Paul Pedriana, Maxis - * - * Modified to support Clang++ (v2.8) by Austin Seipp, 2010. - * + * Copyright (c) Electronic Arts Inc. All rights reserved. *----------------------------------------------------------------------------- * Currently supported defines include: * EA_COMPILER_GNUC - * EA_COMPILER_CLANG * EA_COMPILER_ARM * EA_COMPILER_EDG * EA_COMPILER_SN @@ -46,11 +13,18 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * EA_COMPILER_INTEL * EA_COMPILER_BORLANDC * EA_COMPILER_IBM - * + * EA_COMPILER_QNX + * EA_COMPILER_GREEN_HILLS + * EA_COMPILER_CLANG + * EA_COMPILER_CLANG_CL + * * EA_COMPILER_VERSION = * EA_COMPILER_NAME = * EA_COMPILER_STRING = - * + * + * EA_COMPILER_VA_COPY_REQUIRED + * + * C++98/03 functionality * EA_COMPILER_NO_STATIC_CONSTANTS * EA_COMPILER_NO_TEMPLATE_SPECIALIZATION * EA_COMPILER_NO_TEMPLATE_PARTIAL_SPECIALIZATION @@ -66,14 +40,73 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * EA_COMPILER_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS * EA_COMPILER_NO_RTTI * EA_COMPILER_NO_EXCEPTIONS + * EA_COMPILER_NO_NEW_THROW_SPEC + * EA_THROW_SPEC_NEW / EA_THROW_SPEC_DELETE * EA_COMPILER_NO_UNWIND * EA_COMPILER_NO_STANDARD_CPP_LIBRARY * EA_COMPILER_NO_STATIC_VARIABLE_INIT * EA_COMPILER_NO_STATIC_FUNCTION_INIT + * EA_COMPILER_NO_VARIADIC_MACROS + * + * C++11 functionality + * EA_COMPILER_NO_RVALUE_REFERENCES + * EA_COMPILER_NO_EXTERN_TEMPLATE + * EA_COMPILER_NO_RANGE_BASED_FOR_LOOP + * EA_COMPILER_NO_CONSTEXPR + * EA_COMPILER_NO_OVERRIDE + * EA_COMPILER_NO_INHERITANCE_FINAL + * EA_COMPILER_NO_NULLPTR + * EA_COMPILER_NO_AUTO + * EA_COMPILER_NO_DECLTYPE + * EA_COMPILER_NO_DEFAULTED_FUNCTIONS + * EA_COMPILER_NO_DELETED_FUNCTIONS + * EA_COMPILER_NO_LAMBDA_EXPRESSIONS + * EA_COMPILER_NO_TRAILING_RETURN_TYPES + * EA_COMPILER_NO_STRONGLY_TYPED_ENUMS + * EA_COMPILER_NO_FORWARD_DECLARED_ENUMS + * EA_COMPILER_NO_VARIADIC_TEMPLATES + * EA_COMPILER_NO_TEMPLATE_ALIASES + * EA_COMPILER_NO_INITIALIZER_LISTS + * EA_COMPILER_NO_NORETURN + * EA_COMPILER_NO_CARRIES_DEPENDENCY + * EA_COMPILER_NO_FALLTHROUGH + * EA_COMPILER_NO_NODISCARD + * EA_COMPILER_NO_MAYBE_UNUSED + * EA_COMPILER_NO_NONSTATIC_MEMBER_INITIALIZERS + * EA_COMPILER_NO_RIGHT_ANGLE_BRACKETS + * EA_COMPILER_NO_ALIGNOF + * EA_COMPILER_NO_ALIGNAS + * EA_COMPILER_NO_DELEGATING_CONSTRUCTORS + * EA_COMPILER_NO_INHERITING_CONSTRUCTORS + * EA_COMPILER_NO_USER_DEFINED_LITERALS + * EA_COMPILER_NO_STANDARD_LAYOUT_TYPES + * EA_COMPILER_NO_EXTENDED_SIZEOF + * EA_COMPILER_NO_INLINE_NAMESPACES + * EA_COMPILER_NO_UNRESTRICTED_UNIONS + * EA_COMPILER_NO_EXPLICIT_CONVERSION_OPERATORS + * EA_COMPILER_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS + * EA_COMPILER_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS + * EA_COMPILER_NO_NOEXCEPT + * EA_COMPILER_NO_RAW_LITERALS + * EA_COMPILER_NO_UNICODE_STRING_LITERALS + * EA_COMPILER_NO_NEW_CHARACTER_TYPES + * EA_COMPILER_NO_UNICODE_CHAR_NAME_LITERALS + * EA_COMPILER_NO_UNIFIED_INITIALIZATION_SYNTAX + * EA_COMPILER_NO_EXTENDED_FRIEND_DECLARATIONS + * + * C++14 functionality + * EA_COMPILER_NO_VARIABLE_TEMPLATES + * + * C++17 functionality + * EA_COMPILER_NO_INLINE_VARIABLES + * EA_COMPILER_NO_ALIGNED_NEW + * + * C++20 functionality + * EA_COMPILER_NO_DESIGNATED_INITIALIZERS * *----------------------------------------------------------------------------- * - * Documentation + * Supplemental documentation * EA_COMPILER_NO_STATIC_CONSTANTS * Code such as this is legal, but some compilers fail to compile it: * struct A{ static const a = 1; }; @@ -94,7 +127,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * EA_COMPILER_NO_MEMBER_TEMPLATE_SPECIALIZATION * Some compilers fail to allow member template specialization, such as with this: - * struct A{ + * struct A{ * template void DoSomething(U u); * void DoSomething(int x); * }; @@ -116,9 +149,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * EA_COMPILER_NO_COVARIANT_RETURN_TYPE * See the C++ standard sec 10.3,p5. - * + * * EA_COMPILER_NO_DEDUCED_TYPENAME - * Some compilers don't support the use of 'typename' for + * Some compilers don't support the use of 'typename' for * dependent types in deduced contexts, as with this: * template void Function(T, typename T::type); * @@ -126,17 +159,17 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * Also known as Koenig lookup. Basically, if you have a function * that is a namespace and you call that function without prefixing * it with the namespace the compiler should look at any arguments - * you pass to that function call and search their namespace *first* + * you pass to that function call and search their namespace *first* * to see if the given function exists there. * * EA_COMPILER_NO_EXCEPTION_STD_NAMESPACE - * is in namespace std. Some std libraries fail to - * put the contents of in namespace std. The following + * is in namespace std. Some std libraries fail to + * put the contents of in namespace std. The following * code should normally be legal: * void Function(){ std::terminate(); } * * EA_COMPILER_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS - * Some compilers fail to execute DoSomething() properly, though they + * Some compilers fail to execute DoSomething() properly, though they * succeed in compiling it, as with this: * template * bool DoSomething(int j){ return i == j; }; @@ -144,12 +177,12 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * EA_COMPILER_NO_EXCEPTIONS * The compiler is configured to disallow the use of try/throw/catch - * syntax (often to improve performance). Use of such syntax in this - * case will cause a compilation error. - * + * syntax (often to improve performance). Use of such syntax in this + * case will cause a compilation error. + * * EA_COMPILER_NO_UNWIND - * The compiler is configured to allow the use of try/throw/catch - * syntax and behaviour but disables the generation of stack unwinding + * The compiler is configured to allow the use of try/throw/catch + * syntax and behaviour but disables the generation of stack unwinding * code for responding to exceptions (often to improve performance). * *---------------------------------------------------------------------------*/ @@ -157,356 +190,1589 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef INCLUDED_eacompiler_H #define INCLUDED_eacompiler_H -#ifndef INCLUDED_eaplatform_H -# include "EABase/config/eaplatform.h" -#endif +#include - // Note: This is used to generate the EA_COMPILER_STRING macros +// Note: This is used to generate the EA_COMPILER_STRING macros #ifndef INTERNAL_STRINGIZE -# define INTERNAL_STRINGIZE(x) INTERNAL_PRIMITIVE_STRINGIZE(x) +#define INTERNAL_STRINGIZE(x) INTERNAL_PRIMITIVE_STRINGIZE(x) #endif #ifndef INTERNAL_PRIMITIVE_STRINGIZE -# define INTERNAL_PRIMITIVE_STRINGIZE(x) #x +#define INTERNAL_PRIMITIVE_STRINGIZE(x) #x #endif - // Note: this is for compatibility with non-clang compilers -#ifndef __has_feature -# define __has_feature(x) 0 +// EA_COMPILER_HAS_FEATURE +#ifndef EA_COMPILER_HAS_FEATURE +#if defined(__clang__) +#define EA_COMPILER_HAS_FEATURE(x) __has_feature(x) +#else +#define EA_COMPILER_HAS_FEATURE(x) 0 #endif - - // Note: this is for compatibility with non-clang compilers -#ifndef __has_attribute -# define __has_attribute(x) 0 #endif - // Note: this is for compatibility with non-clang compilers -#ifndef __has_builtin -# define __has_builtin(x) 0 + +// EA_COMPILER_HAS_BUILTIN +#ifndef EA_COMPILER_HAS_BUILTIN +#if defined(__clang__) +#define EA_COMPILER_HAS_BUILTIN(x) __has_builtin(x) +#else +#define EA_COMPILER_HAS_BUILTIN(x) 0 #endif +#endif + - // EDG (EDG compiler front-end, used by other compilers such as SN) +// EDG (EDG compiler front-end, used by other compilers such as SN) #if defined(__EDG_VERSION__) -# define EA_COMPILER_EDG +#define EA_COMPILER_EDG 1 + +#if defined(_MSC_VER) +#define EA_COMPILER_EDG_VC_MODE 1 +#endif +#if defined(__GNUC__) +#define EA_COMPILER_EDG_GCC_MODE 1 +#endif +#endif + +// EA_COMPILER_WINRTCX_ENABLED +// +// Defined as 1 if the compiler has its available C++/CX support enabled, else undefined. +// This specifically means the corresponding compilation unit has been built with Windows Runtime +// Components enabled, usually via the '-ZW' compiler flags being used. This option allows for using +// ref counted hat-type '^' objects and other C++/CX specific keywords like "ref new" +#if !defined(EA_COMPILER_WINRTCX_ENABLED) && defined(__cplusplus_winrt) +#define EA_COMPILER_WINRTCX_ENABLED 1 +#endif + + +// EA_COMPILER_CPP11_ENABLED +// +// Defined as 1 if the compiler has its available C++11 support enabled, else undefined. +// This does not mean that all of C++11 or any particular feature of C++11 is supported +// by the compiler. It means that whatever C++11 support the compiler has is enabled. +// This also includes existing and older compilers that still identify C++11 as C++0x. +// +// We cannot use (__cplusplus >= 201103L) alone because some compiler vendors have +// decided to not define __cplusplus like thus until they have fully completed their +// C++11 support. +// +#if !defined(EA_COMPILER_CPP11_ENABLED) && defined(__cplusplus) +#if (__cplusplus >= 201103L) // Clang and GCC defines this like so in C++11 mode. +#define EA_COMPILER_CPP11_ENABLED 1 +#elif defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) +#define EA_COMPILER_CPP11_ENABLED 1 +#elif defined(_MSC_VER) && _MSC_VER >= 1600 // Microsoft unilaterally enables its C++11 support; there is no way to disable it. +#define EA_COMPILER_CPP11_ENABLED 1 +#elif defined(__EDG_VERSION__) // && ??? +// To do: Is there a generic way to determine this? +#endif #endif - // SN -#if defined(__SNC__) // SN Systems compiler - // Note that there are two versions of the SN compiler, one that is - // GNUC-based and a newer one which is based on an EDG (Edison Design - // Group) front-end with a back-end code generator made by SN. - // The EDG-based SN compiler uses "GCC compatibility mode" and thus - // defines __GNUC__ but isn't really GNUC. Also, as of this writing - // it appears that the SN compiler may arrive with MSVC-compatibility - // mode in addition as well. Thus, we define EA_COMPILER_SN - // separately from other EA_COMPILER defines it is possible that both - // may be defined at the same time. Note that while the newer EDG-based - // SN compiler may emulate other compilers, it doesn't act exactly - // the same. -# define EA_COMPILER_SN +// EA_COMPILER_CPP14_ENABLED +// +// Defined as 1 if the compiler has its available C++14 support enabled, else undefined. +// This does not mean that all of C++14 or any particular feature of C++14 is supported +// by the compiler. It means that whatever C++14 support the compiler has is enabled. +// +// We cannot use (__cplusplus >= 201402L) alone because some compiler vendors have +// decided to not define __cplusplus like thus until they have fully completed their +// C++14 support. +#if !defined(EA_COMPILER_CPP14_ENABLED) && defined(__cplusplus) +#if (__cplusplus >= 201402L) // Clang and GCC defines this like so in C++14 mode. +#define EA_COMPILER_CPP14_ENABLED 1 +#elif defined(_MSC_VER) && (_MSC_VER >= 1900) // VS2015+ +#define EA_COMPILER_CPP14_ENABLED 1 +#endif +#endif + + +// EA_COMPILER_CPP17_ENABLED +// +// Defined as 1 if the compiler has its available C++17 support enabled, else undefined. +// This does not mean that all of C++17 or any particular feature of C++17 is supported +// by the compiler. It means that whatever C++17 support the compiler has is enabled. +// +// We cannot use (__cplusplus >= 201703L) alone because some compiler vendors have +// decided to not define __cplusplus like thus until they have fully completed their +// C++17 support. +#if !defined(EA_COMPILER_CPP17_ENABLED) && defined(__cplusplus) +#if (__cplusplus >= 201703L) +#define EA_COMPILER_CPP17_ENABLED 1 +#elif defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L) // C++17+ +#define EA_COMPILER_CPP17_ENABLED 1 +#endif #endif - // Airplay SDK (third party mobile middleware compiler) -#if defined(__S3E__) -# define EA_COMPILER_NO_EXCEPTION_STD_NAMESPACE +// EA_COMPILER_CPP20_ENABLED +// +// Defined as 1 if the compiler has its available C++20 support enabled, else undefined. +// This does not mean that all of C++20 or any particular feature of C++20 is supported +// by the compiler. It means that whatever C++20 support the compiler has is enabled. +// +// We cannot use (__cplusplus >= 202003L) alone because some compiler vendors have +// decided to not define __cplusplus like thus until they have fully completed their +// C++20 support. +#if !defined(EA_COMPILER_CPP20_ENABLED) && defined(__cplusplus) +// TODO(rparoin): enable once a C++20 value for the __cplusplus macro has been published +// #if (__cplusplus >= 202003L) +// #define EA_COMPILER_CPP20_ENABLED 1 +// #elif defined(_MSVC_LANG) && (_MSVC_LANG >= 202003L) // C++20+ +// #define EA_COMPILER_CPP20_ENABLED 1 +// #endif #endif - // SNC (SN Systems) -#if defined(__SNC__) -# define EA_COMPILER_NAME "SNC" -# ifdef __GNUC__ // If SN is using GCC-compatibility mode (which it usually is)... -# define EA_COMPILER_GNUC -# define EA_COMPILER_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) // We intentionally report the GCC version here. SN -# define EA_COMPILER_STRING EA_COMPILER_NAME " compiler, GCC version " INTERNAL_STRINGIZE( __GNUC__ ) "." INTERNAL_STRINGIZE( __GNUC_MINOR__ ) ", SNC version " INTERNAL_STRINGIZE( __SN_VER__ ) ", EDG version " INTERNAL_STRINGIZE( __EDG_VERSION__ ) -# else -# define EA_COMPILER_VERSION __SN_VER__ -# define EA_COMPILER_STRING EA_COMPILER_NAME " compiler, version " INTERNAL_STRINGIZE( EA_COMPILER_VERSION ) ", EDG version " INTERNAL_STRINGIZE( __EDG_VERSION__ ) -# endif +#if defined(__ARMCC_VERSION) +// Note that this refers to the ARM RVCT compiler (armcc or armcpp), but there +// are other compilers that target ARM processors, such as GCC and Microsoft VC++. +// If you want to detect compiling for the ARM processor, check for EA_PROCESSOR_ARM +// being defined. +// This compiler is also identified by defined(__CC_ARM) || defined(__ARMCC__). +#define EA_COMPILER_RVCT 1 +#define EA_COMPILER_ARM 1 +#define EA_COMPILER_VERSION __ARMCC_VERSION +#define EA_COMPILER_NAME "RVCT" +//#define EA_COMPILER_STRING (defined below) - // GCC (a.k.a. GNUC) +// Clang's GCC-compatible driver. +#elif defined(__clang__) && !defined(_MSC_VER) +#define EA_COMPILER_CLANG 1 +#define EA_COMPILER_VERSION (__clang_major__ * 100 + __clang_minor__) +#define EA_COMPILER_NAME "clang" +#define EA_COMPILER_STRING EA_COMPILER_NAME __clang_version__ + +// GCC (a.k.a. GNUC) #elif defined(__GNUC__) // GCC compilers exist for many platforms. -# define EA_COMPILER_GNUC -# define EA_COMPILER_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) -# define EA_COMPILER_NAME "GCC" -# define EA_COMPILER_STRING EA_COMPILER_NAME " compiler, version " INTERNAL_STRINGIZE( __GNUC__ ) "." INTERNAL_STRINGIZE( __GNUC_MINOR__ ) - -# if (__GNUC__ == 2) && (__GNUC_MINOR__ < 95) // If GCC < 2.95... -# define EA_COMPILER_NO_MEMBER_TEMPLATES -# endif -# if (__GNUC__ == 2) && (__GNUC_MINOR__ <= 97) // If GCC <= 2.97... -# define EA_COMPILER_NO_MEMBER_TEMPLATE_FRIENDS -# endif -# if (__GNUC__ == 3) && ((__GNUC_MINOR__ == 1) || (__GNUC_MINOR__ == 2)) // If GCC 3.1 or 3.2 (but not pre 3.1 or post 3.2)... -# define EA_COMPILER_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS -# endif - - // Clang (quite compatible with GCC) -#elif defined(__clang__) -# define EA_COMPILER_CLANG -# define EA_COMPILER_VERSION (__clang_major__ * 1000 + __clang_minor__) -# define EA_COMPILER_NAME "Clang++" -# define EA_COMPILER_STRING EA_COMPILER_NAME " compiler, version " INTERNAL_STRINGIZE( __clang_version__ ) - - // Borland C++ +#define EA_COMPILER_GNUC 1 +#define EA_COMPILER_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) +#define EA_COMPILER_NAME "GCC" +#define EA_COMPILER_STRING EA_COMPILER_NAME " compiler, version " INTERNAL_STRINGIZE( __GNUC__ ) "." INTERNAL_STRINGIZE( __GNUC_MINOR__ ) + +#if (__GNUC__ == 2) && (__GNUC_MINOR__ < 95) // If GCC < 2.95... +#define EA_COMPILER_NO_MEMBER_TEMPLATES 1 +#endif +#if (__GNUC__ == 2) && (__GNUC_MINOR__ <= 97) // If GCC <= 2.97... +#define EA_COMPILER_NO_MEMBER_TEMPLATE_FRIENDS 1 +#endif +#if (__GNUC__ == 3) && ((__GNUC_MINOR__ == 1) || (__GNUC_MINOR__ == 2)) // If GCC 3.1 or 3.2 (but not pre 3.1 or post 3.2)... +#define EA_COMPILER_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS 1 +#endif + +// Borland C++ #elif defined(__BORLANDC__) -# define EA_COMPILER_BORLANDC -# define EA_COMPILER_VERSION __BORLANDC__ -# define EA_COMPILER_NAME "Borland C" - //#define EA_COMPILER_STRING (defined below) +#define EA_COMPILER_BORLANDC 1 +#define EA_COMPILER_VERSION __BORLANDC__ +#define EA_COMPILER_NAME "Borland C" +//#define EA_COMPILER_STRING (defined below) -# if (__BORLANDC__ <= 0x0550) // If Borland C++ Builder 4 and 5... -# define EA_COMPILER_NO_MEMBER_TEMPLATE_FRIENDS -# endif -# if (__BORLANDC__ >= 0x561) && (__BORLANDC__ < 0x600) -# define EA_COMPILER_NO_MEMBER_FUNCTION_SPECIALIZATION -# endif +#if (__BORLANDC__ <= 0x0550) // If Borland C++ Builder 4 and 5... +#define EA_COMPILER_NO_MEMBER_TEMPLATE_FRIENDS 1 +#endif +#if (__BORLANDC__ >= 0x561) && (__BORLANDC__ < 0x600) +#define EA_COMPILER_NO_MEMBER_FUNCTION_SPECIALIZATION 1 +#endif - // Intel C++ (via EDG front-end) +// Intel C++ +// The Intel Windows compiler masquerades as VC++ and defines _MSC_VER. +// The Intel compiler is based on the EDG compiler front-end. #elif defined(__ICL) || defined(__ICC) -# define EA_COMPILER_INTEL -# if defined(__ICL) -# define EA_COMPILER_VERSION __ICL -# elif defined(__ICC) -# define EA_COMPILER_VERSION __ICC -# endif -# define EA_COMPILER_NAME "Intel C++" - //#define EA_COMPILER_STRING (defined below) - - // Intel is based ont the EDG (Edison Design Group) front end and - // all recent versions are very compliant to the C++ standard. - - - // Metrowerks -#elif defined(__MWERKS__) || defined(__CWCC__) // Metrowerks compilers exist for many platforms. -# define EA_COMPILER_METROWERKS -# ifdef __MWERKS__ -# define EA_COMPILER_VERSION __MWERKS__ -# else -# define EA_COMPILER_VERSION __CWCC__ -# endif -# define EA_COMPILER_NAME "Metrowerks" - //#define EA_COMPILER_STRING (defined below) - -# if (__MWERKS__ <= 0x2407) // If less than v7.x... -# define EA_COMPILER_NO_MEMBER_FUNCTION_SPECIALIZATION -# endif -# if (__MWERKS__ <= 0x3003) // If less than v8.x... -# define EA_COMPILER_NO_MEMBER_TEMPLATE_FRIENDS -# endif - - - // Microsoft VC++ -#elif defined(_MSC_VER) && !(defined(__S3E__) && defined(__arm__) && defined(__aarch64__)) // S3E is a mobile SDK which mistakenly masquerades as VC++ on ARM. -# define EA_COMPILER_MSVC -# define EA_COMPILER_VERSION _MSC_VER -# define EA_COMPILER_NAME "Microsoft Visual C++" - //#define EA_COMPILER_STRING (defined below) - -# if (_MSC_VER <= 1200) // If VC6.x and earlier... -# if (_MSC_VER < 1200) -# define EA_COMPILER_MSVCOLD -# else -# define EA_COMPILER_MSVC6 -# endif - -# if (_MSC_VER < 1200) // If VC5.x or earlier... -# define EA_COMPILER_NO_TEMPLATE_SPECIALIZATION -# endif -# define EA_COMPILER_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS // The compiler compiles this OK, but executes it wrong. Fixed in VC7.0 -# define EA_COMPILER_NO_VOID_RETURNS // The compiler fails to compile such cases. Fixed in VC7.0 -# define EA_COMPILER_NO_EXCEPTION_STD_NAMESPACE // The compiler fails to compile such cases. Fixed in VC7.0 -# define EA_COMPILER_NO_DEDUCED_TYPENAME // The compiler fails to compile such cases. Fixed in VC7.0 -# define EA_COMPILER_NO_STATIC_CONSTANTS // The compiler fails to compile such cases. Fixed in VC7.0 -# define EA_COMPILER_NO_COVARIANT_RETURN_TYPE // The compiler fails to compile such cases. Fixed in VC7.1 -# define EA_COMPILER_NO_ARGUMENT_DEPENDENT_LOOKUP // The compiler compiles this OK, but executes it wrong. Fixed in VC7.1 -# define EA_COMPILER_NO_TEMPLATE_TEMPLATES // The compiler fails to compile such cases. Fixed in VC7.1 -# define EA_COMPILER_NO_TEMPLATE_PARTIAL_SPECIALIZATION // The compiler fails to compile such cases. Fixed in VC7.1 -# define EA_COMPILER_NO_MEMBER_TEMPLATE_FRIENDS // The compiler fails to compile such cases. Fixed in VC7.1 - //#define EA_COMPILER_NO_MEMBER_TEMPLATES // VC6.x supports member templates properly 95% of the time. So do we flag the remaining 5%? - //#define EA_COMPILER_NO_MEMBER_TEMPLATE_SPECIALIZATION // VC6.x supports member templates properly 95% of the time. So do we flag the remaining 5%? - -# elif (_MSC_VER <= 1300) // If VC7.0 and earlier... -# define EA_COMPILER_MSVC7 - -# define EA_COMPILER_NO_COVARIANT_RETURN_TYPE // The compiler fails to compile such cases. Fixed in VC7.1 -# define EA_COMPILER_NO_ARGUMENT_DEPENDENT_LOOKUP // The compiler compiles this OK, but executes it wrong. Fixed in VC7.1 -# define EA_COMPILER_NO_TEMPLATE_TEMPLATES // The compiler fails to compile such cases. Fixed in VC7.1 -# define EA_COMPILER_NO_TEMPLATE_PARTIAL_SPECIALIZATION // The compiler fails to compile such cases. Fixed in VC7.1 -# define EA_COMPILER_NO_MEMBER_TEMPLATE_FRIENDS // The compiler fails to compile such cases. Fixed in VC7.1 -# define EA_COMPILER_NO_MEMBER_FUNCTION_SPECIALIZATION // This is the case only for VC7.0 and not VC6 or VC7.1+. Fixed in VC7.1 - //#define EA_COMPILER_NO_MEMBER_TEMPLATES // VC7.0 supports member templates properly 95% of the time. So do we flag the remaining 5%? - -# elif (_MSC_VER < 1400) // If VC7.1 ... - // The VC7.1 and later compiler is fairly close to the C++ standard - // and thus has no compiler limitations that we are concerned about. -# define EA_COMPILER_MSVC7_2003 -# define EA_COMPILER_MSVC7_1 - -# else // _MSC_VER of 1400 means VC8 (VS2005), 1500 means VC9 (VS2008) -# define EA_COMPILER_MSVC8_2005 -# define EA_COMPILER_MSVC8_0 - -# endif - - - // IBM +#define EA_COMPILER_INTEL 1 + +// Should we enable the following? We probably should do so since enabling it does a lot more good than harm +// for users. The Intel Windows compiler does a pretty good job of emulating VC++ and so the user would likely +// have to handle few special cases where the Intel compiler doesn't emulate VC++ correctly. +#if defined(_MSC_VER) +#define EA_COMPILER_MSVC 1 +#define EA_COMPILER_MICROSOFT 1 +#endif + +// Should we enable the following? This isn't as clear because as of this writing we don't know if the Intel +// compiler truly emulates GCC well enough that enabling this does more good than harm. +#if defined(__GNUC__) +#define EA_COMPILER_GNUC 1 +#endif + +#if defined(__ICL) +#define EA_COMPILER_VERSION __ICL +#elif defined(__ICC) +#define EA_COMPILER_VERSION __ICC +#endif +#define EA_COMPILER_NAME "Intel C++" +#if defined(_MSC_VER) +#define EA_COMPILER_STRING EA_COMPILER_NAME " compiler, version " INTERNAL_STRINGIZE( EA_COMPILER_VERSION ) ", EDG version " INTERNAL_STRINGIZE( __EDG_VERSION__ ) ", VC++ version " INTERNAL_STRINGIZE( _MSC_VER ) +#elif defined(__GNUC__) +#define EA_COMPILER_STRING EA_COMPILER_NAME " compiler, version " INTERNAL_STRINGIZE( EA_COMPILER_VERSION ) ", EDG version " INTERNAL_STRINGIZE( __EDG_VERSION__ ) ", GCC version " INTERNAL_STRINGIZE( __GNUC__ ) +#else +#define EA_COMPILER_STRING EA_COMPILER_NAME " compiler, version " INTERNAL_STRINGIZE( EA_COMPILER_VERSION ) ", EDG version " INTERNAL_STRINGIZE( __EDG_VERSION__ ) +#endif + + +#elif defined(_MSC_VER) +#define EA_COMPILER_MSVC 1 +#define EA_COMPILER_MICROSOFT 1 +#define EA_COMPILER_VERSION _MSC_VER +#define EA_COMPILER_NAME "Microsoft Visual C++" +//#define EA_COMPILER_STRING (defined below) + +#if defined(__clang__) +// Clang's MSVC-compatible driver. +#define EA_COMPILER_CLANG_CL 1 +#endif + +#define EA_STANDARD_LIBRARY_MSVC 1 +#define EA_STANDARD_LIBRARY_MICROSOFT 1 + +#if (_MSC_VER <= 1200) // If VC6.x and earlier... +#if (_MSC_VER < 1200) +#define EA_COMPILER_MSVCOLD 1 +#else +#define EA_COMPILER_MSVC6 1 +#endif + +#if (_MSC_VER < 1200) // If VC5.x or earlier... +#define EA_COMPILER_NO_TEMPLATE_SPECIALIZATION 1 +#endif +#define EA_COMPILER_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS 1 // The compiler compiles this OK, but executes it wrong. Fixed in VC7.0 +#define EA_COMPILER_NO_VOID_RETURNS 1 // The compiler fails to compile such cases. Fixed in VC7.0 +#define EA_COMPILER_NO_EXCEPTION_STD_NAMESPACE 1 // The compiler fails to compile such cases. Fixed in VC7.0 +#define EA_COMPILER_NO_DEDUCED_TYPENAME 1 // The compiler fails to compile such cases. Fixed in VC7.0 +#define EA_COMPILER_NO_STATIC_CONSTANTS 1 // The compiler fails to compile such cases. Fixed in VC7.0 +#define EA_COMPILER_NO_COVARIANT_RETURN_TYPE 1 // The compiler fails to compile such cases. Fixed in VC7.1 +#define EA_COMPILER_NO_ARGUMENT_DEPENDENT_LOOKUP 1 // The compiler compiles this OK, but executes it wrong. Fixed in VC7.1 +#define EA_COMPILER_NO_TEMPLATE_TEMPLATES 1 // The compiler fails to compile such cases. Fixed in VC7.1 +#define EA_COMPILER_NO_TEMPLATE_PARTIAL_SPECIALIZATION 1 // The compiler fails to compile such cases. Fixed in VC7.1 +#define EA_COMPILER_NO_MEMBER_TEMPLATE_FRIENDS 1 // The compiler fails to compile such cases. Fixed in VC7.1 +//#define EA_COMPILER_NO_MEMBER_TEMPLATES 1 // VC6.x supports member templates properly 95% of the time. So do we flag the remaining 5%? +//#define EA_COMPILER_NO_MEMBER_TEMPLATE_SPECIALIZATION 1 // VC6.x supports member templates properly 95% of the time. So do we flag the remaining 5%? + +#elif (_MSC_VER <= 1300) // If VC7.0 and earlier... +#define EA_COMPILER_MSVC7 1 + +#define EA_COMPILER_NO_COVARIANT_RETURN_TYPE 1 // The compiler fails to compile such cases. Fixed in VC7.1 +#define EA_COMPILER_NO_ARGUMENT_DEPENDENT_LOOKUP 1 // The compiler compiles this OK, but executes it wrong. Fixed in VC7.1 +#define EA_COMPILER_NO_TEMPLATE_TEMPLATES 1 // The compiler fails to compile such cases. Fixed in VC7.1 +#define EA_COMPILER_NO_TEMPLATE_PARTIAL_SPECIALIZATION 1 // The compiler fails to compile such cases. Fixed in VC7.1 +#define EA_COMPILER_NO_MEMBER_TEMPLATE_FRIENDS 1 // The compiler fails to compile such cases. Fixed in VC7.1 +#define EA_COMPILER_NO_MEMBER_FUNCTION_SPECIALIZATION 1 // This is the case only for VC7.0 and not VC6 or VC7.1+. Fixed in VC7.1 +//#define EA_COMPILER_NO_MEMBER_TEMPLATES 1 // VC7.0 supports member templates properly 95% of the time. So do we flag the remaining 5%? + +#elif (_MSC_VER < 1400) // VS2003 _MSC_VER of 1300 means VC7 (VS2003) +// The VC7.1 and later compiler is fairly close to the C++ standard +// and thus has no compiler limitations that we are concerned about. +#define EA_COMPILER_MSVC7_2003 1 +#define EA_COMPILER_MSVC7_1 1 + +#elif (_MSC_VER < 1500) // VS2005 _MSC_VER of 1400 means VC8 (VS2005) +#define EA_COMPILER_MSVC8_2005 1 +#define EA_COMPILER_MSVC8_0 1 + +#elif (_MSC_VER < 1600) // VS2008. _MSC_VER of 1500 means VC9 (VS2008) +#define EA_COMPILER_MSVC9_2008 1 +#define EA_COMPILER_MSVC9_0 1 + +#elif (_MSC_VER < 1700) // VS2010 _MSC_VER of 1600 means VC10 (VS2010) +#define EA_COMPILER_MSVC_2010 1 +#define EA_COMPILER_MSVC10_0 1 + +#elif (_MSC_VER < 1800) // VS2012 _MSC_VER of 1700 means VS2011/VS2012 +#define EA_COMPILER_MSVC_2011 1 // Microsoft changed the name to VS2012 before shipping, despite referring to it as VS2011 up to just a few weeks before shipping. +#define EA_COMPILER_MSVC11_0 1 +#define EA_COMPILER_MSVC_2012 1 +#define EA_COMPILER_MSVC12_0 1 + +#elif (_MSC_VER < 1900) // VS2013 _MSC_VER of 1800 means VS2013 +#define EA_COMPILER_MSVC_2013 1 +#define EA_COMPILER_MSVC13_0 1 + +#elif (_MSC_VER < 1910) // VS2015 _MSC_VER of 1900 means VS2015 +#define EA_COMPILER_MSVC_2015 1 +#define EA_COMPILER_MSVC14_0 1 + +#elif (_MSC_VER < 1911) // VS2017 _MSC_VER of 1910 means VS2017 +#define EA_COMPILER_MSVC_2017 1 +#define EA_COMPILER_MSVC15_0 1 + +#endif + + +// IBM #elif defined(__xlC__) -# define EA_COMPILER_IBM -# define EA_COMPILER_NAME "IBM XL C" -# define EA_COMPILER_VERSION __xlC__ -# define EA_COMPILER_STRING "IBM XL C compiler, version " INTERNAL_STRINGIZE( __xlC__ ) - - - // ARM compiler -# if defined(__ARMCC_VERSION) - // Note that this refers to the ARM compiler (armcc or armcpp), but there - // are other compilers that target ARM processors, such as GCC and Microsoft VC++. - // If you want to detect compiling for the ARM processor, check for EA_PROCESSOR_ARM - // being defined. -# define EA_COMPILER_ARM -# define EA_COMPILER_VERSION __ARMCC_VERSION -# define EA_COMPILER_NAME __CC_ARM - //#define EA_COMPILER_STRING (defined below) - -# endif - - // Green Hills -#elif defined(__ghs__) -# define EA_COMPILER_GHS -# define EA_COMPILER_VERSION __GHS_VERSION_NUMBER -# define EA_COMPILER_NAME "Green Hills" - //#define EA_COMPILER_STRING (defined below) - - - // Unknown +#define EA_COMPILER_IBM 1 +#define EA_COMPILER_NAME "IBM XL C" +#define EA_COMPILER_VERSION __xlC__ +#define EA_COMPILER_STRING "IBM XL C compiler, version " INTERNAL_STRINGIZE( __xlC__ ) + +// Unknown #else // Else the compiler is unknown -# define EA_COMPILER_VERSION 0 -# define EA_COMPILER_NAME "Unknown" +#define EA_COMPILER_VERSION 0 +#define EA_COMPILER_NAME "Unknown" #endif #ifndef EA_COMPILER_STRING -# define EA_COMPILER_STRING EA_COMPILER_NAME " compiler, version " INTERNAL_STRINGIZE(EA_COMPILER_VERSION) +#define EA_COMPILER_STRING EA_COMPILER_NAME " compiler, version " INTERNAL_STRINGIZE(EA_COMPILER_VERSION) #endif - // Deprecated definitions - // For backwards compatibility, should be supported for at least the life of EABase v2.0.x. +// Deprecated definitions +// For backwards compatibility, should be supported for at least the life of EABase v2.0.x. #ifndef EA_COMPILER_NO_TEMPLATE_PARTIAL_SPECIALIZATION -# define EA_COMPILER_PARTIAL_TEMPLATE_SPECIALIZATION +#define EA_COMPILER_PARTIAL_TEMPLATE_SPECIALIZATION 1 #endif #ifndef EA_COMPILER_NO_TEMPLATE_SPECIALIZATION -# define EA_COMPILER_TEMPLATE_SPECIALIZATION +#define EA_COMPILER_TEMPLATE_SPECIALIZATION 1 #endif #ifndef EA_COMPILER_NO_MEMBER_TEMPLATES -# define EA_COMPILER_MEMBER_TEMPLATES +#define EA_COMPILER_MEMBER_TEMPLATES 1 #endif #ifndef EA_COMPILER_NO_MEMBER_TEMPLATE_SPECIALIZATION -# define EA_COMPILER_MEMBER_TEMPLATE_SPECIALIZATION +#define EA_COMPILER_MEMBER_TEMPLATE_SPECIALIZATION 1 #endif - // EA_COMPILER_NO_RTTI - // - // If EA_COMPILER_NO_RTTI is defined, then RTTI (run-time type information) - // is not available (possibly due to being disabled by the user). - // -#if defined(__SNC__) && !defined(__RTTI) -# define EA_COMPILER_NO_RTTI +/////////////////////////////////////////////////////////////////////////////// +// EA_COMPILER_VA_COPY_REQUIRED +// +// Defines whether va_copy must be used to copy or save va_list objects between uses. +// Some compilers on some platforms implement va_list whereby its contents +// are destroyed upon usage, even if passed by value to another function. +// With these compilers you can use va_copy to save and restore a va_list. +// Known compiler/platforms that destroy va_list contents upon usage include: +// CodeWarrior on PowerPC +// GCC on x86-64 +// However, va_copy is part of the C99 standard and not part of earlier C and +// C++ standards. So not all compilers support it. VC++ doesn't support va_copy, +// but it turns out that VC++ doesn't usually need it on the platforms it supports, +// and va_copy can usually be implemented via memcpy(va_list, va_list) with VC++. +/////////////////////////////////////////////////////////////////////////////// + +#ifndef EA_COMPILER_VA_COPY_REQUIRED +#if ((defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__clang__)) && (!defined(__i386__) || defined(__x86_64__)) && !defined(__ppc__) && !defined(__PPC__) && !defined(__PPC64__) +#define EA_COMPILER_VA_COPY_REQUIRED 1 +#endif +#endif + + +// EA_COMPILER_NO_RTTI +// +// If EA_COMPILER_NO_RTTI is defined, then RTTI (run-time type information) +// is not available (possibly due to being disabled by the user). +// +#if defined(__EDG_VERSION__) && !defined(__RTTI) +#define EA_COMPILER_NO_RTTI 1 +#elif defined(__clang__) && !EA_COMPILER_HAS_FEATURE(cxx_rtti) +#define EA_COMPILER_NO_RTTI 1 +#elif defined(__IBMCPP__) && !defined(__RTTI_ALL__) +#define EA_COMPILER_NO_RTTI 1 #elif defined(__GXX_ABI_VERSION) && !defined(__GXX_RTTI) -# define EA_COMPILER_NO_RTTI -#elif defined(__clang__) && !__has_feature(cxx_rtti) -# define EA_COMPILER_NO_RTTI +#define EA_COMPILER_NO_RTTI 1 #elif defined(_MSC_VER) && !defined(_CPPRTTI) -# define EA_COMPILER_NO_RTTI -#elif defined(__MWERKS__) -# if !__option(RTTI) -# define EA_COMPILER_NO_RTTI -# endif -#endif - - - - // EA_COMPILER_NO_EXCEPTIONS / EA_COMPILER_NO_UNWIND - // - // If EA_COMPILER_NO_EXCEPTIONS is defined, then the compiler is - // configured to not recognize C++ exception-handling statements - // such as try/catch/throw. Thus, when EA_COMPILER_NO_EXCEPTIONS is - // defined, code that attempts to use exception handling statements - // will usually cause a compilation error. If is often desirable - // for projects to disable exception handling because exception - // handling causes extra code and/or data generation which might - // not be needed, especially if it is known that exceptions won't - // be happening. When writing code that is to be portable between - // systems of which some enable exception handling while others - // don't, check for EA_COMPILER_NO_EXCEPTIONS being defined. - // -#if defined(EA_COMPILER_GNUC) && defined(_NO_EX) // GCC on some platforms (e.g. PS3) defines _NO_EX when exceptions are disabled. -# define EA_COMPILER_NO_EXCEPTIONS - -#elif (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_INTEL) || defined(EA_COMPILER_SN)) && !defined(__EXCEPTIONS) // GCC and most EDG-based compilers define __EXCEPTIONS when exception handling is enabled. -# define EA_COMPILER_NO_EXCEPTIONS - -#elif defined(EA_COMPILER_CLANG) && !__has_feature(cxx_exceptions) -# define EA_COMPILER_NO_EXCEPTIONS - -#elif defined(EA_COMPILER_METROWERKS) -# if !__option(exceptions) -# define EA_COMPILER_NO_EXCEPTIONS -# endif - - // Borland and Micrsoft use the _CPUUNWIND define to denote that - // exception stack unwinding code generation is disabled. The result - // is that you can call try/catch/throw and that exceptions will be - // caught handled, but that no automatic object destruction will - // happen between a throw and the resulting catch. We thus don't - // want to define EA_COMPILER_NO_EXCEPTIONS, but perhaps users might - // be interesting in knowing that unwinding is disabled. -#elif (defined(EA_COMPILER_BORLAND) || defined(EA_COMPILER_MSVC)) && !defined(_CPPUNWIND) -# define EA_COMPILER_NO_UNWIND +#define EA_COMPILER_NO_RTTI 1 +#elif defined(__ARMCC_VERSION) && defined(__TARGET_CPU_MPCORE) && !defined(__RTTI) +#define EA_COMPILER_NO_RTTI 1 +#endif + + + +// EA_COMPILER_NO_EXCEPTIONS / EA_COMPILER_NO_UNWIND +// +// If EA_COMPILER_NO_EXCEPTIONS is defined, then the compiler is +// configured to not recognize C++ exception-handling statements +// such as try/catch/throw. Thus, when EA_COMPILER_NO_EXCEPTIONS is +// defined, code that attempts to use exception handling statements +// will usually cause a compilation error. If is often desirable +// for projects to disable exception handling because exception +// handling causes extra code and/or data generation which might +// not be needed, especially if it is known that exceptions won't +// be happening. When writing code that is to be portable between +// systems of which some enable exception handling while others +// don't, check for EA_COMPILER_NO_EXCEPTIONS being defined. +// +#if !defined(EA_COMPILER_NO_EXCEPTIONS) && !defined(EA_COMPILER_NO_UNWIND) +#if defined(EA_COMPILER_GNUC) && defined(_NO_EX) // GCC on some platforms defines _NO_EX when exceptions are disabled. +#define EA_COMPILER_NO_EXCEPTIONS 1 + +#elif (defined(EA_COMPILER_CLANG) || defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_INTEL) || defined(EA_COMPILER_RVCT)) && !defined(__EXCEPTIONS) // GCC and most EDG-based compilers define __EXCEPTIONS when exception handling is enabled. +#define EA_COMPILER_NO_EXCEPTIONS 1 + +#elif (defined(EA_COMPILER_MSVC)) && !defined(_CPPUNWIND) +#define EA_COMPILER_NO_UNWIND 1 #endif // EA_COMPILER_NO_EXCEPTIONS / EA_COMPILER_NO_UNWIND +#endif // !defined(EA_COMPILER_NO_EXCEPTIONS) && !defined(EA_COMPILER_NO_UNWIND) + + +// ------------------------------------------------------------------------ +// EA_DISABLE_ALL_VC_WARNINGS / EA_RESTORE_ALL_VC_WARNINGS +// +// Disable and re-enable all warning(s) within code. +// +// Example usage: +// EA_DISABLE_ALL_VC_WARNINGS() +// +// EA_RESTORE_ALL_VC_WARNINGS() +// +//This is duplicated from EABase's eacompilertraits.h +#ifndef EA_DISABLE_ALL_VC_WARNINGS +#if defined(_MSC_VER) +#define EA_DISABLE_ALL_VC_WARNINGS() \ + __pragma(warning(push, 0)) \ + __pragma(warning(disable: 4244 4265 4267 4350 4472 4509 4548 4623 4710 4985 6320 4755 4625 4626 4702)) // Some warnings need to be explicitly called out. +#else +#define EA_DISABLE_ALL_VC_WARNINGS() +#endif +#endif + +//This is duplicated from EABase's eacompilertraits.h +#ifndef EA_RESTORE_ALL_VC_WARNINGS +#if defined(_MSC_VER) +#define EA_RESTORE_ALL_VC_WARNINGS() \ + __pragma(warning(pop)) +#else +#define EA_RESTORE_ALL_VC_WARNINGS() +#endif +#endif + +// Dinkumware +//This is duplicated from EABase's eahave.h +#if !defined(EA_HAVE_DINKUMWARE_CPP_LIBRARY) && !defined(EA_NO_HAVE_DINKUMWARE_CPP_LIBRARY) +#if defined(__cplusplus) +EA_DISABLE_ALL_VC_WARNINGS() +#include // Need to trigger the compilation of yvals.h without directly using because it might not exist. +EA_RESTORE_ALL_VC_WARNINGS() +#endif + +#if defined(__cplusplus) && defined(_CPPLIB_VER) /* If using the Dinkumware Standard library... */ +#define EA_HAVE_DINKUMWARE_CPP_LIBRARY 1 +#else +#define EA_NO_HAVE_DINKUMWARE_CPP_LIBRARY 1 +#endif +#endif +// EA_COMPILER_NO_ALIGNED_NEW +// +// +#if !defined(EA_COMPILER_NO_ALIGNED_NEW) +#if defined(_HAS_ALIGNED_NEW) && _HAS_ALIGNED_NEW // VS2017 15.5 Preview +// supported. +#elif defined(EA_COMPILER_CPP17_ENABLED) +// supported. +#else +#define EA_COMPILER_NO_ALIGNED_NEW 1 +#endif +#endif - // EA_COMPILER_NO_STANDARD_CPP_LIBRARY - // - // If defined, then the compiler doesn't provide a Standard C++ library. - // +// EA_COMPILER_NO_NEW_THROW_SPEC / EA_THROW_SPEC_NEW / EA_THROW_SPEC_DELETE +// +// If defined then the compiler's version of operator new is not decorated +// with a throw specification. This is useful for us to know because we +// often want to write our own overloaded operator new implementations. +// We need such operator new overrides to be declared identically to the +// way the compiler is defining operator new itself. +// +// Example usage: +// void* operator new(std::size_t) EA_THROW_SPEC_NEW(std::bad_alloc); +// void* operator new[](std::size_t) EA_THROW_SPEC_NEW(std::bad_alloc); +// void* operator new(std::size_t, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE(); +// void* operator new[](std::size_t, const std::nothrow_t&) EA_THROW_SPEC_NEW_NONE(); +// void operator delete(void*) EA_THROW_SPEC_DELETE_NONE(); +// void operator delete[](void*) EA_THROW_SPEC_DELETE_NONE(); +// void operator delete(void*, const std::nothrow_t&) EA_THROW_SPEC_DELETE_NONE(); +// void operator delete[](void*, const std::nothrow_t&) EA_THROW_SPEC_DELETE_NONE(); +// +#if defined(EA_HAVE_DINKUMWARE_CPP_LIBRARY) +#if defined(_MSC_VER) && (_MSC_VER >= 1912) // VS2017 15.3+ +#define EA_THROW_SPEC_NEW(x) noexcept(false) +#define EA_THROW_SPEC_NEW_NONE() noexcept +#define EA_THROW_SPEC_DELETE_NONE() noexcept + +#elif defined(_MSC_VER) && (_MSC_VER >= 1910) // VS2017+ +#define EA_THROW_SPEC_NEW(x) throw(x) +#define EA_THROW_SPEC_NEW_NONE() throw() +#define EA_THROW_SPEC_DELETE_NONE() throw() + +#else +#if defined(EA_PLATFORM_SONY) +#define EA_THROW_SPEC_NEW(X) _THROWS(X) +#elif defined(_MSC_VER) +// Disabled warning "nonstandard extension used: 'throw (...)'" as this warning is a W4 warning which is usually off by default +// and doesn't convey any important information but will still complain when building with /Wall (which most teams do) +#define EA_THROW_SPEC_NEW(X) __pragma(warning(push)) __pragma(warning(disable: 4987)) _THROWS(X) __pragma(warning(pop)) +#else +#define EA_THROW_SPEC_NEW(X) _THROW1(X) +#endif +#define EA_THROW_SPEC_NEW_NONE() _THROW0() +#define EA_THROW_SPEC_DELETE_NONE() _THROW0() + +#endif +#elif defined(EA_COMPILER_NO_EXCEPTIONS) && !defined(EA_COMPILER_RVCT) && !defined(EA_PLATFORM_LINUX) && !defined(EA_PLATFORM_APPLE) && !defined(CS_UNDEFINED_STRING) +#define EA_COMPILER_NO_NEW_THROW_SPEC 1 + +#define EA_THROW_SPEC_NEW(x) +#define EA_THROW_SPEC_NEW_NONE() +#define EA_THROW_SPEC_DELETE_NONE() +#else +#define EA_THROW_SPEC_NEW(x) throw(x) +#define EA_THROW_SPEC_NEW_NONE() throw() +#define EA_THROW_SPEC_DELETE_NONE() throw() +#endif + + +// EA_COMPILER_NO_STANDARD_CPP_LIBRARY +// +// If defined, then the compiler doesn't provide a Standard C++ library. +// #if defined(EA_PLATFORM_ANDROID) -# define EA_COMPILER_NO_STANDARD_CPP_LIBRARY +// Disabled because EA's eaconfig/android_config/android_sdk packages currently +// don't support linking STL libraries. Perhaps we can figure out what linker arguments +// are needed for an app so we can manually specify them and then re-enable this code. +//#include +// +//#if (__ANDROID_API__ < 9) // Earlier versions of Android provide no std C++ STL implementation. +#define EA_COMPILER_NO_STANDARD_CPP_LIBRARY 1 +//#endif +#endif + + +// EA_COMPILER_NO_STATIC_VARIABLE_INIT +// +// If defined, it means that global or static C++ variables will be +// constructed. Not all compiler/platorm combinations support this. +// User code that needs to be portable must avoid having C++ variables +// that construct before main. +// +//#if defined(EA_PLATFORM_MOBILE) +// #define EA_COMPILER_NO_STATIC_VARIABLE_INIT 1 +//#endif + + +// EA_COMPILER_NO_STATIC_FUNCTION_INIT +// +// If defined, it means that functions marked as startup functions +// (e.g. __attribute__((constructor)) in GCC) are supported. It may +// be that some compiler/platform combinations don't support this. +// +//#if defined(XXX) // So far, all compiler/platforms we use support this. +// #define EA_COMPILER_NO_STATIC_VARIABLE_INIT 1 +//#endif + +// EA_COMPILER_NO_VARIADIC_MACROS +// +// If defined, the compiler doesn't support C99/C++11 variadic macros. +// With a variadic macro, you can do this: +// #define MY_PRINTF(format, ...) printf(format, __VA_ARGS__) +// +#if !defined(EA_COMPILER_NO_VARIADIC_MACROS) +#if defined(_MSC_VER) && (_MSC_VER < 1500) // If earlier than VS2008.. +#define EA_COMPILER_NO_VARIADIC_MACROS 1 +#elif defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__)) < 401 // If earlier than GCC 4.1.. +#define EA_COMPILER_NO_VARIADIC_MACROS 1 +#elif defined(EA_COMPILER_EDG) // Includes other compilers +// variadic macros are supported +#endif +#endif + + +// EA_COMPILER_NO_RVALUE_REFERENCES +// +// If defined, the compiler doesn't fully support C++11 rvalue reference semantics. +// This applies to the compiler only and not the Standard Library in use with the compiler, +// which is required by the Standard to have some support itself. +// +#if !defined(EA_COMPILER_NO_RVALUE_REFERENCES) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (_MSC_VER >= 1600) // VS2010+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403) // EDG 4.3+. +// supported. Earlier EDG supported a subset of rvalue references. Implicit move constructors and assignment operators aren't supported until EDG 4.5. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && EA_COMPILER_HAS_FEATURE(cxx_rvalue_references) +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4005) // GCC 4.5+ +// supported. +#else +#define EA_COMPILER_NO_RVALUE_REFERENCES 1 +#endif +#endif + + +// EA_COMPILER_NO_EXTERN_TEMPLATE +// +// If defined, the compiler doesn't support C++11 extern template. +// With extern templates, you can do this: +// extern template void DoSomething(KnownType u); +// +#if !defined(EA_COMPILER_NO_EXTERN_TEMPLATE) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (_MSC_VER >= 1700) // VS2012+... +// Extern template is supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401) // EDG 4.1+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && defined(__apple_build_version__) && (EA_COMPILER_VERSION >= 401) +// Extern template is supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && !defined(__apple_build_version__) // Clang other than Apple's Clang +// Extern template is supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4006) // GCC 4.6+ +// Extern template is supported. +#else +#define EA_COMPILER_NO_EXTERN_TEMPLATE 1 +#endif +#endif + + +// EA_COMPILER_NO_RANGE_BASED_FOR_LOOP +// +// If defined, the compiler doesn't support C++11 range-based for loops. +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2930.html +// You must #include for range-based for loops to work. +// Example usage: +// #include +// #include +// std::vector floatVector; +// for(float& f : floatVector) +// f += 1.0; +// +#if !defined(EA_COMPILER_NO_RANGE_BASED_FOR_LOOP) +#if defined(EA_COMPILER_CPP11_ENABLED) && (defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1700)) // VS2012+... +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405) // EDG 4.5+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && (defined(__clang__) && (EA_COMPILER_VERSION >= 300)) // Clang 3.x+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && (defined(__GNUC__) && (EA_COMPILER_VERSION >= 4006)) // GCC 4.6+ +// supported. +#else +#define EA_COMPILER_NO_RANGE_BASED_FOR_LOOP 1 +#endif +#endif + + +// EA_COMPILER_NO_CONSTEXPR +// +// Refers to C++11 = constexpr (const expression) declarations. +// +#if !defined(EA_COMPILER_NO_CONSTEXPR) +#if defined(EA_COMPILER_CPP11_ENABLED) && (defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1900)) // VS2015+... Not present in VC++ up to and including VS2013. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406) // EDG 4.6+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && EA_COMPILER_HAS_FEATURE(cxx_constexpr) +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4006) // GCC 4.6+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1900) // VS 2015+ +// supported. +#else +#define EA_COMPILER_NO_CONSTEXPR 1 +#endif +#endif + + +// EA_COMPILER_NO_CONSTEXPR_IF +// +// Refers to C++17 = constexpr if(const expression) conditionals. +// +#if !defined(EA_COMPILER_NO_CONSTEXPR_IF) +#if defined(EA_COMPILER_CPP17_ENABLED) && (defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1911)) // VS2017 15.3+ +// supported. +#elif defined(EA_COMPILER_CPP17_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 309) // Clang 3.9+ +// supported. +#elif defined(EA_COMPILER_CPP17_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 7000) // GCC 7+ +// supported. +#else +#define EA_COMPILER_NO_CONSTEXPR_IF 1 +#endif +#endif + + +// EA_COMPILER_NO_OVERRIDE +// +// Refers to the C++11 override specifier. +// +#ifndef EA_COMPILER_NO_OVERRIDE +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION > 1600) // VC++ > VS2010, even without C++11 support. VS2010 does support override, however will generate warnings due to the keyword being 'non-standard' +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 209) // Clang 2.9+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4007) // GCC 4.7+ +// supported. +#else +#define EA_COMPILER_NO_OVERRIDE 1 +#endif +#endif + + +// EA_COMPILER_NO_INHERITANCE_FINAL +// +// Refers to the C++11 final specifier. +// +#ifndef EA_COMPILER_NO_INHERITANCE_FINAL +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1500) // VS2008+, even without C++11 support. +// supported, though you need to use EA_INHERITANCE_FINAL for it to work with VS versions prior to 2012. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 209) // Clang 2.9+ +// supported +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4007) // GCC 4.7+ +// supported +#else +#define EA_COMPILER_NO_INHERITANCE_FINAL 1 +#endif +#endif + + +// EA_COMPILER_NO_AUTO +// +// Refers to C++11 auto. +// +#if !defined(EA_COMPILER_NO_AUTO) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1600) // VS2010+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401) // EDG 4.1+. +// supported with the exception of the usage of braced initializer lists as of EDG 4.3. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 209) // Clang 2.9+, including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4004) // GCC 4.4+ +// supported. +#else +#define EA_COMPILER_NO_AUTO 1 +#endif +#endif + + +// EA_COMPILER_NO_NULLPTR +// +// Refers to C++11 nullptr (which is a built in type). std::nullptr_t is defined in C++11 . +// Note that implements a portable nullptr implementation. +// +#if !defined(EA_COMPILER_NO_NULLPTR) +#if (defined(_MSC_VER) && (_MSC_VER >= 1600)) && defined(EA_COMPILER_CPP11_ENABLED) +// supported +#elif defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION >= 4006) && defined(EA_COMPILER_CPP11_ENABLED) +// supported +#elif defined(__clang__) && defined(EA_COMPILER_CPP11_ENABLED) +// supported +#elif defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403) && defined(EA_COMPILER_CPP11_ENABLED) +// supported +#else +#define EA_COMPILER_NO_NULLPTR 1 +#endif +#endif + + +// EA_COMPILER_NO_DECLTYPE +// +// Refers to C++11 decltype. +// +#if !defined(EA_COMPILER_NO_DECLTYPE) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1600) // VS2010+ +// supported, though VS2010 doesn't support the spec completely as specified in the final standard. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401) // EDG 4.1+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 209) // Clang 2.9+, including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4003) // GCC 4.3+ +// supported. +#else +#define EA_COMPILER_NO_DECLTYPE 1 +#endif +#endif + + + +// EA_COMPILER_NO_DEFAULTED_FUNCTIONS +// EA_COMPILER_NO_DELETED_FUNCTIONS +// +// Refers to C++11 = default and = delete function declarations. +// +#if !defined(EA_COMPILER_NO_DEFAULTED_FUNCTIONS) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1800) // VS2013+ +// supported, but as of VS2013 it isn't supported for defaulted move constructors and move assignment operators. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401) // EDG 4.1+. +// supported, but as of EDG 4.3 it isn't supported for defaulted move constructors and move assignment operators until EDG 4.5. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 300) // Clang 3.0+, including Apple's Clang +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4004) // GCC 4.4+ +// supported. +#else +// VC++ doesn't support it as of VS2012. +#define EA_COMPILER_NO_DEFAULTED_FUNCTIONS 1 +#endif +#endif + +#if !defined(EA_COMPILER_NO_DELETED_FUNCTIONS) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1800) // VS2013+ +// supported, but as of VS2013 it isn't supported for defaulted move constructors and move assignment operators. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401) // EDG 4.1+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 209) // Clang 2.9+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4004) // GCC 4.4+ +// supported. +#else +// VC++ doesn't support it as of VS2012. +#define EA_COMPILER_NO_DELETED_FUNCTIONS 1 +#endif +#endif + + +// EA_COMPILER_NO_LAMBDA_EXPRESSIONS +// +// Refers to C++11 lambda expressions. +// +#if !defined(EA_COMPILER_NO_LAMBDA_EXPRESSIONS) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1600) // VS2010+ +// supported, though VS2010 doesn't support the spec completely as specified in the final standard. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401) // EDG 4.1+. +// supported. However, converting lambdas to function pointers is not supported until EDG 4.5. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 301) && !defined(__apple_build_version__) // Clang 3.1+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4004) // GCC 4.4+ +// supported. +#else +#define EA_COMPILER_NO_LAMBDA_EXPRESSIONS 1 +#endif +#endif + + +// EA_COMPILER_NO_TRAILING_RETURN_TYPES +// +// Refers to C++11 trailing-return-type. Also sometimes referred to as "incomplete return type". +// +#if !defined(EA_COMPILER_NO_TRAILING_RETURN_TYPES) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1600) // VS2010+ +// supported, though VS2010 doesn't support the spec completely as specified in the final standard. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402) // EDG 4.2+. +// supported. However, use of "this" in trailing return types is not supported untiil EDG 4.4 +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 301) && !defined(__apple_build_version__) // Clang 3.1+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4004) // GCC 4.4+ +// supported. +#else +#define EA_COMPILER_NO_TRAILING_RETURN_TYPES 1 +#endif +#endif + + +// EA_COMPILER_NO_STRONGLY_TYPED_ENUMS +// +// Refers to C++11 strongly typed enums, which includes enum classes and sized enums. Doesn't include forward-declared enums. +// +#if !defined(EA_COMPILER_NO_STRONGLY_TYPED_ENUMS) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1700) // VS2012+ +// supported. A subset of this is actually supported by VS2010. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 400) // EDG 4.0+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 209) // Clang 2.9+, including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4004) // GCC 4.4+ +// supported. +#else +#define EA_COMPILER_NO_STRONGLY_TYPED_ENUMS 1 +#endif +#endif + + +// EA_COMPILER_NO_FORWARD_DECLARED_ENUMS +// +// Refers to C++11 forward declared enums. +// +#if !defined(EA_COMPILER_NO_FORWARD_DECLARED_ENUMS) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1700) // VS2012+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405) // EDG 4.5+. +// supported. EDG 4.3 supports basic forward-declared enums, but not forward-declared strongly typed enums. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 301) && !defined(__apple_build_version__) // Clang 3.1+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4006) // GCC 4.6+ +// supported. +#else +#define EA_COMPILER_NO_FORWARD_DECLARED_ENUMS 1 +#endif +#endif + + +// EA_COMPILER_NO_VARIADIC_TEMPLATES +// +// Refers to C++11 variadic templates. +// +#if !defined(EA_COMPILER_NO_VARIADIC_TEMPLATES) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1800) // VS2013+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (_MSC_FULL_VER == 170051025) // VS2012 November Preview for Windows only. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403) // EDG 4.3+. +// supported, though 4.1 has partial support for variadic templates. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 209) // Clang 2.9+, including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4004) // GCC 4.4+ +// supported, though GCC 4.3 has partial support for variadic templates. +#else +#define EA_COMPILER_NO_VARIADIC_TEMPLATES 1 +#endif +#endif + + +// EA_COMPILER_NO_TEMPLATE_ALIASES +// +// Refers to C++11 alias templates. +// Example alias template usage: +// template +// using Dictionary = eastl::map; +// +// Dictionary StringIntDictionary; +// +#if !defined(EA_COMPILER_NO_TEMPLATE_ALIASES) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1800) // VS2013+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402) // EDG 4.2+. +// supported, though 4.1 has partial support for variadic templates. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 300) && !defined(__apple_build_version__) // Clang 3.0+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4007) // GCC 4.7+ +// supported, though GCC 4.3 has partial support for variadic templates. +#else +#define EA_COMPILER_NO_TEMPLATE_ALIASES 1 +#endif +#endif + + +// EA_COMPILER_NO_VARIABLE_TEMPLATES +// +// Refers to C++14 variable templates. +// Example variable template usage: +// template +// constexpr T pi = T(3.1415926535897932385); +// +#if !defined(EA_COMPILER_NO_VARIABLE_TEMPLATES) +#if defined(_MSC_VER) && (_MSC_FULL_VER >= 190023918) // VS2015 Update 2 and above. +// supported. +#elif defined(EA_COMPILER_CPP14_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 304) && !defined(__apple_build_version__) // Clang 3.4+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP14_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 5000) // GCC 5+ +// supported. +#elif !defined(EA_COMPILER_CPP14_ENABLED) +#define EA_COMPILER_NO_VARIABLE_TEMPLATES 1 +#endif +#endif + + +// EA_COMPILER_NO_INLINE_VARIABLES +// +// Refers to C++17 inline variables that allows the definition of variables in header files +// +// Example usage: +// struct Foo +// { +// static inline constexpr int kConstant = 42; // no out of class definition +// }; +// +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4424.pdf +// http://en.cppreference.com/w/cpp/language/inline +// +#if !defined(EA_COMPILER_NO_INLINE_VARIABLES) +#define EA_COMPILER_NO_INLINE_VARIABLES 1 +#endif + + +// EA_COMPILER_NO_INITIALIZER_LISTS +// +// Refers to C++11 initializer lists. +// This refers to the compiler support for this and not the Standard Library support (std::initializer_list). +// +#if !defined(EA_COMPILER_NO_INITIALIZER_LISTS) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1800) // VS2013+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (_MSC_FULL_VER == 170051025) // VS2012 November Preview for Windows only. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405) // EDG 4.5+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 301) && !defined(__apple_build_version__) // Clang 3.1+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4004) // GCC 4.4+ +// supported, though GCC 4.3 has partial support for it. +#else +#define EA_COMPILER_NO_INITIALIZER_LISTS 1 +#endif +#endif + + +// EA_COMPILER_NO_NORETURN +// +// Refers to C++11 declaration attribute: noreturn. +// http://en.cppreference.com/w/cpp/language/attributes +// http://blog.aaronballman.com/2011/09/understanding-attributes/ +// +#if !defined(EA_COMPILER_NO_NORETURN) +#if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1300) // VS2003+ +// supported via __declspec(noreturn). You need to use that or EA_NORETURN. VC++ up to VS2013 doesn't support any C++11 attribute types. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402) // EDG 4.2+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 300) && !defined(__apple_build_version__) // Clang 3.0+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4008) // GCC 4.8+ +// supported. +#else +#define EA_COMPILER_NO_NORETURN 1 +#endif +#endif + + +// EA_COMPILER_NO_CARRIES_DEPENDENCY +// +// Refers to C++11 declaration attribute: carries_dependency. +// http://en.cppreference.com/w/cpp/language/attributes +// http://blog.aaronballman.com/2011/09/understanding-attributes/ +// +#if !defined(EA_COMPILER_NO_CARRIES_DEPENDENCY) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) // Apple clang 4.1+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402) // EDG 4.2+. +// supported; stricter than other compilers in its usage. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 300) && !defined(__apple_build_version__) // Clang 3.0+, not including Apple's Clang. +// supported. +// Currently GNUC doesn't appear to support this attribute. +//#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4008) // GCC 4.8+ +// // supported. +#else +#define EA_COMPILER_NO_CARRIES_DEPENDENCY 1 +#endif +#endif + + +// EA_COMPILER_NO_FALLTHROUGH +// +// Refers to C++17 declaration attribute: fallthrough. +// http://en.cppreference.com/w/cpp/language/attributes +// +#if !defined(EA_COMPILER_NO_FALLTHROUGH) +#if defined(EA_COMPILER_CPP17_ENABLED) +// supported. +#else +#define EA_COMPILER_NO_FALLTHROUGH 1 +#endif +#endif + + +// EA_COMPILER_NO_NODISCARD +// +// Refers to C++17 declaration attribute: nodiscard. +// http://en.cppreference.com/w/cpp/language/attributes +// +#if !defined(EA_COMPILER_NO_NODISCARD) +#if defined(EA_COMPILER_CPP17_ENABLED) +// supported. +#else +#define EA_COMPILER_NO_NODISCARD 1 +#endif +#endif + + +// EA_COMPILER_NO_MAYBE_UNUSED +// +// Refers to C++17 declaration attribute: maybe_unused. +// http://en.cppreference.com/w/cpp/language/attributes +// +#if !defined(EA_COMPILER_NO_MAYBE_UNUSED) +#if defined(EA_COMPILER_CPP17_ENABLED) +// supported. +#elif defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1912) // VS2017 15.3+ +// supported. +#else +#define EA_COMPILER_NO_MAYBE_UNUSED 1 +#endif +#endif + + +// EA_COMPILER_NO_STRUCTURED_BINDING +// +// Indicates if target compiler supports the C++17 "structured binding" language feature. +// https://en.cppreference.com/w/cpp/language/structured_binding +// +// +#if !defined(EA_COMPILER_NO_STRUCTURED_BINDING) +#if defined(EA_COMPILER_CPP17_ENABLED) +// supported. +#elif defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1912) // VS2017 15.3+ +// supported. +#else +#define EA_COMPILER_NO_STRUCTURED_BINDING 1 +#endif +#endif + + +// EA_COMPILER_NO_DESIGNATED_INITIALIZERS +// +// Indicates the target compiler supports the C++20 "designated initializer" language feature. +// https://en.cppreference.com/w/cpp/language/aggregate_initialization +// +// Example: +// struct A { int x; int y; }; +// A a = { .y = 42, .x = 1 }; +// +#if !defined(EA_COMPILER_NO_DESIGNATED_INITIALIZERS) +#if defined(EA_COMPILER_CPP20_ENABLED) +// supported. +#else +#define EA_COMPILER_NO_DESIGNATED_INITIALIZERS 1 +#endif +#endif + + +// EA_COMPILER_NO_NONSTATIC_MEMBER_INITIALIZERS +// +// Refers to C++11 declaration attribute: carries_dependency. +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2756.htm +// +#if !defined(EA_COMPILER_NO_NONSTATIC_MEMBER_INITIALIZERS) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1800) // VS2013+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) // Apple clang 4.1+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 300) && !defined(__apple_build_version__) // Clang 3.0+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4007) // GCC 4.7+ +// supported. +#else +#define EA_COMPILER_NO_NONSTATIC_MEMBER_INITIALIZERS 1 +#endif +#endif + + +// EA_COMPILER_NO_RIGHT_ANGLE_BRACKETS +// +// Defines if the compiler supports >> (as opposed to > >) in template +// declarations such as typedef eastl::list> ListList; +// +#if !defined(EA_COMPILER_NO_RIGHT_ANGLE_BRACKETS) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1600) // VS2010+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401) // EDG 4.1+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 209) // Clang 2.9+, including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4003) // GCC 4.3+ +// supported. +#else +#define EA_COMPILER_NO_RIGHT_ANGLE_BRACKETS 1 +#endif +#endif + + +// EA_COMPILER_NO_ALIGNOF +// +// Refers specifically to C++11 alignof and not old compiler extensions such as __alignof__(). +// However, EABase provides a portable EA_ALIGN_OF which works for all compilers. +// +#if !defined(EA_COMPILER_NO_ALIGNOF) +// Not supported by VC++ as of VS2013, though EA_ALIGN_OF is supported on all coompilers as an alternative. +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 209) // Clang 2.9+, including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4005) // GCC 4.5+ +// supported. +#else +#define EA_COMPILER_NO_ALIGNOF 1 +#endif +#endif + + +// EA_COMPILER_NO_ALIGNAS +// +// Refers to C++11 alignas. +// +#if !defined(EA_COMPILER_NO_ALIGNAS) +// Not supported by VC++ as of VS2013. +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) // Apple clang 4.1+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 300) && !defined(__apple_build_version__) // Clang 3.0+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4008) // GCC 4.8+ +// supported. +#else +#define EA_COMPILER_NO_ALIGNAS 1 +#endif +#endif + + +// EA_COMPILER_NO_DELEGATING_CONSTRUCTORS +// +// Refers to C++11 constructor delegation. +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf +// https://www.ibm.com/developerworks/mydeveloperworks/blogs/5894415f-be62-4bc0-81c5-3956e82276f3/entry/c_0x_delegating_constructors +// +#if !defined(EA_COMPILER_NO_DELEGATING_CONSTRUCTORS) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1800) // VS2013+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407) // EDG 4.7+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) // Apple clang 4.1+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 300) && !defined(__apple_build_version__) // Clang 3.0+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4007) // GCC 4.7+ +// supported. +#else +#define EA_COMPILER_NO_DELEGATING_CONSTRUCTORS 1 +#endif #endif - // EA_COMPILER_NO_STATIC_VARIABLE_INIT - // - // If defined, it means that global or static C++ variables will be - // constructed. Not all compiler/platorm combinations support this. - // User code that needs to be portable must avoid having C++ variables - // that construct before main. - // - //#if defined(EA_PLATFORM_MOBILE) - // #define EA_COMPILER_NO_STATIC_VARIABLE_INIT - //#endif +// EA_COMPILER_NO_INHERITING_CONSTRUCTORS +// +// Refers to C++11 constructor inheritance via 'using'. +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm +// +#if !defined(EA_COMPILER_NO_INHERITING_CONSTRUCTORS) +// Not supported by VC++ as of VS2013. +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && EA_COMPILER_HAS_FEATURE(cxx_inheriting_constructors) // Clang +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4008) // GCC 4.8+ +// supported. +#else +#define EA_COMPILER_NO_INHERITING_CONSTRUCTORS 1 +#endif +#endif +// EA_COMPILER_NO_USER_DEFINED_LITERALS +// +// http://en.cppreference.com/w/cpp/language/user_literal +// http://stackoverflow.com/questions/237804/what-new-capabilities-do-user-defined-literals-add-to-c +// +#if !defined(EA_COMPILER_NO_USER_DEFINED_LITERALS) +// Not supported by VC++ as of VS2013. +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) // Apple clang 4.1+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 301) && !defined(__apple_build_version__) // Clang 3.1+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4007) // GCC 4.7+ +// supported. +#else +#define EA_COMPILER_NO_USER_DEFINED_LITERALS 1 +#endif +#endif - // EA_COMPILER_NO_STATIC_FUNCTION_INIT - // - // If defined, it means that functions marked as startup functions - // (e.g. __attribute__((constructor)) in GCC) are supported. It may - // be that some compiler/platform combinations don't support this. - // - //#if defined(XXX) // So far, all compiler/platforms we use support this. - // #define EA_COMPILER_NO_STATIC_VARIABLE_INIT - //#endif +// EA_COMPILER_NO_STANDARD_LAYOUT_TYPES +// a.k.a. POD relaxation +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm +// +#if !defined(EA_COMPILER_NO_STANDARD_LAYOUT_TYPES) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1700) // VS2012+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) // Apple clang 4.1+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 300) && !defined(__apple_build_version__) // Clang 3.0+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4005) // GCC 4.5+ +// supported. +#else +#define EA_COMPILER_NO_STANDARD_LAYOUT_TYPES 1 +#endif +#endif + + +// EA_COMPILER_NO_EXTENDED_SIZEOF +// +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2253.html +// Allows you to do this: sizeof(SomeClass::mSomeMember) +// +#if !defined(EA_COMPILER_NO_EXTENDED_SIZEOF) +// Not supported by VC++ as of VS2013. +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) // Apple clang 4.1+ +// supported. +// Versions of EDG prior to 4.5 only support extended sizeof in non-member functions. Full support was added in 4.5 +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405) // EDG 4.5+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 301) && !defined(__apple_build_version__) // Clang 3.1+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4005) // GCC 4.5+ +// supported. +#else +#define EA_COMPILER_NO_EXTENDED_SIZEOF 1 +#endif +#endif + + +// EA_COMPILER_NO_INLINE_NAMESPACES +// +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2535.htm +// http://blog.aaronballman.com/2011/07/inline-namespaces/ +// +#if !defined(EA_COMPILER_NO_INLINE_NAMESPACES) +// Not supported by VC++ as of VS2013. +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405) // EDG 4.5+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 209) // Clang 2.9+, including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4004) // GCC 4.4+ +// supported. +#else +#define EA_COMPILER_NO_INLINE_NAMESPACES 1 +#endif +#endif + + +// EA_COMPILER_NO_UNRESTRICTED_UNIONS +// +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf +// +#if !defined(EA_COMPILER_NO_UNRESTRICTED_UNIONS) +// Not supported by VC++ as of VS2013. +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406) // EDG 4.6+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) // Apple clang 4.1+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 301) && !defined(__apple_build_version__) // Clang 3.1+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4006) // GCC 4.6+ +// supported. +#else +#define EA_COMPILER_NO_UNRESTRICTED_UNIONS 1 +#endif +#endif + + +// EA_COMPILER_NO_EXPLICIT_CONVERSION_OPERATORS +// +// http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_conversion_operators +// +#if !defined(EA_COMPILER_NO_EXPLICIT_CONVERSION_OPERATORS) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1800) // VS2013+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (_MSC_FULL_VER == 170051025) // VS2012 November Preview for Windows only. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 404) // EDG 4.4+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) // Apple clang 4.1+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 300) && !defined(__apple_build_version__) // Clang 3.0+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4005) // GCC 4.5+ +// supported. +#else +#define EA_COMPILER_NO_EXPLICIT_CONVERSION_OPERATORS 1 +#endif +#endif + + +// EA_COMPILER_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +// +// The compiler does not support default template arguments for function templates. +// http://stackoverflow.com/questions/2447458/default-template-arguments-for-function-templates +// +#if !defined(EA_COMPILER_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1800) // VS2013+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403) // EDG 4.4+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 209) // Clang 2.9+, including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4003) // GCC 4.3+ +// supported. +#else +#define EA_COMPILER_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS 1 +#endif +#endif + + +// EA_COMPILER_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS +// +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm +// http://stackoverflow.com/questions/5751977/local-type-as-template-arguments-in-c +// +#if !defined(EA_COMPILER_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1600) // VS2010+ +// supported. +#if (EA_COMPILER_VERSION < 1700) // VS2010 generates a warning, but the C++ language now allows it. +#pragma warning(disable: 4836) // nonstandard extension used: local types or unnamed types cannot be used as template arguments. +#endif +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402) // EDG 4.2+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 209) // Clang 2.9+, including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4005) // GCC 4.5+ +// supported. +#else +#define EA_COMPILER_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS 1 +#endif +#endif + + +// EA_COMPILER_NO_NOEXCEPT +// +// C++11 noexcept +// http://en.cppreference.com/w/cpp/language/attributes +// http://en.cppreference.com/w/cpp/language/noexcept +// +#if !defined(EA_COMPILER_NO_NOEXCEPT) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1900) // VS2014+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) // Apple clang 4.1+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405) // EDG 4.5+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 300) && !defined(__apple_build_version__) // Clang 3.0+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4006) // GCC 4.6+ +// supported. +#else +#define EA_COMPILER_NO_NOEXCEPT 1 +#endif +#endif + + +// EA_COMPILER_NO_RAW_LITERALS +// +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm +// http://en.wikipedia.org/wiki/C%2B%2B11#New_string_literals +// +#if !defined(EA_COMPILER_NO_RAW_LITERALS) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1800) // VS2013+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407) // EDG 4.7+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) // Apple clang 4.1+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 300) && !defined(__apple_build_version__) // Clang 3.0+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4005) // GCC 4.5+ +// supported. +#else +#define EA_COMPILER_NO_RAW_LITERALS 1 +#endif +#endif + + +// EA_COMPILER_NO_UNICODE_STRING_LITERALS +// +// http://en.wikipedia.org/wiki/C%2B%2B11#New_string_literals +// +#if !defined(EA_COMPILER_NO_UNICODE_STRING_LITERALS) +// Not supported by VC++ as of VS2013. +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407) // EDG 4.7+. +// supported. It's not clear if it's v4.4 or v4.7 that adds this support. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) // Apple clang 4.1+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 300) && !defined(__apple_build_version__) // Clang 3.0+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4004) // GCC 4.4+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407) // EDG 4.7+. +// supported. It's not clear if it's v4.4 or v4.7 that adds this support. +#else +#define EA_COMPILER_NO_UNICODE_STRING_LITERALS 1 +#endif +#endif + + +// EA_COMPILER_NO_NEW_CHARACTER_TYPES +// +// Refers to char16_t and char32_t as true native types (and not something simply typedef'd from uint16_t and uint32_t). +// http://en.cppreference.com/w/cpp/language/types +// +#if !defined(EA_COMPILER_NO_NEW_CHARACTER_TYPES) +#if defined(EA_COMPILER_NO_UNICODE_STRING_LITERALS) // Some compilers have had support for char16_t prior to support for u"", but it's not useful to have the former without the latter. +#define EA_COMPILER_NO_NEW_CHARACTER_TYPES 1 +#endif +#endif + + +// EA_COMPILER_NO_UNICODE_CHAR_NAME_LITERALS +// +// C++ 11 relaxed \u\U sequences in strings. +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2170.html +// +#if !defined(EA_COMPILER_NO_UNICODE_CHAR_NAME_LITERALS) +// VC++ up till at least VS2013 supports \u and \U but supports them wrong with respect to the C++11 Standard. + +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) // Apple clang 4.1+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 301) && !defined(__apple_build_version__) // Clang 3.1+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4005) // GCC 4.5+ +// supported. +#else +#define EA_COMPILER_NO_UNICODE_CHAR_NAME_LITERALS 1 +#endif +#endif + + +// EA_COMPILER_NO_UNIFIED_INITIALIZATION_SYNTAX +// +// http://en.wikipedia.org/wiki/C%2B%2B11#Uniform_initialization +// +#if !defined(EA_COMPILER_NO_UNIFIED_INITIALIZATION_SYNTAX) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1800) // VS2013+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 401) && defined(__apple_build_version__) // Apple clang 4.1+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 301) && !defined(__apple_build_version__) // Clang 3.1+, not including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4004) // GCC 4.4+ +// supported. +#else +#define EA_COMPILER_NO_UNIFIED_INITIALIZATION_SYNTAX 1 +#endif +#endif + + +// EA_COMPILER_NO_EXTENDED_FRIEND_DECLARATIONS +// +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf +// +#if !defined(EA_COMPILER_NO_EXTENDED_FRIEND_DECLARATIONS) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1600) // VS2010+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401) // EDG 4.1+. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 209) // Clang 2.9+, including Apple's Clang. +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4007) // GCC 4.7+ +// supported. +#else +#define EA_COMPILER_NO_EXTENDED_FRIEND_DECLARATIONS 1 +#endif +#endif + + +// EA_COMPILER_NO_THREAD_LOCAL +// +// Refers specifically to C++ thread_local, which is like compiler __thread implementations except +// that it also supports non-trivial classes (e.g. with ctors). EA_COMPILER_NO_THREAD_LOCAL refers +// specifically to full C++11 thread_local support. The EAThread package provides a wrapper for +// __thread via EA_THREAD_LOCAL (which unfortunately sounds like C++ thread_local). +// +// https://en.cppreference.com/w/cpp/keyword/thread_local +// +#if !defined(EA_COMPILER_NO_THREAD_LOCAL) +#if defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && EA_COMPILER_HAS_FEATURE(cxx_thread_local) +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(_MSC_VER) && (EA_COMPILER_VERSION >= 1900) // VS2015+ +// supported. +#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__GNUC__) && (EA_COMPILER_VERSION >= 4008) // GCC 4.8+ +// supported. +#else +#define EA_COMPILER_NO_THREAD_LOCAL 1 +#endif +#endif #endif // INCLUDED_eacompiler_H + + + + + diff --git a/UnknownVersion/include/EABase/config/eacompilertraits.h b/UnknownVersion/include/EABase/config/eacompilertraits.h index f2aa3f7..791bff9 100644 --- a/UnknownVersion/include/EABase/config/eacompilertraits.h +++ b/UnknownVersion/include/EABase/config/eacompilertraits.h @@ -1,49 +1,23 @@ -/* -Copyright (C) 2009 Electronic Arts, Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of - its contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - /*----------------------------------------------------------------------------- * config/eacompilertraits.h * - * Copyright (c) 2002 - 2005 Electronic Arts Inc. All rights reserved. - * Maintained by Paul Pedriana, Maxis - * + * Copyright (c) Electronic Arts Inc. All rights reserved. *----------------------------------------------------------------------------- * Currently supported defines include: - * EA_COMPILER_HAS_C99_TYPES - * EA_COMPILER_HAS_CHAR_16_32 + * EA_PREPROCESSOR_JOIN + * * EA_COMPILER_IS_ANSIC * EA_COMPILER_IS_C99 + * EA_COMPILER_IS_C11 + * EA_COMPILER_HAS_C99_TYPES * EA_COMPILER_IS_CPLUSPLUS - * EA_COMPILER_IS_CPLUSPLUS_11_ENABLED - * EA_COMPILER_HAS_MOVE_SEMANTICS * EA_COMPILER_MANAGED_CPP + * EA_COMPILER_INTMAX_SIZE + * EA_OFFSETOF + * EA_SIZEOF_MEMBER * * EA_ALIGN_OF() + * EA_ALIGN_MAX_STATIC / EA_ALIGN_MAX_AUTOMATIC * EA_ALIGN() / EA_PREFIX_ALIGN() / EA_POSTFIX_ALIGN() * EA_ALIGNED() * EA_PACKED() @@ -53,8 +27,11 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * EA_INIT_PRIORITY() * EA_MAY_ALIAS() * EA_ASSUME() + * EA_ANALYSIS_ASSUME() * EA_PURE * EA_WEAK + * EA_UNUSED() + * EA_EMPTY() * * EA_WCHAR_T_NON_NATIVE * EA_WCHAR_SIZE = @@ -70,16 +47,41 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * EA_IMPORT * EA_EXPORT * EA_PRAGMA_ONCE_SUPPORTED + * EA_ONCE * EA_OVERRIDE + * EA_INHERITANCE_FINAL * EA_SEALED * EA_ABSTRACT + * EA_CONSTEXPR / EA_CONSTEXPR_OR_CONST + * EA_CONSTEXPR_IF + * EA_EXTERN_TEMPLATE + * EA_NOEXCEPT + * EA_NORETURN + * EA_CARRIES_DEPENDENCY + * EA_NON_COPYABLE / struct EANonCopyable + * EA_OPTIMIZE_OFF / EA_OPTIMIZE_ON + * EA_SIGNED_RIGHT_SHIFT_IS_UNSIGNED + * + * EA_DISABLE_VC_WARNING / EA_RESTORE_VC_WARNING / EA_DISABLE_ALL_VC_WARNINGS / EA_RESTORE_ALL_VC_WARNINGS + * EA_DISABLE_GCC_WARNING / EA_RESTORE_GCC_WARNING + * EA_DISABLE_CLANG_WARNING / EA_RESTORE_CLANG_WARNING + * EA_DISABLE_SN_WARNING / EA_RESTORE_SN_WARNING / EA_DISABLE_ALL_SN_WARNINGS / EA_RESTORE_ALL_SN_WARNINGS + * EA_DISABLE_GHS_WARNING / EA_RESTORE_GHS_WARNING + * EA_DISABLE_EDG_WARNING / EA_RESTORE_EDG_WARNING + * EA_DISABLE_CW_WARNING / EA_RESTORE_CW_WARNING + * + * EA_DISABLE_DEFAULT_CTOR + * EA_DISABLE_COPY_CTOR + * EA_DISABLE_MOVE_CTOR + * EA_DISABLE_ASSIGNMENT_OPERATOR + * EA_DISABLE_MOVE_OPERATOR * * Todo: - * Find a way to reliably detect wchar_t size at preprocessor time and + * Find a way to reliably detect wchar_t size at preprocessor time and * implement it below for EA_WCHAR_SIZE. * * Todo: - * Find out how to support EA_PASCAL and EA_PASCAL_FUNC for systems in + * Find out how to support EA_PASCAL and EA_PASCAL_FUNC for systems in * which it hasn't yet been found out for. *---------------------------------------------------------------------------*/ @@ -87,948 +89,2473 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef INCLUDED_eacompilertraits_H #define INCLUDED_eacompilertraits_H -#ifndef INCLUDED_eaplatform_H -# include "EABase/config/eaplatform.h" -#endif +#include +#include -#ifndef INCLUDED_eacompiler_H -# include "EABase/config/eacompiler.h" -#endif - // Metrowerks uses #defines in its core C header files to define - // the kind of information we need below (e.g. C99 compatibility) -#if defined(__MWERKS__) - // Defining the following causes C99 compilers to enable the macros - // associated with the defines. The C99 standard specifies that you - // should define these as such. -# ifndef __STDC_LIMIT_MACROS -# define __STDC_LIMIT_MACROS -# endif +// Metrowerks uses #defines in its core C header files to define +// the kind of information we need below (e.g. C99 compatibility) + -# ifndef __STDC_CONSTANT_MACROS -# define __STDC_CONSTANT_MACROS -# endif -# include +// Determine if this compiler is ANSI C compliant and if it is C99 compliant. +#if defined(__STDC__) +#define EA_COMPILER_IS_ANSIC 1 // The compiler claims to be ANSI C + +// Is the compiler a C99 compiler or equivalent? +// From ISO/IEC 9899:1999: +// 6.10.8 Predefined macro names +// __STDC_VERSION__ The integer constant 199901L. (150) +// +// 150) This macro was not specified in ISO/IEC 9899:1990 and was +// specified as 199409L in ISO/IEC 9899/AMD1:1995. The intention +// is that this will remain an integer constant of type long int +// that is increased with each revision of this International Standard. +// +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#define EA_COMPILER_IS_C99 1 +#endif + +// Is the compiler a C11 compiler? +// From ISO/IEC 9899:2011: +// Page 176, 6.10.8.1 (Predefined macro names) : +// __STDC_VERSION__ The integer constant 201112L. (178) +// +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) +#define EA_COMPILER_IS_C11 1 +#endif #endif -#if defined(__SNC__) || defined(EA_PLATFORM_PS3) || defined(__S3E__) -# ifndef __STDC_LIMIT_MACROS -# define __STDC_LIMIT_MACROS -# endif +// Some compilers (e.g. GCC) define __USE_ISOC99 if they are not +// strictly C99 compilers (or are simply C++ compilers) but are set +// to use C99 functionality. Metrowerks defines _MSL_C99 as 1 in +// this case, but 0 otherwise. +#if (defined(__USE_ISOC99) || (defined(_MSL_C99) && (_MSL_C99 == 1))) && !defined(EA_COMPILER_IS_C99) +#define EA_COMPILER_IS_C99 1 +#endif -# ifndef __STDC_CONSTANT_MACROS -# define __STDC_CONSTANT_MACROS -# endif +// Metrowerks defines C99 types (e.g. intptr_t) instrinsically when in C99 mode (-lang C99 on the command line). +#if (defined(_MSL_C99) && (_MSL_C99 == 1)) +#define EA_COMPILER_HAS_C99_TYPES 1 +#endif -# include +#if defined(__GNUC__) +#if (((__GNUC__ * 100) + __GNUC_MINOR__) >= 302) // Also, GCC defines _HAS_C9X. +#define EA_COMPILER_HAS_C99_TYPES 1 // The compiler is not necessarily a C99 compiler, but it defines C99 types. -# if !defined(EA_COMPILER_HAS_INTTYPES) -# if !defined(__S3E__) -# define EA_COMPILER_HAS_INTTYPES -# endif -# endif +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 #endif - // Determine if this compiler is ANSI C compliant and if it is C99 compliant. -#if defined(__STDC__) -# define EA_COMPILER_IS_ANSIC // The compiler claims to be ANSI C - - // Is the compiler a C99 compiler or equivalent? - // From ISO/IEC 9899:1999: - // 6.10.8 Predefined macro names - // __STDC_VERSION__ The integer constant 199901L. (150) - // - // 150) This macro was not specified in ISO/IEC 9899:1990 and was - // specified as 199409L in ISO/IEC 9899/AMD1:1995. The intention - // is that this will remain an integer constant of type long int - // that is increased with each revision of this International Standard. - // -# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) -# define EA_COMPILER_IS_C99 -# endif -#endif - - // Some compilers (e.g. GCC) define __USE_ISOC99 if they are not - // strictly C99 compilers (or are simply C++ compilers) but are set - // to use C99 functionality. Metrowerks defines _MSL_C99 as 1 in - // this case, but 0 otherwise. -#if (defined(__USE_ISOC99) || (defined(_MSL_C99) && (_MSL_C99 == 1))) && !defined(EA_COMPILER_IS_C99) -# define EA_COMPILER_IS_C99 +#ifndef __STDC_CONSTANT_MACROS +#define __STDC_CONSTANT_MACROS 1 // This tells the GCC compiler that we want it to use its native C99 types. #endif - - // Metrowerks defines C99 types (e.g. intptr_t) instrinsically when in C99 mode (-lang C99 on the command line). -#if (defined(_MSL_C99) && (_MSL_C99 == 1)) -# define EA_COMPILER_HAS_C99_TYPES -#endif - -#if defined(__GNUC__) -# if (((__GNUC__ * 100) + __GNUC_MINOR__) >= 302) // Also, GCC defines _HAS_C9X. -# define EA_COMPILER_HAS_C99_TYPES // The compiler is not necessarily a C99 compiler, but it defines C99 types. -# ifndef __STDC_LIMIT_MACROS -# define __STDC_LIMIT_MACROS -# endif -# ifndef __STDC_CONSTANT_MACROS -# define __STDC_CONSTANT_MACROS // This tells the GCC compiler that we want it to use its native C99 types. -# endif -# endif -# if (defined(__GXX_EXPERIMENTAL_CXX0X__) && !defined(EA_COMPILER_IS_CPLUSPLUS_11_ENABLED)) -# define EA_COMPILER_IS_CPLUSPLUS_11_ENABLED -# define EA_COMPILER_HAS_MOVE_SEMANTICS -# endif - -# define EASTL_GNU_VERSION_NUM (__GNUC__ * 100) + __GNUC_MINOR__ -# ifdef EA_COMPILER_IS_CPLUSPLUS_11_ENABLED -# if EASTL_GNU_VERSION_NUM >= 404 -# define EA_COMPILER_HAS_CHAR_16_32 -# define EA_COMPILER_HAS_VARIADIC_TEMPLATES -# endif -# endif -#endif - -#if defined(__clang__) -# if (defined(__GXX_EXPERIMENTAL_CXX0X__) && !defined(EA_COMPILER_IS_CPLUSPLUS_11_ENABLED)) -# define EA_COMPILER_IS_CPLUSPLUS_11_ENABLED -# define EA_COMPILER_HAS_MOVE_SEMANTICS -# endif - -# define EASTL_CLANG_VERSION_NUM (__clang_major__ * 10) + __clang_minor__ -# if EASTL_CLANG_VERSION_NUM >= 29 -# define EA_COMPILER_HAS_C99_TYPES -# endif -# ifdef EA_COMPILER_IS_CPLUSPLUS_11_ENABLED -# if EASTL_CLANG_VERSION_NUM >= 29 -# define EA_COMPILER_HAS_CHAR_16_32 -# define EA_COMPILER_HAS_VARIADIC_TEMPLATES -# endif -# endif - -# ifndef __STDC_LIMIT_MACROS -# define __STDC_LIMIT_MACROS -# endif -# ifndef __STDC_CONSTANT_MACROS -# define __STDC_CONSTANT_MACROS // This tells the GCC compiler that we want it to use its native C99 types. -# endif -#endif - -#if defined(_MSC_VER) -# if (_MSC_VER >= 1600) -# define EA_COMPILER_IS_CPLUSPLUS_11_ENABLED -# define EA_COMPILER_HAS_MOVE_SEMANTICS -# endif -#endif - -#if defined(__ghs__) -# if __GHS_VERSION_NUMBER >= 201505 -# define EA_COMPILER_HAS_CHAR_16_32 -# define EA_COMPILER_HAS_VARIADIC_TEMPLATES -# define EA_COMPILER_IS_CPLUSPLUS_11_ENABLED -# endif +#endif +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +#define EA_COMPILER_HAS_C99_TYPES 1 #endif #ifdef __cplusplus -# define EA_COMPILER_IS_CPLUSPLUS -# if (__cplusplus > 199711L) -# define EA_COMPILER_IS_CPLUSPLUS_11_ENABLED -# endif +#define EA_COMPILER_IS_CPLUSPLUS 1 +#endif + + +// ------------------------------------------------------------------------ +// EA_PREPROCESSOR_JOIN +// +// This macro joins the two arguments together, even when one of +// the arguments is itself a macro (see 16.3.1 in C++98 standard). +// This is often used to create a unique name with __LINE__. +// +// For example, this declaration: +// char EA_PREPROCESSOR_JOIN(unique_, __LINE__); +// expands to this: +// char unique_73; +// +// Note that all versions of MSVC++ up to at least version 7.1 +// fail to properly compile macros that use __LINE__ in them +// when the "program database for edit and continue" option +// is enabled. The result is that __LINE__ gets converted to +// something like __LINE__(Var+37). +// +#ifndef EA_PREPROCESSOR_JOIN +#define EA_PREPROCESSOR_JOIN(a, b) EA_PREPROCESSOR_JOIN1(a, b) +#define EA_PREPROCESSOR_JOIN1(a, b) EA_PREPROCESSOR_JOIN2(a, b) +#define EA_PREPROCESSOR_JOIN2(a, b) a##b +#endif + + +// ------------------------------------------------------------------------ +// EA_STRINGIFY +// +// Example usage: +// printf("Line: %s", EA_STRINGIFY(__LINE__)); +// +#ifndef EA_STRINGIFY +#define EA_STRINGIFY(x) EA_STRINGIFYIMPL(x) +#define EA_STRINGIFYIMPL(x) #x +#endif + + +// ------------------------------------------------------------------------ +// EA_IDENTITY +// +#ifndef EA_IDENTITY +#define EA_IDENTITY(x) x #endif - // ------------------------------------------------------------------------ - // EA_COMPILER_MANAGED_CPP - // Defined if this is being compiled with Managed C++ extensions +// ------------------------------------------------------------------------ +// EA_COMPILER_MANAGED_CPP +// Defined if this is being compiled with Managed C++ extensions #ifdef EA_COMPILER_MSVC -# if EA_COMPILER_VERSION >= 1300 -# ifdef _MANAGED -# define EA_COMPILER_MANAGED_CPP -# endif -# endif -#endif - - - // ------------------------------------------------------------------------ - // alignment expressions - // - // Here we define - // EA_ALIGN_OF(type) // Returns size_t. - // 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. - // EA_PREFIX_ALIGN(n) // n is byte alignment, with being a power of two. You should need this only for unusual compilers. - // EA_POSTFIX_ALIGN(n) // Valid values for n are 1, 2, 4, 8, etc. You should need this only for unusual compilers. - // EA_ALIGNED(t, v, n) // Type, variable, alignment. Used to align an instance. You should need this only for unusual compilers. - // EA_PACKED // Specifies that the given structure be packed (and not have its members aligned). - // - // Example usage: - // size_t x = EA_ALIGN_OF(int); Non-aligned equivalents. Meaning - // 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. - // EA_ALIGN(8) int x; int x; Align x on 8 for compilers that allow prefix attributes. - // int x EA_POSTFIX_ALIGN(8); int x; Align x on 8 for compilers that require postfix attributes. - // int x EA_POSTFIX_ALIGN(8) = 5; int x = 5; Align x on 8 for compilers that require postfix attributes. - // int x EA_POSTFIX_ALIGN(8)(5); int x(5); Align x on 8 for compilers that require postfix attributes. - // 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. - // EA_ALIGNED(int, x, 8) = 5; int x = 5; Align x on 8. - // EA_ALIGNED(int, x, 16)(5); int x(5); Align x on 16. - // EA_ALIGNED(int, x[3], 16); int x[3]; Align x array on 16. - // EA_ALIGNED(int, x[3], 16) = { 1, 2, 3 }; int x[3] = { 1, 2, 3 }; Align x array on 16. - // 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. - // 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. - // 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. - // 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. - // struct X { int x; int y; } EA_PACKED; struct X { int x; int y; }; Pack the members of struct X. - // typedef EA_ALIGNED(int, int16, 16); int16 n16; typedef int int16; int16 n16; Define int16 as an int which is aligned on 16. - // typedef EA_ALIGNED(X, X16, 16); X16 x16; typedef X X16; X16 x16; Define X16 as an X which is aligned on 16. - - // SNC (EDG) intends to be compatible with GCC but has a bug whereby it - // fails to support calling a constructor in an aligned declaration when - // using postfix alignment attributes. Prefix works for alignment, but does not align - // the size like postfix does. Prefix also fails on templates. So gcc style post fix - // is still used, but the user will need to use EA_POSTFIX_ALIGN before the constructor parameters. - // this note by Paul and Frank -#if defined(EA_COMPILER_SN) && defined(__GNUC__) // If using the SN compiler in GCC compatibility mode... -# define EA_ALIGN_OF(type) ((size_t)__alignof__(type)) -# define EA_ALIGN(n) __attribute__((aligned(n))) -# define EA_PREFIX_ALIGN(n) -# define EA_POSTFIX_ALIGN(n) __attribute__((aligned(n))) -# define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n))) -# define EA_PACKED __attribute__((packed)) - - // GCC 2.x doesn't support prefix attributes. -#elif defined(__GNUC__) && (__GNUC__ < 3) -# define EA_ALIGN_OF(type) ((size_t)__alignof__(type)) -# define EA_ALIGN(n) -# define EA_PREFIX_ALIGN(n) -# define EA_POSTFIX_ALIGN(n) __attribute__((aligned(n))) -# define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n))) -# define EA_PACKED __attribute__((packed)) - - // GCC 3.x+ and IBM C support prefix attributes. -#elif (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__xlC__) -# define EA_ALIGN_OF(type) ((size_t)__alignof__(type)) -# define EA_ALIGN(n) __attribute__((aligned(n))) -# define EA_PREFIX_ALIGN(n) -# define EA_POSTFIX_ALIGN(n) __attribute__((aligned(n))) -# define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n))) -# define EA_PACKED __attribute__((packed)) +#if EA_COMPILER_VERSION >= 1300 +#ifdef _MANAGED +#define EA_COMPILER_MANAGED_CPP 1 +#endif +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_COMPILER_INTMAX_SIZE +// +// This is related to the concept of intmax_t uintmax_t, but is available +// in preprocessor form as opposed to compile-time form. At compile-time +// you can use intmax_t and uintmax_t to use the actual types. +// +#if defined(__GNUC__) && defined(__x86_64__) +#define EA_COMPILER_INTMAX_SIZE 16 // intmax_t is __int128_t (GCC extension) and is 16 bytes. +#else +#define EA_COMPILER_INTMAX_SIZE 8 // intmax_t is int64_t and is 8 bytes. +#endif + + + +// ------------------------------------------------------------------------ +// EA_LPAREN / EA_RPAREN / EA_COMMA / EA_SEMI +// +// These are used for using special characters in macro-using expressions. +// Note that this macro intentionally uses (), as in some cases it can't +// work unless it does. +// +// Example usage: +// int x = SOME_MACRO(SomeTemplate); +// +#ifndef EA_LPAREN +#define EA_LPAREN() ( +#endif +#ifndef EA_RPAREN +#define EA_RPAREN() ) +#endif +#ifndef EA_COMMA +#define EA_COMMA() , +#endif +#ifndef EA_SEMI +#define EA_SEMI() ; +#endif -#elif defined(EA_COMPILER_CLANG) - // Checks for clang-supported attributes -# if __has_attribute(aligned) -# define CLANG_ALIGNED(n) __attribute__((aligned(n))) -# else -# define CLANG_ALIGNED(n) -# endif - -# if __has_attribute(packed) -# define CLANG_PACKED __attribute__((packed)) -# else -# define CLANG_PACKED -# endif - - // Now we define the alignment stuff -# define EA_ALIGN_OF(type) ((size_t)__alignof__(type)) -# define EA_ALIGN(n) CLANG_ALIGNED(n) -# define EA_PREFIX_ALIGN(n) -# define EA_POSTFIX_ALIGN(n) CLANG_ALIGNED(n) -# define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n))) -# define EA_PACKED CLANG_PACKED - - // Make sure we get no macro naming conflicts -# undef CLANG_ALIGNED -# undef CLANG_PACKED - - // Metrowerks supports prefix attributes. - // Metrowerks does not support packed alignment attributes. -#elif defined(EA_COMPILER_METROWERKS) -# define EA_ALIGN_OF(type) ((size_t)__alignof__(type)) -# define EA_ALIGN(n) __attribute__((aligned(n))) -# define EA_PREFIX_ALIGN(n) -# define EA_POSTFIX_ALIGN(n) __attribute__((aligned(n))) -# define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n))) -# define EA_PACKED - - // Microsoft supports prefix alignment via __declspec, but the alignment value must be a literal number, not just a constant expression. - // Contrary to VC7.x and earlier documentation, __declspec(align) works on stack variables. VC8+ (VS2005+) documents correctly. - // Microsoft does not support packed alignment attributes; you must use #pragma pack. -#elif defined(EA_COMPILER_INTEL) || defined(EA_PLATFORM_XBOX) || (defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1300)) -# define EA_ALIGN_OF(type) ((size_t)__alignof(type)) -# define EA_ALIGN(n) __declspec(align(n)) -# define EA_PREFIX_ALIGN(n) __declspec(align(n)) -# define EA_POSTFIX_ALIGN(n) -# define EA_ALIGNED(variable_type, variable, n) __declspec(align(n)) variable_type variable -# define EA_PACKED - - // Arm brand compiler -#elif defined(__ARMCC_VERSION) -# define EA_ALIGN_OF(type) ((size_t)__ALIGNOF__(type)) -# define EA_ALIGN(n) __align(n) -# define EA_PREFIX_ALIGN(n) __align(n) -# define EA_POSTFIX_ALIGN(n) -# define EA_ALIGNED(variable_type, variable, n) __align(n) variable_type variable -# define EA_PACKED __packed + + + +// ------------------------------------------------------------------------ +// EA_OFFSETOF +// Implements a portable version of the non-standard offsetof macro. +// +// The offsetof macro is guaranteed to only work with POD types. However, we wish to use +// it for non-POD types but where we know that offsetof will still work for the cases +// in which we use it. GCC unilaterally gives a warning when using offsetof with a non-POD, +// even if the given usage happens to work. So we make a workaround version of offsetof +// here for GCC which has the same effect but tricks the compiler into not issuing the warning. +// The 65536 does the compiler fooling; the reinterpret_cast prevents the possibility of +// an overloaded operator& for the class getting in the way. +// +// Example usage: +// struct A{ int x; int y; }; +// size_t n = EA_OFFSETOF(A, y); +// +#if defined(__GNUC__) // We can't use GCC 4's __builtin_offsetof because it mistakenly complains about non-PODs that are really PODs. +#define EA_OFFSETOF(struct_, member_) ((size_t)(((uintptr_t)&reinterpret_cast((((struct_*)65536)->member_))) - 65536)) +#else +#define EA_OFFSETOF(struct_, member_) offsetof(struct_, member_) +#endif + +// ------------------------------------------------------------------------ +// EA_SIZEOF_MEMBER +// Implements a portable way to determine the size of a member. +// +// The EA_SIZEOF_MEMBER simply returns the size of a member within a class or struct; member +// access rules still apply. We offer two approaches depending on the compiler's support for non-static member +// initializers although most C++11 compilers support this. +// +// Example usage: +// struct A{ int x; int y; }; +// size_t n = EA_SIZEOF_MEMBER(A, y); +// +#ifndef EA_COMPILER_NO_EXTENDED_SIZEOF +#define EA_SIZEOF_MEMBER(struct_, member_) (sizeof(struct_::member_)) +#else +#define EA_SIZEOF_MEMBER(struct_, member_) (sizeof(((struct_*)0)->member_)) +#endif + +// ------------------------------------------------------------------------ +// alignment expressions +// +// Here we define +// EA_ALIGN_OF(type) // Returns size_t. +// EA_ALIGN_MAX_STATIC // The max align value that the compiler will respect for EA_ALIGN for static data (global and static variables). Some compilers allow high values, some allow no more than 8. EA_ALIGN_MIN is assumed to be 1. +// EA_ALIGN_MAX_AUTOMATIC // The max align value for automatic variables (variables declared as local to a function). +// 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. +// EA_ALIGNED(t, v, n) // Type, variable, alignment. Used to align an instance. You should need this only for unusual compilers. +// EA_PACKED // Specifies that the given structure be packed (and not have its members aligned). +// +// Also we define the following for rare cases that it's needed. +// EA_PREFIX_ALIGN(n) // n is byte alignment, with being a power of two. You should need this only for unusual compilers. +// EA_POSTFIX_ALIGN(n) // Valid values for n are 1, 2, 4, 8, etc. You should need this only for unusual compilers. +// +// Example usage: +// size_t x = EA_ALIGN_OF(int); Non-aligned equivalents. Meaning +// 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. +// EA_ALIGN(8) int x; int x; Align x on 8 for compilers that allow prefix attributes. +// int x EA_POSTFIX_ALIGN(8); int x; Align x on 8 for compilers that require postfix attributes. +// int x EA_POSTFIX_ALIGN(8) = 5; int x = 5; Align x on 8 for compilers that require postfix attributes. +// int x EA_POSTFIX_ALIGN(8)(5); int x(5); Align x on 8 for compilers that require postfix attributes. +// 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. +// EA_ALIGNED(int, x, 8) = 5; int x = 5; Align x on 8. +// EA_ALIGNED(int, x, 16)(5); int x(5); Align x on 16. +// EA_ALIGNED(int, x[3], 16); int x[3]; Align x array on 16. +// EA_ALIGNED(int, x[3], 16) = { 1, 2, 3 }; int x[3] = { 1, 2, 3 }; Align x array on 16. +// 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. +// 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. +// 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. +// 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. +// struct X { int x; int y; } EA_PACKED; struct X { int x; int y; }; Pack the members of struct X. +// typedef EA_ALIGNED(int, int16, 16); int16 n16; typedef int int16; int16 n16; Define int16 as an int which is aligned on 16. +// typedef EA_ALIGNED(X, X16, 16); X16 x16; typedef X X16; X16 x16; Define X16 as an X which is aligned on 16. + +#if !defined(EA_ALIGN_MAX) // If the user hasn't globally set an alternative value... +#if defined(EA_PROCESSOR_ARM) // ARM compilers in general tend to limit automatic variables to 8 or less. +#define EA_ALIGN_MAX_STATIC 1048576 +#define EA_ALIGN_MAX_AUTOMATIC 1 // Typically they support only built-in natural aligment types (both arm-eabi and apple-abi). +#elif defined(EA_PLATFORM_APPLE) +#define EA_ALIGN_MAX_STATIC 1048576 +#define EA_ALIGN_MAX_AUTOMATIC 16 +#else +#define EA_ALIGN_MAX_STATIC 1048576 // Arbitrarily high value. What is the actual max? +#define EA_ALIGN_MAX_AUTOMATIC 1048576 +#endif +#endif + +// EDG intends to be compatible with GCC but has a bug whereby it +// fails to support calling a constructor in an aligned declaration when +// using postfix alignment attributes. Prefix works for alignment, but does not align +// the size like postfix does. Prefix also fails on templates. So gcc style post fix +// is still used, but the user will need to use EA_POSTFIX_ALIGN before the constructor parameters. +#if defined(__GNUC__) && (__GNUC__ < 3) +#define EA_ALIGN_OF(type) ((size_t)__alignof__(type)) +#define EA_ALIGN(n) +#define EA_PREFIX_ALIGN(n) +#define EA_POSTFIX_ALIGN(n) __attribute__((aligned(n))) +#define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n))) +#define EA_PACKED __attribute__((packed)) + +// GCC 3.x+, IBM, and clang support prefix attributes. +#elif (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__xlC__) || defined(__clang__) +#define EA_ALIGN_OF(type) ((size_t)__alignof__(type)) +#define EA_ALIGN(n) __attribute__((aligned(n))) +#define EA_PREFIX_ALIGN(n) +#define EA_POSTFIX_ALIGN(n) __attribute__((aligned(n))) +#define EA_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((aligned(n))) +#define EA_PACKED __attribute__((packed)) + +// Metrowerks supports prefix attributes. +// Metrowerks does not support packed alignment attributes. +#elif defined(EA_COMPILER_INTEL) || defined(CS_UNDEFINED_STRING) || (defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1300)) +#define EA_ALIGN_OF(type) ((size_t)__alignof(type)) +#define EA_ALIGN(n) __declspec(align(n)) +#define EA_PREFIX_ALIGN(n) EA_ALIGN(n) +#define EA_POSTFIX_ALIGN(n) +#define EA_ALIGNED(variable_type, variable, n) EA_ALIGN(n) variable_type variable +#define EA_PACKED // See EA_PRAGMA_PACK_VC for an alternative. + +// Arm brand compiler +#elif defined(EA_COMPILER_ARM) +#define EA_ALIGN_OF(type) ((size_t)__ALIGNOF__(type)) +#define EA_ALIGN(n) __align(n) +#define EA_PREFIX_ALIGN(n) __align(n) +#define EA_POSTFIX_ALIGN(n) +#define EA_ALIGNED(variable_type, variable, n) __align(n) variable_type variable +#define EA_PACKED __packed #else // Unusual compilers - // There is nothing we can do about some of these. This is not as bad a problem as it seems. - // If the given platform/compiler doesn't support alignment specifications, then it's somewhat - // likely that alignment doesn't matter for that platform. Otherwise they would have defined - // functionality to manipulate alignment. -# define EA_ALIGN(n) -# define EA_PREFIX_ALIGN(n) -# define EA_POSTFIX_ALIGN(n) -# define EA_ALIGNED(variable_type, variable, n) variable_type variable -# define EA_PACKED - -# ifdef __cplusplus - template struct EAAlignOf1 { enum { s = sizeof (T), value = s ^ (s & (s - 1)) }; }; - template struct EAAlignOf2; - template struct helper { template struct Val { enum { value = size_diff }; }; }; - template <> struct helper<0> { template struct Val { enum { value = EAAlignOf2::value }; }; }; - template struct EAAlignOf2 { struct Big { T x; char c; }; - enum { diff = sizeof (Big) - sizeof (T), value = helper::template Val::value }; }; - template struct EAAlignof3 { enum { x = EAAlignOf2::value, y = EAAlignOf1::value, value = x < y ? x : y }; }; -# define EA_ALIGN_OF(type) ((size_t)EAAlignof3::value) - -# else - // C implementation of EA_ALIGN_OF - // This implementation works for most cases, but doesn't directly work - // for types such as function pointer declarations. To work with those - // types you need to typedef the type and then use the typedef in EA_ALIGN_OF. -# define EA_ALIGN_OF(type) ((size_t)offsetof(struct { char c; type m; }, m)) -# endif -#endif - - - // ------------------------------------------------------------------------ - // EA_LIKELY / EA_UNLIKELY - // - // Defined as a macro which gives a hint to the compiler for branch - // prediction. GCC gives you the ability to manually give a hint to - // the compiler about the result of a comparison, though it's often - // best to compile shipping code with profiling feedback under both - // GCC (-fprofile-arcs) and VC++ (/LTCG:PGO, etc.). However, there - // are times when you feel very sure that a boolean expression will - // usually evaluate to either true or false and can help the compiler - // by using an explicity directive... - // - // Example usage: - // if(EA_LIKELY(a == 0)) // Tell the compiler that a will usually equal 0. - // { ... } - // - // Example usage: - // if(EA_UNLIKELY(a == 0)) // Tell the compiler that a will usually not equal 0. - // { ... } - // +// There is nothing we can do about some of these. This is not as bad a problem as it seems. +// If the given platform/compiler doesn't support alignment specifications, then it's somewhat +// likely that alignment doesn't matter for that platform. Otherwise they would have defined +// functionality to manipulate alignment. +#define EA_ALIGN(n) +#define EA_PREFIX_ALIGN(n) +#define EA_POSTFIX_ALIGN(n) +#define EA_ALIGNED(variable_type, variable, n) variable_type variable +#define EA_PACKED + +#ifdef __cplusplus +template struct EAAlignOf1 { enum { s = sizeof (T), value = s ^ (s & (s - 1)) }; }; +template struct EAAlignOf2; +template struct helper { template struct Val { enum { value = size_diff }; }; }; +template <> struct helper<0> { template struct Val { enum { value = EAAlignOf2::value }; }; }; +template struct EAAlignOf2 { struct Big { T x; char c; }; + enum { diff = sizeof (Big) - sizeof (T), value = helper::template Val::value }; }; +template struct EAAlignof3 { enum { x = EAAlignOf2::value, y = EAAlignOf1::value, value = x < y ? x : y }; }; +#define EA_ALIGN_OF(type) ((size_t)EAAlignof3::value) + +#else +// C implementation of EA_ALIGN_OF +// This implementation works for most cases, but doesn't directly work +// for types such as function pointer declarations. To work with those +// types you need to typedef the type and then use the typedef in EA_ALIGN_OF. +#define EA_ALIGN_OF(type) ((size_t)offsetof(struct { char c; type m; }, m)) +#endif +#endif + +// EA_PRAGMA_PACK_VC +// +// Wraps #pragma pack in a way that allows for cleaner code. +// +// Example usage: +// EA_PRAGMA_PACK_VC(push, 1) +// struct X{ char c; int i; }; +// EA_PRAGMA_PACK_VC(pop) +// +#if !defined(EA_PRAGMA_PACK_VC) +#if defined(EA_COMPILER_MSVC) +#define EA_PRAGMA_PACK_VC(...) __pragma(pack(__VA_ARGS__)) +#elif !defined(EA_COMPILER_NO_VARIADIC_MACROS) +#define EA_PRAGMA_PACK_VC(...) +#else +// No support. However, all compilers of significance to us support variadic macros. +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_LIKELY / EA_UNLIKELY +// +// Defined as a macro which gives a hint to the compiler for branch +// prediction. GCC gives you the ability to manually give a hint to +// the compiler about the result of a comparison, though it's often +// best to compile shipping code with profiling feedback under both +// GCC (-fprofile-arcs) and VC++ (/LTCG:PGO, etc.). However, there +// are times when you feel very sure that a boolean expression will +// usually evaluate to either true or false and can help the compiler +// by using an explicity directive... +// +// Example usage: +// if(EA_LIKELY(a == 0)) // Tell the compiler that a will usually equal 0. +// { ... } +// +// Example usage: +// if(EA_UNLIKELY(a == 0)) // Tell the compiler that a will usually not equal 0. +// { ... } +// #ifndef EA_LIKELY -# if (defined(__GNUC__) && (__GNUC__ >= 3)) || \ - (defined(__clang__) && __has_builtin(__builtin_expect)) || \ - defined(__MWERKS__) // Metrowerks supports __builtin_expect, but with some platforms (e.g. Wii) it appears to ignore it. - -# if defined(__cplusplus) -# define EA_LIKELY(x) __builtin_expect(!!(x), true) -# define EA_UNLIKELY(x) __builtin_expect(!!(x), false) -# else -# define EA_LIKELY(x) __builtin_expect(!!(x), 1) -# define EA_UNLIKELY(x) __builtin_expect(!!(x), 0) -# endif -# else -# define EA_LIKELY(x) (x) -# define EA_UNLIKELY(x) (x) -# endif -#endif - - - // ------------------------------------------------------------------------ - // EA_INIT_PRIORITY - // - // This is simply a wrapper for the GCC init_priority attribute that allows - // multiplatform code to be easier to read. This attribute doesn't apply - // to VC++ because VC++ uses file-level pragmas to control init ordering. - // - // Example usage: - // SomeClass gSomeClass EA_INIT_PRIORITY(2000); - // +#if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__clang__) +#if defined(__cplusplus) +#define EA_LIKELY(x) __builtin_expect(!!(x), true) +#define EA_UNLIKELY(x) __builtin_expect(!!(x), false) +#else +#define EA_LIKELY(x) __builtin_expect(!!(x), 1) +#define EA_UNLIKELY(x) __builtin_expect(!!(x), 0) +#endif +#else +#define EA_LIKELY(x) (x) +#define EA_UNLIKELY(x) (x) +#endif +#endif + +// ------------------------------------------------------------------------ +// EA_HAS_INCLUDE_AVAILABLE +// +// Used to guard against the EA_HAS_INCLUDE() macro on compilers that do not +// support said feature. +// +// Example usage: +// +// #if EA_HAS_INCLUDE_AVAILABLE +// #if EA_HAS_INCLUDE("myinclude.h") +// #include "myinclude.h" +// #endif +// #endif +#if !defined(EA_HAS_INCLUDE_AVAILABLE) +#if EA_COMPILER_CPP17_ENABLED || EA_COMPILER_CLANG || EA_COMPILER_GNUC +#define EA_HAS_INCLUDE_AVAILABLE 1 +#else +#define EA_HAS_INCLUDE_AVAILABLE 0 +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_HAS_INCLUDE +// +// May be used in #if and #elif expressions to test for the existence +// of the header referenced in the operand. If possible it evaluates to a +// non-zero value and zero otherwise. The operand is the same form as the file +// in a #include directive. +// +// Example usage: +// +// #if EA_HAS_INCLUDE("myinclude.h") +// #include "myinclude.h" +// #endif +// +// #if EA_HAS_INCLUDE() +// #include +// #endif + +#if !defined(EA_HAS_INCLUDE) +#if EA_COMPILER_CPP17_ENABLED +#define EA_HAS_INCLUDE(x) __has_include(x) +#elif EA_COMPILER_CLANG +#define EA_HAS_INCLUDE(x) __has_include(x) +#elif EA_COMPILER_GNUC +#define EA_HAS_INCLUDE(x) __has_include(x) +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_INIT_PRIORITY_AVAILABLE +// +// This value is either not defined, or defined to 1. +// Defines if the GCC attribute init_priority is supported by the compiler. +// +#if !defined(EA_INIT_PRIORITY_AVAILABLE) +#if defined(__GNUC__) && !defined(__EDG__) // EDG typically #defines __GNUC__ but doesn't implement init_priority. +#define EA_INIT_PRIORITY_AVAILABLE 1 +#elif defined(__clang__) +#define EA_INIT_PRIORITY_AVAILABLE 1 // Clang implements init_priority +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_INIT_PRIORITY +// +// This is simply a wrapper for the GCC init_priority attribute that allows +// multiplatform code to be easier to read. This attribute doesn't apply +// to VC++ because VC++ uses file-level pragmas to control init ordering. +// +// Example usage: +// SomeClass gSomeClass EA_INIT_PRIORITY(2000); +// #if !defined(EA_INIT_PRIORITY) -# if defined(__GNUC__) -# define EA_INIT_PRIORITY(x) __attribute__ ((init_priority (x))) -# else -# define EA_INIT_PRIORITY(x) -# endif -#endif - - - // ------------------------------------------------------------------------ - // EA_MAY_ALIAS - // - // Defined as a macro that wraps the GCC may_alias attribute. This attribute - // has no significance for VC++ because VC++ doesn't support the concept of - // strict aliasing. Users should avoid writing code that breaks strict - // aliasing rules; EA_MAY_ALIAS is for cases with no alternative. - // - // Example usage: - // void* EA_MAY_ALIAS gPtr = NULL; - // - // Example usage: - // typedef void* EA_MAY_ALIAS pvoid_may_alias; - // pvoid_may_alias gPtr = NULL; - // +#if defined(EA_INIT_PRIORITY_AVAILABLE) +#define EA_INIT_PRIORITY(x) __attribute__ ((init_priority (x))) +#else +#define EA_INIT_PRIORITY(x) +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_INIT_SEG_AVAILABLE +// +// +#if !defined(EA_INIT_SEG_AVAILABLE) +#if defined(_MSC_VER) +#define EA_INIT_SEG_AVAILABLE 1 +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_INIT_SEG +// +// Specifies a keyword or code section that affects the order in which startup code is executed. +// +// https://docs.microsoft.com/en-us/cpp/preprocessor/init-seg?view=vs-2019 +// +// Example: +// EA_INIT_SEG(compiler) MyType gMyTypeGlobal; +// EA_INIT_SEG("my_section") MyOtherType gMyOtherTypeGlobal; +// +#if !defined(EA_INIT_SEG) +#if defined(EA_INIT_SEG_AVAILABLE) +#define EA_INIT_SEG(x) \ + __pragma(warning(push)) __pragma(warning(disable : 4074)) __pragma(warning(disable : 4075)) __pragma(init_seg(x)) \ + __pragma(warning(pop)) +#else +#define EA_INIT_SEG(x) +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_MAY_ALIAS_AVAILABLE +// +// Defined as 0, 1, or 2. +// Defines if the GCC attribute may_alias is supported by the compiler. +// Consists of a value 0 (unsupported, shouldn't be used), 1 (some support), +// or 2 (full proper support). +// +#ifndef EA_MAY_ALIAS_AVAILABLE #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 303) -# define EA_MAY_ALIAS __attribute__((__may_alias__)) -#elif defined(EA_COMPILER_CLANG) && __has_attribute(__may_alias__) -# define EA_MAY_ALIAS __attribute__((__may_alias__)) -#else -# define EA_MAY_ALIAS -#endif - - - // ------------------------------------------------------------------------ - // EA_ASSUME - // - // This acts the same as the VC++ __assume directive and is implemented - // simply as a wrapper around it to allow portable usage of it and to take - // advantage of it if and when it appears in other compilers. - // - // Example usage: - // void Function(int a) { - // switch(a) { - // case 1: - // DoSomething(1); - // break; - // case 2: - // DoSomething(-1); - // break; - // default: - // EA_ASSUME(0); // This tells the optimizer that the default cannot be reached. - // } - // } - // +#if !defined(__EDG__) // define it as 1 while defining GCC's support as 2. +#define EA_MAY_ALIAS_AVAILABLE 2 +#else +#define EA_MAY_ALIAS_AVAILABLE 0 +#endif +#else +#define EA_MAY_ALIAS_AVAILABLE 0 +#endif +#endif + + +// EA_MAY_ALIAS +// +// Defined as a macro that wraps the GCC may_alias attribute. This attribute +// has no significance for VC++ because VC++ doesn't support the concept of +// strict aliasing. Users should avoid writing code that breaks strict +// aliasing rules; EA_MAY_ALIAS is for cases with no alternative. +// +// Example usage: +// void* EA_MAY_ALIAS gPtr = NULL; +// +// Example usage: +// typedef void* EA_MAY_ALIAS pvoid_may_alias; +// pvoid_may_alias gPtr = NULL; +// +#if EA_MAY_ALIAS_AVAILABLE +#define EA_MAY_ALIAS __attribute__((__may_alias__)) +#else +#define EA_MAY_ALIAS +#endif + + +// ------------------------------------------------------------------------ +// EA_ASSUME +// +// This acts the same as the VC++ __assume directive and is implemented +// simply as a wrapper around it to allow portable usage of it and to take +// advantage of it if and when it appears in other compilers. +// +// Example usage: +// void Function(int a) { +// switch(a) { +// case 1: +// DoSomething(1); +// break; +// case 2: +// DoSomething(-1); +// break; +// default: +// EA_ASSUME(0); // This tells the optimizer that the default cannot be reached. +// } +// } +// #ifndef EA_ASSUME -# if defined(_MSC_VER) && (_MSC_VER >= 1300) // If VC7.0 and later (including XBox, and XBox 360)... -# define EA_ASSUME(x) __assume(x) -# else -# define EA_ASSUME(x) -# endif -#endif - - - - // ------------------------------------------------------------------------ - // EA_PURE - // - // This acts the same as the GCC __attribute__ ((pure)) directive and is - // implemented simply as a wrapper around it to allow portable usage of - // it and to take advantage of it if and when it appears in other compilers. - // - // A "pure" function is one that has no effects except its return value and - // its return value is a function of only the function's parameters or - // non-volatile global variables. Any parameter or global variable access - // must be read-only. Loop optimization and subexpression elimination can be - // applied to such functions. A common example is strlen(): Given identical - // inputs, the function's return value (its only effect) is invariant across - // multiple invocations and thus can be pulled out of a loop and called but once. - // - // Example usage: - // EA_PURE void Function(); - // -#ifndef EA_PURE -# if defined(EA_COMPILER_GNUC) -# define EA_PURE __attribute__((pure)) -# elif defined(EA_COMPILER_CLANG) && __has_attribute(pure) -# define EA_PURE __attribute__((pure)) -# elif defined(__ARMCC_VERSION) // Arm brand compiler for ARM CPU -# define EA_PURE __pure -# else -# define EA_PURE -# endif -#endif - - - - // ------------------------------------------------------------------------ - // EA_WEAK - // EA_WEAK_SUPPORTED -- defined as 0 or 1. - // - // GCC - // The weak attribute causes the declaration to be emitted as a weak - // symbol rather than a global. This is primarily useful in defining - // library functions which can be overridden in user code, though it - // can also be used with non-function declarations. - // - // VC++ - // At link time, if multiple definitions of a COMDAT are seen, the linker - // picks one and discards the rest. If the linker option /OPT:REF - // is selected, then COMDAT elimination will occur to remove all the - // unreferenced data items in the linker output. - // - // Example usage: - // EA_WEAK void Function(); - // -#ifndef EA_WEAK -# if defined(_MSC_VER) && (_MSC_VER >= 1300) // If VC7.0 and later (including XBox)... -# define EA_WEAK __declspec(selectany) -# define EA_WEAK_SUPPORTED 1 -# elif defined(_MSC_VER) || (defined(__GNUC__) && defined(__CYGWIN__)) -# define EA_WEAK -# define EA_WEAK_SUPPORTED 0 -# elif defined(__ARMCC_VERSION) // Arm brand compiler for ARM CPU -# define EA_WEAK __weak -# define EA_WEAK_SUPPORTED 1 -# else // GCC and IBM compilers, others. -# define EA_WEAK __attribute__((weak)) -# define EA_WEAK_SUPPORTED 1 -# endif -#endif - - - - // ------------------------------------------------------------------------ - // wchar_t - // Here we define: - // EA_WCHAR_T_NON_NATIVE - // EA_WCHAR_SIZE = - // -#ifndef EA_WCHAR_T_NON_NATIVE - // Compilers that always implement wchar_t as native include: - // COMEAU, new SN, and other EDG-based compilers. - // GCC - // Borland - // SunPro - // IBM Visual Age -# if defined(EA_COMPILER_INTEL) -# if (EA_COMPILER_VERSION < 700) -# define EA_WCHAR_T_NON_NATIVE 1 -# else -# if (!defined(_WCHAR_T_DEFINED) && !defined(_WCHAR_T)) -# define EA_WCHAR_T_NON_NATIVE 1 -# endif -# endif -# elif defined(EA_COMPILER_MSVC) || defined(EA_COMPILER_BORLAND) -# ifndef _NATIVE_WCHAR_T_DEFINED -# define EA_WCHAR_T_NON_NATIVE 1 -# endif -# elif defined(EA_COMPILER_METROWERKS) -# if !__option(wchar_type) -# define EA_WCHAR_T_NON_NATIVE 1 -# endif -# elif defined(__SNC__) && !defined(__cplusplus) // If compiling C under SNC... -# define EA_WCHAR_T_NON_NATIVE 1 -# endif +#if defined(_MSC_VER) && (_MSC_VER >= 1300) // If VC7.0 and later +#define EA_ASSUME(x) __assume(x) +#else +#define EA_ASSUME(x) +#endif #endif -#ifndef EA_WCHAR_SIZE // If the user hasn't specified that it is a given size... -# if defined(__WCHAR_MAX__) // GCC defines this for most platforms. -# if (__WCHAR_MAX__ == 2147483647) || (__WCHAR_MAX__ == 4294967295) -# define EA_WCHAR_SIZE 4 -# elif (__WCHAR_MAX__ == 32767) || (__WCHAR_MAX__ == 65535) -# define EA_WCHAR_SIZE 2 -# elif (__WCHAR_MAX__ == 127) || (__WCHAR_MAX__ == 255) -# define EA_WCHAR_SIZE 1 -# else -# define EA_WCHAR_SIZE 4 -# endif -# elif defined(WCHAR_MAX) // The SN and Arm compilers define this. -# if (WCHAR_MAX == 2147483647) || (WCHAR_MAX == 4294967295) -# define EA_WCHAR_SIZE 4 -# elif (WCHAR_MAX == 32767) || (WCHAR_MAX == 65535) -# define EA_WCHAR_SIZE 2 -# elif (WCHAR_MAX == 127) || (WCHAR_MAX == 255) -# define EA_WCHAR_SIZE 1 -# else -# define EA_WCHAR_SIZE 4 -# endif -# elif defined(_WCMAX) // The SN and Arm compilers define this. -# if (_WCMAX == 2147483647) || (_WCMAX == 4294967295) -# define EA_WCHAR_SIZE 4 -# elif (_WCMAX == 32767) || (_WCMAX == 65535) -# define EA_WCHAR_SIZE 2 -# elif (_WCMAX == 127) || (_WCMAX == 255) -# define EA_WCHAR_SIZE 1 -# else -# define EA_WCHAR_SIZE 4 -# endif -# elif defined(EA_PLATFORM_UNIX) || defined(EA_PLATFORM_PS3) || defined(EA_PLATFORM_PS3_SPU) - // It is standard on Unix to have wchar_t be int32_t or uint32_t. - // All versions of GNUC default to a 32 bit wchar_t, but has been used - // with the -fshort-wchar GCC command line option to force it to 16 bit. - // If you know that the compiler is set to use a wchar_t of other than - // the default, you need to manually define EA_WCHAR_SIZE for the build. -# define EA_WCHAR_SIZE 4 -# else - // It is standard on Windows to have wchar_t be uint16_t. - // Metrowerks and the new EDG-based SN compilers define wchar_t - // as uint16_t. Given that there is currently no known way to tell at preprocessor - // time what the size of wchar_t is, we declare it to be 2. - // If you have EA_WCHAR_SIZE != sizeof(wchar_t), then your - // code might not be broken, but it also won't work with wchar libraries - // and data from other parts of EA. Under GCC, you can force wchar_t - // to two bytes with the -fshort-wchar compiler argument. -# define EA_WCHAR_SIZE 2 -# endif -#endif - - - // ------------------------------------------------------------------------ - // EA_RESTRICT - // - // The C99 standard defines a new keyword, restrict, which allows for the - // improvement of code generation regarding memory usage. Compilers can - // generate significantly faster code when you are able to use restrict. - // - // Example usage: - // void DoSomething(char* EA_RESTRICT p1, char* EA_RESTRICT p2); - // -#ifndef EA_RESTRICT -# if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // If VC8 (VS2005) or later... -# define EA_RESTRICT __restrict -# elif defined(EA_COMPILER_GNUC) -# define EA_RESTRICT __restrict // GCC defines 'restrict' (as opposed to __restrict) in C99 mode only. -# elif defined(EA_COMPILER_CLANG) -# define EA_RESTRICT __restrict -# elif defined(EA_COMPILER_GHS) -# define EA_RESTRICT restrict -# elif defined(__ARMCC_VERSION) -# define EA_RESTRICT __restrict -# elif defined(__MWERKS__) -# if __option(c99) -# define EA_RESTRICT restrict -# else -# define EA_RESTRICT -# endif -# elif defined(EA_COMPILER_IS_C99) -# define EA_RESTRICT restrict -# else - // If the compiler didn't support restricted pointers, defining EA_RESTRICT - // away would result in compiling and running fine but you just wouldn't - // the same level of optimization. On the other hand, all the major compilers - // support restricted pointers. -# define EA_RESTRICT -# endif -#endif - - - // ------------------------------------------------------------------------ - // EA_DEPRECATED // Used as a prefix. - // EA_PREFIX_DEPRECATED // You should need this only for unusual compilers. - // EA_POSTFIX_DEPRECATED // You should need this only for unusual compilers. - // - // Example usage: - // EA_DEPRECATED void Function(); - // - // or for maximum portability: - // EA_PREFIX_DEPRECATED void Function() EA_POSTFIX_DEPRECATED; - // -#ifndef EA_DEPRECATED -# if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION > 1300) // If VC7 (VS2003) or later... -# define EA_DEPRECATED __declspec(deprecated) -# elif defined(EA_COMPILER_MSVC) -# define EA_DEPRECATED -# else -# define EA_DEPRECATED __attribute__((deprecated)) -# endif + + +// ------------------------------------------------------------------------ +// EA_ANALYSIS_ASSUME +// +// This acts the same as the VC++ __analysis_assume directive and is implemented +// simply as a wrapper around it to allow portable usage of it and to take +// advantage of it if and when it appears in other compilers. +// +// Example usage: +// char Function(char* p) { +// EA_ANALYSIS_ASSUME(p != NULL); +// return *p; +// } +// +#ifndef EA_ANALYSIS_ASSUME +#if defined(_MSC_VER) && (_MSC_VER >= 1300) // If VC7.0 and later +#define EA_ANALYSIS_ASSUME(x) __analysis_assume(!!(x)) // !! because that allows for convertible-to-bool in addition to bool. +#else +#define EA_ANALYSIS_ASSUME(x) +#endif #endif -#ifndef EA_PREFIX_DEPRECATED -# if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION > 1300) // If VC7 (VS2003) or later... -# define EA_PREFIX_DEPRECATED __declspec(deprecated) -# define EA_POSTFIX_DEPRECATED -# elif defined(EA_COMPILER_MSVC) -# define EA_PREFIX_DEPRECATED -# define EA_POSTFIX_DEPRECATED -# else -# define EA_PREFIX_DEPRECATED -# define EA_POSTFIX_DEPRECATED __attribute__((deprecated)) -# endif -#endif - - - // ------------------------------------------------------------------------ - // EA_FORCE_INLINE // Used as a prefix. - // EA_PREFIX_FORCE_INLINE // You should need this only for unusual compilers. - // EA_POSTFIX_FORCE_INLINE // You should need this only for unusual compilers. - // - // Example usage: - // EA_FORCE_INLINE void Foo(); // Implementation elsewhere. - // EA_PREFIX_FORCE_INLINE void Foo() EA_POSTFIX_FORCE_INLINE; // Implementation elsewhere. - // - // Note that when the prefix version of this function is used, it replaces - // the regular C++ 'inline' statement. Thus you should not use both the - // C++ inline statement and this macro with the same function declaration. - // - // To force inline usage under GCC 3.1+, you use this: - // inline void Foo() __attribute__((always_inline)); - // or - // inline __attribute__((always_inline)) void Foo(); - // - // The CodeWarrior compiler doesn't have the concept of forcing inlining per function. - // -#ifndef EA_FORCE_INLINE -# if defined(EA_COMPILER_MSVC) -# define EA_FORCE_INLINE __forceinline -# elif defined(EA_COMPILER_GNUC) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 301) -# if defined(__cplusplus) -# define EA_FORCE_INLINE inline __attribute__((always_inline)) -# else -# define EA_FORCE_INLINE __inline__ __attribute__((always_inline)) -# endif -# elif defined(EA_COMPILER_CLANG) && __has_attribute(always_inline) -# if defined(__cplusplus) -# define EA_FORCE_INLINE inline __attribute__((always_inline)) -# else -# define EA_FORCE_INLINE __inline__ __attribute__((always_inline)) -# endif -# else -# if defined(__cplusplus) -# define EA_FORCE_INLINE inline -# else -# define EA_FORCE_INLINE __inline -# endif -# endif -#endif - -#if defined(EA_COMPILER_SN) && defined(EA_PLATFORM_PS3) // SN's implementation of always_inline is broken and sometimes fails to link the function. -# define EA_PREFIX_FORCE_INLINE inline -# define EA_POSTFIX_FORCE_INLINE -#elif defined(EA_COMPILER_GNUC) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 301) -# define EA_PREFIX_FORCE_INLINE inline -# define EA_POSTFIX_FORCE_INLINE __attribute__((always_inline)) -#else -# define EA_PREFIX_FORCE_INLINE inline -# define EA_POSTFIX_FORCE_INLINE -#endif - - - // ------------------------------------------------------------------------ - // EA_NO_INLINE // Used as a prefix. - // EA_PREFIX_NO_INLINE // You should need this only for unusual compilers. - // EA_POSTFIX_NO_INLINE // You should need this only for unusual compilers. - // - // Example usage: - // EA_NO_INLINE void Foo(); // Implementation elsewhere. - // EA_PREFIX_NO_INLINE void Foo() EA_POSTFIX_NO_INLINE; // Implementation elsewhere. - // - // That this declaration is incompatbile with C++ 'inline' and any - // variant of EA_FORCE_INLINE. - // - // To disable inline usage under VC++ priof to VS2005, you need to use this: - // #pragma inline_depth(0) // Disable inlining. - // void Foo() { ... } - // #pragma inline_depth() // Restore to default. - // - // Since there is no easy way to disable inlining on a function-by-function - // basis in VC++ prior to VS2005, the best strategy is to write platform-specific - // #ifdefs in the code or to disable inlining for a given module and enable - // functions individually with EA_FORCE_INLINE. - // -#ifndef EA_NO_INLINE -# if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // If VC8 (VS2005) or later... -# define EA_NO_INLINE __declspec(noinline) -# elif defined(EA_COMPILER_MSVC) -# define EA_NO_INLINE -# else -# define EA_NO_INLINE __attribute__((noinline)) -# endif + + +// ------------------------------------------------------------------------ +// EA_DISABLE_VC_WARNING / EA_RESTORE_VC_WARNING +// +// Disable and re-enable warning(s) within code. +// This is simply a wrapper for VC++ #pragma warning(disable: nnnn) for the +// purpose of making code easier to read due to avoiding nested compiler ifdefs +// directly in code. +// +// Example usage: +// EA_DISABLE_VC_WARNING(4127 3244) +// +// EA_RESTORE_VC_WARNING() +// +#ifndef EA_DISABLE_VC_WARNING +#if defined(_MSC_VER) +#define EA_DISABLE_VC_WARNING(w) \ + __pragma(warning(push)) \ + __pragma(warning(disable:w)) +#else +#define EA_DISABLE_VC_WARNING(w) +#endif #endif -#if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // If VC8 (VS2005) or later... -# define EA_PREFIX_NO_INLINE __declspec(noinline) -# define EA_POSTFIX_NO_INLINE -#elif defined(EA_COMPILER_MSVC) -# define EA_PREFIX_NO_INLINE -# define EA_POSTFIX_NO_INLINE -#else -# define EA_PREFIX_NO_INLINE -# define EA_POSTFIX_NO_INLINE __attribute__((noinline)) -#endif - - - // ------------------------------------------------------------------------ - // EA_NO_VTABLE - // - // Example usage: - // class EA_NO_VTABLE X { - // virtual void InterfaceFunction(); - // }; - // - // EA_CLASS_NO_VTABLE(X) { - // virtual void InterfaceFunction(); - // }; - // -#ifdef EA_COMPILER_MSVC -# define EA_NO_VTABLE __declspec(novtable) -# define EA_CLASS_NO_VTABLE(x) class __declspec(novtable) x -# define EA_STRUCT_NO_VTABLE(x) struct __declspec(novtable) x -#else -# define EA_NO_VTABLE -# define EA_CLASS_NO_VTABLE(x) class x -# define EA_STRUCT_NO_VTABLE(x) struct x -#endif - - - // ------------------------------------------------------------------------ - // EA_PASCAL - // - // Also known on PC platforms as stdcall. - // This convention causes the compiler to assume that the called function - // will pop off the stack space used to pass arguments, unless it takes a - // variable number of arguments. - // - // Example usage: - // this: - // void DoNothing(int x); - // void DoNothing(int x){} - // would be written as this: - // void EA_PASCAL_FUNC(DoNothing(int x)); - // void EA_PASCAL_FUNC(DoNothing(int x)){} - // -#ifndef EA_PASCAL -# if defined(EA_COMPILER_MSVC) -# define EA_PASCAL __stdcall -# elif defined(EA_COMPILER_GNUC) && defined(EA_PROCESSOR_X86) -# define EA_PASCAL __attribute__((stdcall)) -# elif defined(EA_COMPILER_METROWERKS) && defined(EA_PLATFORM_WINDOWS) - // You need to make sure you have the Metrowerks "ANSI keywords only' - // compilation option disabled for the pascal keyword to work. -# define EA_PASCAL pascal -# else - // Some compilers simply don't support pascal calling convention. - // As a result, there isn't an issue here, since the specification of - // pascal calling convention is for the purpose of disambiguating the - // calling convention that is applied. -# define EA_PASCAL -# endif +#ifndef EA_RESTORE_VC_WARNING +#if defined(_MSC_VER) +#define EA_RESTORE_VC_WARNING() \ + __pragma(warning(pop)) +#else +#define EA_RESTORE_VC_WARNING() +#endif #endif -#ifndef EA_PASCAL_FUNC -# if defined(EA_COMPILER_MSVC) -# define EA_PASCAL_FUNC(funcname_and_paramlist) __stdcall funcname_and_paramlist -# elif defined(EA_COMPILER_GNUC) && defined(EA_PROCESSOR_X86) -# define EA_PASCAL_FUNC(funcname_and_paramlist) __attribute__((stdcall)) funcname_and_paramlist -# elif defined(EA_COMPILER_METROWERKS) && defined(EA_PLATFORM_WINDOWS) -# define EA_PASCAL_FUNC(funcname_and_paramlist) pascal funcname_and_paramlist -# else -# define EA_PASCAL_FUNC(funcname_and_paramlist) funcname_and_paramlist -# endif -#endif - - - // ------------------------------------------------------------------------ - // EA_SSE - // Visual C Processor Packs define _MSC_FULL_VER and are needed for SSE - // Intel C also has SSE support. - // EA_SSE is used to select FPU or SSE versions in hw_select.inl -#ifndef EA_SSE -# if defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG) -# if defined(__SSE2__) -# define EA_SSE 2 -# elif defined(__SSE__) && __SSE__ -# define EA_SSE 1 -# else -# define EA_SSE 0 -# endif -# elif defined(EA_PROCESSOR_X86) && defined(_MSC_FULL_VER) && !defined(__NOSSE__) && defined(_M_IX86_FP) -# define EA_SSE _M_IX86_FP -# elif defined(EA_PROCESSOR_X86) && defined(EA_COMPILER_INTEL) && !defined(__NOSSE__) -# define EA_SSE 1 -# else -# define EA_SSE 0 -# endif -#endif - - - // ------------------------------------------------------------------------ - // EA_IMPORT - // import declaration specification - // specifies that the declared symbol is imported from another dynamic library. -#ifndef EA_IMPORT -# if defined(EA_COMPILER_MSVC) -# define EA_IMPORT __declspec(dllimport) -# else -# define EA_IMPORT -# endif + +// ------------------------------------------------------------------------ +// EA_ENABLE_VC_WARNING_AS_ERROR / EA_DISABLE_VC_WARNING_AS_ERROR +// +// Disable and re-enable treating a warning as error within code. +// This is simply a wrapper for VC++ #pragma warning(error: nnnn) for the +// purpose of making code easier to read due to avoiding nested compiler ifdefs +// directly in code. +// +// Example usage: +// EA_ENABLE_VC_WARNING_AS_ERROR(4996) +// +// EA_DISABLE_VC_WARNING_AS_ERROR() +// +#ifndef EA_ENABLE_VC_WARNING_AS_ERROR +#if defined(_MSC_VER) +#define EA_ENABLE_VC_WARNING_AS_ERROR(w) \ + __pragma(warning(push)) \ + __pragma(warning(error:w)) +#else +#define EA_ENABLE_VC_WARNING_AS_ERROR(w) +#endif +#endif + +#ifndef EA_DISABLE_VC_WARNING_AS_ERROR +#if defined(_MSC_VER) +#define EA_DISABLE_VC_WARNING_AS_ERROR() \ + __pragma(warning(pop)) +#else +#define EA_DISABLE_VC_WARNING_AS_ERROR() +#endif #endif - // ------------------------------------------------------------------------ - // EA_EXPORT - // export declaration specification - // specifies that the declared symbol is exported from the current dynamic library. - // this is not the same as the C++ export keyword. -#ifndef EA_EXPORT -# if defined(EA_COMPILER_MSVC) -# define EA_EXPORT __declspec(dllexport) -# else -# define EA_EXPORT -# endif -#endif - - - // ------------------------------------------------------------------------ - // EA_PRAGMA_ONCE_SUPPORTED - // - // This is a wrapper for the #pragma once preprocessor directive. - // It allows for some compilers (in particular VC++) to implement signifcantly - // faster include file preprocessing. #pragma once can be used to replace - // header include guards or to augment them. However, #pragma once isn't - // necessarily supported by all compilers and isn't guaranteed to be so in - // the future, so using #pragma once to replace traditional include guards - // is not strictly portable. Note that a direct #define for #pragma once is - // impossible with VC++, due to limitations, but can be done with other - // compilers/preprocessors via _Pragma("once"). - // - // Example usage (which includes traditional header guards for portability): - // #ifndef SOMEPACKAGE_SOMEHEADER_H - // #define SOMEPACKAGE_SOMEHEADER_H - // - // #if defined(EA_PRAGMA_ONCE_SUPPORTED) - // #pragma once - // #endif - // - // - // - // #endif - // -#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__GNUC__) || defined(__SNC__) || defined(__ICC) || defined(__ICL) || defined(__clang__) -# define EA_PRAGMA_ONCE_SUPPORTED 1 -#endif - - - // ------------------------------------------------------------------------ - // EA_OVERRIDE - // - // See http://msdn.microsoft.com/en-us/library/41w3sh1c.aspx for more information. - // -#ifndef EA_OVERRIDE -# if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // VS2005 (VC8) and later -# define EA_OVERRIDE override -# else -# define EA_OVERRIDE -# endif +// ------------------------------------------------------------------------ +// EA_DISABLE_GCC_WARNING / EA_RESTORE_GCC_WARNING +// +// Example usage: +// // Only one warning can be ignored per statement, due to how GCC works. +// EA_DISABLE_GCC_WARNING(-Wuninitialized) +// EA_DISABLE_GCC_WARNING(-Wunused) +// +// EA_RESTORE_GCC_WARNING() +// EA_RESTORE_GCC_WARNING() +// +#ifndef EA_DISABLE_GCC_WARNING +#if defined(EA_COMPILER_GNUC) +#define EAGCCWHELP0(x) #x +#define EAGCCWHELP1(x) EAGCCWHELP0(GCC diagnostic ignored x) +#define EAGCCWHELP2(x) EAGCCWHELP1(#x) #endif +#if defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION >= 4006) // Can't test directly for __GNUC__ because some compilers lie. +#define EA_DISABLE_GCC_WARNING(w) \ + _Pragma("GCC diagnostic push") \ + _Pragma(EAGCCWHELP2(w)) +#elif defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION >= 4004) +#define EA_DISABLE_GCC_WARNING(w) \ + _Pragma(EAGCCWHELP2(w)) +#else +#define EA_DISABLE_GCC_WARNING(w) +#endif +#endif - // ------------------------------------------------------------------------ - // EA_SEALED - // - // See http://msdn.microsoft.com/en-us/library/49k3w2fx%28VS.71%29.aspx for more information. - // -#ifndef EA_SEALED -# if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // VS2005 (VC8) and later -# define EA_SEALED sealed -# else -# define EA_SEALED -# endif +#ifndef EA_RESTORE_GCC_WARNING +#if defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION >= 4006) +#define EA_RESTORE_GCC_WARNING() \ + _Pragma("GCC diagnostic pop") +#else +#define EA_RESTORE_GCC_WARNING() +#endif #endif - // ------------------------------------------------------------------------ - // EA_ABSTRACT - // - // See http://msdn.microsoft.com/en-us/library/49k3w2fx%28VS.71%29.aspx for more information. - // -#ifndef EA_ABSTRACT -# if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // VS2005 (VC8) and later -# define EA_ABSTRACT abstract -# else -# define EA_ABSTRACT -# endif +// ------------------------------------------------------------------------ +// EA_DISABLE_ALL_GCC_WARNINGS / EA_RESTORE_ALL_GCC_WARNINGS +// +// This isn't possible except via using _Pragma("GCC system_header"), though +// that has some limitations in how it works. Another means is to manually +// disable individual warnings within a GCC diagnostic push statement. +// GCC doesn't have as many warnings as VC++ and EDG and so this may be feasible. +// ------------------------------------------------------------------------ + + +// ------------------------------------------------------------------------ +// EA_ENABLE_GCC_WARNING_AS_ERROR / EA_DISABLE_GCC_WARNING_AS_ERROR +// +// Example usage: +// // Only one warning can be treated as an error per statement, due to how GCC works. +// EA_ENABLE_GCC_WARNING_AS_ERROR(-Wuninitialized) +// EA_ENABLE_GCC_WARNING_AS_ERROR(-Wunused) +// +// EA_DISABLE_GCC_WARNING_AS_ERROR() +// EA_DISABLE_GCC_WARNING_AS_ERROR() +// +#ifndef EA_ENABLE_GCC_WARNING_AS_ERROR +#if defined(EA_COMPILER_GNUC) +#define EAGCCWERRORHELP0(x) #x +#define EAGCCWERRORHELP1(x) EAGCCWERRORHELP0(GCC diagnostic error x) +#define EAGCCWERRORHELP2(x) EAGCCWERRORHELP1(#x) +#endif + +#if defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION >= 4006) // Can't test directly for __GNUC__ because some compilers lie. +#define EA_ENABLE_GCC_WARNING_AS_ERROR(w) \ + _Pragma("GCC diagnostic push") \ + _Pragma(EAGCCWERRORHELP2(w)) +#elif defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION >= 4004) +#define EA_DISABLE_GCC_WARNING(w) \ + _Pragma(EAGCCWERRORHELP2(w)) +#else +#define EA_DISABLE_GCC_WARNING(w) +#endif +#endif + +#ifndef EA_DISABLE_GCC_WARNING_AS_ERROR +#if defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION >= 4006) +#define EA_DISABLE_GCC_WARNING_AS_ERROR() \ + _Pragma("GCC diagnostic pop") +#else +#define EA_DISABLE_GCC_WARNING_AS_ERROR() +#endif #endif -#endif // Header include guard +// ------------------------------------------------------------------------ +// EA_DISABLE_CLANG_WARNING / EA_RESTORE_CLANG_WARNING +// +// Example usage: +// // Only one warning can be ignored per statement, due to how clang works. +// EA_DISABLE_CLANG_WARNING(-Wuninitialized) +// EA_DISABLE_CLANG_WARNING(-Wunused) +// +// EA_RESTORE_CLANG_WARNING() +// EA_RESTORE_CLANG_WARNING() +// +#ifndef EA_DISABLE_CLANG_WARNING +#if defined(EA_COMPILER_CLANG) || defined(EA_COMPILER_CLANG_CL) +#define EACLANGWHELP0(x) #x +#define EACLANGWHELP1(x) EACLANGWHELP0(clang diagnostic ignored x) +#define EACLANGWHELP2(x) EACLANGWHELP1(#x) + +#define EA_DISABLE_CLANG_WARNING(w) \ + _Pragma("clang diagnostic push") \ + _Pragma(EACLANGWHELP2(-Wunknown-warning-option))\ + _Pragma(EACLANGWHELP2(w)) +#else +#define EA_DISABLE_CLANG_WARNING(w) +#endif +#endif + +#ifndef EA_RESTORE_CLANG_WARNING +#if defined(EA_COMPILER_CLANG) || defined(EA_COMPILER_CLANG_CL) +#define EA_RESTORE_CLANG_WARNING() \ + _Pragma("clang diagnostic pop") +#else +#define EA_RESTORE_CLANG_WARNING() +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_DISABLE_ALL_CLANG_WARNINGS / EA_RESTORE_ALL_CLANG_WARNINGS +// +// The situation for clang is the same as for GCC. See above. +// ------------------------------------------------------------------------ + + +// ------------------------------------------------------------------------ +// EA_ENABLE_CLANG_WARNING_AS_ERROR / EA_DISABLE_CLANG_WARNING_AS_ERROR +// +// Example usage: +// // Only one warning can be treated as an error per statement, due to how clang works. +// EA_ENABLE_CLANG_WARNING_AS_ERROR(-Wuninitialized) +// EA_ENABLE_CLANG_WARNING_AS_ERROR(-Wunused) +// +// EA_DISABLE_CLANG_WARNING_AS_ERROR() +// EA_DISABLE_CLANG_WARNING_AS_ERROR() +// +#ifndef EA_ENABLE_CLANG_WARNING_AS_ERROR +#if defined(EA_COMPILER_CLANG) || defined(EA_COMPILER_CLANG_CL) +#define EACLANGWERRORHELP0(x) #x +#define EACLANGWERRORHELP1(x) EACLANGWERRORHELP0(clang diagnostic error x) +#define EACLANGWERRORHELP2(x) EACLANGWERRORHELP1(#x) + +#define EA_ENABLE_CLANG_WARNING_AS_ERROR(w) \ + _Pragma("clang diagnostic push") \ + _Pragma(EACLANGWERRORHELP2(w)) +#else +#define EA_DISABLE_CLANG_WARNING(w) +#endif +#endif + +#ifndef EA_DISABLE_CLANG_WARNING_AS_ERROR +#if defined(EA_COMPILER_CLANG) || defined(EA_COMPILER_CLANG_CL) +#define EA_DISABLE_CLANG_WARNING_AS_ERROR() \ + _Pragma("clang diagnostic pop") +#else +#define EA_DISABLE_CLANG_WARNING_AS_ERROR() +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_DISABLE_SN_WARNING / EA_RESTORE_SN_WARNING +// +// Note that we define this macro specifically for the SN compiler instead of +// having a generic one for EDG-based compilers. The reason for this is that +// while SN is indeed based on EDG, SN has different warning value mappings +// and thus warning 1234 for SN is not the same as 1234 for all other EDG compilers. +// +// Example usage: +// // Currently we are limited to one warning per line. +// EA_DISABLE_SN_WARNING(1787) +// EA_DISABLE_SN_WARNING(552) +// +// EA_RESTORE_SN_WARNING() +// EA_RESTORE_SN_WARNING() +// +#ifndef EA_DISABLE_SN_WARNING +#define EA_DISABLE_SN_WARNING(w) +#endif + +#ifndef EA_RESTORE_SN_WARNING +#define EA_RESTORE_SN_WARNING() +#endif + + +// ------------------------------------------------------------------------ +// EA_DISABLE_ALL_SN_WARNINGS / EA_RESTORE_ALL_SN_WARNINGS +// +// Example usage: +// EA_DISABLE_ALL_SN_WARNINGS() +// +// EA_RESTORE_ALL_SN_WARNINGS() +// +#ifndef EA_DISABLE_ALL_SN_WARNINGS +#define EA_DISABLE_ALL_SN_WARNINGS() +#endif + +#ifndef EA_RESTORE_ALL_SN_WARNINGS +#define EA_RESTORE_ALL_SN_WARNINGS() +#endif + + + +// ------------------------------------------------------------------------ +// EA_DISABLE_GHS_WARNING / EA_RESTORE_GHS_WARNING +// +// Disable warnings from the Green Hills compiler. +// +// Example usage: +// EA_DISABLE_GHS_WARNING(193) +// EA_DISABLE_GHS_WARNING(236, 5323) +// +// EA_RESTORE_GHS_WARNING() +// EA_RESTORE_GHS_WARNING() +// +#ifndef EA_DISABLE_GHS_WARNING +#define EA_DISABLE_GHS_WARNING(w) +#endif + +#ifndef EA_RESTORE_GHS_WARNING +#define EA_RESTORE_GHS_WARNING() +#endif + + +// ------------------------------------------------------------------------ +// EA_DISABLE_ALL_GHS_WARNINGS / EA_RESTORE_ALL_GHS_WARNINGS +// +// #ifndef EA_DISABLE_ALL_GHS_WARNINGS +// #if defined(EA_COMPILER_GREEN_HILLS) +// #define EA_DISABLE_ALL_GHS_WARNINGS(w) \_ +// _Pragma("_________") +// #else +// #define EA_DISABLE_ALL_GHS_WARNINGS(w) +// #endif +// #endif +// +// #ifndef EA_RESTORE_ALL_GHS_WARNINGS +// #if defined(EA_COMPILER_GREEN_HILLS) +// #define EA_RESTORE_ALL_GHS_WARNINGS() \_ +// _Pragma("_________") +// #else +// #define EA_RESTORE_ALL_GHS_WARNINGS() +// #endif +// #endif + + + +// ------------------------------------------------------------------------ +// EA_DISABLE_EDG_WARNING / EA_RESTORE_EDG_WARNING +// +// Example usage: +// // Currently we are limited to one warning per line. +// EA_DISABLE_EDG_WARNING(193) +// EA_DISABLE_EDG_WARNING(236) +// +// EA_RESTORE_EDG_WARNING() +// EA_RESTORE_EDG_WARNING() +// +#ifndef EA_DISABLE_EDG_WARNING +// EDG-based compilers are inconsistent in how the implement warning pragmas. +#if defined(EA_COMPILER_EDG) && !defined(EA_COMPILER_INTEL) && !defined(EA_COMPILER_RVCT) +#define EAEDGWHELP0(x) #x +#define EAEDGWHELP1(x) EAEDGWHELP0(diag_suppress x) + +#define EA_DISABLE_EDG_WARNING(w) \ + _Pragma("control %push diag") \ + _Pragma(EAEDGWHELP1(w)) +#else +#define EA_DISABLE_EDG_WARNING(w) +#endif +#endif + +#ifndef EA_RESTORE_EDG_WARNING +#if defined(EA_COMPILER_EDG) && !defined(EA_COMPILER_INTEL) && !defined(EA_COMPILER_RVCT) +#define EA_RESTORE_EDG_WARNING() \ + _Pragma("control %pop diag") +#else +#define EA_RESTORE_EDG_WARNING() +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_DISABLE_ALL_EDG_WARNINGS / EA_RESTORE_ALL_EDG_WARNINGS +// +//#ifndef EA_DISABLE_ALL_EDG_WARNINGS +// #if defined(EA_COMPILER_EDG) && !defined(EA_COMPILER_SN) +// #define EA_DISABLE_ALL_EDG_WARNINGS(w) \_ +// _Pragma("_________") +// #else +// #define EA_DISABLE_ALL_EDG_WARNINGS(w) +// #endif +//#endif +// +//#ifndef EA_RESTORE_ALL_EDG_WARNINGS +// #if defined(EA_COMPILER_EDG) && !defined(EA_COMPILER_SN) +// #define EA_RESTORE_ALL_EDG_WARNINGS() \_ +// _Pragma("_________") +// #else +// #define EA_RESTORE_ALL_EDG_WARNINGS() +// #endif +//#endif + + + +// ------------------------------------------------------------------------ +// EA_DISABLE_CW_WARNING / EA_RESTORE_CW_WARNING +// +// Note that this macro can only control warnings via numbers and not by +// names. The reason for this is that the compiler's syntax for such +// warnings is not the same as for numbers. +// +// Example usage: +// // Currently we are limited to one warning per line and must also specify the warning in the restore macro. +// EA_DISABLE_CW_WARNING(10317) +// EA_DISABLE_CW_WARNING(10324) +// +// EA_RESTORE_CW_WARNING(10317) +// EA_RESTORE_CW_WARNING(10324) +// +#ifndef EA_DISABLE_CW_WARNING +#define EA_DISABLE_CW_WARNING(w) +#endif + +#ifndef EA_RESTORE_CW_WARNING + +#define EA_RESTORE_CW_WARNING(w) + +#endif + + +// ------------------------------------------------------------------------ +// EA_DISABLE_ALL_CW_WARNINGS / EA_RESTORE_ALL_CW_WARNINGS +// +#ifndef EA_DISABLE_ALL_CW_WARNINGS +#define EA_DISABLE_ALL_CW_WARNINGS() + +#endif + +#ifndef EA_RESTORE_ALL_CW_WARNINGS +#define EA_RESTORE_ALL_CW_WARNINGS() +#endif + + + +// ------------------------------------------------------------------------ +// EA_PURE +// +// This acts the same as the GCC __attribute__ ((pure)) directive and is +// implemented simply as a wrapper around it to allow portable usage of +// it and to take advantage of it if and when it appears in other compilers. +// +// A "pure" function is one that has no effects except its return value and +// its return value is a function of only the function's parameters or +// non-volatile global variables. Any parameter or global variable access +// must be read-only. Loop optimization and subexpression elimination can be +// applied to such functions. A common example is strlen(): Given identical +// inputs, the function's return value (its only effect) is invariant across +// multiple invocations and thus can be pulled out of a loop and called but once. +// +// Example usage: +// EA_PURE void Function(); +// +#ifndef EA_PURE +#if defined(EA_COMPILER_GNUC) +#define EA_PURE __attribute__((pure)) +#elif defined(EA_COMPILER_ARM) // Arm brand compiler for ARM CPU +#define EA_PURE __pure +#else +#define EA_PURE +#endif +#endif + + + +// ------------------------------------------------------------------------ +// EA_WEAK +// EA_WEAK_SUPPORTED -- defined as 0 or 1. +// +// GCC +// The weak attribute causes the declaration to be emitted as a weak +// symbol rather than a global. This is primarily useful in defining +// library functions which can be overridden in user code, though it +// can also be used with non-function declarations. +// +// VC++ +// At link time, if multiple definitions of a COMDAT are seen, the linker +// picks one and discards the rest. If the linker option /OPT:REF +// is selected, then COMDAT elimination will occur to remove all the +// unreferenced data items in the linker output. +// +// Example usage: +// EA_WEAK void Function(); +// +#ifndef EA_WEAK +#if defined(_MSC_VER) && (_MSC_VER >= 1300) // If VC7.0 and later +#define EA_WEAK __declspec(selectany) +#define EA_WEAK_SUPPORTED 1 +#elif defined(_MSC_VER) || (defined(__GNUC__) && defined(__CYGWIN__)) +#define EA_WEAK +#define EA_WEAK_SUPPORTED 0 +#elif defined(EA_COMPILER_ARM) // Arm brand compiler for ARM CPU +#define EA_WEAK __weak +#define EA_WEAK_SUPPORTED 1 +#else // GCC and IBM compilers, others. +#define EA_WEAK __attribute__((weak)) +#define EA_WEAK_SUPPORTED 1 +#endif +#endif + + + +// ------------------------------------------------------------------------ +// EA_UNUSED +// +// Makes compiler warnings about unused variables go away. +// +// Example usage: +// void Function(int x) +// { +// int y; +// EA_UNUSED(x); +// EA_UNUSED(y); +// } +// +#ifndef EA_UNUSED +// The EDG solution below is pretty weak and needs to be augmented or replaced. +// It can't handle the C language, is limited to places where template declarations +// can be used, and requires the type x to be usable as a functions reference argument. +#if defined(__cplusplus) && defined(__EDG__) +template +inline void EABaseUnused(T const volatile & x) { (void)x; } +#define EA_UNUSED(x) EABaseUnused(x) +#else +#define EA_UNUSED(x) (void)x +#endif +#endif + + + +// ------------------------------------------------------------------------ +// EA_EMPTY +// +// Allows for a null statement, usually for the purpose of avoiding compiler warnings. +// +// Example usage: +// #ifdef EA_DEBUG +// #define MyDebugPrintf(x, y) printf(x, y) +// #else +// #define MyDebugPrintf(x, y) EA_EMPTY +// #endif +// +#ifndef EA_EMPTY +#define EA_EMPTY (void)0 +#endif + + +// ------------------------------------------------------------------------ +// EA_CURRENT_FUNCTION +// +// Provides a consistent way to get the current function name as a macro +// like the __FILE__ and __LINE__ macros work. The C99 standard specifies +// that __func__ be provided by the compiler, but most compilers don't yet +// follow that convention. However, many compilers have an alternative. +// +// We also define EA_CURRENT_FUNCTION_SUPPORTED for when it is not possible +// to have EA_CURRENT_FUNCTION work as expected. +// +// Defined inside a function because otherwise the macro might not be +// defined and code below might not compile. This happens with some +// compilers. +// +#ifndef EA_CURRENT_FUNCTION +#if defined __GNUC__ || (defined __ICC && __ICC >= 600) +#define EA_CURRENT_FUNCTION __PRETTY_FUNCTION__ +#elif defined(__FUNCSIG__) +#define EA_CURRENT_FUNCTION __FUNCSIG__ +#elif (defined __INTEL_COMPILER && __INTEL_COMPILER >= 600) || (defined __IBMCPP__ && __IBMCPP__ >= 500) || (defined CS_UNDEFINED_STRING && CS_UNDEFINED_STRING >= 0x4200) +#define EA_CURRENT_FUNCTION __FUNCTION__ +#elif defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901 +#define EA_CURRENT_FUNCTION __func__ +#else +#define EA_CURRENT_FUNCTION "(unknown function)" +#endif +#endif + + +// ------------------------------------------------------------------------ +// wchar_t +// Here we define: +// EA_WCHAR_T_NON_NATIVE +// EA_WCHAR_SIZE = +// +#ifndef EA_WCHAR_T_NON_NATIVE +// Compilers that always implement wchar_t as native include: +// COMEAU, new SN, and other EDG-based compilers. +// GCC +// Borland +// SunPro +// IBM Visual Age +#if defined(EA_COMPILER_INTEL) +#if (EA_COMPILER_VERSION < 700) +#define EA_WCHAR_T_NON_NATIVE 1 +#else +#if (!defined(_WCHAR_T_DEFINED) && !defined(_WCHAR_T)) +#define EA_WCHAR_T_NON_NATIVE 1 +#endif +#endif +#elif defined(EA_COMPILER_MSVC) || (defined(EA_COMPILER_CLANG) && defined(EA_PLATFORM_WINDOWS)) +#ifndef _NATIVE_WCHAR_T_DEFINED +#define EA_WCHAR_T_NON_NATIVE 1 +#endif +#elif defined(__EDG_VERSION__) && (!defined(_WCHAR_T) && (__EDG_VERSION__ < 400)) // EDG prior to v4 uses _WCHAR_T to indicate if wchar_t is native. v4+ may define something else, but we're not currently aware of it. +#define EA_WCHAR_T_NON_NATIVE 1 +#endif +#endif + +#ifndef EA_WCHAR_SIZE // If the user hasn't specified that it is a given size... +#if defined(__WCHAR_MAX__) // GCC defines this for most platforms. +#if (__WCHAR_MAX__ == 2147483647) || (__WCHAR_MAX__ == 4294967295) +#define EA_WCHAR_SIZE 4 +#elif (__WCHAR_MAX__ == 32767) || (__WCHAR_MAX__ == 65535) +#define EA_WCHAR_SIZE 2 +#elif (__WCHAR_MAX__ == 127) || (__WCHAR_MAX__ == 255) +#define EA_WCHAR_SIZE 1 +#else +#define EA_WCHAR_SIZE 4 +#endif +#elif defined(WCHAR_MAX) // The SN and Arm compilers define this. +#if (WCHAR_MAX == 2147483647) || (WCHAR_MAX == 4294967295) +#define EA_WCHAR_SIZE 4 +#elif (WCHAR_MAX == 32767) || (WCHAR_MAX == 65535) +#define EA_WCHAR_SIZE 2 +#elif (WCHAR_MAX == 127) || (WCHAR_MAX == 255) +#define EA_WCHAR_SIZE 1 +#else +#define EA_WCHAR_SIZE 4 +#endif +#elif defined(__WCHAR_BIT) // Green Hills (and other versions of EDG?) uses this. +#if (__WCHAR_BIT == 16) +#define EA_WCHAR_SIZE 2 +#elif (__WCHAR_BIT == 32) +#define EA_WCHAR_SIZE 4 +#elif (__WCHAR_BIT == 8) +#define EA_WCHAR_SIZE 1 +#else +#define EA_WCHAR_SIZE 4 +#endif +#elif defined(_WCMAX) // The SN and Arm compilers define this. +#if (_WCMAX == 2147483647) || (_WCMAX == 4294967295) +#define EA_WCHAR_SIZE 4 +#elif (_WCMAX == 32767) || (_WCMAX == 65535) +#define EA_WCHAR_SIZE 2 +#elif (_WCMAX == 127) || (_WCMAX == 255) +#define EA_WCHAR_SIZE 1 +#else +#define EA_WCHAR_SIZE 4 +#endif +#elif defined(EA_PLATFORM_UNIX) +// It is standard on Unix to have wchar_t be int32_t or uint32_t. +// All versions of GNUC default to a 32 bit wchar_t, but EA has used +// the -fshort-wchar GCC command line option to force it to 16 bit. +// If you know that the compiler is set to use a wchar_t of other than +// the default, you need to manually define EA_WCHAR_SIZE for the build. +#define EA_WCHAR_SIZE 4 +#else +// It is standard on Windows to have wchar_t be uint16_t. GCC +// defines wchar_t as int by default. Electronic Arts has +// standardized on wchar_t being an unsigned 16 bit value on all +// console platforms. Given that there is currently no known way to +// tell at preprocessor time what the size of wchar_t is, we declare +// it to be 2, as this is the Electronic Arts standard. If you have +// EA_WCHAR_SIZE != sizeof(wchar_t), then your code might not be +// broken, but it also won't work with wchar libraries and data from +// other parts of EA. Under GCC, you can force wchar_t to two bytes +// with the -fshort-wchar compiler argument. +#define EA_WCHAR_SIZE 2 +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_RESTRICT +// +// The C99 standard defines a new keyword, restrict, which allows for the +// improvement of code generation regarding memory usage. Compilers can +// generate significantly faster code when you are able to use restrict. +// +// Example usage: +// void DoSomething(char* EA_RESTRICT p1, char* EA_RESTRICT p2); +// +#ifndef EA_RESTRICT +#if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // If VC8 (VS2005) or later... +#define EA_RESTRICT __restrict +#elif defined(EA_COMPILER_CLANG) +#define EA_RESTRICT __restrict +#elif defined(EA_COMPILER_GNUC) // Includes GCC and other compilers emulating GCC. +#define EA_RESTRICT __restrict // GCC defines 'restrict' (as opposed to __restrict) in C99 mode only. +#elif defined(EA_COMPILER_ARM) +#define EA_RESTRICT __restrict +#elif defined(EA_COMPILER_IS_C99) +#define EA_RESTRICT restrict +#else +// If the compiler didn't support restricted pointers, defining EA_RESTRICT +// away would result in compiling and running fine but you just wouldn't +// the same level of optimization. On the other hand, all the major compilers +// support restricted pointers. +#define EA_RESTRICT +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_DEPRECATED // Used as a prefix. +// EA_PREFIX_DEPRECATED // You should need this only for unusual compilers. +// EA_POSTFIX_DEPRECATED // You should need this only for unusual compilers. +// EA_DEPRECATED_MESSAGE // Used as a prefix and provides a deprecation message. +// +// Example usage: +// EA_DEPRECATED void Function(); +// EA_DEPRECATED_MESSAGE("Use 1.0v API instead") void Function(); +// +// or for maximum portability: +// EA_PREFIX_DEPRECATED void Function() EA_POSTFIX_DEPRECATED; +// + +#ifndef EA_DEPRECATED +#if defined(EA_COMPILER_CPP14_ENABLED) +#define EA_DEPRECATED [[deprecated]] +#elif defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION > 1300) // If VC7 (VS2003) or later... +#define EA_DEPRECATED __declspec(deprecated) +#elif defined(EA_COMPILER_MSVC) +#define EA_DEPRECATED +#else +#define EA_DEPRECATED __attribute__((deprecated)) +#endif +#endif + +#ifndef EA_PREFIX_DEPRECATED +#if defined(EA_COMPILER_CPP14_ENABLED) +#define EA_PREFIX_DEPRECATED [[deprecated]] +#define EA_POSTFIX_DEPRECATED +#elif defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION > 1300) // If VC7 (VS2003) or later... +#define EA_PREFIX_DEPRECATED __declspec(deprecated) +#define EA_POSTFIX_DEPRECATED +#elif defined(EA_COMPILER_MSVC) +#define EA_PREFIX_DEPRECATED +#define EA_POSTFIX_DEPRECATED +#else +#define EA_PREFIX_DEPRECATED +#define EA_POSTFIX_DEPRECATED __attribute__((deprecated)) +#endif +#endif + +#ifndef EA_DEPRECATED_MESSAGE +#if defined(EA_COMPILER_CPP14_ENABLED) +#define EA_DEPRECATED_MESSAGE(msg) [[deprecated(#msg)]] +#else +// Compiler does not support depreaction messages, explicitly drop the msg but still mark the function as deprecated +#define EA_DEPRECATED_MESSAGE(msg) EA_DEPRECATED +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_FORCE_INLINE // Used as a prefix. +// EA_PREFIX_FORCE_INLINE // You should need this only for unusual compilers. +// EA_POSTFIX_FORCE_INLINE // You should need this only for unusual compilers. +// +// Example usage: +// EA_FORCE_INLINE void Foo(); // Implementation elsewhere. +// EA_PREFIX_FORCE_INLINE void Foo() EA_POSTFIX_FORCE_INLINE; // Implementation elsewhere. +// +// Note that when the prefix version of this function is used, it replaces +// the regular C++ 'inline' statement. Thus you should not use both the +// C++ inline statement and this macro with the same function declaration. +// +// To force inline usage under GCC 3.1+, you use this: +// inline void Foo() __attribute__((always_inline)); +// or +// inline __attribute__((always_inline)) void Foo(); +// +// The CodeWarrior compiler doesn't have the concept of forcing inlining per function. +// +#ifndef EA_FORCE_INLINE +#if defined(EA_COMPILER_MSVC) +#define EA_FORCE_INLINE __forceinline +#elif defined(EA_COMPILER_GNUC) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 301) || defined(EA_COMPILER_CLANG) +#if defined(__cplusplus) +#define EA_FORCE_INLINE inline __attribute__((always_inline)) +#else +#define EA_FORCE_INLINE __inline__ __attribute__((always_inline)) +#endif +#else +#if defined(__cplusplus) +#define EA_FORCE_INLINE inline +#else +#define EA_FORCE_INLINE __inline +#endif +#endif +#endif + +#if defined(EA_COMPILER_GNUC) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 301) || defined(EA_COMPILER_CLANG) +#define EA_PREFIX_FORCE_INLINE inline +#define EA_POSTFIX_FORCE_INLINE __attribute__((always_inline)) +#else +#define EA_PREFIX_FORCE_INLINE inline +#define EA_POSTFIX_FORCE_INLINE +#endif + + +// ------------------------------------------------------------------------ +// EA_FORCE_INLINE_LAMBDA +// +// EA_FORCE_INLINE_LAMBDA is used to force inline a call to a lambda when possible. +// Force inlining a lambda can be useful to reduce overhead in situations where a lambda may +// may only be called once, or inlining allows the compiler to apply other optimizations that wouldn't +// otherwise be possible. +// +// The ability to force inline a lambda is currently only available on a subset of compilers. +// +// Example usage: +// +// auto lambdaFunction = []() EA_FORCE_INLINE_LAMBDA +// { +// }; +// +#ifndef EA_FORCE_INLINE_LAMBDA +#if defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG) +#define EA_FORCE_INLINE_LAMBDA __attribute__((always_inline)) +#else +#define EA_FORCE_INLINE_LAMBDA +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_NO_INLINE // Used as a prefix. +// EA_PREFIX_NO_INLINE // You should need this only for unusual compilers. +// EA_POSTFIX_NO_INLINE // You should need this only for unusual compilers. +// +// Example usage: +// EA_NO_INLINE void Foo(); // Implementation elsewhere. +// EA_PREFIX_NO_INLINE void Foo() EA_POSTFIX_NO_INLINE; // Implementation elsewhere. +// +// That this declaration is incompatbile with C++ 'inline' and any +// variant of EA_FORCE_INLINE. +// +// To disable inline usage under VC++ priof to VS2005, you need to use this: +// #pragma inline_depth(0) // Disable inlining. +// void Foo() { ... } +// #pragma inline_depth() // Restore to default. +// +// Since there is no easy way to disable inlining on a function-by-function +// basis in VC++ prior to VS2005, the best strategy is to write platform-specific +// #ifdefs in the code or to disable inlining for a given module and enable +// functions individually with EA_FORCE_INLINE. +// +#ifndef EA_NO_INLINE +#if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // If VC8 (VS2005) or later... +#define EA_NO_INLINE __declspec(noinline) +#elif defined(EA_COMPILER_MSVC) +#define EA_NO_INLINE +#else +#define EA_NO_INLINE __attribute__((noinline)) +#endif +#endif + +#if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // If VC8 (VS2005) or later... +#define EA_PREFIX_NO_INLINE __declspec(noinline) +#define EA_POSTFIX_NO_INLINE +#elif defined(EA_COMPILER_MSVC) +#define EA_PREFIX_NO_INLINE +#define EA_POSTFIX_NO_INLINE +#else +#define EA_PREFIX_NO_INLINE +#define EA_POSTFIX_NO_INLINE __attribute__((noinline)) +#endif + + +// ------------------------------------------------------------------------ +// EA_NO_VTABLE +// +// Example usage: +// class EA_NO_VTABLE X { +// virtual void InterfaceFunction(); +// }; +// +// EA_CLASS_NO_VTABLE(X) { +// virtual void InterfaceFunction(); +// }; +// +#ifdef EA_COMPILER_MSVC +#define EA_NO_VTABLE __declspec(novtable) +#define EA_CLASS_NO_VTABLE(x) class __declspec(novtable) x +#define EA_STRUCT_NO_VTABLE(x) struct __declspec(novtable) x +#else +#define EA_NO_VTABLE +#define EA_CLASS_NO_VTABLE(x) class x +#define EA_STRUCT_NO_VTABLE(x) struct x +#endif + + +// ------------------------------------------------------------------------ +// EA_PASCAL +// +// Also known on PC platforms as stdcall. +// This convention causes the compiler to assume that the called function +// will pop off the stack space used to pass arguments, unless it takes a +// variable number of arguments. +// +// Example usage: +// this: +// void DoNothing(int x); +// void DoNothing(int x){} +// would be written as this: +// void EA_PASCAL_FUNC(DoNothing(int x)); +// void EA_PASCAL_FUNC(DoNothing(int x)){} +// +#ifndef EA_PASCAL +#if defined(EA_COMPILER_MSVC) +#define EA_PASCAL __stdcall +#elif defined(EA_COMPILER_GNUC) && defined(EA_PROCESSOR_X86) +#define EA_PASCAL __attribute__((stdcall)) +#else +// Some compilers simply don't support pascal calling convention. +// As a result, there isn't an issue here, since the specification of +// pascal calling convention is for the purpose of disambiguating the +// calling convention that is applied. +#define EA_PASCAL +#endif +#endif + +#ifndef EA_PASCAL_FUNC +#if defined(EA_COMPILER_MSVC) +#define EA_PASCAL_FUNC(funcname_and_paramlist) __stdcall funcname_and_paramlist +#elif defined(EA_COMPILER_GNUC) && defined(EA_PROCESSOR_X86) +#define EA_PASCAL_FUNC(funcname_and_paramlist) __attribute__((stdcall)) funcname_and_paramlist +#else +#define EA_PASCAL_FUNC(funcname_and_paramlist) funcname_and_paramlist +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_SSE +// Visual C Processor Packs define _MSC_FULL_VER and are needed for SSE +// Intel C also has SSE support. +// EA_SSE is used to select FPU or SSE versions in hw_select.inl +// +// EA_SSE defines the level of SSE support: +// 0 indicates no SSE support +// 1 indicates SSE1 is supported +// 2 indicates SSE2 is supported +// 3 indicates SSE3 (or greater) is supported +// +// Note: SSE support beyond SSE3 can't be properly represented as a single +// version number. Instead users should use specific SSE defines (e.g. +// EA_SSE4_2) to detect what specific support is available. EA_SSE being +// equal to 3 really only indicates that SSE3 or greater is supported. +#ifndef EA_SSE +#if defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG) +#if defined(__SSE3__) +#define EA_SSE 3 +#elif defined(__SSE2__) +#define EA_SSE 2 +#elif defined(__SSE__) && __SSE__ +#define EA_SSE 1 +#else +#define EA_SSE 0 +#endif +#elif (defined(EA_SSE3) && EA_SSE3) || defined EA_PLATFORM_XBOXONE || defined CS_UNDEFINED_STRING +#define EA_SSE 3 +#elif defined(EA_SSE2) && EA_SSE2 +#define EA_SSE 2 +#elif defined(EA_PROCESSOR_X86) && defined(_MSC_FULL_VER) && !defined(__NOSSE__) && defined(_M_IX86_FP) +#define EA_SSE _M_IX86_FP +#elif defined(EA_PROCESSOR_X86) && defined(EA_COMPILER_INTEL) && !defined(__NOSSE__) +#define EA_SSE 1 +#elif defined(EA_PROCESSOR_X86_64) +// All x64 processors support SSE2 or higher +#define EA_SSE 2 +#else +#define EA_SSE 0 +#endif +#endif + +// ------------------------------------------------------------------------ +// We define separate defines for SSE support beyond SSE1. These defines +// are particularly useful for detecting SSE4.x features since there isn't +// a single concept of SSE4. +// +// The following SSE defines are always defined. 0 indicates the +// feature/level of SSE is not supported, and 1 indicates support is +// available. +#ifndef EA_SSE2 +#if EA_SSE >= 2 +#define EA_SSE2 1 +#else +#define EA_SSE2 0 +#endif +#endif +#ifndef EA_SSE3 +#if EA_SSE >= 3 +#define EA_SSE3 1 +#else +#define EA_SSE3 0 +#endif +#endif +#ifndef EA_SSSE3 +#if defined __SSSE3__ || defined EA_PLATFORM_XBOXONE || defined CS_UNDEFINED_STRING +#define EA_SSSE3 1 +#else +#define EA_SSSE3 0 +#endif +#endif +#ifndef EA_SSE4_1 +#if defined __SSE4_1__ || defined EA_PLATFORM_XBOXONE || defined CS_UNDEFINED_STRING +#define EA_SSE4_1 1 +#else +#define EA_SSE4_1 0 +#endif +#endif +#ifndef EA_SSE4_2 +#if defined __SSE4_2__ || defined EA_PLATFORM_XBOXONE || defined CS_UNDEFINED_STRING +#define EA_SSE4_2 1 +#else +#define EA_SSE4_2 0 +#endif +#endif +#ifndef EA_SSE4A +#if defined __SSE4A__ || defined EA_PLATFORM_XBOXONE || defined CS_UNDEFINED_STRING +#define EA_SSE4A 1 +#else +#define EA_SSE4A 0 +#endif +#endif + +// ------------------------------------------------------------------------ +// EA_AVX +// EA_AVX may be used to determine if Advanced Vector Extensions are available for the target architecture +// +// EA_AVX defines the level of AVX support: +// 0 indicates no AVX support +// 1 indicates AVX1 is supported +// 2 indicates AVX2 is supported +#ifndef EA_AVX +#if defined __AVX2__ +#define EA_AVX 2 +#elif defined __AVX__ || defined EA_PLATFORM_XBOXONE || defined CS_UNDEFINED_STRING +#define EA_AVX 1 +#else +#define EA_AVX 0 +#endif +#endif +#ifndef EA_AVX2 +#if EA_AVX >= 2 +#define EA_AVX2 1 +#else +#define EA_AVX2 0 +#endif +#endif + +// EA_FP16C may be used to determine the existence of float <-> half conversion operations on an x86 CPU. +// (For example to determine if _mm_cvtph_ps or _mm_cvtps_ph could be used.) +#ifndef EA_FP16C +#if defined __F16C__ || defined EA_PLATFORM_XBOXONE || defined CS_UNDEFINED_STRING +#define EA_FP16C 1 +#else +#define EA_FP16C 0 +#endif +#endif + +// EA_FP128 may be used to determine if __float128 is a supported type for use. This type is enabled by a GCC extension (_GLIBCXX_USE_FLOAT128) +// but has support by some implementations of clang (__FLOAT128__) +// PS4 does not support __float128 as of SDK 5.500 https://ps4.siedev.net/resources/documents/SDK/5.500/CPU_Compiler_ABI-Overview/0003.html +#ifndef EA_FP128 +#if (defined __FLOAT128__ || defined _GLIBCXX_USE_FLOAT128) && !defined(EA_PLATFORM_SONY) +#define EA_FP128 1 +#else +#define EA_FP128 0 +#endif +#endif + +// ------------------------------------------------------------------------ +// EA_ABM +// EA_ABM may be used to determine if Advanced Bit Manipulation sets are available for the target architecture (POPCNT, LZCNT) +// +#ifndef EA_ABM +#if defined(__ABM__) || defined(EA_PLATFORM_XBOXONE) || defined(EA_PLATFORM_SONY) || defined(CS_UNDEFINED_STRING) +#define EA_ABM 1 +#else +#define EA_ABM 0 +#endif +#endif + +// ------------------------------------------------------------------------ +// EA_NEON +// EA_NEON may be used to determine if NEON is supported. +#ifndef EA_NEON +#if defined(__ARM_NEON__) || defined(__ARM_NEON) +#define EA_NEON 1 +#else +#define EA_NEON 0 +#endif +#endif + +// ------------------------------------------------------------------------ +// EA_BMI +// EA_BMI may be used to determine if Bit Manipulation Instruction sets are available for the target architecture +// +// EA_BMI defines the level of BMI support: +// 0 indicates no BMI support +// 1 indicates BMI1 is supported +// 2 indicates BMI2 is supported +#ifndef EA_BMI +#if defined(__BMI2__) +#define EA_BMI 2 +#elif defined(__BMI__) || defined(EA_PLATFORM_XBOXONE) || defined(CS_UNDEFINED_STRING) +#define EA_BMI 1 +#else +#define EA_BMI 0 +#endif +#endif +#ifndef EA_BMI2 +#if EA_BMI >= 2 +#define EA_BMI2 1 +#else +#define EA_BMI2 0 +#endif +#endif + +// ------------------------------------------------------------------------ +// EA_FMA3 +// EA_FMA3 may be used to determine if Fused Multiply Add operations are available for the target architecture +// __FMA__ is defined only by GCC, Clang, and ICC; MSVC only defines __AVX__ and __AVX2__ +// FMA3 was introduced alongside AVX2 on Intel Haswell +// All AMD processors support FMA3 if AVX2 is also supported +// +// EA_FMA3 defines the level of FMA3 support: +// 0 indicates no FMA3 support +// 1 indicates FMA3 is supported +#ifndef EA_FMA3 +#if defined(__FMA__) || EA_AVX2 >= 1 +#define EA_FMA3 1 +#else +#define EA_FMA3 0 +#endif +#endif + +// ------------------------------------------------------------------------ +// EA_TBM +// EA_TBM may be used to determine if Trailing Bit Manipulation instructions are available for the target architecture +#ifndef EA_TBM +#if defined(__TBM__) +#define EA_TBM 1 +#else +#define EA_TBM 0 +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_IMPORT +// import declaration specification +// specifies that the declared symbol is imported from another dynamic library. +#ifndef EA_IMPORT +#if defined(EA_COMPILER_MSVC) +#define EA_IMPORT __declspec(dllimport) +#else +#define EA_IMPORT +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_EXPORT +// export declaration specification +// specifies that the declared symbol is exported from the current dynamic library. +// this is not the same as the C++ export keyword. The C++ export keyword has been +// removed from the language as of C++11. +#ifndef EA_EXPORT +#if defined(EA_COMPILER_MSVC) +#define EA_EXPORT __declspec(dllexport) +#else +#define EA_EXPORT +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_PRAGMA_ONCE_SUPPORTED +// +// This is a wrapper for the #pragma once preprocessor directive. +// It allows for some compilers (in particular VC++) to implement signifcantly +// faster include file preprocessing. #pragma once can be used to replace +// header include guards or to augment them. However, #pragma once isn't +// necessarily supported by all compilers and isn't guaranteed to be so in +// the future, so using #pragma once to replace traditional include guards +// is not strictly portable. Note that a direct #define for #pragma once is +// impossible with VC++, due to limitations, but can be done with other +// compilers/preprocessors via _Pragma("once"). +// +// Example usage (which includes traditional header guards for portability): +// #ifndef SOMEPACKAGE_SOMEHEADER_H +// #define SOMEPACKAGE_SOMEHEADER_H +// +// #if defined(EA_PRAGMA_ONCE_SUPPORTED) +// #pragma once +// #endif +// +// +// +// #endif +// +#if defined(_MSC_VER) || defined(__GNUC__) || defined(__EDG__) || defined(__APPLE__) +#define EA_PRAGMA_ONCE_SUPPORTED 1 +#endif + + + +// ------------------------------------------------------------------------ +// EA_ONCE +// +// Example usage (which includes traditional header guards for portability): +// #ifndef SOMEPACKAGE_SOMEHEADER_H +// #define SOMEPACKAGE_SOMEHEADER_H +// +// EA_ONCE() +// +// +// +// #endif +// +#if defined(EA_PRAGMA_ONCE_SUPPORTED) +#if defined(_MSC_VER) +#define EA_ONCE() __pragma(once) +#else +#define EA_ONCE() // _Pragma("once") It turns out that _Pragma("once") isn't supported by many compilers. +#endif +#endif + + + +// ------------------------------------------------------------------------ +// EA_OVERRIDE +// +// C++11 override +// See http://msdn.microsoft.com/en-us/library/jj678987.aspx for more information. +// You can use EA_FINAL_OVERRIDE to combine usage of EA_OVERRIDE and EA_INHERITANCE_FINAL in a single statement. +// +// Example usage: +// struct B { virtual void f(int); }; +// struct D : B { void f(int) EA_OVERRIDE; }; +// +#ifndef EA_OVERRIDE +#if defined(EA_COMPILER_NO_OVERRIDE) +#define EA_OVERRIDE +#else +#define EA_OVERRIDE override +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_INHERITANCE_FINAL +// +// Portably wraps the C++11 final specifier. +// See http://msdn.microsoft.com/en-us/library/jj678985.aspx for more information. +// You can use EA_FINAL_OVERRIDE to combine usage of EA_OVERRIDE and EA_INHERITANCE_FINAL in a single statement. +// This is not called EA_FINAL because that term is used within EA to denote debug/release/final builds. +// +// Example usage: +// struct B { virtual void f() EA_INHERITANCE_FINAL; }; +// +#ifndef EA_INHERITANCE_FINAL +#if defined(EA_COMPILER_NO_INHERITANCE_FINAL) +#define EA_INHERITANCE_FINAL +#elif (defined(_MSC_VER) && (EA_COMPILER_VERSION < 1700)) // Pre-VS2012 +#define EA_INHERITANCE_FINAL sealed +#else +#define EA_INHERITANCE_FINAL final +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_FINAL_OVERRIDE +// +// Portably wraps the C++11 override final specifiers combined. +// +// Example usage: +// struct A { virtual void f(); }; +// struct B : public A { virtual void f() EA_FINAL_OVERRIDE; }; +// +#ifndef EA_FINAL_OVERRIDE +#define EA_FINAL_OVERRIDE EA_OVERRIDE EA_INHERITANCE_FINAL +#endif + + +// ------------------------------------------------------------------------ +// EA_SEALED +// +// This is deprecated, as the C++11 Standard has final (EA_INHERITANCE_FINAL) instead. +// See http://msdn.microsoft.com/en-us/library/0w2w91tf.aspx for more information. +// Example usage: +// struct B { virtual void f() EA_SEALED; }; +// +#ifndef EA_SEALED +#if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // VS2005 (VC8) and later +#define EA_SEALED sealed +#else +#define EA_SEALED +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_ABSTRACT +// +// This is a Microsoft language extension. +// See http://msdn.microsoft.com/en-us/library/b0z6b513.aspx for more information. +// Example usage: +// struct X EA_ABSTRACT { virtual void f(){} }; +// +#ifndef EA_ABSTRACT +#if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1400) // VS2005 (VC8) and later +#define EA_ABSTRACT abstract +#else +#define EA_ABSTRACT +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_CONSTEXPR +// EA_CONSTEXPR_OR_CONST +// +// Portable wrapper for C++11's 'constexpr' support. +// +// See http://www.cprogramming.com/c++11/c++11-compile-time-processing-with-constexpr.html for more information. +// Example usage: +// EA_CONSTEXPR int GetValue() { return 37; } +// EA_CONSTEXPR_OR_CONST double gValue = std::sin(kTwoPi); +// +#if !defined(EA_CONSTEXPR) +#if defined(EA_COMPILER_NO_CONSTEXPR) +#define EA_CONSTEXPR +#else +#define EA_CONSTEXPR constexpr +#endif +#endif + +#if !defined(EA_CONSTEXPR_OR_CONST) +#if defined(EA_COMPILER_NO_CONSTEXPR) +#define EA_CONSTEXPR_OR_CONST const +#else +#define EA_CONSTEXPR_OR_CONST constexpr +#endif +#endif + +// ------------------------------------------------------------------------ +// EA_CONSTEXPR_IF +// +// Portable wrapper for C++17's 'constexpr if' support. +// +// https://en.cppreference.com/w/cpp/language/if +// +// Example usage: +// +// EA_CONSTEXPR_IF(eastl::is_copy_constructible_v) +// { ... } +// +#if !defined(EA_CONSTEXPR_IF) +#if defined(EA_COMPILER_NO_CONSTEXPR_IF) +#define EA_CONSTEXPR_IF(predicate) if ((predicate)) +#else +#define EA_CONSTEXPR_IF(predicate) if constexpr ((predicate)) +#endif +#endif + + + +// ------------------------------------------------------------------------ +// EA_EXTERN_TEMPLATE +// +// Portable wrapper for C++11's 'extern template' support. +// +// Example usage: +// EA_EXTERN_TEMPLATE(class basic_string); +// +#if !defined(EA_EXTERN_TEMPLATE) +#if defined(EA_COMPILER_NO_EXTERN_TEMPLATE) +#define EA_EXTERN_TEMPLATE(declaration) +#else +#define EA_EXTERN_TEMPLATE(declaration) extern template declaration +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_NOEXCEPT +// EA_NOEXCEPT_IF(predicate) +// EA_NOEXCEPT_EXPR(expression) +// +// Portable wrapper for C++11 noexcept +// http://en.cppreference.com/w/cpp/language/noexcept +// http://en.cppreference.com/w/cpp/language/noexcept_spec +// +// Example usage: +// EA_NOEXCEPT +// EA_NOEXCEPT_IF(predicate) +// EA_NOEXCEPT_EXPR(expression) +// +// This function never throws an exception. +// void DoNothing() EA_NOEXCEPT +// { } +// +// This function throws an exception of T::T() throws an exception. +// template +// void DoNothing() EA_NOEXCEPT_IF(EA_NOEXCEPT_EXPR(T())) +// { T t; } +// +#if !defined(EA_NOEXCEPT) +#if defined(EA_COMPILER_NO_NOEXCEPT) +#define EA_NOEXCEPT +#define EA_NOEXCEPT_IF(predicate) +#define EA_NOEXCEPT_EXPR(expression) false +#else +#define EA_NOEXCEPT noexcept +#define EA_NOEXCEPT_IF(predicate) noexcept((predicate)) +#define EA_NOEXCEPT_EXPR(expression) noexcept((expression)) +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_NORETURN +// +// Wraps the C++11 noreturn attribute. See EA_COMPILER_NO_NORETURN +// http://en.cppreference.com/w/cpp/language/attributes +// http://msdn.microsoft.com/en-us/library/k6ktzx3s%28v=vs.80%29.aspx +// http://blog.aaronballman.com/2011/09/understanding-attributes/ +// +// Example usage: +// EA_NORETURN void SomeFunction() +// { throw "error"; } +// +#if !defined(EA_NORETURN) +#if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1300) // VS2003 (VC7) and later +#define EA_NORETURN __declspec(noreturn) +#elif defined(EA_COMPILER_NO_NORETURN) +#define EA_NORETURN +#else +#define EA_NORETURN [[noreturn]] +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_CARRIES_DEPENDENCY +// +// Wraps the C++11 carries_dependency attribute +// http://en.cppreference.com/w/cpp/language/attributes +// http://blog.aaronballman.com/2011/09/understanding-attributes/ +// +// Example usage: +// EA_CARRIES_DEPENDENCY int* SomeFunction() +// { return &mX; } +// +// +#if !defined(EA_CARRIES_DEPENDENCY) +#if defined(EA_COMPILER_NO_CARRIES_DEPENDENCY) +#define EA_CARRIES_DEPENDENCY +#else +#define EA_CARRIES_DEPENDENCY [[carries_dependency]] +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_FALLTHROUGH +// +// [[fallthrough] is a C++17 standard attribute that appears in switch +// statements to indicate that the fallthrough from the previous case in the +// switch statement is intentially and not a bug. +// +// http://en.cppreference.com/w/cpp/language/attributes +// +// Example usage: +// void f(int n) +// { +// switch(n) +// { +// case 1: +// DoCase1(); +// // Compiler may generate a warning for fallthrough behaviour +// +// case 2: +// DoCase2(); +// +// EA_FALLTHROUGH; +// case 3: +// DoCase3(); +// } +// } +// +#if !defined(EA_FALLTHROUGH) +#if defined(EA_COMPILER_NO_FALLTHROUGH) +#define EA_FALLTHROUGH +#else +#define EA_FALLTHROUGH [[fallthrough]] +#endif +#endif + + + +// ------------------------------------------------------------------------ +// EA_NODISCARD +// +// [[nodiscard]] is a C++17 standard attribute that can be applied to a +// function declaration, enum, or class declaration. If a any of the list +// previously are returned from a function (without the user explicitly +// casting to void) the addition of the [[nodiscard]] attribute encourages +// the compiler to generate a warning about the user discarding the return +// value. This is a useful practice to encourage client code to check API +// error codes. +// +// http://en.cppreference.com/w/cpp/language/attributes +// +// Example usage: +// +// EA_NODISCARD int baz() { return 42; } +// +// void foo() +// { +// baz(); // warning: ignoring return value of function declared with 'nodiscard' attribute +// } +// +#if !defined(EA_NODISCARD) +#if defined(EA_COMPILER_NO_NODISCARD) +#define EA_NODISCARD +#else +#define EA_NODISCARD [[nodiscard]] +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_MAYBE_UNUSED +// +// [[maybe_unused]] is a C++17 standard attribute that suppresses warnings +// on unused entities that are declared as maybe_unused. +// +// http://en.cppreference.com/w/cpp/language/attributes +// +// Example usage: +// void foo(EA_MAYBE_UNUSED int i) +// { +// assert(i == 42); // warning suppressed when asserts disabled. +// } +// +#if !defined(EA_MAYBE_UNUSED) +#if defined(EA_COMPILER_NO_MAYBE_UNUSED) +#define EA_MAYBE_UNUSED +#else +#define EA_MAYBE_UNUSED [[maybe_unused]] +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_NO_UBSAN +// +// The LLVM/Clang undefined behaviour sanitizer will not analyse a function tagged with the following attribute. +// +// https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#disabling-instrumentation-with-attribute-no-sanitize-undefined +// +// Example usage: +// EA_NO_UBSAN int SomeFunction() { ... } +// +#ifndef EA_NO_UBSAN +#if defined(EA_COMPILER_CLANG) +#define EA_NO_UBSAN __attribute__((no_sanitize("undefined"))) +#else +#define EA_NO_UBSAN +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_NO_ASAN +// +// The LLVM/Clang address sanitizer will not analyse a function tagged with the following attribute. +// +// https://clang.llvm.org/docs/AddressSanitizer.html#disabling-instrumentation-with-attribute-no-sanitize-address +// +// Example usage: +// EA_NO_ASAN int SomeFunction() { ... } +// +#ifndef EA_NO_ASAN +#if defined(EA_COMPILER_CLANG) +#define EA_NO_ASAN __attribute__((no_sanitize("address"))) +#else +#define EA_NO_ASAN +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_ASAN_ENABLED +// +// Defined as 0 or 1. It's value depends on the compile environment. +// Specifies whether the code is being built with Clang's Address Sanitizer. +// +#if defined(__has_feature) +#if __has_feature(address_sanitizer) +#define EA_ASAN_ENABLED 1 +#else +#define EA_ASAN_ENABLED 0 +#endif +#else +#define EA_ASAN_ENABLED 0 +#endif + + +// ------------------------------------------------------------------------ +// EA_NON_COPYABLE +// +// This macro defines as a class as not being copy-constructable +// or assignable. This is useful for preventing class instances +// from being passed to functions by value, is useful for preventing +// compiler warnings by some compilers about the inability to +// auto-generate a copy constructor and assignment, and is useful +// for simply declaring in the interface that copy semantics are +// not supported by the class. Your class needs to have at least a +// default constructor when using this macro. +// +// Beware that this class works by declaring a private: section of +// the class in the case of compilers that don't support C++11 deleted +// functions. +// +// Note: With some pre-C++11 compilers (e.g. Green Hills), you may need +// to manually define an instances of the hidden functions, even +// though they are not used. +// +// Example usage: +// class Widget { +// Widget(); +// . . . +// EA_NON_COPYABLE(Widget) +// }; +// +#if !defined(EA_NON_COPYABLE) +#if defined(EA_COMPILER_NO_DELETED_FUNCTIONS) +#define EA_NON_COPYABLE(EAClass_) \ + private: \ + EA_DISABLE_VC_WARNING(4822); /* local class member function does not have a body */ \ + EAClass_(const EAClass_&); \ + void operator=(const EAClass_&); \ + EA_RESTORE_VC_WARNING(); +#else +#define EA_NON_COPYABLE(EAClass_) \ + EA_DISABLE_VC_WARNING(4822); /* local class member function does not have a body */ \ + EAClass_(const EAClass_&) = delete; \ + void operator=(const EAClass_&) = delete; \ + EA_RESTORE_VC_WARNING(); +#endif +#endif + + +// ------------------------------------------------------------------------ +// EA_FUNCTION_DELETE +// +// Semi-portable way of specifying a deleted function which allows for +// cleaner code in class declarations. +// +// Example usage: +// +// class Example +// { +// private: // For portability with pre-C++11 compilers, make the function private. +// void foo() EA_FUNCTION_DELETE; +// }; +// +// Note: EA_FUNCTION_DELETE'd functions should be private to prevent the +// functions from being called even when the compiler does not support +// deleted functions. Some compilers (e.g. Green Hills) that don't support +// C++11 deleted functions can require that you define the function, +// which you can do in the associated source file for the class. +// +#if defined(EA_COMPILER_NO_DELETED_FUNCTIONS) +#define EA_FUNCTION_DELETE +#else +#define EA_FUNCTION_DELETE = delete +#endif + +// ------------------------------------------------------------------------ +// EA_DISABLE_DEFAULT_CTOR +// +// Disables the compiler generated default constructor. This macro is +// provided to improve portability and clarify intent of code. +// +// Example usage: +// +// class Example +// { +// private: +// EA_DISABLE_DEFAULT_CTOR(Example); +// }; +// +#define EA_DISABLE_DEFAULT_CTOR(ClassName) ClassName() EA_FUNCTION_DELETE + +// ------------------------------------------------------------------------ +// EA_DISABLE_COPY_CTOR +// +// Disables the compiler generated copy constructor. This macro is +// provided to improve portability and clarify intent of code. +// +// Example usage: +// +// class Example +// { +// private: +// EA_DISABLE_COPY_CTOR(Example); +// }; +// +#define EA_DISABLE_COPY_CTOR(ClassName) ClassName(const ClassName &) EA_FUNCTION_DELETE + +// ------------------------------------------------------------------------ +// EA_DISABLE_MOVE_CTOR +// +// Disables the compiler generated move constructor. This macro is +// provided to improve portability and clarify intent of code. +// +// Example usage: +// +// class Example +// { +// private: +// EA_DISABLE_MOVE_CTOR(Example); +// }; +// +#define EA_DISABLE_MOVE_CTOR(ClassName) ClassName(ClassName&&) EA_FUNCTION_DELETE + +// ------------------------------------------------------------------------ +// EA_DISABLE_ASSIGNMENT_OPERATOR +// +// Disables the compiler generated assignment operator. This macro is +// provided to improve portability and clarify intent of code. +// +// Example usage: +// +// class Example +// { +// private: +// EA_DISABLE_ASSIGNMENT_OPERATOR(Example); +// }; +// +#define EA_DISABLE_ASSIGNMENT_OPERATOR(ClassName) ClassName & operator=(const ClassName &) EA_FUNCTION_DELETE + +// ------------------------------------------------------------------------ +// EA_DISABLE_MOVE_OPERATOR +// +// Disables the compiler generated move operator. This macro is +// provided to improve portability and clarify intent of code. +// +// Example usage: +// +// class Example +// { +// private: +// EA_DISABLE_MOVE_OPERATOR(Example); +// }; +// +#define EA_DISABLE_MOVE_OPERATOR(ClassName) ClassName & operator=(ClassName&&) EA_FUNCTION_DELETE + +// ------------------------------------------------------------------------ +// EANonCopyable +// +// Declares a class as not supporting copy construction or assignment. +// May be more reliable with some situations that EA_NON_COPYABLE alone, +// though it may result in more code generation. +// +// Note that VC++ will generate warning C4625 and C4626 if you use EANonCopyable +// and you are compiling with /W4 and /Wall. There is no resolution but +// to redelare EA_NON_COPYABLE in your subclass or disable the warnings with +// code like this: +// EA_DISABLE_VC_WARNING(4625 4626) +// ... +// EA_RESTORE_VC_WARNING() +// +// Example usage: +// struct Widget : EANonCopyable { +// . . . +// }; +// +#ifdef __cplusplus +struct EANonCopyable +{ +#if defined(EA_COMPILER_NO_DEFAULTED_FUNCTIONS) || defined(__EDG__) + // EDG doesn't appear to behave properly for the case of defaulted constructors; + // it generates a mistaken warning about missing default constructors. + EANonCopyable() {} // Putting {} here has the downside that it allows a class to create itself, + ~EANonCopyable() {} // but avoids linker errors that can occur with some compilers (e.g. Green Hills). +#else + EANonCopyable() = default; + ~EANonCopyable() = default; +#endif + + EA_NON_COPYABLE(EANonCopyable) +}; +#endif + + +// ------------------------------------------------------------------------ +// EA_OPTIMIZE_OFF / EA_OPTIMIZE_ON +// +// Implements portable inline optimization enabling/disabling. +// Usage of these macros must be in order OFF then ON. This is +// because the OFF macro pushes a set of settings and the ON +// macro pops them. The nesting of OFF/ON sets (e.g. OFF, OFF, ON, ON) +// is not guaranteed to work on all platforms. +// +// This is often used to allow debugging of some code that's +// otherwise compiled with undebuggable optimizations. It's also +// useful for working around compiler code generation problems +// that occur in optimized builds. +// +// Some compilers (e.g. VC++) don't allow doing this within a function and +// so the usage must be outside a function, as with the example below. +// GCC on x86 appears to have some problem with argument passing when +// using EA_OPTIMIZE_OFF in optimized builds. +// +// Example usage: +// // Disable optimizations for SomeFunction. +// EA_OPTIMIZE_OFF() +// void SomeFunction() +// { +// ... +// } +// EA_OPTIMIZE_ON() +// +#if !defined(EA_OPTIMIZE_OFF) +#if defined(EA_COMPILER_MSVC) +#define EA_OPTIMIZE_OFF() __pragma(optimize("", off)) +#elif defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION > 4004) && (defined(__i386__) || defined(__x86_64__)) // GCC 4.4+ - Seems to work only on x86/Linux so far. However, GCC 4.4 itself appears broken and screws up parameter passing conventions. +#define EA_OPTIMIZE_OFF() \ + _Pragma("GCC push_options") \ + _Pragma("GCC optimize 0") +#elif defined(EA_COMPILER_CLANG) && (!defined(EA_PLATFORM_ANDROID) || (EA_COMPILER_VERSION >= 380)) +#define EA_OPTIMIZE_OFF() \ + EA_DISABLE_CLANG_WARNING(-Wunknown-pragmas) \ + _Pragma("clang optimize off") \ + EA_RESTORE_CLANG_WARNING() +#else +#define EA_OPTIMIZE_OFF() +#endif +#endif + +#if !defined(EA_OPTIMIZE_ON) +#if defined(EA_COMPILER_MSVC) +#define EA_OPTIMIZE_ON() __pragma(optimize("", on)) +#elif defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION > 4004) && (defined(__i386__) || defined(__x86_64__)) // GCC 4.4+ - Seems to work only on x86/Linux so far. However, GCC 4.4 itself appears broken and screws up parameter passing conventions. +#define EA_OPTIMIZE_ON() _Pragma("GCC pop_options") +#elif defined(EA_COMPILER_CLANG) && (!defined(EA_PLATFORM_ANDROID) || (EA_COMPILER_VERSION >= 380)) +#define EA_OPTIMIZE_ON() \ + EA_DISABLE_CLANG_WARNING(-Wunknown-pragmas) \ + _Pragma("clang optimize on") \ + EA_RESTORE_CLANG_WARNING() +#else +#define EA_OPTIMIZE_ON() +#endif +#endif + + + +// ------------------------------------------------------------------------ +// EA_SIGNED_RIGHT_SHIFT_IS_UNSIGNED +// +// Defined if right shifts of signed integers (i.e. arithmetic shifts) fail +// to propogate the high bit downward, and thus preserve sign. Most hardware +// and their corresponding compilers do this. +// +// + +#endif // Header include guard + + + + + + + + + + diff --git a/UnknownVersion/include/EABase/config/eaplatform.h b/UnknownVersion/include/EABase/config/eaplatform.h index 830ca64..90e00a4 100644 --- a/UnknownVersion/include/EABase/config/eaplatform.h +++ b/UnknownVersion/include/EABase/config/eaplatform.h @@ -1,67 +1,79 @@ -/* -Copyright (C) 2009 Electronic Arts, Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of - its contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - /*----------------------------------------------------------------------------- * config/eaplatform.h * - * Copyright (c) 2002 - 2005 Electronic Arts Inc. All rights reserved. - * Maintained by Paul Pedriana, Maxis - * + * Copyright (c) Electronic Arts Inc. All rights reserved. *----------------------------------------------------------------------------- * Currently supported platform indentification defines include: - * EA_PLATFORM_PS3 - * EA_PLATFORM_PS3_PPU - * EA_PLATFORM_PS3_SPU - * EA_PLATFORM_XENON (a.k.a. XBox2) - * EA_PLATFORM_MAC - * EA_PLATFORM_OSX - * EA_PLATFORM_LINUX - * EA_PLATFORM_WINDOWS - * EA_PLATFORM_WIN32 - * EA_PLATFORM_WIN64 - * EA_PLATFORM_HPUX - * EA_PLATFORM_SUN - * EA_PLATFORM_LRB (Larrabee) - * EA_PLATFORM_UNIX (pseudo-platform; may be defined along with another platform like EA_PLATFORM_LINUX) - * EA_PLATFORM_CYGWIN (pseudo-platform; may be defined along with another platform like EA_PLATFORM_LINUX) - * EA_PLATFORM_MINGW (pseudo-platform; may be defined along with another platform like EA_PLATFORM_WINDOWS) - * EA_PLATFORM_MICROSOFT (pseudo-platform; may be defined along with another platform like EA_PLATFORM_WINDOWS) - * - * Other definitions emanated from this file inclue: - * EA_PLATFORM_NAME = - * EA_PLATFORM_DESCRIPTION = - * EA_PROCESSOR_XXX - * EA_SYSTEM_LITTLE_ENDIAN | EA_SYSTEM_BIG_ENDIAN - * EA_ASM_STYLE_ATT | EA_ASM_STYLE_INTEL | EA_ASM_STYLE_MOTOROLA - * EA_PLATFORM_PTR_SIZE = - * EA_PLATFORM_WORD_SIZE = - * - *---------------------------------------------------------------------------*/ + */ +#ifdef EA_PLATFORM_PS4 // ifdef for code stripping purposes +// EA_PLATFORM_PS4 (EA_PLATFORM_KETTLE) +#endif +#ifdef EA_PLATFORM_XBOXONE // ifdef for code stripping purposes +// EA_PLATFORM_XBOXONE (EA_PLATFORM_CAPILANO) +// EA_PLATFORM_XBOXONE_XDK (EA_PLATFORM_CAPILANO_XDK), set by capilano_config package +// EA_PLATFORM_XBOXONE_ADK (EA_PLATFORM_CAPILANO_ADK), set by capilano_config package +#endif +// EA_PLATFORM_ANDROID +// EA_PLATFORM_APPLE +// EA_PLATFORM_IPHONE +// EA_PLATFORM_IPHONE_SIMULATOR +// EA_PLATFORM_OSX +// EA_PLATFORM_LINUX +// EA_PLATFORM_SAMSUNG_TV +// EA_PLATFORM_WINDOWS +// EA_PLATFORM_WIN32 +// EA_PLATFORM_WIN64 +// EA_PLATFORM_WINDOWS_PHONE +// EA_PLATFORM_WINRT +// EA_PLATFORM_SUN +// EA_PLATFORM_LRB (Larrabee) +// EA_PLATFORM_POSIX (pseudo-platform; may be defined along with another platform like EA_PLATFORM_LINUX, EA_PLATFORM_UNIX, EA_PLATFORM_QNX) +// EA_PLATFORM_UNIX (pseudo-platform; may be defined along with another platform like EA_PLATFORM_LINUX) +// EA_PLATFORM_CYGWIN (pseudo-platform; may be defined along with another platform like EA_PLATFORM_LINUX) +// EA_PLATFORM_MINGW (pseudo-platform; may be defined along with another platform like EA_PLATFORM_WINDOWS) +// EA_PLATFORM_MICROSOFT (pseudo-platform; may be defined along with another platform like EA_PLATFORM_WINDOWS) +// +// EA_ABI_ARM_LINUX (a.k.a. "eabi". for all platforms that use the CodeSourcery GNU/Linux toolchain, like Android) +// EA_ABI_ARM_APPLE (similar to eabi but not identical) +// EA_ABI_ARM64_APPLE (similar to eabi but not identical) https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARM64FunctionCallingConventions.html +// EA_ABI_ARM_WINCE (similar to eabi but not identical) +// +// Other definitions emanated from this file inclue: +// EA_PLATFORM_NAME = +// EA_PLATFORM_DESCRIPTION = +// EA_PROCESSOR_XXX +// EA_MISALIGNED_SUPPORT_LEVEL=0|1|2 +// EA_SYSTEM_LITTLE_ENDIAN | EA_SYSTEM_BIG_ENDIAN +// EA_ASM_STYLE_ATT | EA_ASM_STYLE_INTEL | EA_ASM_STYLE_MOTOROLA +// EA_PLATFORM_PTR_SIZE = +// EA_PLATFORM_WORD_SIZE = +// EA_CACHE_LINE_SIZE = +//--------------------------------------------------------------------------- + +/* + EA_PLATFORM_MOBILE + EA_PLATFORM_MOBILE is a peer to EA_PLATORM_DESKTOP and EA_PLATFORM_CONSOLE. Their definition is qualitative rather + than quantitative, and refers to the general (usually weaker) capabilities of the machine. Mobile devices have a + similar set of weaknesses that are useful to generally categorize. The primary motivation is to avoid code that + tests for multiple mobile platforms on a line and needs to be updated every time we get a new one. + For example, mobile platforms tend to have weaker ARM processors, don't have full multiple processor support, + are hand-held, don't have mice (though may have touch screens or basic cursor controls), have writable solid + state permanent storage. Production user code shouldn't have too many expectations about the meaning of this define. + + EA_PLATFORM_DESKTOP + This is similar to EA_PLATFORM_MOBILE in its qualitative nature and refers to platforms that are powerful. + For example, they nearly always have virtual memory, mapped memory, hundreds of GB of writable disk storage, + TCP/IP network connections, mice, keyboards, 512+ MB of RAM, multiprocessing, multiple display support. + Production user code shouldn't have too many expectations about the meaning of this define. + + EA_PLATFORM_CONSOLE + This is similar to EA_PLATFORM_MOBILE in its qualitative nature and refers to platforms that are consoles. + This means platforms that are connected to TVs, are fairly powerful (especially graphics-wise), are tightly + controlled by vendors, tend not to have mapped memory, tend to have TCP/IP, don't have multiple process support + though they might have multiple CPUs, support TV output only. Production user code shouldn't have too many + expectations about the meaning of this define. + +*/ #ifndef INCLUDED_eaplatform_H @@ -72,271 +84,301 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // This is a pseudo-platform which will be defined along with EA_PLATFORM_LINUX when // using the Cygwin build environment. #if defined(__CYGWIN__) - #define EA_PLATFORM_CYGWIN - #define EA_PLATFORM_DESKTOP +#define EA_PLATFORM_CYGWIN 1 +#define EA_PLATFORM_DESKTOP 1 #endif // MinGW -// This is a pseudo-platform which will be defined along with EA_PLATFORM_WINDOWS when +// This is a pseudo-platform which will be defined along with EA_PLATFORM_WINDOWS when // using the MinGW Windows build environment. #if defined(__MINGW32__) || defined(__MINGW64__) - #define EA_PLATFORM_MINGW - #define EA_PLATFORM_DESKTOP -#endif - -// PlayStation 3 PPU (Primary Processing Unit) -#if defined(EA_PLATFORM_PS3_PPU) || defined(EA_PLATFORM_PS3) || defined(__PU__) || defined(__PPU__) - #undef EA_PLATFORM_PS3_PPU - #define EA_PLATFORM_PS3_PPU 1 - #undef EA_PLATFORM_PS3 - #define EA_PLATFORM_PS3 1 - #define EA_PLATFORM_NAME "PS3" - #define EA_PROCESSOR_POWERPC - #define EA_PROCESSOR_POWERPC_64 - #define EA_SYSTEM_BIG_ENDIAN - #define EA_PLATFORM_DESCRIPTION "PS3 on PowerPC" - #define EA_PLATFORM_CONSOLE - -// PlayStation 3 SPU (Synergistic Processing Unit) -#elif defined(EA_PLATFORM_PS3_SPU) || defined(__SPU__) - #undef EA_PLATFORM_PS3_SPU - #define EA_PLATFORM_PS3_SPU 1 - #define EA_PLATFORM_NAME "PS3 SPU" - #define EA_PROCESSOR_SPU - #define EA_SYSTEM_BIG_ENDIAN - #define EA_PLATFORM_DESCRIPTION "PS3 SPU on SPU" - #define EA_PLATFORM_CONSOLE - -// XBox -// _XBOX is defined by the VC++ project, not the compiler. There is no way -// to tell if the compiler is compiling for XBox unless _XBOX is #defined -// in the project files or otherwise. _M_IX86 is the VC++ way of detecting -// an x86 target, which would mean XBox and not Xenon (a.k.a. XBox2). -#elif defined(EA_PLATFORM_XBOX) || (defined(_XBOX) && defined(_M_IX86)) - #undef EA_PLATFORM_XBOX - #define EA_PLATFORM_XBOX 1 - #define EA_PLATFORM_NAME "XBox" - #define EA_PROCESSOR_X86 - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "XBox on X86" - #if defined(_MSC_VER) || defined(__ICL) - #define EA_ASM_STYLE_INTEL - #endif - #define EA_PLATFORM_CONSOLE - -// Xenon (XBox 360) -// The Xenon compiler doesn't define anything in particular to indicate that the -// target is the Xenon platform. The Xenon SDK, however, expects that XBOX and -// _XBOX are #defined, so the project build file must make sure these are defined. -// Since the Xenon compiler in fact defines _M_PPC, we can use this information -// to infer that Xenon is the target if neither _XENON nor _XBOX2 are specifically -// defined by the project build file. -#elif defined(EA_PLATFORM_XENON) || defined(_XENON) || defined(_XBOX2) || ((defined(_XBOX) || defined(XBOX)) && defined(_M_PPC)) - #undef EA_PLATFORM_XENON - #define EA_PLATFORM_XENON 1 - #define EA_PLATFORM_NAME "Xenon" - #define EA_PROCESSOR_POWERPC - #define EA_PROCESSOR_POWERPC_64 - #define EA_SYSTEM_BIG_ENDIAN - #define EA_PLATFORM_DESCRIPTION "Xenon on PowerPC" - #if defined(_MSC_VER) || defined(__ICL) - #define EA_ASM_STYLE_INTEL - #endif - #define EA_PLATFORM_CONSOLE - #define EA_PLATFORM_MICROSOFT 1 - -// Larrabee // This part to be removed once __LRB__ is supported by the Larrabee compiler in 2009. +#define EA_PLATFORM_MINGW 1 +#define EA_PLATFORM_DESKTOP 1 +#endif + +#if defined(EA_PLATFORM_PS4) || defined(__ORBIS__) || defined(EA_PLATFORM_KETTLE) +// PlayStation 4 +// Orbis was Sony's code-name for the platform, which is now obsolete. +// Kettle was an EA-specific code-name for the platform, which is now obsolete. +#if defined(EA_PLATFORM_PS4) +#undef EA_PLATFORM_PS4 +#endif +#define EA_PLATFORM_PS4 1 + +// Backward compatibility: +#if defined(EA_PLATFORM_KETTLE) +#undef EA_PLATFORM_KETTLE +#endif +// End backward compatbility + +#define EA_PLATFORM_KETTLE 1 +#define EA_PLATFORM_NAME "PS4" +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "PS4 on x64" +#define EA_PLATFORM_CONSOLE 1 +#define EA_PLATFORM_SONY 1 +#define EA_PLATFORM_POSIX 1 +// #define EA_POSIX_THREADS_AVAILABLE 1 // POSIX threading API is available but discouraged. Sony indicated use of the scePthreads* API is preferred. +#define EA_PROCESSOR_X86_64 1 +#if defined(__GNUC__) || defined(__clang__) +#define EA_ASM_STYLE_ATT 1 +#endif + +#elif defined(EA_PLATFORM_XBOXONE) || defined(_DURANGO) || defined(_XBOX_ONE) || defined(EA_PLATFORM_CAPILANO) || defined(_GAMING_XBOX) +// XBox One +// Durango was Microsoft's code-name for the platform, which is now obsolete. +// Microsoft uses _DURANGO instead of some variation of _XBOX, though it's not natively defined by the compiler. +// Capilano was an EA-specific code-name for the platform, which is now obsolete. +#if defined(EA_PLATFORM_XBOXONE) +#undef EA_PLATFORM_XBOXONE +#endif +#define EA_PLATFORM_XBOXONE 1 + +// Backward compatibility: +#if defined(EA_PLATFORM_CAPILANO) +#undef EA_PLATFORM_CAPILANO +#endif +#define EA_PLATFORM_CAPILANO 1 +#if defined(EA_PLATFORM_CAPILANO_XDK) && !defined(EA_PLATFORM_XBOXONE_XDK) +#define EA_PLATFORM_XBOXONE_XDK 1 +#endif +#if defined(EA_PLATFORM_CAPILANO_ADK) && !defined(EA_PLATFORM_XBOXONE_ADK) +#define EA_PLATFORM_XBOXONE_ADK 1 +#endif +// End backward compatibility + +#if !defined(_DURANGO) +#define _DURANGO +#endif +#define EA_PLATFORM_NAME "XBox One" +//#define EA_PROCESSOR_X86 Currently our policy is that we don't define this, even though x64 is something of a superset of x86. +#define EA_PROCESSOR_X86_64 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "XBox One on x64" +#define EA_ASM_STYLE_INTEL 1 +#define EA_PLATFORM_CONSOLE 1 +#define EA_PLATFORM_MICROSOFT 1 + +// WINAPI_FAMILY defines - mirrored from winapifamily.h +#define EA_WINAPI_FAMILY_APP 1000 +#define EA_WINAPI_FAMILY_DESKTOP_APP 1001 +#define EA_WINAPI_FAMILY_PHONE_APP 1002 +#define EA_WINAPI_FAMILY_TV_APP 1003 +#define EA_WINAPI_FAMILY_TV_TITLE 1004 +#define EA_WINAPI_FAMILY_GAMES 1006 + +#if defined(WINAPI_FAMILY) +#include +#if defined(WINAPI_FAMILY_TV_TITLE) && WINAPI_FAMILY == WINAPI_FAMILY_TV_TITLE +#define EA_WINAPI_FAMILY EA_WINAPI_FAMILY_TV_TITLE +#elif defined(WINAPI_FAMILY_DESKTOP_APP) && WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP +#define EA_WINAPI_FAMILY EA_WINAPI_FAMILY_DESKTOP_APP +#elif defined(WINAPI_FAMILY_GAMES) && WINAPI_FAMILY == WINAPI_FAMILY_GAMES +#define EA_WINAPI_FAMILY EA_WINAPI_FAMILY_GAMES +#else +#error Unsupported WINAPI_FAMILY +#endif +#else +#error WINAPI_FAMILY should always be defined on Capilano. +#endif + +// Macro to determine if a partition is enabled. +#define EA_WINAPI_FAMILY_PARTITION(Partition) (Partition) + +#if EA_WINAPI_FAMILY == EA_WINAPI_FAMILY_DESKTOP_APP +#define EA_WINAPI_PARTITION_CORE 1 +#define EA_WINAPI_PARTITION_DESKTOP 1 +#define EA_WINAPI_PARTITION_APP 1 +#define EA_WINAPI_PARTITION_PC_APP 0 +#define EA_WIANPI_PARTITION_PHONE 0 +#define EA_WINAPI_PARTITION_TV_APP 0 +#define EA_WINAPI_PARTITION_TV_TITLE 0 +#define EA_WINAPI_PARTITION_GAMES 0 +#elif EA_WINAPI_FAMILY == EA_WINAPI_FAMILY_TV_TITLE +#define EA_WINAPI_PARTITION_CORE 1 +#define EA_WINAPI_PARTITION_DESKTOP 0 +#define EA_WINAPI_PARTITION_APP 0 +#define EA_WINAPI_PARTITION_PC_APP 0 +#define EA_WIANPI_PARTITION_PHONE 0 +#define EA_WINAPI_PARTITION_TV_APP 0 +#define EA_WINAPI_PARTITION_TV_TITLE 1 +#define EA_WINAPI_PARTITION_GAMES 0 +#elif EA_WINAPI_FAMILY == EA_WINAPI_FAMILY_GAMES +#define EA_WINAPI_PARTITION_CORE 1 +#define EA_WINAPI_PARTITION_DESKTOP 0 +#define EA_WINAPI_PARTITION_APP 0 +#define EA_WINAPI_PARTITION_PC_APP 0 +#define EA_WIANPI_PARTITION_PHONE 0 +#define EA_WINAPI_PARTITION_TV_APP 0 +#define EA_WINAPI_PARTITION_TV_TITLE 0 +#define EA_WINAPI_PARTITION_GAMES 1 +#else +#error Unsupported WINAPI_FAMILY +#endif + +#if EA_WINAPI_FAMILY_PARTITION(EA_WINAPI_PARTITION_GAMES) +#define CS_UNDEFINED_STRING 1 +#define CS_UNDEFINED_STRING 1 +#endif + +#if EA_WINAPI_FAMILY_PARTITION(EA_WINAPI_PARTITION_TV_TITLE) +#define EA_PLATFORM_XBOXONE_XDK 1 +#endif #elif defined(EA_PLATFORM_LRB) || defined(__LRB__) || (defined(__EDG__) && defined(__ICC) && defined(__x86_64__)) - #undef EA_PLATFORM_LRB - #define EA_PLATFORM_LRB 1 - #define EA_PLATFORM_NAME "Larrabee" - #define EA_PLATFORM_DESCRIPTION "Larrabee on LRB1" - #define EA_PROCESSOR_X86_64 - #if defined(BYTE_ORDER) && (BYTE_ORDER == 4321) - #define EA_SYSTEM_BIG_ENDIAN - #else - #define EA_SYSTEM_LITTLE_ENDIAN - #endif - #define EA_PROCESSOR_LRB - #define EA_PROCESSOR_LRB1 // Larrabee version 1 - #define EA_ASM_STYLE_ATT // Both types of asm style - #define EA_ASM_STYLE_INTEL // are supported. - #define EA_PLATFORM_DESKTOP +#undef EA_PLATFORM_LRB +#define EA_PLATFORM_LRB 1 +#define EA_PLATFORM_NAME "Larrabee" +#define EA_PLATFORM_DESCRIPTION "Larrabee on LRB1" +#define EA_PROCESSOR_X86_64 1 +#if defined(BYTE_ORDER) && (BYTE_ORDER == 4321) +#define EA_SYSTEM_BIG_ENDIAN 1 +#else +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#endif +#define EA_PROCESSOR_LRB 1 +#define EA_PROCESSOR_LRB1 1 // Larrabee version 1 +#define EA_ASM_STYLE_ATT 1 // Both types of asm style +#define EA_ASM_STYLE_INTEL 1 // are supported. +#define EA_PLATFORM_DESKTOP 1 // Android (Google phone OS) #elif defined(EA_PLATFORM_ANDROID) || defined(__ANDROID__) - #undef EA_PLATFORM_ANDROID - #define EA_PLATFORM_ANDROID 1 - #define EA_PLATFORM_LINUX 1 - #define EA_PLATFORM_UNIX 1 - #define EA_PLATFORM_NAME "Android" - #define EA_ASM_STYLE_ATT - #if defined(__arm__) || defined(__aarch64__) - #define EA_PROCESSOR_ARM - #define EA_PLATFORM_DESCRIPTION "Android on ARM" - #elif defined(__i386__) - #define EA_PROCESSOR_X86 - #define EA_PLATFORM_DESCRIPTION "Android on x86" - #elif defined(__x86_64) - #define EA_PROCESSOR_X86_64 - #define EA_PLATFORM_DESCRIPTION "Android on x86_64" - #else - #error Unknown processor - #endif - #if !defined(EA_SYSTEM_BIG_ENDIAN) && !defined(EA_SYSTEM_LITTLE_ENDIAN) - #define EA_SYSTEM_LITTLE_ENDIAN - #endif - #define EA_PLATFORM_MOBILE - -// Palm OS for Mobile (Linux variant) -#elif defined(EA_PLATFORM_PALM) - #undef EA_PLATFORM_PALM - #define EA_PLATFORM_PALM 1 - #define EA_PLATFORM_LINUX 1 - #define EA_PLATFORM_UNIX 1 - #define EA_PLATFORM_NAME "Palm" - #define EA_POSIX_THREADS_AVAILABLE 1 - #define EA_ASM_STYLE_ATT - #if defined(__arm__) - #define EA_PROCESSOR_ARM - #define EA_PLATFORM_DESCRIPTION "Palm on ARM" - #else - #error Unknown processor - #endif - #if !defined(EA_SYSTEM_BIG_ENDIAN) && !defined(EA_SYSTEM_LITTLE_ENDIAN) - #define EA_SYSTEM_LITTLE_ENDIAN - #endif - #define EA_PLATFORM_MOBILE - -// Airplay -#elif defined(EA_PLATFORM_AIRPLAY) || defined(__S3E__) - #undef EA_PLATFORM_AIRPLAY - #define EA_PLATFORM_AIRPLAY - #define EA_PLATFORM_NAME "Airplay" - #if defined(__arm__) - #define EA_PROCESSOR_ARM - #define EA_PLATFORM_DESCRIPTION "Airplay on ARM" - #define EA_ASM_STYLE_ATT - #undef _MSC_VER - #elif defined(_M_IX86) - #define EA_PROCESSOR_X86 - #define EA_PLATFORM_DESCRIPTION "Airplay on x86" - #define EA_ASM_STYLE_INTEL - #else - #error Unknown processor - #endif - #if !defined(EA_SYSTEM_BIG_ENDIAN) && !defined(EA_SYSTEM_LITTLE_ENDIAN) - #if defined(HAVE_BIG_ENDIAN) || (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN))) - #define EA_SYSTEM_BIG_ENDIAN - #else - #define EA_SYSTEM_LITTLE_ENDIAN - #endif - #endif - #define EA_PLATFORM_MOBILE - -// Samsung Bada OS for Mobile (Linux variant) -#elif defined(EA_PLATFORM_BADA) - #undef EA_PLATFORM_BADA - #define EA_PLATFORM_BADA 1 - //#define EA_PLATFORM_LINUX 1 // The underlying OS is Linux, but the app mostly doesn't see this. - //#define EA_PLATFORM_UNIX 1 - #define EA_PLATFORM_NAME "bada" - #define EA_ASM_STYLE_ATT - #if defined(__arm__) - #define EA_PROCESSOR_ARM - #define EA_PLATFORM_DESCRIPTION "bada on ARM" - #elif defined(__i386__) - #define EA_PLATFORM_BADA_SIMULATOR - #define EA_PROCESSOR_X86 - #define EA_PLATFORM_DESCRIPTION "bada simulator on x86" - #else - #error Unknown processor - #endif - #if !defined(EA_SYSTEM_BIG_ENDIAN) && !defined(EA_SYSTEM_LITTLE_ENDIAN) - #define EA_SYSTEM_LITTLE_ENDIAN - #endif - #define EA_PLATFORM_MOBILE - -#elif defined(__APPLE__) && __APPLE__ - #include - - // Apple family of operating systems. - #define EA_PLATFORM_APPLE - - // iPhone - // TARGET_OS_IPHONE will be undefined on an unknown compiler, and will be defined on gcc. - #if defined(EA_PLATFORM_IPHONE) || defined(__IPHONE__) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR) - #undef EA_PLATFORM_IPHONE - #define EA_PLATFORM_IPHONE 1 - #define EA_PLATFORM_NAME "iPhone" - #define EA_ASM_STYLE_ATT - #define EA_POSIX_THREADS_AVAILABLE 1 - #if defined(__arm__) || defined(__aarch64__) - #define EA_PROCESSOR_ARM - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "iPhone on ARM" - #elif defined(__i386__) - #define EA_PLATFORM_IPHONE_SIMULATOR - #define EA_PROCESSOR_X86 - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "iPhone simulator on x86" - #elif defined(__x86_64) - #define EA_PLATFORM_IPHONE_SIMULATOR - #define EA_PROCESSOR_X86_64 - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "iPhone simulator on x86_64" - #else - #error Unknown processor - #endif - #define EA_PLATFORM_MOBILE - - // Macintosh OSX - // TARGET_OS_MAC is defined by the Metrowerks and older AppleC compilers. - // Howerver, TARGET_OS_MAC is defined to be 1 in all cases. - // __i386__ and __intel__ are defined by the GCC compiler. - // __dest_os is defined by the Metrowerks compiler. - // __MACH__ is defined by the Metrowerks and GCC compilers. - // powerc and __powerc are defined by the Metrowerks and GCC compilers. - #elif defined(EA_PLATFORM_OSX) || defined(__MACH__) || (defined(__MSL__) && (__dest_os == __mac_os_x)) - #undef EA_PLATFORM_OSX - #define EA_PLATFORM_OSX 1 - #define EA_PLATFORM_UNIX 1 - #define EA_PLATFORM_NAME "OSX" - #if defined(__i386__) || defined(__intel__) - #define EA_PROCESSOR_X86 - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "OSX on x86" - #elif defined(__x86_64) || defined(__amd64) - #define EA_PROCESSOR_X86_64 - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "OSX on x86-64" - #elif defined(__arm__) - #define EA_PROCESSOR_ARM - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "OSX on ARM" - #elif defined(__POWERPC64__) || defined(__powerpc64__) - #define EA_PROCESSOR_POWERPC - #define EA_PROCESSOR_POWERPC_64 - #define EA_SYSTEM_BIG_ENDIAN - #define EA_PLATFORM_DESCRIPTION "OSX on PowerPC 64" - #elif defined(__POWERPC__) || defined(__powerpc__) - #define EA_PROCESSOR_POWERPC - #define EA_PROCESSOR_POWERPC_32 - #define EA_SYSTEM_BIG_ENDIAN - #define EA_PLATFORM_DESCRIPTION "OSX on PowerPC" - #else - #error Unknown processor - #endif - #if defined(__GNUC__) - #define EA_ASM_STYLE_ATT - #else - #define EA_ASM_STYLE_MOTOROLA - #endif - #define EA_PLATFORM_DESKTOP - - #else - #error Unknown Apple Platform - #endif +#undef EA_PLATFORM_ANDROID +#define EA_PLATFORM_ANDROID 1 +#define EA_PLATFORM_LINUX 1 +#define EA_PLATFORM_UNIX 1 +#define EA_PLATFORM_POSIX 1 +#define EA_PLATFORM_NAME "Android" +#define EA_ASM_STYLE_ATT 1 +#if defined(__arm__) +#define EA_ABI_ARM_LINUX 1 // a.k.a. "ARM eabi" +#define EA_PROCESSOR_ARM32 1 +#define EA_PLATFORM_DESCRIPTION "Android on ARM" +#elif defined(__aarch64__) +#define EA_PROCESSOR_ARM64 1 +#define EA_PLATFORM_DESCRIPTION "Android on ARM64" +#elif defined(__i386__) +#define EA_PROCESSOR_X86 1 +#define EA_PLATFORM_DESCRIPTION "Android on x86" +#elif defined(__x86_64) +#define EA_PROCESSOR_X86_64 1 +#define EA_PLATFORM_DESCRIPTION "Android on x64" +#else +#error Unknown processor +#endif +#if !defined(EA_SYSTEM_BIG_ENDIAN) && !defined(EA_SYSTEM_LITTLE_ENDIAN) +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#endif +#define EA_PLATFORM_MOBILE 1 + +// Samsung SMART TV - a Linux-based smart TV +#elif defined(EA_PLATFORM_SAMSUNG_TV) +#undef EA_PLATFORM_SAMSUNG_TV +#define EA_PLATFORM_SAMSUNG_TV 1 +#define EA_PLATFORM_LINUX 1 +#define EA_PLATFORM_UNIX 1 +#define EA_PLATFORM_POSIX 1 +#define EA_PLATFORM_NAME "SamsungTV" +#define EA_PLATFORM_DESCRIPTION "Samsung SMART TV on ARM" +#define EA_ASM_STYLE_ATT 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PROCESSOR_ARM32 1 +#define EA_ABI_ARM_LINUX 1 // a.k.a. "ARM eabi" +#define EA_PROCESSOR_ARM7 1 + +#elif defined(__APPLE__) && __APPLE__ +#include + +// Apple family of operating systems. +#define EA_PLATFORM_APPLE +#define EA_PLATFORM_POSIX 1 + +// iPhone +// TARGET_OS_IPHONE will be undefined on an unknown compiler, and will be defined on gcc. +#if defined(EA_PLATFORM_IPHONE) || defined(__IPHONE__) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR) +#undef EA_PLATFORM_IPHONE +#define EA_PLATFORM_IPHONE 1 +#define EA_PLATFORM_NAME "iPhone" +#define EA_ASM_STYLE_ATT 1 +#define EA_POSIX_THREADS_AVAILABLE 1 +#if defined(__arm__) +#define EA_ABI_ARM_APPLE 1 +#define EA_PROCESSOR_ARM32 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "iPhone on ARM" +#elif defined(__aarch64__) || defined(__AARCH64) +#define EA_ABI_ARM64_APPLE 1 +#define EA_PROCESSOR_ARM64 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "iPhone on ARM64" +#elif defined(__i386__) +#define EA_PLATFORM_IPHONE_SIMULATOR 1 +#define EA_PROCESSOR_X86 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "iPhone simulator on x86" +#elif defined(__x86_64) || defined(__amd64) +#define EA_PROCESSOR_X86_64 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "iPhone simulator on x64" +#else +#error Unknown processor +#endif +#define EA_PLATFORM_MOBILE 1 + +// Macintosh OSX +// TARGET_OS_MAC is defined by the Metrowerks and older AppleC compilers. +// Howerver, TARGET_OS_MAC is defined to be 1 in all cases. +// __i386__ and __intel__ are defined by the GCC compiler. +// __dest_os is defined by the Metrowerks compiler. +// __MACH__ is defined by the Metrowerks and GCC compilers. +// powerc and __powerc are defined by the Metrowerks and GCC compilers. +#elif defined(EA_PLATFORM_OSX) || defined(__MACH__) || (defined(__MSL__) && (__dest_os == __mac_os_x)) +#undef EA_PLATFORM_OSX +#define EA_PLATFORM_OSX 1 +#define EA_PLATFORM_UNIX 1 +#define EA_PLATFORM_POSIX 1 +//#define EA_PLATFORM_BSD 1 We don't currently define this. OSX has some BSD history but a lot of the API is different. +#define EA_PLATFORM_NAME "OSX" +#if defined(__i386__) || defined(__intel__) +#define EA_PROCESSOR_X86 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "OSX on x86" +#elif defined(__x86_64) || defined(__amd64) +#define EA_PROCESSOR_X86_64 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "OSX on x64" +#elif defined(__arm__) +#define EA_ABI_ARM_APPLE 1 +#define EA_PROCESSOR_ARM32 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "OSX on ARM" +#elif defined(__aarch64__) || defined(__AARCH64) +#define EA_ABI_ARM64_APPLE 1 +#define EA_PROCESSOR_ARM64 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "OSX on ARM64" +#elif defined(__POWERPC64__) || defined(__powerpc64__) +#define EA_PROCESSOR_POWERPC 1 +#define EA_PROCESSOR_POWERPC_64 1 +#define EA_SYSTEM_BIG_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "OSX on PowerPC 64" +#elif defined(__POWERPC__) || defined(__powerpc__) +#define EA_PROCESSOR_POWERPC 1 +#define EA_PROCESSOR_POWERPC_32 1 +#define EA_SYSTEM_BIG_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "OSX on PowerPC" +#else +#error Unknown processor +#endif +#if defined(__GNUC__) +#define EA_ASM_STYLE_ATT 1 +#else +#define EA_ASM_STYLE_MOTOROLA 1 +#endif +#define EA_PLATFORM_DESKTOP 1 +#else +#error Unknown Apple Platform +#endif // Linux // __linux and __linux__ are defined by the GCC and Borland compiler. @@ -345,59 +387,137 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // _M_IX86 is defined by the Borland compiler. // __sparc__ is defined by the GCC compiler. // __powerpc__ is defined by the GCC compiler. +// __ARM_EABI__ is defined by GCC on an ARM v6l (Raspberry Pi 1) +// __ARM_ARCH_7A__ is defined by GCC on an ARM v7l (Raspberry Pi 2) #elif defined(EA_PLATFORM_LINUX) || (defined(__linux) || defined(__linux__)) - #undef EA_PLATFORM_LINUX - #define EA_PLATFORM_LINUX 1 - #define EA_PLATFORM_UNIX 1 - #define EA_PLATFORM_NAME "Linux" - #if defined(__i386__) || defined(__intel__) || defined(_M_IX86) - #define EA_PROCESSOR_X86 - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "Linux on x86" - #elif defined(__x86_64__) - #define EA_PROCESSOR_X86_64 - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "Linux on x86-64" - #elif defined(__powerpc64__) - #define EA_PROCESSOR_POWERPC - #define EA_PROCESSOR_POWERPC_64 - #define EA_SYSTEM_BIG_ENDIAN - #define EA_PLATFORM_DESCRIPTION "Linux on PowerPC 64" - #elif defined(__powerpc__) - #define EA_PROCESSOR_POWERPC - #define EA_PROCESSOR_POWERPC_32 - #define EA_SYSTEM_BIG_ENDIAN - #define EA_PLATFORM_DESCRIPTION "Linux on PowerPC" - #elif defined(__arm__) || defined(__aarch64__) - #define EA_PROCESSOR_ARM - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "Linux on ARM" - #else - #error Unknown processor - #error Unknown endianness - #endif - #if defined(__GNUC__) - #define EA_ASM_STYLE_ATT - #endif - #define EA_PLATFORM_DESKTOP - -// Win CE (Windows mobile) -#elif defined(EA_PLATFORM_WINCE) || defined(_WIN32_WCE) - #undef EA_PLATFORM_WINCE - #define EA_PLATFORM_WINCE 1 - #define EA_PLATFORM_NAME "WinCE" - #define EA_ASM_STYLE_INTEL - #define EA_SYSTEM_LITTLE_ENDIAN - #if defined(_M_ARM) // Also there is _M_ARMT - #define EA_PROCESSOR_ARM - #define EA_PLATFORM_DESCRIPTION "Windows CE on ARM" - #elif defined(_M_IX86) - #define EA_PROCESSOR_X86 - #define EA_PLATFORM_DESCRIPTION "Windows CE on X86" - #else //Possibly other Windows CE variants - #error Unknown processor - #endif - #define EA_PLATFORM_MOBILE +#undef EA_PLATFORM_LINUX +#define EA_PLATFORM_LINUX 1 +#define EA_PLATFORM_UNIX 1 +#define EA_PLATFORM_POSIX 1 +#define EA_PLATFORM_NAME "Linux" +#if defined(__i386__) || defined(__intel__) || defined(_M_IX86) +#define EA_PROCESSOR_X86 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "Linux on x86" +#elif defined(__ARM_ARCH_7A__) || defined(__ARM_EABI__) +#define EA_ABI_ARM_LINUX 1 +#define EA_PROCESSOR_ARM32 1 +#define EA_PLATFORM_DESCRIPTION "Linux on ARM 6/7 32-bits" +#elif defined(__aarch64__) || defined(__AARCH64) +#define EA_PROCESSOR_ARM64 1 +#define EA_PLATFORM_DESCRIPTION "Linux on ARM64" +#elif defined(__x86_64__) +#define EA_PROCESSOR_X86_64 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "Linux on x64" +#elif defined(__powerpc64__) +#define EA_PROCESSOR_POWERPC 1 +#define EA_PROCESSOR_POWERPC_64 1 +#define EA_SYSTEM_BIG_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "Linux on PowerPC 64" +#elif defined(__powerpc__) +#define EA_PROCESSOR_POWERPC 1 +#define EA_PROCESSOR_POWERPC_32 1 +#define EA_SYSTEM_BIG_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "Linux on PowerPC" +#else +#error Unknown processor +#error Unknown endianness +#endif +#if defined(__GNUC__) +#define EA_ASM_STYLE_ATT 1 +#endif +#define EA_PLATFORM_DESKTOP 1 + + +#elif defined(EA_PLATFORM_BSD) || (defined(__BSD__) || defined(__FreeBSD__)) +#undef EA_PLATFORM_BSD +#define EA_PLATFORM_BSD 1 +#define EA_PLATFORM_UNIX 1 +#define EA_PLATFORM_POSIX 1 // BSD's posix complaince is not identical to Linux's +#define EA_PLATFORM_NAME "BSD Unix" +#if defined(__i386__) || defined(__intel__) +#define EA_PROCESSOR_X86 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "BSD on x86" +#elif defined(__x86_64__) +#define EA_PROCESSOR_X86_64 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "BSD on x64" +#elif defined(__powerpc64__) +#define EA_PROCESSOR_POWERPC 1 +#define EA_PROCESSOR_POWERPC_64 1 +#define EA_SYSTEM_BIG_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "BSD on PowerPC 64" +#elif defined(__powerpc__) +#define EA_PROCESSOR_POWERPC 1 +#define EA_PROCESSOR_POWERPC_32 1 +#define EA_SYSTEM_BIG_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "BSD on PowerPC" +#else +#error Unknown processor +#error Unknown endianness +#endif +#if !defined(EA_PLATFORM_FREEBSD) && defined(__FreeBSD__) +#define EA_PLATFORM_FREEBSD 1 // This is a variation of BSD. +#endif +#if defined(__GNUC__) +#define EA_ASM_STYLE_ATT 1 +#endif +#define EA_PLATFORM_DESKTOP 1 + + +#elif defined(EA_PLATFORM_WINDOWS_PHONE) +#undef EA_PLATFORM_WINDOWS_PHONE +#define EA_PLATFORM_WINDOWS_PHONE 1 +#define EA_PLATFORM_NAME "Windows Phone" +#if defined(_M_AMD64) || defined(_AMD64_) || defined(__x86_64__) +#define EA_PROCESSOR_X86_64 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "Windows Phone on x64" +#elif defined(_M_IX86) || defined(_X86_) +#define EA_PROCESSOR_X86 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "Windows Phone on X86" +#elif defined(_M_ARM) +#define EA_ABI_ARM_WINCE 1 +#define EA_PROCESSOR_ARM32 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "Windows Phone on ARM" +#else //Possibly other Windows Phone variants +#error Unknown processor +#error Unknown endianness +#endif +#define EA_PLATFORM_MICROSOFT 1 + +// WINAPI_FAMILY defines - mirrored from winapifamily.h +#define EA_WINAPI_FAMILY_APP 1 +#define EA_WINAPI_FAMILY_DESKTOP_APP 2 +#define EA_WINAPI_FAMILY_PHONE_APP 3 + +#if defined(WINAPI_FAMILY) +#include +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#define EA_WINAPI_FAMILY EA_WINAPI_FAMILY_PHONE_APP +#else +#error Unsupported WINAPI_FAMILY for Windows Phone +#endif +#else +#error WINAPI_FAMILY should always be defined on Windows Phone. +#endif + +// Macro to determine if a partition is enabled. +#define EA_WINAPI_FAMILY_PARTITION(Partition) (Partition) + +// Enable the appropriate partitions for the current family +#if EA_WINAPI_FAMILY == EA_WINAPI_FAMILY_PHONE_APP +# define EA_WINAPI_PARTITION_CORE 1 +# define EA_WINAPI_PARTITION_PHONE 1 +# define EA_WINAPI_PARTITION_APP 1 +#else +# error Unsupported WINAPI_FAMILY for Windows Phone +#endif + // Windows // _WIN32 is defined by the VC++, Intel and GCC compilers. @@ -407,128 +527,110 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // _M_IX86, _M_AMD64 and _M_IA64 are defined by the VC++, Intel, and Borland compilers. // _X86_, _AMD64_, and _IA64_ are defined by the Metrowerks compiler. // _M_ARM is defined by the VC++ compiler. -#elif (defined(EA_PLATFORM_WINDOWS) || (defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || (defined(__MWERKS__) && defined(_X86_)))) && !defined(_XBOX) - #undef EA_PLATFORM_WINDOWS - #define EA_PLATFORM_WINDOWS 1 - #define EA_PLATFORM_NAME "Windows" - #ifdef _WIN64 // VC++ defines both _WIN32 and _WIN64 when compiling for Win64. - #define EA_PLATFORM_WIN64 - #else - #define EA_PLATFORM_WIN32 - #endif - #if defined(_M_AMD64) || defined(_AMD64_) || defined(__x86_64__) - #define EA_PROCESSOR_X86_64 - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "Windows on X86-64" - #elif defined(_M_IX86) || defined(_X86_) - #define EA_PROCESSOR_X86 - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "Windows on X86" - #elif defined(_M_IA64) || defined(_IA64_) - #define EA_PROCESSOR_IA64 - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "Windows on IA-64" - #elif defined(_M_ARM) - #define EA_PROCESSOR_ARM - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "Windows CE on ARM" - #else //Possibly other Windows CE variants - #error Unknown processor - #error Unknown endianness - #endif - #if defined(__GNUC__) - #define EA_ASM_STYLE_ATT - #elif defined(_MSC_VER) || defined(__BORLANDC__) || defined(__ICL) - #define EA_ASM_STYLE_INTEL - #endif - #define EA_PLATFORM_DESKTOP - #define EA_PLATFORM_MICROSOFT 1 +#elif (defined(EA_PLATFORM_WINDOWS) || (defined(_WIN32) || defined(__WIN32__) || defined(_WIN64))) && !defined(CS_UNDEFINED_STRING) +#undef EA_PLATFORM_WINDOWS +#define EA_PLATFORM_WINDOWS 1 +#define EA_PLATFORM_NAME "Windows" +#ifdef _WIN64 // VC++ defines both _WIN32 and _WIN64 when compiling for Win64. +#define EA_PLATFORM_WIN64 1 +#else +#define EA_PLATFORM_WIN32 1 +#endif +#if defined(_M_AMD64) || defined(_AMD64_) || defined(__x86_64__) +#define EA_PROCESSOR_X86_64 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "Windows on x64" +#elif defined(_M_IX86) || defined(_X86_) +#define EA_PROCESSOR_X86 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "Windows on X86" +#elif defined(_M_IA64) || defined(_IA64_) +#define EA_PROCESSOR_IA64 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "Windows on IA-64" +#elif defined(_M_ARM) +#define EA_ABI_ARM_WINCE 1 +#define EA_PROCESSOR_ARM32 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "Windows on ARM" +#elif defined(_M_ARM64) +#define EA_PROCESSOR_ARM64 1 +#define EA_SYSTEM_LITTLE_ENDIAN 1 +#define EA_PLATFORM_DESCRIPTION "Windows on ARM64" +#else //Possibly other Windows CE variants +#error Unknown processor +#error Unknown endianness +#endif +#if defined(__GNUC__) +#define EA_ASM_STYLE_ATT 1 +#elif defined(_MSC_VER) || defined(__BORLANDC__) || defined(__ICL) +#define EA_ASM_STYLE_INTEL 1 +#endif +#define EA_PLATFORM_DESKTOP 1 +#define EA_PLATFORM_MICROSOFT 1 + +// WINAPI_FAMILY defines to support Windows 8 Metro Apps - mirroring winapifamily.h in the Windows 8 SDK +#define EA_WINAPI_FAMILY_APP 1000 +#define EA_WINAPI_FAMILY_DESKTOP_APP 1001 +#define EA_WINAPI_FAMILY_GAMES 1006 + +#if defined(WINAPI_FAMILY) +#if defined(_MSC_VER) +#pragma warning(push, 0) +#endif +#include +#if defined(_MSC_VER) +#pragma warning(pop) +#endif +#if defined(WINAPI_FAMILY_DESKTOP_APP) && WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP +#define EA_WINAPI_FAMILY EA_WINAPI_FAMILY_DESKTOP_APP +#elif defined(WINAPI_FAMILY_APP) && WINAPI_FAMILY == WINAPI_FAMILY_APP +#define EA_WINAPI_FAMILY EA_WINAPI_FAMILY_APP +#elif defined(WINAPI_FAMILY_GAMES) && WINAPI_FAMILY == WINAPI_FAMILY_GAMES +#define EA_WINAPI_FAMILY EA_WINAPI_FAMILY_GAMES +#else +#error Unsupported WINAPI_FAMILY +#endif +#else +#define EA_WINAPI_FAMILY EA_WINAPI_FAMILY_DESKTOP_APP +#endif + +#define EA_WINAPI_PARTITION_DESKTOP 1 +#define EA_WINAPI_PARTITION_APP 1 +#define EA_WINAPI_PARTITION_GAMES (EA_WINAPI_FAMILY == EA_WINAPI_FAMILY_GAMES) + +#define EA_WINAPI_FAMILY_PARTITION(Partition) (Partition) + +// EA_PLATFORM_WINRT +// This is a subset of Windows which is used for tablets and the "Metro" (restricted) Windows user interface. +// WinRT doesn't doesn't have access to the Windows "desktop" API, but WinRT can nevertheless run on +// desktop computers in addition to tablets. The Windows Phone API is a subset of WinRT and is not included +// in it due to it being only a part of the API. +#if defined(__cplusplus_winrt) +#define EA_PLATFORM_WINRT 1 +#endif // Sun (Solaris) // __SUNPRO_CC is defined by the Sun compiler. // __sun is defined by the GCC compiler. // __i386 is defined by the Sun and GCC compilers. // __sparc is defined by the Sun and GCC compilers. -#elif defined(EA_PLATFORM_SUN) || (defined(__SUNPRO_CC) || defined(__sun)) - #undef EA_PLATFORM_SUN - #define EA_PLATFORM_SUN 1 - #define EA_PLATFORM_UNIX 1 - #define EA_PLATFORM_NAME "SUN" - #if defined(__i386) - #define EA_PROCESSOR_X86 - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "SUN on x86" - #elif defined(__sparc) - #define EA_PROCESSOR_SPARC - #define EA_SYSTEM_BIG_ENDIAN - #define EA_PLATFORM_DESCRIPTION "SUN on Sparc" - #else - #error Unknown processor - #error Unknown endianness - #endif - #define EA_PLATFORM_DESKTOP - -#elif defined(__ghs__) - #undef EA_PLATFORM_INTEGRITY - #define EA_PLATFORM_INTEGRITY 1 - #undef EA_PLATFORM_LINUX - #define EA_PLATFORM_LINUX 1 - #define EA_PLATFORM_UNIX 1 - #define EA_PLATFORM_NAME "INTEGRITY" - #define EA_PROCESSOR_ARM - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "INTEGRITY on ARM" - #define EA_PLATFORM_DESKTOP - -#elif defined(__QNX__) || defined(__QNXNTO__) - #undef EA_PLATFORM_QNX - #define EA_PLATFORM_QNX 1 - #undef EA_PLATFORM_LINUX - #define EA_PLATFORM_LINUX 1 - #define EA_PLATFORM_UNIX 1 - #define EA_PLATFORM_NAME "QNX" - #if defined(__i386__) || defined(__intel__) || defined(_M_IX86) - #define EA_PROCESSOR_X86 - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "QNX on x86" - #elif defined(__x86_64__) - #define EA_PROCESSOR_X86_64 - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "QNX on x86-64" - #elif defined(__powerpc64__) - #define EA_PROCESSOR_POWERPC - #define EA_PROCESSOR_POWERPC_64 - #define EA_SYSTEM_BIG_ENDIAN - #define EA_PLATFORM_DESCRIPTION "QNX on PowerPC 64" - #elif defined(__powerpc__) - #define EA_PROCESSOR_POWERPC - #define EA_PROCESSOR_POWERPC_32 - #define EA_SYSTEM_BIG_ENDIAN - #define EA_PLATFORM_DESCRIPTION "QNX on PowerPC" - #elif defined(__arm__) || defined(__aarch64__) - #define EA_PROCESSOR_ARM - #define EA_SYSTEM_LITTLE_ENDIAN - #define EA_PLATFORM_DESCRIPTION "QNX on ARM" - #else - #error Unknown processor - #error Unknown endianness - #endif - #if defined(__GNUC__) - #define EA_ASM_STYLE_ATT - #endif - #define EA_PLATFORM_DESKTOP #else - #error Unknown platform - #error Unknown processor - #error Unknown endianness +#error Unknown platform +#error Unknown processor +#error Unknown endianness #endif - +#ifndef EA_PROCESSOR_ARM +#if defined(EA_PROCESSOR_ARM32) || defined(EA_PROCESSOR_ARM64) || defined(EA_PROCESSOR_ARM7) +#define EA_PROCESSOR_ARM +#endif +#endif // EA_PLATFORM_PTR_SIZE // Platform pointer size; same as sizeof(void*). -// This is not the same as sizeof(int), as int is usually 32 bits on -// even 64 bit platforms. +// This is not the same as sizeof(int), as int is usually 32 bits on +// even 64 bit platforms. // // _WIN64 is defined by Win64 compilers, such as VC++. // _M_IA64 is defined by VC++ and Intel compilers for IA64 processors. @@ -542,72 +644,89 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // __sizeof_ptr is defined by the ARM compiler (armcc, armcpp). // #ifndef EA_PLATFORM_PTR_SIZE - #if defined(__WORDSIZE) // Defined by some variations of GCC. - #define EA_PLATFORM_PTR_SIZE ((__WORDSIZE) / 8) - #elif defined(_WIN64) || defined(__LP64__) || defined(_LP64) || defined(_M_IA64) || defined(__ia64__) || defined(__arch64__) || defined(__mips64__) || defined(__64BIT__) - #define EA_PLATFORM_PTR_SIZE 8 - #elif defined(__CC_ARM) && (__sizeof_ptr == 8) - #define EA_PLATFORM_PTR_SIZE 8 - #else - #define EA_PLATFORM_PTR_SIZE 4 - #endif +#if defined(__WORDSIZE) // Defined by some variations of GCC. +#define EA_PLATFORM_PTR_SIZE ((__WORDSIZE) / 8) +#elif defined(_WIN64) || defined(__LP64__) || defined(_LP64) || defined(_M_IA64) || defined(__ia64__) || defined(__arch64__) || defined(__aarch64__) || defined(__mips64__) || defined(__64BIT__) || defined(__Ptr_Is_64) +#define EA_PLATFORM_PTR_SIZE 8 +#elif defined(__CC_ARM) && (__sizeof_ptr == 8) +#define EA_PLATFORM_PTR_SIZE 8 +#else +#define EA_PLATFORM_PTR_SIZE 4 +#endif #endif // EA_PLATFORM_WORD_SIZE -// This defines the size of a machine word. This will be the same as +// This defines the size of a machine word. This will be the same as // the size of registers on the machine but not necessarily the same // as the size of pointers on the machine. A number of 64 bit platforms // have 64 bit registers but 32 bit pointers. // #ifndef EA_PLATFORM_WORD_SIZE - #if defined(EA_PLATFORM_XENON) || defined(EA_PLATFORM_PS3) - #define EA_PLATFORM_WORD_SIZE 8 - #else - #define EA_PLATFORM_WORD_SIZE EA_PLATFORM_PTR_SIZE - #endif +#define EA_PLATFORM_WORD_SIZE EA_PLATFORM_PTR_SIZE #endif +// EA_PLATFORM_MIN_MALLOC_ALIGNMENT +// This defines the minimal alignment that the platform's malloc +// implementation will return. This should be used when writing custom +// allocators to ensure that the alignment matches that of malloc +#ifndef EA_PLATFORM_MIN_MALLOC_ALIGNMENT +#if defined(EA_PLATFORM_APPLE) +#define EA_PLATFORM_MIN_MALLOC_ALIGNMENT 16 +#elif defined(EA_PLATFORM_ANDROID) && defined(EA_PROCESSOR_ARM) +#define EA_PLATFORM_MIN_MALLOC_ALIGNMENT 8 +#elif defined(EA_PLATFORM_ANDROID) && defined(EA_PROCESSOR_X86_64) +#define EA_PLATFORM_MIN_MALLOC_ALIGNMENT 8 +#else +#define EA_PLATFORM_MIN_MALLOC_ALIGNMENT (EA_PLATFORM_PTR_SIZE * 2) +#endif +#endif -// Disabled until and unless deemed useful: -// -// Platform integer types -// These definitions allow us to define other things properly, such as -// sized integer types. In order to bring some order to this chaos, -// we follow a variation of the standard LP64 conventions defined at: -// http://www.opengroup.org/public/tech/aspen/lp64_wp.htm +// EA_MISALIGNED_SUPPORT_LEVEL +// Specifies if the processor can read and write built-in types that aren't +// naturally aligned. +// 0 - not supported. Likely causes an exception. +// 1 - supported but slow. +// 2 - supported and fast. // -// #if defined(EA_PLATFORM_LINUX) || defined(EA_PLATFORM_OSX) || defined(EA_PLATFORM_XBOX) || defined(EA_PLATFORM_XENON) -// #define EA_PLATFORM_ILP32_LL64 // int, long, ptr = 32 bits; long long = 64 bits. -// -// #elif defined(EA_PLATFORM_SUN) || defined(EA_PLATFORM_SGI) -// #if (EA_PLATFORM_WORD_SIZE == 32) -// #define ILP32_LL64 // int, long, ptr = 32 bits; long long = 64 bits. -// #else // 64 bit platform -// #define EA_PLATFORM_I32_LLLP64 // int = 32 bits; long, long long, ptr = 64 bits. -// #endif -// -// #elif defined(EA_PLATFORM_WINDOWS) -// #if (EA_PLATFORM_WORD_SIZE == 32) -// #define ILP32_LL64 // int, long, ptr = 32 bits; long long = 64 bits. -// #else // 64 bit platform -// #if defined(__MWERKS__) || defined(__GNUC__) -// #define EA_PLATFORM_I32_LLLP64 // int = 32 bits; long, long long, ptr = 64 bits. -// #else // MSVC -// #define EA_PLATFORM_IL32_LLP64 // int, long = 32 bits; long long, ptr = 64 bits. -// #endif -// #endif -// #endif - - -#endif // INCLUDED_eaplatform_H +#ifndef EA_MISALIGNED_SUPPORT_LEVEL +#if defined(EA_PROCESSOR_X86_64) +#define EA_MISALIGNED_SUPPORT_LEVEL 2 +#else +#define EA_MISALIGNED_SUPPORT_LEVEL 0 +#endif +#endif +// Macro to determine if a Windows API partition is enabled. Always false on non Microsoft platforms. +#if !defined(EA_WINAPI_FAMILY_PARTITION) +#define EA_WINAPI_FAMILY_PARTITION(Partition) (0) +#endif +// EA_CACHE_LINE_SIZE +// Specifies the cache line size broken down by compile target. +// This the expected best guess values for the targets that we can make at compilation time. + +#ifndef EA_CACHE_LINE_SIZE +#if defined(EA_PROCESSOR_X86) +#define EA_CACHE_LINE_SIZE 32 // This is the minimum possible value. +#elif defined(EA_PROCESSOR_X86_64) +#define EA_CACHE_LINE_SIZE 64 // This is the minimum possible value +#elif defined(EA_PROCESSOR_ARM32) +#define EA_CACHE_LINE_SIZE 32 // This varies between implementations and is usually 32 or 64. +#elif defined(EA_PROCESSOR_ARM64) +#define EA_CACHE_LINE_SIZE 64 // Cache line Cortex-A8 (64 bytes) http://shervinemami.info/armAssembly.html however this remains to be mostly an assumption at this stage +#elif (EA_PLATFORM_WORD_SIZE == 4) +#define EA_CACHE_LINE_SIZE 32 // This is the minimum possible value +#else +#define EA_CACHE_LINE_SIZE 64 // This is the minimum possible value +#endif +#endif +#endif // INCLUDED_eaplatform_H diff --git a/UnknownVersion/include/EABase/eabase.h b/UnknownVersion/include/EABase/eabase.h index 6752124..a378630 100644 --- a/UnknownVersion/include/EABase/eabase.h +++ b/UnknownVersion/include/EABase/eabase.h @@ -1,36 +1,7 @@ -/* -Copyright (C) 2009 Electronic Arts, Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of - its contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - /*----------------------------------------------------------------------------- * eabase.h * - * Copyright (c) 2002 - 2005 Electronic Arts Inc. All rights reserved. - * Maintained by Paul Pedriana, Maxis + * Copyright (c) Electronic Arts Inc. All rights reserved. *---------------------------------------------------------------------------*/ @@ -39,52 +10,23 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Identify the compiler and declare the EA_COMPILER_xxxx defines -#ifndef INCLUDED_eacompiler_H -# include "EABase/config/eacompiler.h" -#endif +#include // Identify traits which this compiler supports, or does not support -#ifndef INCLUDED_eacompilertraits_H -# include "EABase/config/eacompilertraits.h" -#endif +#include // Identify the platform and declare the EA_xxxx defines -#ifndef INCLUDED_eaplatform_H -# include "EABase/config/eaplatform.h" -#endif +#include -# if defined(_MSC_VER) && (_MSC_VER >= 1600) -#include +#if defined(EA_PRAGMA_ONCE_SUPPORTED) +#pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result. #endif +// Always include version.h for backwards compatibility. +#include - -/////////////////////////////////////////////////////////////////////////////// -// EABASE_VERSION -// -// We more or less follow the conventional EA packaging approach to versioning -// here. A primary distinction here is that minor versions are defined as two -// digit entities (e.g. .03") instead of minimal digit entities ".3"). The logic -// here is that the value is a counter and not a floating point fraction. -// Note that the major version doesn't have leading zeros. -// -// Example version strings: -// "0.91.00" // Major version 0, minor version 91, patch version 0. -// "1.00.00" // Major version 1, minor and patch version 0. -// "3.10.02" // Major version 3, minor version 10, patch version 02. -// "12.03.01" // Major version 12, minor version 03, patch version -// -// Example usage: -// printf("EABASE version: %s", EABASE_VERSION); -// printf("EABASE version: %d.%d.%d", EABASE_VERSION_N / 10000 % 100, EABASE_VERSION_N / 100 % 100, EABASE_VERSION_N % 100); -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef EABASE_VERSION -# define EABASE_VERSION "2.00.22" -# define EABASE_VERSION_N 20022 -#endif - +// Define common SI unit macros +#include // ------------------------------------------------------------------------ @@ -92,30 +34,41 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // not standards-compliant in this respect, so we need an additional include. // The case is similar with wchar_t under C++. -#if defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_MSVC) || defined(EA_WCHAR_T_NON_NATIVE) -# include +#if defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_MSVC) || defined(EA_WCHAR_T_NON_NATIVE) || defined(EA_PLATFORM_SONY) +#if defined(EA_COMPILER_MSVC) +#pragma warning(push, 0) +#pragma warning(disable: 4265 4365 4836 4574) +#endif +#include +#if defined(EA_COMPILER_MSVC) +#pragma warning(pop) +#endif #endif +// ------------------------------------------------------------------------ +// Include stddef.h on Apple's clang compiler to ensure the ptrdiff_t type +// is defined. +#if defined(EA_COMPILER_CLANG) && defined(EA_PLATFORM_APPLE) +#include +#endif // ------------------------------------------------------------------------ -// Ensure this header file is only processed once (with certain compilers) -// GCC doesn't need such a pragma because it has special recognition for -// include guards (such as that above) and effectively implements the same -// thing without having to resort to non-portable pragmas. It is possible -// that the decision to use pragma once here is ill-advised, perhaps because -// some compilers masquerade as MSVC but don't implement all features. -#if defined(EA_COMPILER_MSVC) || defined(EA_COMPILER_METROWERKS) -# pragma once +// Include assert.h on C11 supported compilers so we may allow static_assert usage +// http://en.cppreference.com/w/c/error/static_assert +// C11 standard(ISO / IEC 9899:2011) : +// 7.2/3 Diagnostics (p : 186) +#if !defined(__cplusplus) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201100L +#include #endif // ------------------------------------------------------------------------ -// By default, GCC on certain platforms defines NULL as ((void*)0), which is the +// By default, GCC defines NULL as ((void*)0), which is the // C definition. This causes all sort of problems for C++ code, so it is // worked around by undefining NULL. #if defined(NULL) -# undef NULL +#undef NULL #endif @@ -125,9 +78,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // is duplicated here. #if defined(__cplusplus) -# define NULL 0 +#define NULL 0 #else -# define NULL ((void*)0) +#define NULL ((void*)0) #endif @@ -137,482 +90,437 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // inttypes.h or stddef.h. Determining if they are predefined can be // tricky, so we expect some problems on non-standard compilers +//#if (defined(_INTTYPES_H) || defined(_INTTYPES_H_)) && !defined(PRId64) +// #error " was #included before eabase.h, but without __STDC_FORMAT_MACROS #defined. You must #include eabase.h or an equivalent before #including C99 headers, or you must define __STDC_FORMAT_MACRO before #including system headrs." +//#endif + // ------------------------------------------------------------------------ // We need to test this after we potentially include stddef.h, otherwise we // would have put this into the compilertraits header. #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)) -# define EA_COMPILER_HAS_INTTYPES +#define EA_COMPILER_HAS_INTTYPES #endif - #ifdef EA_COMPILER_HAS_INTTYPES // If the compiler supports inttypes... - // ------------------------------------------------------------------------ - // Include the stdint header to define and derive the required types. - // Additionally include inttypes.h as many compilers, including variations - // of GCC define things in inttypes.h that the C99 standard says goes - // in stdint.h. - // - // The C99 standard specifies that inttypes.h only define printf/scanf - // format macros if __STDC_FORMAT_MACROS is defined before #including - // inttypes.h. For consistency, we do that here. -# ifndef __STDC_FORMAT_MACROS -# define __STDC_FORMAT_MACROS -# endif -# if !defined(__psp__) && defined(__GNUC__) // The GCC compiler defines standard int types (e.g. uint32_t) but not PRId8, etc. -# include // PRId8, SCNd8, etc. -# endif -# include // int32_t, INT64_C, UINT8_MAX, etc. -# include // float_t, double_t, etc. -# include // FLT_EVAL_METHOD. - -# 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. -# ifdef __FLT_EVAL_METHOD__ -# define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ -# else -# define FLT_EVAL_METHOD _FEVAL -# endif -# endif - - // MinGW GCC (up to at least v4.3.0-20080502) mistakenly neglects to define float_t and double_t. - // This appears to be an acknowledged bug as of March 2008 and is scheduled to be fixed. - // Similarly, Android uses a mix of custom standard library headers which don't define float_t and double_t. -# if defined(__MINGW32__) || defined(EA_PLATFORM_ANDROID) -# if defined(__FLT_EVAL_METHOD__) -# if(__FLT_EVAL_METHOD__== 0) - typedef float float_t; - typedef double double_t; -# elif(__FLT_EVAL_METHOD__ == 1) - typedef double float_t; - typedef double double_t; -# elif(__FLT_EVAL_METHOD__ == 2) - typedef long double float_t; - typedef long double double_t; -# endif -# else - typedef float float_t; - typedef double double_t; -# endif -# endif - - // Airplay's pretty broken for these types (at least as of 4.1) -# if defined __S3E__ - - typedef float float_t; - typedef double double_t; - -# undef INT32_C -# undef UINT32_C -# undef INT64_C -# undef UINT64_C -# define INT32_C(x) x##L -# define UINT32_C(x) x##UL -# define INT64_C(x) x##LL -# define UINT64_C(x) x##ULL - -# define EA_PRI_64_LENGTH_SPECIFIER "ll" -# define EA_SCN_64_LENGTH_SPECIFIER "ll" - -# define SCNd16 "hd" -# define SCNi16 "hi" -# define SCNo16 "ho" -# define SCNu16 "hu" -# define SCNx16 "hx" - -# define SCNd32 "d" // This works for both 32 bit and 64 bit systems, as we assume LP64 conventions. -# define SCNi32 "i" -# define SCNo32 "o" -# define SCNu32 "u" -# define SCNx32 "x" - -# define SCNd64 EA_SCN_64_LENGTH_SPECIFIER "d" -# define SCNi64 EA_SCN_64_LENGTH_SPECIFIER "i" -# define SCNo64 EA_SCN_64_LENGTH_SPECIFIER "o" -# define SCNu64 EA_SCN_64_LENGTH_SPECIFIER "u" -# define SCNx64 EA_SCN_64_LENGTH_SPECIFIER "x" - -# define PRIdPTR PRId32 // Usage of pointer values will generate warnings with -# define PRIiPTR PRIi32 // some compilers because they are defined in terms of -# define PRIoPTR PRIo32 // integers. However, you can't simply use "p" because -# define PRIuPTR PRIu32 // 'p' is interpreted in a specific and often different -# define PRIxPTR PRIx32 // way by the library. -# define PRIXPTR PRIX32 - -# define PRId8 "hhd" -# define PRIi8 "hhi" -# define PRIo8 "hho" -# define PRIu8 "hhu" -# define PRIx8 "hhx" -# define PRIX8 "hhX" - -# define PRId16 "hd" -# define PRIi16 "hi" -# define PRIo16 "ho" -# define PRIu16 "hu" -# define PRIx16 "hx" -# define PRIX16 "hX" - -# define PRId32 "d" // This works for both 32 bit and 64 bit systems, as we assume LP64 conventions. -# define PRIi32 "i" -# define PRIo32 "o" -# define PRIu32 "u" -# define PRIx32 "x" -# define PRIX32 "X" - -# define PRId64 EA_PRI_64_LENGTH_SPECIFIER "d" -# define PRIi64 EA_PRI_64_LENGTH_SPECIFIER "i" -# define PRIo64 EA_PRI_64_LENGTH_SPECIFIER "o" -# define PRIu64 EA_PRI_64_LENGTH_SPECIFIER "u" -# define PRIx64 EA_PRI_64_LENGTH_SPECIFIER "x" -# define PRIX64 EA_PRI_64_LENGTH_SPECIFIER "X" -# endif - - // The CodeSourcery definitions of PRIxPTR and SCNxPTR are broken for 32 bit systems. -# if defined(__SIZEOF_SIZE_T__) && (__SIZEOF_SIZE_T__ == 4) && (defined(__have_long64) || defined(__have_longlong64) || defined(__S3E__)) -# undef PRIdPTR -# define PRIdPTR "d" -# undef PRIiPTR -# define PRIiPTR "i" -# undef PRIoPTR -# define PRIoPTR "o" -# undef PRIuPTR -# define PRIuPTR "u" -# undef PRIxPTR -# define PRIxPTR "x" -# undef PRIXPTR -# define PRIXPTR "X" - -# undef SCNdPTR -# define SCNdPTR "d" -# undef SCNiPTR -# define SCNiPTR "i" -# undef SCNoPTR -# define SCNoPTR "o" -# undef SCNuPTR -# define SCNuPTR "u" -# undef SCNxPTR -# define SCNxPTR "x" -# endif +// ------------------------------------------------------------------------ +// Include the stdint header to define and derive the required types. +// Additionally include inttypes.h as many compilers, including variations +// of GCC define things in inttypes.h that the C99 standard says goes +// in stdint.h. +// +// The C99 standard specifies that inttypes.h only define printf/scanf +// format macros if __STDC_FORMAT_MACROS is defined before #including +// inttypes.h. For consistency, we do that here. +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif +// The GCC PSP compiler defines standard int types (e.g. uint32_t) but not PRId8, etc. +// MSVC added support for inttypes.h header in VS2013. +#if !defined(EA_COMPILER_MSVC) || (defined(EA_COMPILER_MSVC) && EA_COMPILER_VERSION >= 1800) +#include // PRId8, SCNd8, etc. +#endif +#if defined(_MSC_VER) +#pragma warning(push, 0) +#endif +#include // int32_t, INT64_C, UINT8_MAX, etc. +#include // float_t, double_t, etc. +#include // FLT_EVAL_METHOD. +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#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. +#ifdef __FLT_EVAL_METHOD__ +#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__ +#else +#define FLT_EVAL_METHOD _FEVAL +#endif +#endif + +// MinGW GCC (up to at least v4.3.0-20080502) mistakenly neglects to define float_t and double_t. +// This appears to be an acknowledged bug as of March 2008 and is scheduled to be fixed. +// Similarly, Android uses a mix of custom standard library headers which prior to SDK API level 21 +// don't define float_t and double_t. +#if defined(__MINGW32__) || (defined(EA_PLATFORM_ANDROID) && !(defined(EA_ANDROID_SDK_LEVEL) && EA_ANDROID_SDK_LEVEL >= 21)) +#if defined(__FLT_EVAL_METHOD__) +#if(__FLT_EVAL_METHOD__== 0) +typedef float float_t; +typedef double double_t; +#elif(__FLT_EVAL_METHOD__ == 1) +typedef double float_t; +typedef double double_t; +#elif(__FLT_EVAL_METHOD__ == 2) +typedef long double float_t; +typedef long double double_t; +#endif +#else +typedef float float_t; +typedef double double_t; +#endif +#endif + +// The CodeSourcery definitions of PRIxPTR and SCNxPTR are broken for 32 bit systems. +#if defined(__SIZEOF_SIZE_T__) && (__SIZEOF_SIZE_T__ == 4) && (defined(__have_long64) || defined(__have_longlong64)) +#undef PRIdPTR +#define PRIdPTR "d" +#undef PRIiPTR +#define PRIiPTR "i" +#undef PRIoPTR +#define PRIoPTR "o" +#undef PRIuPTR +#define PRIuPTR "u" +#undef PRIxPTR +#define PRIxPTR "x" +#undef PRIXPTR +#define PRIXPTR "X" + +#undef SCNdPTR +#define SCNdPTR "d" +#undef SCNiPTR +#define SCNiPTR "i" +#undef SCNoPTR +#define SCNoPTR "o" +#undef SCNuPTR +#define SCNuPTR "u" +#undef SCNxPTR +#define SCNxPTR "x" +#endif #else // else we must implement types ourselves. -# if !defined(__S3E__) -# if !defined(__BIT_TYPES_DEFINED__) && !defined(__int8_t_defined) - typedef signed char int8_t; //< 8 bit signed integer -# endif -# if !defined( __int8_t_defined ) - typedef signed short int16_t; //< 16 bit signed integer - 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. -# define __int8_t_defined -# endif - typedef unsigned char uint8_t; //< 8 bit unsigned integer - typedef unsigned short uint16_t; //< 16 bit unsigned integer -# if !defined( __uint32_t_defined ) - 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. -# define __uint32_t_defined -# endif -# endif - - // According to the C98/99 standard, FLT_EVAL_METHOD defines control the - // width used for floating point _t types. -# if defined(__MWERKS__) && ((defined(_MSL_C99) && (_MSL_C99 == 1)) || (__MWERKS__ < 0x4000)) - // Metrowerks defines FLT_EVAL_METHOD and - // float_t/double_t under this condition. -# elif defined(FLT_EVAL_METHOD) -# if (FLT_EVAL_METHOD == 0) - typedef float float_t; - typedef double double_t; -# elif (FLT_EVAL_METHOD == 1) - typedef double float_t; - typedef double double_t; -# elif (FLT_EVAL_METHOD == 2) - typedef long double float_t; - typedef long double double_t; -# endif -# else -# define FLT_EVAL_METHOD 0 - typedef float float_t; - typedef double double_t; -# endif - -# if defined(EA_PLATFORM_LINUX) || defined(EA_PLATFORM_PS3) || defined(EA_PLATFORM_PS3_SPU) - typedef signed long long int64_t; - typedef unsigned long long uint64_t; - -# elif defined(EA_PLATFORM_SUN) || defined(EA_PLATFORM_SGI) -# if (EA_PLATFORM_PTR_SIZE == 4) - typedef signed long long int64_t; - typedef unsigned long long uint64_t; -# else - typedef signed long int64_t; - typedef unsigned long uint64_t; -# endif - -# elif defined(EA_PLATFORM_WINDOWS) || defined(EA_PLATFORM_XBOX) || defined(EA_PLATFORM_XENON) || defined(EA_PLATFORM_MAC) -# if defined(EA_COMPILER_MSVC) || defined(EA_COMPILER_BORLAND) || defined(EA_COMPILER_INTEL) - typedef signed __int64 int64_t; - typedef unsigned __int64 uint64_t; -# else // GCC, Metrowerks, etc. - typedef long long int64_t; - typedef unsigned long long uint64_t; -# endif -# elif defined(EA_PLATFORM_AIRPLAY) -# else - typedef signed long long int64_t; - typedef unsigned long long uint64_t; -# endif - - - // ------------------------------------------------------------------------ - // macros for declaring constants in a portable way. - // - // e.g. int64_t x = INT64_C(1234567812345678); - // e.g. int64_t x = INT64_C(0x1111111122222222); - // e.g. uint64_t x = UINT64_C(0x1111111122222222); - -# ifndef INT8_C_DEFINED // If the user hasn't already defined these... -# define INT8_C_DEFINED - - // VC++ 7.0 and earlier don't handle the LL suffix. -# if defined(EA_COMPILER_MSVC) || defined(EA_COMPILER_BORLAND) -# ifndef INT8_C -# define INT8_C(x) int8_t(x) // x##i8 doesn't work satisfactorilly because -128i8 generates an out of range warning. -# endif -# ifndef UINT8_C -# define UINT8_C(x) uint8_t(x) -# endif -# ifndef INT16_C -# define INT16_C(x) int16_t(x) // x##i16 doesn't work satisfactorilly because -32768i8 generates an out of range warning. -# endif -# ifndef UINT16_C -# define UINT16_C(x) uint16_t(x) -# endif -# ifndef INT32_C -# define INT32_C(x) x##i32 -# endif -# ifndef UINT32_C -# define UINT32_C(x) x##ui32 -# endif -# ifndef INT64_C -# define INT64_C(x) x##i64 -# endif -# ifndef UINT64_C -# define UINT64_C(x) x##ui64 -# endif - -# elif !defined(__STDC_CONSTANT_MACROS) // __STDC_CONSTANT_MACROS is defined by GCC 3 and later when INT8_C(), etc. are defined. -# define INT8_C(x) int8_t(x) // For the majority of compilers and platforms, long is 32 bits and long long is 64 bits. -# define UINT8_C(x) uint8_t(x) -# define INT16_C(x) int16_t(x) -# 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. -# if defined(EA_PLATFORM_PS3) // PS3 defines long as 64 bit, so we cannot use any size suffix. -# define INT32_C(x) int32_t(x) -# define UINT32_C(x) uint32_t(x) -# else // Else we are working on a platform whereby sizeof(long) == sizeof(int32_t). -# define INT32_C(x) x##L -# define UINT32_C(x) x##UL -# endif -# 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. -# define UINT64_C(x) x##ULL // We need to follow a similar approach for LL. -# endif -# endif - - // ------------------------------------------------------------------------ - // type sizes -# ifndef INT8_MAX_DEFINED // If the user hasn't already defined these... -# define INT8_MAX_DEFINED - - // The value must be 2^(n-1)-1 -# ifndef INT8_MAX -# define INT8_MAX 127 -# endif -# ifndef INT16_MAX -# define INT16_MAX 32767 -# endif -# ifndef INT32_MAX -# define INT32_MAX 2147483647 -# endif -# ifndef INT64_MAX -# define INT64_MAX INT64_C(9223372036854775807) -# endif - - // The value must be either -2^(n-1) or 1-2(n-1). -# ifndef INT8_MIN -# define INT8_MIN -128 -# endif -# ifndef INT16_MIN -# define INT16_MIN -32768 -# endif -# ifndef INT32_MIN -# define INT32_MIN (-INT32_MAX - 1) // -2147483648 -# endif -# ifndef INT64_MIN -# define INT64_MIN (-INT64_MAX - 1) // -9223372036854775808 -# endif - - // The value must be 2^n-1 -# ifndef UINT8_MAX -# define UINT8_MAX 0xffU // 255 -# endif -# ifndef UINT16_MAX -# define UINT16_MAX 0xffffU // 65535 -# endif -# ifndef UINT32_MAX -# define UINT32_MAX UINT32_C(0xffffffff) // 4294967295 -# endif -# ifndef UINT64_MAX -# define UINT64_MAX UINT64_C(0xffffffffffffffff) // 18446744073709551615 -# endif -# endif - - // ------------------------------------------------------------------------ - // sized printf and scanf format specifiers - // See the C99 standard, section 7.8.1 -- Macros for format specifiers. - // - // The C99 standard specifies that inttypes.h only define printf/scanf - // format macros if __STDC_FORMAT_MACROS is defined before #including - // inttypes.h. For consistency, we define both __STDC_FORMAT_MACROS and - // the printf format specifiers here. We also skip the "least/most" - // variations of these specifiers, as we've decided to do so with - // basic types. - // - // For 64 bit systems, we assume the LP64 standard is followed - // (as opposed to ILP64, etc.) For 32 bit systems, we assume the - // ILP32 standard is followed. See: - // http://www.opengroup.org/public/tech/aspen/lp64_wp.htm - // for information about this. Thus, on both 32 and 64 bit platforms, - // %l refers to 32 bit data while %ll refers to 64 bit data. - -# ifndef __STDC_FORMAT_MACROS -# define __STDC_FORMAT_MACROS -# endif - -# 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. -# define EA_PRI_64_LENGTH_SPECIFIER "I64" -# define EA_SCN_64_LENGTH_SPECIFIER "I64" -# else -# define EA_PRI_64_LENGTH_SPECIFIER "ll" -# define EA_SCN_64_LENGTH_SPECIFIER "ll" -# 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. - - // Printf format specifiers -# if defined(EA_COMPILER_IS_C99) || defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_METROWERKS) // || defined(EA_COMPILER_INTEL) ? -# define PRId8 "hhd" -# define PRIi8 "hhi" -# define PRIo8 "hho" -# define PRIu8 "hhu" -# define PRIx8 "hhx" -# define PRIX8 "hhX" -# else // VC++, Borland, etc. which have no way to specify 8 bit values other than %c. -# define PRId8 "c" // This may not work properly but it at least will not crash. Try using 16 bit versions instead. -# define PRIi8 "c" // " -# define PRIo8 "o" // " -# define PRIu8 "u" // " -# define PRIx8 "x" // " -# define PRIX8 "X" // " -# endif - -# define PRId16 "hd" -# define PRIi16 "hi" -# define PRIo16 "ho" -# define PRIu16 "hu" -# define PRIx16 "hx" -# define PRIX16 "hX" - -# define PRId32 "d" // This works for both 32 bit and 64 bit systems, as we assume LP64 conventions. -# define PRIi32 "i" -# define PRIo32 "o" -# define PRIu32 "u" -# define PRIx32 "x" -# define PRIX32 "X" - -# define PRId64 EA_PRI_64_LENGTH_SPECIFIER "d" -# define PRIi64 EA_PRI_64_LENGTH_SPECIFIER "i" -# define PRIo64 EA_PRI_64_LENGTH_SPECIFIER "o" -# define PRIu64 EA_PRI_64_LENGTH_SPECIFIER "u" -# define PRIx64 EA_PRI_64_LENGTH_SPECIFIER "x" -# define PRIX64 EA_PRI_64_LENGTH_SPECIFIER "X" - -# if (EA_PLATFORM_PTR_SIZE == 4) -# define PRIdPTR PRId32 // Usage of pointer values will generate warnings with -# define PRIiPTR PRIi32 // some compilers because they are defined in terms of -# define PRIoPTR PRIo32 // integers. However, you can't simply use "p" because -# define PRIuPTR PRIu32 // 'p' is interpreted in a specific and often different -# define PRIxPTR PRIx32 // way by the library. -# define PRIXPTR PRIX32 -# elif (EA_PLATFORM_PTR_SIZE == 8) -# define PRIdPTR PRId64 -# define PRIiPTR PRIi64 -# define PRIoPTR PRIo64 -# define PRIuPTR PRIu64 -# define PRIxPTR PRIx64 -# define PRIXPTR PRIX64 -# endif - - // Scanf format specifiers -# if defined(EA_COMPILER_IS_C99) || defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_METROWERKS) // || defined(EA_COMPILER_INTEL) ? -# define SCNd8 "hhd" -# define SCNi8 "hhi" -# define SCNo8 "hho" -# define SCNu8 "hhu" -# define SCNx8 "hhx" -# else // VC++, Borland, etc. which have no way to specify 8 bit values other than %c. -# define SCNd8 "c" // This will not work properly but it at least will not crash. Try using 16 bit versions instead. -# define SCNi8 "c" // " -# define SCNo8 "c" // " -# define SCNu8 "c" // " -# define SCNx8 "c" // " -# endif - -# define SCNd16 "hd" -# define SCNi16 "hi" -# define SCNo16 "ho" -# define SCNu16 "hu" -# define SCNx16 "hx" - -# define SCNd32 "d" // This works for both 32 bit and 64 bit systems, as we assume LP64 conventions. -# define SCNi32 "i" -# define SCNo32 "o" -# define SCNu32 "u" -# define SCNx32 "x" - -# define SCNd64 EA_SCN_64_LENGTH_SPECIFIER "d" -# define SCNi64 EA_SCN_64_LENGTH_SPECIFIER "i" -# define SCNo64 EA_SCN_64_LENGTH_SPECIFIER "o" -# define SCNu64 EA_SCN_64_LENGTH_SPECIFIER "u" -# define SCNx64 EA_SCN_64_LENGTH_SPECIFIER "x" - -# if (EA_PLATFORM_PTR_SIZE == 4) -# define SCNdPTR SCNd32 // Usage of pointer values will generate warnings with -# define SCNiPTR SCNi32 // some compilers because they are defined in terms of -# define SCNoPTR SCNo32 // integers. However, you can't simply use "p" because -# define SCNuPTR SCNu32 // 'p' is interpreted in a specific and often different -# define SCNxPTR SCNx32 // way by the library. -# elif (EA_PLATFORM_PTR_SIZE == 8) -# define SCNdPTR SCNd64 -# define SCNiPTR SCNi64 -# define SCNoPTR SCNo64 -# define SCNuPTR SCNu64 -# define SCNxPTR SCNx64 -# endif +#if !defined(__BIT_TYPES_DEFINED__) && !defined(__int8_t_defined) +typedef signed char int8_t; //< 8 bit signed integer +#endif +#if !defined( __int8_t_defined ) +typedef signed short int16_t; //< 16 bit signed integer +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. +#define __int8_t_defined +#endif +typedef unsigned char uint8_t; //< 8 bit unsigned integer +typedef unsigned short uint16_t; //< 16 bit unsigned integer +#if !defined( __uint32_t_defined ) +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. +#define __uint32_t_defined +#endif + +// According to the C98/99 standard, FLT_EVAL_METHOD defines control the +// width used for floating point _t types. +#if defined(_MSC_VER) && _MSC_VER >= 1800 +// MSVC's math.h provides float_t, double_t under this condition. +#elif defined(FLT_EVAL_METHOD) +#if (FLT_EVAL_METHOD == 0) +typedef float float_t; +typedef double double_t; +#elif (FLT_EVAL_METHOD == 1) +typedef double float_t; +typedef double double_t; +#elif (FLT_EVAL_METHOD == 2) +typedef long double float_t; +typedef long double double_t; +#endif +#endif + +#if defined(EA_COMPILER_MSVC) +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + +#else +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +#endif +#endif + + +// ------------------------------------------------------------------------ +// macros for declaring constants in a portable way. +// +// e.g. int64_t x = INT64_C(1234567812345678); +// e.g. int64_t x = INT64_C(0x1111111122222222); +// e.g. uint64_t x = UINT64_C(0x1111111122222222); +// +// Microsoft VC++'s definitions of INT8_C/UINT8_C/INT16_C/UINT16_C are like so: +// #define INT8_C(x) (x) +// #define INT16_C(x) (x) +// #define UINT8_C(x) (x) +// #define UINT16_C(x) (x) +// To consider: undefine Microsoft's and use the casting versions below. +// ------------------------------------------------------------------------ + +#ifndef INT8_C_DEFINED // If the user hasn't already defined these... +#define INT8_C_DEFINED + +#ifndef INT8_C +#define INT8_C(x) int8_t(x) // For the majority of compilers and platforms, long is 32 bits and long long is 64 bits. +#endif +#ifndef UINT8_C +#define UINT8_C(x) uint8_t(x) +#endif +#ifndef INT16_C +#define INT16_C(x) int16_t(x) +#endif +#ifndef UINT16_C +#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. +#endif +#ifndef INT32_C +#define INT32_C(x) x##L +#endif +#ifndef UINT32_C +#define UINT32_C(x) x##UL +#endif +#ifndef INT64_C +#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. +#endif +#ifndef UINT64_C +#define UINT64_C(x) x##ULL // We need to follow a similar approach for LL. +#endif +#ifndef UINTMAX_C +#define UINTMAX_C(x) UINT64_C(x) +#endif +#endif + +// ------------------------------------------------------------------------ +// type sizes +#ifndef INT8_MAX_DEFINED // If the user hasn't already defined these... +#define INT8_MAX_DEFINED +// The value must be 2^(n-1)-1 +#ifndef INT8_MAX +#define INT8_MAX 127 +#endif +#ifndef INT16_MAX +#define INT16_MAX 32767 +#endif +#ifndef INT32_MAX +#define INT32_MAX 2147483647 +#endif +#ifndef INT64_MAX +#define INT64_MAX INT64_C(9223372036854775807) +#endif +#ifndef INTMAX_MAX +#define INTMAX_MAX INT64_MAX +#endif +#ifndef INTPTR_MAX +#if EA_PLATFORM_PTR_SIZE == 4 +#define INTPTR_MAX INT32_MAX +#else +#define INTPTR_MAX INT64_MAX +#endif +#endif + +// The value must be either -2^(n-1) or 1-2(n-1). +#ifndef INT8_MIN +#define INT8_MIN -128 +#endif +#ifndef INT16_MIN +#define INT16_MIN -32768 +#endif +#ifndef INT32_MIN +#define INT32_MIN (-INT32_MAX - 1) // -2147483648 +#endif +#ifndef INT64_MIN +#define INT64_MIN (-INT64_MAX - 1) // -9223372036854775808 +#endif +#ifndef INTMAX_MIN +#define INTMAX_MIN INT64_MIN +#endif +#ifndef INTPTR_MIN +#if EA_PLATFORM_PTR_SIZE == 4 +#define INTPTR_MIN INT32_MIN +#else +#define INTPTR_MIN INT64_MIN +#endif +#endif + +// The value must be 2^n-1 +#ifndef UINT8_MAX +#define UINT8_MAX 0xffU // 255 +#endif +#ifndef UINT16_MAX +#define UINT16_MAX 0xffffU // 65535 +#endif +#ifndef UINT32_MAX +#define UINT32_MAX UINT32_C(0xffffffff) // 4294967295 +#endif +#ifndef UINT64_MAX +#define UINT64_MAX UINT64_C(0xffffffffffffffff) // 18446744073709551615 +#endif +#ifndef UINTMAX_MAX +#define UINTMAX_MAX UINT64_MAX +#endif +#ifndef UINTPTR_MAX +#if EA_PLATFORM_PTR_SIZE == 4 +#define UINTPTR_MAX UINT32_MAX +#else +#define UINTPTR_MAX UINT64_MAX +#endif +#endif +#endif + +#ifndef FLT_EVAL_METHOD +#define FLT_EVAL_METHOD 0 +typedef float float_t; +typedef double double_t; +#endif + +#if defined(EA_COMPILER_HAS_INTTYPES) && (!defined(EA_COMPILER_MSVC) || (defined(EA_COMPILER_MSVC) && EA_COMPILER_VERSION >= 1800)) +#define EA_COMPILER_HAS_C99_FORMAT_MACROS +#endif + +#ifndef EA_COMPILER_HAS_C99_FORMAT_MACROS +// ------------------------------------------------------------------------ +// sized printf and scanf format specifiers +// See the C99 standard, section 7.8.1 -- Macros for format specifiers. +// +// The C99 standard specifies that inttypes.h only define printf/scanf +// format macros if __STDC_FORMAT_MACROS is defined before #including +// inttypes.h. For consistency, we define both __STDC_FORMAT_MACROS and +// the printf format specifiers here. We also skip the "least/most" +// variations of these specifiers, as we've decided to do so with +// basic types. +// +// For 64 bit systems, we assume the LP64 standard is followed +// (as opposed to ILP64, etc.) For 32 bit systems, we assume the +// ILP32 standard is followed. See: +// http://www.opengroup.org/public/tech/aspen/lp64_wp.htm +// for information about this. Thus, on both 32 and 64 bit platforms, +// %l refers to 32 bit data while %ll refers to 64 bit data. + +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif + +#if defined(EA_COMPILER_MSVC) // VC++ 7.1+ understands long long as a data type but doesn't accept %ll as a printf specifier. +#define EA_PRI_64_LENGTH_SPECIFIER "I64" +#define EA_SCN_64_LENGTH_SPECIFIER "I64" +#else +#define EA_PRI_64_LENGTH_SPECIFIER "ll" +#define EA_SCN_64_LENGTH_SPECIFIER "ll" +#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. + +// Printf format specifiers +#if defined(EA_COMPILER_IS_C99) || defined(EA_COMPILER_GNUC) +#define PRId8 "hhd" +#define PRIi8 "hhi" +#define PRIo8 "hho" +#define PRIu8 "hhu" +#define PRIx8 "hhx" +#define PRIX8 "hhX" +#else // VC++, Borland, etc. which have no way to specify 8 bit values other than %c. +#define PRId8 "c" // This may not work properly but it at least will not crash. Try using 16 bit versions instead. +#define PRIi8 "c" // " +#define PRIo8 "o" // " +#define PRIu8 "u" // " +#define PRIx8 "x" // " +#define PRIX8 "X" // " +#endif + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" + +#define PRId32 "d" // This works for both 32 bit and 64 bit systems, as we assume LP64 conventions. +#define PRIi32 "i" +#define PRIo32 "o" +#define PRIu32 "u" +#define PRIx32 "x" +#define PRIX32 "X" + +#define PRId64 EA_PRI_64_LENGTH_SPECIFIER "d" +#define PRIi64 EA_PRI_64_LENGTH_SPECIFIER "i" +#define PRIo64 EA_PRI_64_LENGTH_SPECIFIER "o" +#define PRIu64 EA_PRI_64_LENGTH_SPECIFIER "u" +#define PRIx64 EA_PRI_64_LENGTH_SPECIFIER "x" +#define PRIX64 EA_PRI_64_LENGTH_SPECIFIER "X" + +#if (EA_PLATFORM_PTR_SIZE == 4) +#define PRIdPTR PRId32 // Usage of pointer values will generate warnings with +#define PRIiPTR PRIi32 // some compilers because they are defined in terms of +#define PRIoPTR PRIo32 // integers. However, you can't simply use "p" because +#define PRIuPTR PRIu32 // 'p' is interpreted in a specific and often different +#define PRIxPTR PRIx32 // way by the library. +#define PRIXPTR PRIX32 +#elif (EA_PLATFORM_PTR_SIZE == 8) +#define PRIdPTR PRId64 +#define PRIiPTR PRIi64 +#define PRIoPTR PRIo64 +#define PRIuPTR PRIu64 +#define PRIxPTR PRIx64 +#define PRIXPTR PRIX64 +#endif + +// Scanf format specifiers +#if defined(EA_COMPILER_IS_C99) || defined(EA_COMPILER_GNUC) +#define SCNd8 "hhd" +#define SCNi8 "hhi" +#define SCNo8 "hho" +#define SCNu8 "hhu" +#define SCNx8 "hhx" +#else // VC++, Borland, etc. which have no way to specify 8 bit values other than %c. +#define SCNd8 "c" // This will not work properly but it at least will not crash. Try using 16 bit versions instead. +#define SCNi8 "c" // " +#define SCNo8 "c" // " +#define SCNu8 "c" // " +#define SCNx8 "c" // " +#endif + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" + +#define SCNd32 "d" // This works for both 32 bit and 64 bit systems, as we assume LP64 conventions. +#define SCNi32 "i" +#define SCNo32 "o" +#define SCNu32 "u" +#define SCNx32 "x" + +#define SCNd64 EA_SCN_64_LENGTH_SPECIFIER "d" +#define SCNi64 EA_SCN_64_LENGTH_SPECIFIER "i" +#define SCNo64 EA_SCN_64_LENGTH_SPECIFIER "o" +#define SCNu64 EA_SCN_64_LENGTH_SPECIFIER "u" +#define SCNx64 EA_SCN_64_LENGTH_SPECIFIER "x" + +#if defined(EA_COMPILER_MSVC) && (EA_COMPILER_VERSION >= 1900) +#define SCNdPTR PRIdPTR +#define SCNiPTR PRIiPTR +#define SCNoPTR PRIoPTR +#define SCNuPTR PRIuPTR +#define SCNxPTR PRIxPTR +#elif (EA_PLATFORM_PTR_SIZE == 4) +#define SCNdPTR SCNd32 // Usage of pointer values will generate warnings with +#define SCNiPTR SCNi32 // some compilers because they are defined in terms of +#define SCNoPTR SCNo32 // integers. However, you can't simply use "p" because +#define SCNuPTR SCNu32 // 'p' is interpreted in a specific and often different +#define SCNxPTR SCNx32 // way by the library. +#elif (EA_PLATFORM_PTR_SIZE == 8) +#define SCNdPTR SCNd64 +#define SCNiPTR SCNi64 +#define SCNoPTR SCNo64 +#define SCNuPTR SCNu64 +#define SCNxPTR SCNx64 +#endif #endif // ------------------------------------------------------------------------ // bool8_t -// The definition of a bool8_t is controversial with some, as it doesn't +// The definition of a bool8_t is controversial with some, as it doesn't // act just like built-in bool. For example, you can assign -100 to it. -// +// #ifndef BOOL8_T_DEFINED // If the user hasn't already defined this... -# define BOOL8_T_DEFINED -# if defined(EA_COMPILER_MSVC) || defined(EA_COMPILER_METROWERKS) || (defined(EA_COMPILER_INTEL) && defined(EA_PLATFORM_WINDOWS)) || defined(EA_COMPILER_BORLAND) -# if defined(__cplusplus) - typedef bool bool8_t; -# else - typedef int8_t bool8_t; -# endif -# else // EA_COMPILER_GNUC generally uses 4 bytes per bool. - typedef int8_t bool8_t; -# endif +#define BOOL8_T_DEFINED +#if defined(EA_COMPILER_MSVC) || (defined(EA_COMPILER_INTEL) && defined(EA_PLATFORM_WINDOWS)) +#if defined(__cplusplus) +typedef bool bool8_t; +#else +typedef int8_t bool8_t; +#endif +#else // EA_COMPILER_GNUC generally uses 4 bytes per bool. +typedef int8_t bool8_t; +#endif #endif @@ -622,155 +530,281 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // a native pointer ( intptr_t is defined in STDDEF.H ) // #if !defined(_INTPTR_T_DEFINED) && !defined(_intptr_t_defined) && !defined(EA_COMPILER_HAS_C99_TYPES) -# if (EA_PLATFORM_PTR_SIZE == 4) - typedef int32_t intptr_t; -# elif (EA_PLATFORM_PTR_SIZE == 8) - typedef int64_t intptr_t; -# endif +#if (EA_PLATFORM_PTR_SIZE == 4) +typedef int32_t intptr_t; +#elif (EA_PLATFORM_PTR_SIZE == 8) +typedef int64_t intptr_t; +#endif -# define _intptr_t_defined -# define _INTPTR_T_DEFINED +#define _intptr_t_defined +#define _INTPTR_T_DEFINED #endif #if !defined(_UINTPTR_T_DEFINED) && !defined(_uintptr_t_defined) && !defined(EA_COMPILER_HAS_C99_TYPES) -# if (EA_PLATFORM_PTR_SIZE == 4) - typedef uint32_t uintptr_t; -# elif (EA_PLATFORM_PTR_SIZE == 8) - typedef uint64_t uintptr_t; -# endif +#if (EA_PLATFORM_PTR_SIZE == 4) +typedef uint32_t uintptr_t; +#elif (EA_PLATFORM_PTR_SIZE == 8) +typedef uint64_t uintptr_t; +#endif -# define _uintptr_t_defined -# define _UINTPTR_T_DEFINED +#define _uintptr_t_defined +#define _UINTPTR_T_DEFINED #endif #if !defined(EA_COMPILER_HAS_INTTYPES) -# ifndef INTMAX_T_DEFINED -# define INTMAX_T_DEFINED - - // At this time, all supported compilers have int64_t as the max - // integer type. Some compilers support a 128 bit inteter type, - // but in those cases it is not a true int128_t but rather a - // crippled data type. - typedef int64_t intmax_t; - typedef uint64_t uintmax_t; -# endif +#ifndef INTMAX_T_DEFINED +#define INTMAX_T_DEFINED + +// At this time, all supported compilers have int64_t as the max +// integer type. Some compilers support a 128 bit integer type, +// but in some cases it is not a true int128_t but rather a +// crippled data type. Also, it turns out that Unix 64 bit ABIs +// require that intmax_t be int64_t and nothing larger. So we +// play it safe here and set intmax_t to int64_t, even though +// an int128_t type may exist. + +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; +#endif #endif // ------------------------------------------------------------------------ // ssize_t // signed equivalent to size_t. -// This is defined by GCC but not by other compilers. +// This is defined by GCC (except the QNX implementation of GCC) but not by other compilers. // -#if !defined(_SIZE_T) #if !defined(__GNUC__) - // As of this writing, all non-GCC compilers significant to us implement - // uintptr_t the same as size_t. However, this isn't guaranteed to be - // so for all compilers, as size_t may be based on int, long, or long long. -# if defined(_MSC_VER) && (EA_PLATFORM_PTR_SIZE == 8) - typedef __int64 ssize_t; -# elif !defined(__S3E__) - typedef long ssize_t; -# endif -#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. -# include +// As of this writing, all non-GCC compilers significant to us implement +// uintptr_t the same as size_t. However, this isn't guaranteed to be +// so for all compilers, as size_t may be based on int, long, or long long. +#if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) +#define _SSIZE_T_ +#define _SSIZE_T_DEFINED + +#if defined(_MSC_VER) && (EA_PLATFORM_PTR_SIZE == 8) +typedef __int64 ssize_t; +#else +typedef long ssize_t; #endif #endif +#else +#include +#endif + // ------------------------------------------------------------------------ // Character types - -#if defined(EA_COMPILER_MSVC) || defined(EA_COMPILER_BORLAND) -# if defined(EA_WCHAR_T_NON_NATIVE) - // In this case, wchar_t is not defined unless we include - // wchar.h or if the compiler makes it built-in. -# ifdef EA_COMPILER_MSVC -# pragma warning(push, 3) -# endif -# include -# ifdef EA_COMPILER_MSVC -# pragma warning(pop) -# endif -# endif +// +#if defined(EA_COMPILER_MSVC) +#if defined(EA_WCHAR_T_NON_NATIVE) +// In this case, wchar_t is not defined unless we include +// wchar.h or if the compiler makes it built-in. +#ifdef EA_COMPILER_MSVC +#pragma warning(push, 3) +#endif +#include +#ifdef EA_COMPILER_MSVC +#pragma warning(pop) +#endif +#endif #endif // ------------------------------------------------------------------------ // char8_t -- Guaranteed to be equal to the compiler's char data type. -// Some compilers implement char8_t as unsigned, though char +// Some compilers implement char8_t as unsigned, though char // is usually set to be signed. // // char16_t -- This is set to be an unsigned 16 bit value. If the compiler -// has wchar_t as an unsigned 16 bit value, then char16_t is -// set to be the same thing as wchar_t in order to allow the +// has wchar_t as an unsigned 16 bit value, then char16_t is +// set to be the same thing as wchar_t in order to allow the // user to use char16_t with standard wchar_t functions. // // char32_t -- This is set to be an unsigned 32 bit value. If the compiler -// has wchar_t as an unsigned 32 bit value, then char32_t is -// set to be the same thing as wchar_t in order to allow the +// has wchar_t as an unsigned 32 bit value, then char32_t is +// set to be the same thing as wchar_t in order to allow the // user to use char32_t with standard wchar_t functions. // +// EA_CHAR8_UNIQUE +// EA_CHAR16_NATIVE +// EA_CHAR32_NATIVE +// EA_WCHAR_UNIQUE +// // VS2010 unilaterally defines char16_t and char32_t in its yvals.h header -// unless _HAS_CHAR16_T_LANGUAGE_SUPPORT or _CHAR16T are defined. -// However, VS2010 does not support the C++0x u"" and U"" string literals, -// which makes its definition of char16_t and char32_t somewhat useless. -// Until VC++ supports string literals, the buildystems should define +// unless _HAS_CHAR16_T_LANGUAGE_SUPPORT or _CHAR16T are defined. +// However, VS2010 does not support the C++0x u"" and U"" string literals, +// which makes its definition of char16_t and char32_t somewhat useless. +// Until VC++ supports string literals, the build system should define // _CHAR16T and let EABase define char16_t and EA_CHAR16. // -// GCC defines char16_t and char32_t in the C compiler in -std=gnu99 mode, -// as __CHAR16_TYPE__ and __CHAR32_TYPE__, and for the C++ compiler +// GCC defines char16_t and char32_t in the C compiler in -std=gnu99 mode, +// as __CHAR16_TYPE__ and __CHAR32_TYPE__, and for the C++ compiler // in -std=c++0x and -std=gnu++0x modes, as char16_t and char32_t too. +// +// The EA_WCHAR_UNIQUE symbol is defined to 1 if wchar_t is distinct from +// char8_t, char16_t, and char32_t, and defined to 0 if not. In some cases, +// if the compiler does not support char16_t/char32_t, one of these two types +// is typically a typedef or define of wchar_t. For compilers that support +// the C++11 unicode character types often overloads must be provided to +// support existing code that passes a wide char string to a function that +// takes a unicode string. +// +// The EA_CHAR8_UNIQUE symbol is defined to 1 if char8_t is distinct type +// from char in the type system, and defined to 0 if otherwise. #if !defined(EA_CHAR16_NATIVE) -# if defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(_CHAR16T) || (defined(_HAS_CHAR16_T_LANGUAGE_SUPPORT) && _HAS_CHAR16_T_LANGUAGE_SUPPORT) // VS2010+ -# define EA_CHAR16_NATIVE 1 -# elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 404) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__STDC_VERSION__) || defined(_CHAR16T)) // g++ (C++ compiler) 4.4+ with -std=c++0x or gcc (C compiler) 4.4+ with -std=gnu99 or QNX660 has defined char16_t and char32_t in its yvals.h header -# define EA_CHAR16_NATIVE 1 -# else -# define EA_CHAR16_NATIVE 0 -# endif +// To do: Change this to be based on EA_COMPILER_NO_NEW_CHARACTER_TYPES. +#if defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(_HAS_CHAR16_T_LANGUAGE_SUPPORT) && _HAS_CHAR16_T_LANGUAGE_SUPPORT // VS2010+ +#define EA_CHAR16_NATIVE 1 +#elif defined(EA_COMPILER_CLANG) && defined(EA_COMPILER_CPP11_ENABLED) +#if __has_feature(cxx_unicode_literals) +#define EA_CHAR16_NATIVE 1 +#elif (EA_COMPILER_VERSION >= 300) && !(defined(EA_PLATFORM_IPHONE) || defined(EA_PLATFORM_OSX)) +#define EA_CHAR16_NATIVE 1 +#elif defined(EA_PLATFORM_APPLE) +#define EA_CHAR16_NATIVE 1 +#else +#define EA_CHAR16_NATIVE 0 +#endif +#elif defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 404) && defined(__CHAR16_TYPE__) && defined(EA_COMPILER_CPP11_ENABLED)// EDG 4.4+. +#define EA_CHAR16_NATIVE 1 +#elif defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION >= 4004) && !defined(EA_COMPILER_EDG) && (defined(EA_COMPILER_CPP11_ENABLED) || defined(__STDC_VERSION__)) // g++ (C++ compiler) 4.4+ with -std=c++0x or gcc (C compiler) 4.4+ with -std=gnu99 +#define EA_CHAR16_NATIVE 1 +#else +#define EA_CHAR16_NATIVE 0 +#endif #endif -#if !defined(EA_CHAR32_NATIVE) -# if defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(_HAS_CHAR16_T_LANGUAGE_SUPPORT) && _HAS_CHAR16_T_LANGUAGE_SUPPORT // VS2010+ -# define EA_CHAR32_NATIVE 1 -# 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 -# define EA_CHAR32_NATIVE 1 -# else -# define EA_CHAR32_NATIVE 0 -# endif +#if !defined(EA_CHAR32_NATIVE) // Microsoft currently ties char32_t language support to char16_t language support. So we use CHAR16_T here. +// To do: Change this to be based on EA_COMPILER_NO_NEW_CHARACTER_TYPES. +#if defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(_HAS_CHAR16_T_LANGUAGE_SUPPORT) && _HAS_CHAR16_T_LANGUAGE_SUPPORT // VS2010+ +#define EA_CHAR32_NATIVE 1 +#elif defined(EA_COMPILER_CLANG) && defined(EA_COMPILER_CPP11_ENABLED) +#if __has_feature(cxx_unicode_literals) +#define EA_CHAR32_NATIVE 1 +#elif (EA_COMPILER_VERSION >= 300) && !(defined(EA_PLATFORM_IPHONE) || defined(EA_PLATFORM_OSX)) +#define EA_CHAR32_NATIVE 1 +#elif defined(EA_PLATFORM_APPLE) +#define EA_CHAR32_NATIVE 1 +#else +#define EA_CHAR32_NATIVE 0 +#endif +#elif defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 404) && defined(__CHAR32_TYPE__) && defined(EA_COMPILER_CPP11_ENABLED)// EDG 4.4+. +#define EA_CHAR32_NATIVE 1 +#elif defined(EA_COMPILER_GNUC) && (EA_COMPILER_VERSION >= 4004) && !defined(EA_COMPILER_EDG) && (defined(EA_COMPILER_CPP11_ENABLED) || defined(__STDC_VERSION__)) // g++ (C++ compiler) 4.4+ with -std=c++0x or gcc (C compiler) 4.4+ with -std=gnu99 +#define EA_CHAR32_NATIVE 1 +#else +#define EA_CHAR32_NATIVE 0 +#endif +#endif + + +#if EA_CHAR16_NATIVE || EA_CHAR32_NATIVE +#define EA_WCHAR_UNIQUE 1 +#else +#define EA_WCHAR_UNIQUE 0 +#endif + + +// EA_CHAR8_UNIQUE +// +// Check for char8_t support in the cpp type system. Moving forward from c++20, +// the char8_t type allows users to overload function for character encoding. +// +// EA_CHAR8_UNIQUE is 1 when the type is a unique in the type system and +// can there be used as a valid overload. EA_CHAR8_UNIQUE is 0 otherwise. +// +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0482r6.html +// +#ifdef __cpp_char8_t +#define CHAR8_T_DEFINED +#define EA_CHAR8_UNIQUE 1 +#else +#define EA_CHAR8_UNIQUE 0 #endif #ifndef CHAR8_T_DEFINED // If the user hasn't already defined these... -# define CHAR8_T_DEFINED - -# if EA_CHAR16_NATIVE - typedef char char8_t; - - // In C++, char16_t and char32_t are already defined by the compiler. - // In MS C, char16_t and char32_t are already defined by the compiler/standard library. - // In GCC C, __CHAR16_TYPE__ and __CHAR32_TYPE__ are defined instead, and we must define char16_t and char32_t from these. -# if defined(__GNUC__) && !defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(__CHAR16_TYPE__) // If using GCC and compiling in C... - typedef __CHAR16_TYPE__ char16_t; - typedef __CHAR32_TYPE__ char32_t; -# endif -# elif defined(EA_COMPILER_HAS_CHAR_16_32) - typedef char char8_t; -# elif (EA_WCHAR_SIZE == 2) -# define _CHAR16T - typedef char char8_t; - typedef wchar_t char16_t; - typedef uint32_t char32_t; -# else - typedef char char8_t; - typedef uint16_t char16_t; - typedef wchar_t char32_t; -# endif -#endif - - -// EA_CHAR16 / EA_CHAR32 +#define CHAR8_T_DEFINED +#if defined(EA_PLATFORM_APPLE) +#define char8_t char // The Apple debugger is too stupid to realize char8_t is typedef'd to char, so we #define it. +#else +typedef char char8_t; +#endif + +#if EA_CHAR16_NATIVE +// In C++, char16_t and char32_t are already defined by the compiler. +// In MS C, char16_t and char32_t are already defined by the compiler/standard library. +// In GCC C, __CHAR16_TYPE__ and __CHAR32_TYPE__ are defined instead, and we must define char16_t and char32_t from these. +#if defined(__GNUC__) && !defined(__GXX_EXPERIMENTAL_CXX0X__) && defined(__CHAR16_TYPE__) // If using GCC and compiling in C... +typedef __CHAR16_TYPE__ char16_t; +typedef __CHAR32_TYPE__ char32_t; +#endif +#elif (EA_WCHAR_SIZE == 2) +#if (defined(_MSC_VER) && (_MSC_VER >= 1600)) // if VS2010+ or using platforms that use Dinkumware under a compiler that doesn't natively support C++11 char16_t. +#if !defined(_CHAR16T) +#define _CHAR16T +#endif +#if !defined(_HAS_CHAR16_T_LANGUAGE_SUPPORT) || !_HAS_CHAR16_T_LANGUAGE_SUPPORT +typedef wchar_t char16_t; +typedef uint32_t char32_t; +#endif +#else +typedef wchar_t char16_t; +typedef uint32_t char32_t; +#endif +#else +typedef uint16_t char16_t; +#if defined(__cplusplus) +typedef wchar_t char32_t; +#else +typedef uint32_t char32_t; +#endif +#endif +#endif + + +// CHAR8_MIN, CHAR8_MAX, etc. +// +#define EA_LIMITS_DIGITS_S(T) ((sizeof(T) * 8) - 1) +#define EA_LIMITS_DIGITS_U(T) ((sizeof(T) * 8)) +#define EA_LIMITS_DIGITS(T) ((EA_LIMITS_IS_SIGNED(T) ? EA_LIMITS_DIGITS_S(T) : EA_LIMITS_DIGITS_U(T))) +#define EA_LIMITS_IS_SIGNED(T) ((T)(-1) < 0) +#define EA_LIMITS_MIN_S(T) ((T)((T)1 << EA_LIMITS_DIGITS_S(T))) +#define EA_LIMITS_MIN_U(T) ((T)0) +#define EA_LIMITS_MIN(T) ((EA_LIMITS_IS_SIGNED(T) ? EA_LIMITS_MIN_S(T) : EA_LIMITS_MIN_U(T))) +#define EA_LIMITS_MAX_S(T) ((T)(((((T)1 << (EA_LIMITS_DIGITS(T) - 1)) - 1) << 1) + 1)) +#define EA_LIMITS_MAX_U(T) ((T)~(T)0) +#define EA_LIMITS_MAX(T) ((EA_LIMITS_IS_SIGNED(T) ? EA_LIMITS_MAX_S(T) : EA_LIMITS_MAX_U(T))) + +#if !defined(CHAR8_MIN) +#define CHAR8_MIN EA_LIMITS_MIN(char8_t) +#endif + +#if !defined(CHAR8_MAX) +#define CHAR8_MAX EA_LIMITS_MAX(char8_t) +#endif + +#if !defined(CHAR16_MIN) +#define CHAR16_MIN EA_LIMITS_MIN(char16_t) +#endif + +#if !defined(CHAR16_MAX) +#define CHAR16_MAX EA_LIMITS_MAX(char16_t) +#endif + +#if !defined(CHAR32_MIN) +#define CHAR32_MIN EA_LIMITS_MIN(char32_t) +#endif + +#if !defined(CHAR32_MAX) +#define CHAR32_MAX EA_LIMITS_MAX(char32_t) +#endif + + + +// EA_CHAR8 / EA_CHAR16 / EA_CHAR32 / EA_WCHAR // // Supports usage of portable string constants. // @@ -780,47 +814,104 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // const char16_t c = EA_CHAR16('\x3001'); // const char32_t c = EA_CHAR32('\x3001'); // +#ifndef EA_CHAR8 +#if EA_CHAR8_UNIQUE +#define EA_CHAR8(s) u8 ## s +#else +#define EA_CHAR8(s) s +#endif +#endif + +#ifndef EA_WCHAR +#define EA_WCHAR_(s) L ## s +#define EA_WCHAR(s) EA_WCHAR_(s) +#endif + #ifndef EA_CHAR16 -# if EA_CHAR16_NATIVE && !defined(_MSC_VER) // Microsoft doesn't support char16_t string literals. -# define EA_CHAR16(s) u ## s -# elif (EA_WCHAR_SIZE == 2) -# define EA_CHAR16(s) L ## s -# else - //#define EA_CHAR16(s) // Impossible to implement. -# endif +#if EA_CHAR16_NATIVE && !defined(_MSC_VER) // Microsoft doesn't support char16_t string literals. +#define EA_CHAR16_(s) u ## s +#define EA_CHAR16(s) EA_CHAR16_(s) +#elif (EA_WCHAR_SIZE == 2) +#if defined(_MSC_VER) && (_MSC_VER >= 1900) && defined(__cplusplus) // VS2015 supports u"" string literals. +#define EA_CHAR16_(s) u ## s +#define EA_CHAR16(s) EA_CHAR16_(s) +#else +#define EA_CHAR16_(s) L ## s +#define EA_CHAR16(s) EA_CHAR16_(s) +#endif +#else +//#define EA_CHAR16(s) // Impossible to implement efficiently. +#endif #endif #ifndef EA_CHAR32 -# if EA_CHAR32_NATIVE && !defined(_MSC_VER) // Microsoft doesn't support char32_t string literals. -# define EA_CHAR32(s) U ## s -# elif (EA_WCHAR_SIZE == 2) - //#define EA_CHAR32(s) // Impossible to implement. -# else -# define EA_CHAR32(s) L ## s -# endif +#if EA_CHAR32_NATIVE && !defined(_MSC_VER) // Microsoft doesn't support char32_t string literals. +#define EA_CHAR32_(s) U ## s +#define EA_CHAR32(s) EA_CHAR32_(s) +#elif (EA_WCHAR_SIZE == 2) +#if defined(_MSC_VER) && (_MSC_VER >= 1900) && defined(__cplusplus) // VS2015 supports u"" string literals. +#define EA_CHAR32_(s) U ## s +#define EA_CHAR32(s) EA_CHAR32_(s) +#else +//#define EA_CHAR32(s) // Impossible to implement. +#endif +#elif (EA_WCHAR_SIZE == 4) +#define EA_CHAR32_(s) L ## s +#define EA_CHAR32(s) EA_CHAR32_(s) +#else +#error Unexpected size of wchar_t +#endif #endif +// EAText8 / EAText16 +// +// Provided for backwards compatibility with older code. +// +#if defined(EABASE_ENABLE_EATEXT_MACROS) +#define EAText8(x) x +#define EAChar8(x) x + +#define EAText16(x) EA_CHAR16(x) +#define EAChar16(x) EA_CHAR16(x) +#endif + + + // ------------------------------------------------------------------------ // EAArrayCount // // Returns the count of items in a built-in C array. This is a common technique -// which is often used to help properly calculate the number of items in an +// which is often used to help properly calculate the number of items in an // array at runtime in order to prevent overruns, etc. // // Example usage: // int array[75]; // size_t arrayCount = EAArrayCount(array); // arrayCount is 75. // +#if defined(EA_COMPILER_NO_CONSTEXPR) #ifndef EAArrayCount -# define EAArrayCount(x) (sizeof(x) / sizeof(x[0])) +#define EAArrayCount(x) (sizeof(x) / sizeof(x[0])) +#endif +#else +// This C++11 version is a little smarter than the macro version above; +// it can tell the difference between arrays and pointers. Other simpler +// templated versions have failed in various subtle ways. + +template +char (&EAArraySizeHelper(T (&x)[N]))[N]; + +template +char (&EAArraySizeHelper(T (&&x)[N]))[N]; + +#define EAArrayCount(x) (sizeof(EAArraySizeHelper(x))) #endif // ------------------------------------------------------------------------ // static_assert // -// C++0x static_assert (a.k.a. compile-time assert). +// C++11 static_assert (a.k.a. compile-time assert). // // Specification: // void static_assert(bool const_expression, const char* description); @@ -828,57 +919,92 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Example usage: // static_assert(sizeof(int) == 4, "int must be 32 bits"); // -#if !defined(EABASE_STATIC_ASSERT_ENABLED) -# if defined(EA_DEBUG) || defined(_DEBUG) -# define EABASE_STATIC_ASSERT_ENABLED 1 -# else -# define EABASE_STATIC_ASSERT_ENABLED 0 -# endif +#if defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(__cplusplus) +// static_assert is defined by the compiler for both C and C++. +#elif !defined(__cplusplus) && defined(EA_PLATFORM_ANDROID) && ((defined(__STDC_VERSION__) && __STDC_VERSION__ < 201100L) || !defined(__STDC_VERSION__)) +// AndroidNDK does not support static_assert despite claiming it's a C11 compiler +#define NEED_CUSTOM_STATIC_ASSERT +#elif defined(__clang__) && defined(__cplusplus) +// We need to separate these checks on a new line, as the pre-processor on other compilers will fail on the _has_feature macros +#if !(__has_feature(cxx_static_assert) || __has_extension(cxx_static_assert)) +#define NEED_CUSTOM_STATIC_ASSERT #endif - -#ifndef EA_PREPROCESSOR_JOIN -# define EA_PREPROCESSOR_JOIN(a, b) EA_PREPROCESSOR_JOIN1(a, b) -# define EA_PREPROCESSOR_JOIN1(a, b) EA_PREPROCESSOR_JOIN2(a, b) -# define EA_PREPROCESSOR_JOIN2(a, b) a##b +#elif defined(__GNUC__) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(__cplusplus) && (__cplusplus >= 201103L))) +// static_assert is defined by the compiler. +#elif defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401) && defined(EA_COMPILER_CPP11_ENABLED) +// static_assert is defined by the compiler. +#elif !defined(__cplusplus) && defined(__GLIBC__) && defined(__USE_ISOC11) +// static_assert is defined by the compiler. +#elif !defined(__cplusplus) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201100L +// static_assert is defined by the compiler. +#else +#define NEED_CUSTOM_STATIC_ASSERT #endif -#if defined(_MSC_VER) && (_MSC_VER >= 1600) - // static_assert is defined by the compiler for both C and C++. -#elif defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) - // static_assert is defined by the compiler. -#elif defined(__clang__) && __has_feature(cxx_static_assert) - // static_assert is defined by the compiler. -#elif defined(EA_COMPILER_GHS) - // static_assert is defined by the compiler. +#ifdef NEED_CUSTOM_STATIC_ASSERT +#ifdef __GNUC__ +// On GCC the 'unused' attribute can be used to indicate a typedef is not actually used +// (such as in the static_assert implementation below). New versions of GCC generate +// warnings for unused typedefs in function/method scopes. +#define EA_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) #else -# if EABASE_STATIC_ASSERT_ENABLED -# if defined(__COUNTER__) // If this VC++ extension is available... -# define static_assert(expression, description) enum { EA_PREPROCESSOR_JOIN(static_assert_, __COUNTER__) = 1 / ((!!(expression)) ? 1 : 0) } -# else -# define static_assert(expression, description) enum { EA_PREPROCESSOR_JOIN(static_assert_, __LINE__) = 1 / ((!!(expression)) ? 1 : 0) } -# endif -# else -# if defined(EA_COMPILER_METROWERKS) -# if defined(__cplusplus) -# define static_assert(expression, description) struct EA_PREPROCESSOR_JOIN(EACTAssertUnused_, __LINE__){ } -# else -# define static_assert(expression, description) enum { EA_PREPROCESSOR_JOIN(static_assert_, __LINE__) = 1 / ((!!(expression)) ? 1 : 0) } -# endif -# else -# define static_assert(expression, description) -# endif -# endif +#define EA_STATIC_ASSERT_UNUSED_ATTRIBUTE #endif +#define EA_STATIC_ASSERT_TOKEN_PASTE(a,b) a ## b +#define EA_STATIC_ASSERT_CONCATENATE_HELPER(a,b) EA_STATIC_ASSERT_TOKEN_PASTE(a,b) -#if defined(__cplusplus) +#if defined(__COUNTER__) // If this extension is available, which allows multiple statements per line... +#define static_assert(expression, description) typedef char EA_STATIC_ASSERT_CONCATENATE_HELPER(compileTimeAssert,__COUNTER__) [((expression) != 0) ? 1 : -1] EA_STATIC_ASSERT_UNUSED_ATTRIBUTE +#else +#define static_assert(expression, description) typedef char EA_STATIC_ASSERT_CONCATENATE_HELPER(compileTimeAssert,__LINE__) [((expression) != 0) ? 1 : -1] EA_STATIC_ASSERT_UNUSED_ATTRIBUTE #endif -#endif // Header include guard +#undef NEED_CUSTOM_STATIC_ASSERT +#endif +// ------------------------------------------------------------------------ +// EA_IS_ENABLED +// +// EA_IS_ENABLED is intended to be used for detecting if compile time features are enabled or disabled. +// +// It has some advantages over using a standard #if or #ifdef tests: +// 1) Fails to compile when passes numeric macro values. Valid options are strictly enabled or disabled. +// 2) Fails to compile when passed undefined macro values rather than disabling by default +// 3) Fails to compile when the passed macro is defined to but empty +// +// To use the macro, the calling code should create a define for the feature to enable or disable. This feature define +// must be set to either EA_ENABLED or EA_DISABLED. (Do not try to set the feature define directly to some other +// value.) +// +// Note: These macros are analogous to the Frostbite macro FB_USING used in combination with FB_OFF / FB_ON and are +// designed to be compatible to support gradual migration. +// +// Example usage: +// +// // The USER_PROVIDED_FEATURE_DEFINE should be defined as either +// // EA_ENABLED or EA_DISABLED. +// #define USER_PROVIDED_FEATURE_DEFINE EA_ENABLED +// +// #if EA_IS_ENABLED(USER_PROVIDED_FEATURE_DEFINE) +// // USER_PROVIDED_FEATURE_DEFINE is enabled +// #else +// // USER_PROVIDED_FEATURE_DEFINE is disabled +// #endif +// +#define EA_ENABLED 111- +#define EA_DISABLED 333- +// NOTE: Numeric values for x will produce a parse error while empty values produce a divide by zero, and the test is a bool for proper negation behavior +#define EA_IS_ENABLED(x) (333 == 333 * 111 / ((x 0) * (((x 0) == 333 ? 1 : 0) + ((x 0) == 111 ? 1 : 0)))) +// Define int128_t / uint128_t types. +// NOTE(rparolin): include file at the end because we want all the signed integral types defined. +#ifdef __cplusplus +#include +#endif +#endif // Header include guard diff --git a/UnknownVersion/include/EABase/earesult.h b/UnknownVersion/include/EABase/earesult.h index 928d9fc..8cd6996 100644 --- a/UnknownVersion/include/EABase/earesult.h +++ b/UnknownVersion/include/EABase/earesult.h @@ -1,36 +1,7 @@ -/* -Copyright (C) 2009 Electronic Arts, Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of - its contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - /*----------------------------------------------------------------------------- * earesult.h * - * Copyright (c) 2002 - 2005 Electronic Arts Inc. All rights reserved. - * Maintained by Paul Pedriana, Maxis + * Copyright (c) Electronic Arts Inc. All rights reserved. *---------------------------------------------------------------------------*/ @@ -38,36 +9,49 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define INCLUDED_earesult_H -#ifndef INCLUDED_eabase_H - #include "EABase/eabase.h" +#include + +#if defined(EA_PRAGMA_ONCE_SUPPORTED) +#pragma once /* Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result. */ #endif -/// \brief This result type is width-compatible with most systems +/* This result type is width-compatible with most systems. */ typedef int32_t ea_result_type; namespace EA { - typedef int32_t result_type; +typedef int32_t result_type; + +enum +{ +#ifndef SUCCESS + // Deprecated + // Note: a public MS header has created a define of this name which causes a build error. Fortunately they + // define it to 0 which is compatible. + // see: WindowsSDK\8.1.51641-fb\installed\Include\um\RasError.h + SUCCESS = 0, +#endif + // Deprecated + FAILURE = -1, - enum - { - SUCCESS = 0, - FAILURE = -1 - }; + // These values are now the preferred constants + EA_SUCCESS = 0, + EA_FAILURE = -1, +}; } -/// \brief Macro to simplify testing for success +/* Macro to simplify testing for success. */ #ifndef EA_SUCCEEDED - #define EA_SUCCEEDED(result) ((result) >= 0) +#define EA_SUCCEEDED(result) ((result) >= 0) #endif -/// \brief Macro to simplfify testing for general failure +/* Macro to simplfify testing for general failure. */ #ifndef EA_FAILED - #define EA_FAILED(result) ((result) < 0) +#define EA_FAILED(result) ((result) < 0) #endif diff --git a/UnknownVersion/include/EABase/eaunits.h b/UnknownVersion/include/EABase/eaunits.h new file mode 100644 index 0000000..2ff7f5f --- /dev/null +++ b/UnknownVersion/include/EABase/eaunits.h @@ -0,0 +1,54 @@ +/*----------------------------------------------------------------------------- + * eaunits.h + * + * Copyright (c) Electronic Arts Inc. All rights reserved. + *---------------------------------------------------------------------------*/ + + +#ifndef INCLUDED_eaunits_h +#define INCLUDED_eaunits_h + +#include + +#if defined(EA_PRAGMA_ONCE_SUPPORTED) +#pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result. +#endif + +// Defining common SI unit macros. +// +// The mebibyte is a multiple of the unit byte for digital information. Technically a +// megabyte (MB) is a power of ten, while a mebibyte (MiB) is a power of two, +// appropriate for binary machines. Many Linux distributions use the unit, but it is +// not widely acknowledged within the industry or media. +// Reference: https://en.wikipedia.org/wiki/Mebibyte +// +// Examples: +// auto size1 = EA_KILOBYTE(16); +// auto size2 = EA_MEGABYTE(128); +// auto size3 = EA_MEBIBYTE(8); +// auto size4 = EA_GIBIBYTE(8); + +// define byte for completeness +#define EA_BYTE(x) (x) + +// Decimal SI units +#define EA_KILOBYTE(x) (size_t(x) * 1000) +#define EA_MEGABYTE(x) (size_t(x) * 1000 * 1000) +#define EA_GIGABYTE(x) (size_t(x) * 1000 * 1000 * 1000) +#define EA_TERABYTE(x) (size_t(x) * 1000 * 1000 * 1000 * 1000) +#define EA_PETABYTE(x) (size_t(x) * 1000 * 1000 * 1000 * 1000 * 1000) +#define EA_EXABYTE(x) (size_t(x) * 1000 * 1000 * 1000 * 1000 * 1000 * 1000) + +// Binary SI units +#define EA_KIBIBYTE(x) (size_t(x) * 1024) +#define EA_MEBIBYTE(x) (size_t(x) * 1024 * 1024) +#define EA_GIBIBYTE(x) (size_t(x) * 1024 * 1024 * 1024) +#define EA_TEBIBYTE(x) (size_t(x) * 1024 * 1024 * 1024 * 1024) +#define EA_PEBIBYTE(x) (size_t(x) * 1024 * 1024 * 1024 * 1024 * 1024) +#define EA_EXBIBYTE(x) (size_t(x) * 1024 * 1024 * 1024 * 1024 * 1024 * 1024) + +#endif // INCLUDED_earesult_H + + + + diff --git a/UnknownVersion/include/EABase/int128.h b/UnknownVersion/include/EABase/int128.h new file mode 100644 index 0000000..62e2bc5 --- /dev/null +++ b/UnknownVersion/include/EABase/int128.h @@ -0,0 +1,1268 @@ +/*----------------------------------------------------------------------------- + * eaint128_t.h + * + * Copyright (c) Electronic Arts Inc. All rights reserved. + *---------------------------------------------------------------------------*/ + + +#ifndef INCLUDED_int128_h +#define INCLUDED_int128_h + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// EA_INT128_INTRINSIC_AVAILABLE +// +#if (EA_COMPILER_INTMAX_SIZE >= 16) && (defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG)) +// __int128_t/__uint128_t is supported +#define EA_INT128_INTRINSIC_AVAILABLE 1 +#else +#define EA_INT128_INTRINSIC_AVAILABLE 0 +#endif + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// EA_INT128_ALIGNAS +// +#if EA_INT128_INTRINSIC_AVAILABLE && !defined(EA_COMPILER_NO_ALIGNAS) +#define EA_INT128_ALIGNAS alignas(unsigned __int128) +#else +#define EA_INT128_ALIGNAS +#endif + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// EA_HAVE_INT128 +// +// Indicates that EABase implements 128-bit integer types +// +#define EA_HAVE_INT128 1 + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// uint128_t_base +// +struct EA_INT128_ALIGNAS int128_t_base +{ + // Constructors / destructors + int128_t_base() = default; + int128_t_base(uint32_t nPart0, uint32_t nPart1, uint32_t nPart2, uint32_t nPart3); + int128_t_base(uint64_t nPart0, uint64_t nPart1); + int128_t_base(uint8_t value); + int128_t_base(uint16_t value); + int128_t_base(uint32_t value); + int128_t_base(uint64_t value); + int128_t_base(const int128_t_base& value) = default; + + // Assignment operator + int128_t_base& operator=(const int128_t_base& value) = default; + + // Explicit operators to convert back to basic types + EA_CONSTEXPR explicit operator bool() const; + EA_CONSTEXPR explicit operator char() const; + EA_CONSTEXPR explicit operator int() const; + EA_CONSTEXPR explicit operator long() const; + EA_CONSTEXPR explicit operator long long() const; + EA_CONSTEXPR explicit operator short() const; + EA_CONSTEXPR explicit operator signed char() const; + EA_CONSTEXPR explicit operator unsigned char() const; + EA_CONSTEXPR explicit operator unsigned int() const; + EA_CONSTEXPR explicit operator unsigned long long() const; + EA_CONSTEXPR explicit operator unsigned long() const; + EA_CONSTEXPR explicit operator unsigned short() const; +#if EA_WCHAR_UNIQUE + // EA_CONSTEXPR explicit operator char16_t() const; + // EA_CONSTEXPR explicit operator char32_t() const; + // EA_CONSTEXPR explicit operator wchar_t() const; +#endif + EA_CONSTEXPR explicit operator float() const; + EA_CONSTEXPR explicit operator double() const; + EA_CONSTEXPR explicit operator long double() const; +#if EA_INT128_INTRINSIC_AVAILABLE + EA_CONSTEXPR explicit operator __int128() const; + EA_CONSTEXPR explicit operator unsigned __int128() const; +#endif + + // Math operators + static void OperatorPlus (const int128_t_base& value1, const int128_t_base& value2, int128_t_base& result); + static void OperatorMinus(const int128_t_base& value1, const int128_t_base& value2, int128_t_base& result); + static void OperatorMul (const int128_t_base& value1, const int128_t_base& value2, int128_t_base& result); + + // Shift operators + static void OperatorShiftRight(const int128_t_base& value, int nShift, int128_t_base& result); + static void OperatorShiftLeft (const int128_t_base& value, int nShift, int128_t_base& result); + + // Unary arithmetic/logic operators + bool operator!() const; + + // Logical operators + static void OperatorXOR(const int128_t_base& value1, const int128_t_base& value2, int128_t_base& result); + static void OperatorOR (const int128_t_base& value1, const int128_t_base& value2, int128_t_base& result); + static void OperatorAND(const int128_t_base& value1, const int128_t_base& value2, int128_t_base& result); + + bool IsZero() const; + void SetZero(); + void TwosComplement(); + void InverseTwosComplement(); + + int GetBit(int nIndex) const; + void SetBit(int nIndex, int value); + +protected: + void DoubleToUint128(double value); + + EA_CONSTEXPR uint64_t Low() const + { + return mPart0; + } + + EA_CONSTEXPR uint64_t High() const + { + return mPart1; + } + +protected: +#ifdef EA_SYSTEM_BIG_ENDIAN + uint64_t mPart1; // Most significant byte. + uint64_t mPart0; // Least significant byte. +#else + uint64_t mPart0; // Most significant byte. + uint64_t mPart1; // Least significant byte. +#endif +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// int128_t +// +// Implements signed 128 bit integer. +// +struct int128_t : public int128_t_base +{ + // Constructors / destructors + using int128_t_base::int128_t_base; + + // Assignment operator + using int128_t_base::operator=; + + // Unary arithmetic/logic operators + int128_t operator-() const; + int128_t& operator++(); + int128_t& operator--(); + int128_t operator++(int); + int128_t operator--(int); + int128_t operator~() const; + int128_t operator+() const; + + // Math operators + int128_t operator+ (const int128_t& other); + int128_t operator- (const int128_t& other); + int128_t operator* (const int128_t& other); + int128_t operator/ (const int128_t& other); + int128_t operator% (const int128_t& other); + int128_t& operator+=(const int128_t& other); + int128_t& operator-=(const int128_t& other); + int128_t& operator*=(const int128_t& other); + int128_t& operator/=(const int128_t& other); + int128_t& operator%=(const int128_t& other); + + // Shift operators + int128_t operator>> (int nShift) const; + int128_t operator<< (int nShift) const; + int128_t& operator>>=(int nShift); + int128_t& operator<<=(int nShift); + + // Logical operators + int128_t operator^ (const int128_t& other) const; + int128_t operator| (const int128_t& other) const; + int128_t operator& (const int128_t& other) const; + int128_t& operator^=(const int128_t& other); + int128_t& operator|=(const int128_t& other); + int128_t& operator&=(const int128_t& other); + + // Equality operators + bool operator==(const int128_t& other) const; + bool operator!=(const int128_t& other) const; + bool operator> (const int128_t& other) const; + bool operator>=(const int128_t& other) const; + bool operator< (const int128_t& other) const; + bool operator<=(const int128_t& other) const; + +protected: + int compare(const int128_t& other) const; + void Negate(); + void Modulus(const int128_t& divisor, int128_t& quotient, int128_t& remainder) const; + bool IsNegative() const; // Returns true for value < 0 + bool IsPositive() const; // Returns true for value >= 0 +}; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// uint128_t +// +// Implements unsigned 128 bit integer. +// +struct uint128_t : public int128_t_base +{ + // Constructors / destructors + using int128_t_base::int128_t_base; + + // Assignment operator + using int128_t_base::operator=; + + // Unary arithmetic/logic operators + uint128_t operator-() const; + uint128_t& operator++(); + uint128_t& operator--(); + uint128_t operator++(int); + uint128_t operator--(int); + uint128_t operator~() const; + uint128_t operator+() const; + + // Math operators + uint128_t operator+ (const uint128_t& other); + uint128_t operator- (const uint128_t& other); + uint128_t operator* (const uint128_t& other); + uint128_t operator/ (const uint128_t& other); + uint128_t operator% (const uint128_t& other); + uint128_t& operator+=(const uint128_t& other); + uint128_t& operator-=(const uint128_t& other); + uint128_t& operator*=(const uint128_t& other); + uint128_t& operator/=(const uint128_t& other); + uint128_t& operator%=(const uint128_t& other); + + // Shift operators + uint128_t operator>> (int nShift) const; + uint128_t operator<< (int nShift) const; + uint128_t& operator>>=(int nShift); + uint128_t& operator<<=(int nShift); + + // Logical operators + uint128_t operator^ (const uint128_t& other) const; + uint128_t operator| (const uint128_t& other) const; + uint128_t operator& (const uint128_t& other) const; + uint128_t& operator^=(const uint128_t& other); + uint128_t& operator|=(const uint128_t& other); + uint128_t& operator&=(const uint128_t& other); + + // Equality operators + bool operator==(const uint128_t& other) const; + bool operator!=(const uint128_t& other) const; + bool operator> (const uint128_t& other) const; + bool operator>=(const uint128_t& other) const; + bool operator< (const uint128_t& other) const; + bool operator<=(const uint128_t& other) const; + +protected: + int compare(const uint128_t& other) const; + void Negate(); + void Modulus(const uint128_t& divisor, uint128_t& quotient, uint128_t& remainder) const; + bool IsNegative() const; // Returns true for value < 0 + bool IsPositive() const; // Returns true for value >= 0 +}; + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// uint128_t_base implementation +/////////////////////////////////////////////////////////////////////////////////////////////////////// +EA_CONSTEXPR inline int128_t_base::operator bool() const { return mPart0 || mPart1; } +EA_CONSTEXPR inline int128_t_base::operator char() const { return static_cast(Low()); } +#if EA_WCHAR_UNIQUE +// EA_CONSTEXPR inline int128_t_base::operator char16_t() const { return static_cast(Low()); } +// EA_CONSTEXPR inline int128_t_base::operator char32_t() const { return static_cast(Low()); } +// EA_CONSTEXPR inline int128_t_base::operator wchar_t() const { return static_cast(Low()); } +#endif +EA_CONSTEXPR inline int128_t_base::operator int() const { return static_cast(Low()); } +EA_CONSTEXPR inline int128_t_base::operator long() const { return static_cast(Low()); } +EA_CONSTEXPR inline int128_t_base::operator long long() const { return static_cast(Low()); } +EA_CONSTEXPR inline int128_t_base::operator short() const { return static_cast(Low()); } +EA_CONSTEXPR inline int128_t_base::operator signed char() const { return static_cast(Low()); } +EA_CONSTEXPR inline int128_t_base::operator unsigned char() const { return static_cast(Low()); } +EA_CONSTEXPR inline int128_t_base::operator unsigned int() const { return static_cast(Low()); } +EA_CONSTEXPR inline int128_t_base::operator unsigned long long() const { return static_cast(Low()); } +EA_CONSTEXPR inline int128_t_base::operator unsigned long() const { return static_cast(Low()); } +EA_CONSTEXPR inline int128_t_base::operator unsigned short() const { return static_cast(Low()); } +EA_CONSTEXPR inline int128_t_base::operator float() const { return static_cast(Low()); } +EA_CONSTEXPR inline int128_t_base::operator double() const { return static_cast(Low()); } +EA_CONSTEXPR inline int128_t_base::operator long double() const { return static_cast(Low()); } +#if EA_INT128_INTRINSIC_AVAILABLE +EA_CONSTEXPR inline int128_t_base::operator __int128() const { return static_cast<__int128>(Low()); } +EA_CONSTEXPR inline int128_t_base::operator unsigned __int128() const { return static_cast(Low()); } +#endif + +inline void int128_t_base::SetBit(int nIndex, int value) +{ + // EA_ASSERT((nIndex >= 0) && (nIndex < 128)); + + const uint64_t nBitMask = ((uint64_t)1 << (nIndex % 64)); + + if(nIndex < 64) + { + if(value) + mPart0 = mPart0 | nBitMask; + else + mPart0 = mPart0 & ~nBitMask; + } + else if(nIndex < 128) + { + if(value) + mPart1 = mPart1 | nBitMask; + else + mPart1 = mPart1 & ~nBitMask; + } +} + +inline int int128_t_base::GetBit(int nIndex) const +{ + // EA_ASSERT((nIndex >= 0) && (nIndex < 128)); + + const uint64_t nBitMask = ((uint64_t)1 << (nIndex % 64)); + + if(nIndex < 64) + return ((mPart0 & nBitMask) ? 1 : 0); + else if(nIndex < 128) + return ((mPart1 & nBitMask) ? 1 : 0); + return 0; +} + +inline int128_t_base::int128_t_base(uint32_t nPart0, uint32_t nPart1, uint32_t nPart2, uint32_t nPart3) +{ + mPart1 = ((uint64_t)nPart3 << 32) + nPart2; + mPart0 = ((uint64_t)nPart1 << 32) + nPart0; +} + +inline int128_t_base::int128_t_base(uint64_t nPart0, uint64_t nPart1) +{ + mPart1 = nPart1; + mPart0 = nPart0; +} + +inline int128_t_base::int128_t_base(uint8_t value) +{ + mPart1 = 0; + mPart0 = value; +} + +inline int128_t_base::int128_t_base(uint16_t value) +{ + mPart1 = 0; + mPart0 = value; +} + +inline int128_t_base::int128_t_base(uint32_t value) +{ + mPart1 = 0; + mPart0 = value; +} + +inline int128_t_base::int128_t_base(uint64_t value) +{ + mPart1 = 0; + mPart0 = value; +} + +/////////////////////////////////////////////////////////////////////////////// +// OperatorPlus +// +// Returns: (value1 + value2) into result. +// The output 'result' *is* allowed to point to the same memory as one of the inputs. +// To consider: Fix 'defect' of this function whereby it doesn't implement overflow wraparound. +// +inline void int128_t_base::OperatorPlus(const int128_t_base& value1, const int128_t_base& value2, int128_t_base& result) +{ + uint64_t t = value1.mPart0 + value2.mPart0; + uint64_t nCarry = (t < value1.mPart0) && (t < value2.mPart0); + result.mPart0 = t; + result.mPart1 = value1.mPart1 + value2.mPart1 + nCarry; +} + +/////////////////////////////////////////////////////////////////////////////// +// OperatorMinus +// +// Returns: (value1 - value2) into result. +// The output 'result' *is* allowed to point to the same memory as one of the inputs. +// To consider: Fix 'defect' of this function whereby it doesn't implement overflow wraparound. +// +inline void int128_t_base::OperatorMinus(const int128_t_base& value1, const int128_t_base& value2, int128_t_base& result) +{ + uint64_t t = (value1.mPart0 - value2.mPart0); + uint64_t nCarry = (value1.mPart0 < value2.mPart0) ? 1u : 0u; + result.mPart0 = t; + result.mPart1 = (value1.mPart1 - value2.mPart1) - nCarry; +} + +/////////////////////////////////////////////////////////////////////////////// +// OperatorMul +// +// 64 bit systems: +// This is how it would be able to work if we could get a 128 bit result from +// two 64 bit values. None of the 64 bit systems that we are currently working +// with have C language support for multiplying two 64 bit numbers and retrieving +// the 128 bit result. However, many 64 bit platforms have support at the asm +// level for doing such a thing. +// Part 1 Part 0 +// 0000000000000002 0000000000000001 +// x 0000000000000002 0000000000000001 +// ------------------------------------------- +// | 0000000000000002 0000000000000001 +// + 0000000000000004 | 0000000000000002 (0000000000000000) +// ------------------------------------------------------------------------- +// +inline void int128_t_base::OperatorMul(const int128_t_base& a, const int128_t_base& b, int128_t_base& result) +{ + // To consider: Use compiler or OS-provided custom functionality here, such as + // Windows UnsignedMultiply128 and GCC's built-in int128_t. + +#if defined(DISABLED_PLATFORM_WIN64) + // To do: Implement x86-64 asm here. + +#else + // Else we are stuck doing something less efficient. In this case we + // fall back to doing 32 bit multiplies as with 32 bit platforms. + result = (a.mPart0 & 0xffffffff) * (b.mPart0 & 0xffffffff); + int128_t v01 = (a.mPart0 & 0xffffffff) * ((b.mPart0 >> 32) & 0xffffffff); + int128_t v02 = (a.mPart0 & 0xffffffff) * (b.mPart1 & 0xffffffff); + int128_t v03 = (a.mPart0 & 0xffffffff) * ((b.mPart1 >> 32) & 0xffffffff); + + int128_t v10 = ((a.mPart0 >> 32) & 0xffffffff) * (b.mPart0 & 0xffffffff); + int128_t v11 = ((a.mPart0 >> 32) & 0xffffffff) * ((b.mPart0 >> 32) & 0xffffffff); + int128_t v12 = ((a.mPart0 >> 32) & 0xffffffff) * (b.mPart1 & 0xffffffff); + + int128_t v20 = (a.mPart1 & 0xffffffff) * (b.mPart0 & 0xffffffff); + int128_t v21 = (a.mPart1 & 0xffffffff) * ((b.mPart0 >> 32) & 0xffffffff); + + int128_t v30 = ((a.mPart1 >> 32) & 0xffffffff) * (b.mPart0 & 0xffffffff); + + // Do row addition, shifting as needed. + OperatorPlus(result, v01 << 32, result); + OperatorPlus(result, v02 << 64, result); + OperatorPlus(result, v03 << 96, result); + + OperatorPlus(result, v10 << 32, result); + OperatorPlus(result, v11 << 64, result); + OperatorPlus(result, v12 << 96, result); + + OperatorPlus(result, v20 << 64, result); + OperatorPlus(result, v21 << 96, result); + + OperatorPlus(result, v30 << 96, result); +#endif +} + +/////////////////////////////////////////////////////////////////////////////// +// OperatorShiftRight +// +// Returns: value >> nShift into result +// The output 'result' may *not* be the same as one the input. +// With rightward shifts of negative numbers, shift in zero from the left side. +// +inline void int128_t_base::OperatorShiftRight(const int128_t_base& value, int nShift, int128_t_base& result) +{ + if(nShift >= 0) + { + if(nShift < 64) + { // 0 - 63 + result.mPart1 = (value.mPart1 >> nShift); + + if(nShift == 0) + result.mPart0 = (value.mPart0 >> nShift); + else + result.mPart0 = (value.mPart0 >> nShift) | (value.mPart1 << (64 - nShift)); + } + else + { // 64+ + result.mPart1 = 0; + result.mPart0 = (value.mPart1 >> (nShift - 64)); + } + } + else // (nShift < 0) + OperatorShiftLeft(value, -nShift, result); +} + + +/////////////////////////////////////////////////////////////////////////////// +// OperatorShiftRight +// +// Returns: value << nShift into result +// The output 'result' may *not* be the same as one the input. +// With rightward shifts of negative numbers, shift in zero from the left side. +// +inline void int128_t_base::OperatorShiftLeft(const int128_t_base& value, int nShift, int128_t_base& result) +{ + if(nShift >= 0) + { + if(nShift < 64) + { + if(nShift) // We need to have a special case because CPUs convert a shift by 64 to a no-op. + { + // 1 - 63 + result.mPart0 = (value.mPart0 << nShift); + result.mPart1 = (value.mPart1 << nShift) | (value.mPart0 >> (64 - nShift)); + } + else + { + result.mPart0 = value.mPart0; + result.mPart1 = value.mPart1; + } + } + else + { // 64+ + result.mPart0 = 0; + result.mPart1 = (value.mPart0 << (nShift - 64)); + } + } + else // (nShift < 0) + OperatorShiftRight(value, -nShift, result); +} + + +inline bool int128_t_base::operator!() const +{ + return (mPart0 == 0) && (mPart1 == 0); +} + + +/////////////////////////////////////////////////////////////////////////////// +// OperatorXOR +// +// Returns: value1 ^ value2 into result +// The output 'result' may be the same as one the input. +// +inline void int128_t_base::OperatorXOR(const int128_t_base& value1, const int128_t_base& value2, int128_t_base& result) +{ + result.mPart0 = (value1.mPart0 ^ value2.mPart0); + result.mPart1 = (value1.mPart1 ^ value2.mPart1); +} + + +/////////////////////////////////////////////////////////////////////////////// +// OperatorOR +// +// Returns: value1 | value2 into result +// The output 'result' may be the same as one the input. +// +inline void int128_t_base::OperatorOR(const int128_t_base& value1, const int128_t_base& value2, int128_t_base& result) +{ + result.mPart0 = (value1.mPart0 | value2.mPart0); + result.mPart1 = (value1.mPart1 | value2.mPart1); +} + + +/////////////////////////////////////////////////////////////////////////////// +// OperatorAND +// +// Returns: value1 & value2 into result +// The output 'result' may be the same as one the input. +// +inline void int128_t_base::OperatorAND(const int128_t_base& value1, const int128_t_base& value2, int128_t_base& result) +{ + result.mPart0 = (value1.mPart0 & value2.mPart0); + result.mPart1 = (value1.mPart1 & value2.mPart1); +} + + +inline bool int128_t_base::IsZero() const +{ + return (mPart0 == 0) && // Check mPart0 first as this will likely yield faster execution. + (mPart1 == 0); +} + + +inline void int128_t_base::SetZero() +{ + mPart1 = 0; + mPart0 = 0; +} + + +inline void int128_t_base::TwosComplement() +{ + mPart1 = ~mPart1; + mPart0 = ~mPart0; + + // What we want to do, but isn't available at this level: + // operator++(); + // Alternative: + int128_t_base one((uint32_t)1); + OperatorPlus(*this, one, *this); +} + + +inline void int128_t_base::InverseTwosComplement() +{ + // What we want to do, but isn't available at this level: + // operator--(); + // Alternative: + int128_t_base one((uint32_t)1); + OperatorMinus(*this, one, *this); + + mPart1 = ~mPart1; + mPart0 = ~mPart0; +} + + +inline void int128_t_base::DoubleToUint128(double value) +{ + // Currently this function is limited to 64 bits of integer input. + // We need to make a better version of this function. Perhaps we should implement + // it via dissecting the IEEE floating point format (sign, exponent, matissa). + // EA_ASSERT(fabs(value) < 18446744073709551616.0); // Assert that the input is <= 64 bits of integer. + + mPart1 = 0; + mPart0 = (value >= 0 ? (uint64_t)value : (uint64_t)-value); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// uint128_t implementation +/////////////////////////////////////////////////////////////////////////////////////////////////////// + +inline uint128_t uint128_t::operator^(const uint128_t& other) const +{ + uint128_t temp; + uint128_t::OperatorXOR(*this, other, temp); + return temp; +} + +inline uint128_t uint128_t::operator|(const uint128_t& other) const +{ + uint128_t temp; + uint128_t::OperatorOR(*this, other, temp); + return temp; +} + +inline uint128_t uint128_t::operator&(const uint128_t& other) const +{ + uint128_t temp; + uint128_t::OperatorAND(*this, other, temp); + return temp; +} + +inline uint128_t& uint128_t::operator^=(const uint128_t& value) +{ + OperatorXOR(*this, value, *this); + return *this; +} + +inline uint128_t& uint128_t::operator|=(const uint128_t& value) +{ + OperatorOR(*this, value, *this); + return *this; +} + +inline uint128_t& uint128_t::operator&=(const uint128_t& value) +{ + OperatorAND(*this, value, *this); + return *this; +} + +// With rightward shifts of negative numbers, shift in zero from the left side. +inline uint128_t uint128_t::operator>>(int nShift) const +{ + uint128_t temp; + OperatorShiftRight(*this, nShift, temp); + return temp; +} + +// With rightward shifts of negative numbers, shift in zero from the left side. +inline uint128_t uint128_t::operator<<(int nShift) const +{ + uint128_t temp; + OperatorShiftLeft(*this, nShift, temp); + return temp; +} + +inline uint128_t& uint128_t::operator>>=(int nShift) +{ + uint128_t temp; + OperatorShiftRight(*this, nShift, temp); + *this = temp; + return *this; +} + +inline uint128_t& uint128_t::operator<<=(int nShift) +{ + uint128_t temp; + OperatorShiftLeft(*this, nShift, temp); + *this = temp; + return *this; +} + +inline uint128_t& uint128_t::operator+=(const uint128_t& value) +{ + OperatorPlus(*this, value, *this); + return *this; +} + +inline uint128_t& uint128_t::operator-=(const uint128_t& value) +{ + OperatorMinus(*this, value, *this); + return *this; +} + +inline uint128_t& uint128_t::operator*=(const uint128_t& value) +{ + *this = *this * value; + return *this; +} + +inline uint128_t& uint128_t::operator/=(const uint128_t& value) +{ + *this = *this / value; + return *this; +} + +inline uint128_t& uint128_t::operator%=(const uint128_t& value) +{ + *this = *this % value; + return *this; +} + +inline uint128_t uint128_t::operator+(const uint128_t& other) +{ + uint128_t temp; + uint128_t::OperatorPlus(*this, other, temp); + return temp; +} + +inline uint128_t uint128_t::operator-(const uint128_t& other) +{ + uint128_t temp; + uint128_t::OperatorMinus(*this, other, temp); + return temp; +} + +inline uint128_t uint128_t::operator*(const uint128_t& other) +{ + uint128_t returnValue; + int128_t_base::OperatorMul(*this, other, returnValue); + return returnValue; +} + +inline uint128_t uint128_t::operator/(const uint128_t& other) +{ + uint128_t remainder; + uint128_t quotient; + this->Modulus(other, quotient, remainder); + return quotient; +} + +inline uint128_t uint128_t::operator%(const uint128_t& other) +{ + uint128_t remainder; + uint128_t quotient; + this->Modulus(other, quotient, remainder); + return remainder; +} + +inline uint128_t uint128_t::operator+() const +{ + return *this; +} + +inline uint128_t uint128_t::operator~() const +{ + return uint128_t(~mPart0, ~mPart1); +} + +inline uint128_t& uint128_t::operator--() +{ + int128_t_base one((uint32_t)1); + OperatorMinus(*this, one, *this); + return *this; +} + +inline uint128_t uint128_t::operator--(int) +{ + uint128_t temp((uint32_t)1); + OperatorMinus(*this, temp, temp); + return temp; +} + +inline uint128_t uint128_t::operator++(int) +{ + uint128_t prev = *this; + uint128_t temp((uint32_t)1); + OperatorPlus(*this, temp, *this); + return prev; +} + +inline uint128_t& uint128_t::operator++() +{ + int128_t_base one((uint32_t)1); + OperatorPlus(*this, one, *this); + return *this; +} + +inline void uint128_t::Negate() +{ + TwosComplement(); +} + +inline uint128_t uint128_t::operator-() const +{ + uint128_t returnValue(*this); + returnValue.Negate(); + return returnValue; +} + +// This function forms the basis of all logical comparison functions. +// If value1 < value2, the return value is -1. +// If value1 == value2, the return value is 0. +// If value1 > value2, the return value is 1. +inline int uint128_t::compare(const uint128_t& other) const +{ + // Compare individual parts. At this point, the two numbers have the same sign. + if(mPart1 == other.mPart1) + { + if(mPart0 == other.mPart0) + return 0; + else if(mPart0 > other.mPart0) + return 1; + // return -1; //Just fall through to the end. + } + else if(mPart1 > other.mPart1) + return 1; + return -1; +} + +EA_DISABLE_VC_WARNING(4723) // warning C4723: potential divide by 0 +inline void uint128_t::Modulus(const uint128_t& divisor, uint128_t& quotient, uint128_t& remainder) const +{ + uint128_t tempDividend(*this); + uint128_t tempDivisor(divisor); + + if(tempDivisor.IsZero()) + { + // Force a divide by zero exception. + // We know that tempDivisor.mPart0 is zero. + quotient.mPart0 /= tempDivisor.mPart0; + } + else if(tempDividend.IsZero()) + { + quotient = uint128_t((uint32_t)0); + remainder = uint128_t((uint32_t)0); + } + else + { + remainder.SetZero(); + + for(int i(0); i < 128; i++) + { + remainder += (uint32_t)tempDividend.GetBit(127 - i); + const bool bBit(remainder >= tempDivisor); + quotient.SetBit(127 - i, bBit); + + if(bBit) + remainder -= tempDivisor; + + if((i != 127) && !remainder.IsZero()) + remainder <<= 1; + } + } +} +EA_RESTORE_VC_WARNING() + +inline bool uint128_t::operator==(const uint128_t& other) const +{ + return (mPart0 == other.mPart0) && // Check mPart0 first as this will likely yield faster execution. + (mPart1 == other.mPart1); +} + +inline bool uint128_t::operator< (const uint128_t& other) const { return (compare(other) < 0); } +inline bool uint128_t::operator!=(const uint128_t& other) const { return !(*this == other); } +inline bool uint128_t::operator> (const uint128_t& other) const { return other < *this; } +inline bool uint128_t::operator>=(const uint128_t& other) const { return !(*this < other); } +inline bool uint128_t::operator<=(const uint128_t& other) const { return !(other < *this); } + +inline bool uint128_t::IsNegative() const +{ // True if value < 0 + return false; +} + +inline bool uint128_t::IsPositive() const +{ + // True of value >= 0 + return true; +} + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// int128_t implementation +/////////////////////////////////////////////////////////////////////////////////////////////////////// + +inline void int128_t::Negate() +{ + if (IsPositive()) + TwosComplement(); + else + InverseTwosComplement(); +} + +inline int128_t int128_t::operator-() const +{ + int128_t returnValue(*this); + returnValue.Negate(); + return returnValue; +} + +inline int128_t& int128_t::operator++() +{ + int128_t_base one((uint32_t)1); + OperatorPlus(*this, one, *this); + return *this; +} + +inline int128_t& int128_t::operator--() +{ + int128_t_base one((uint32_t)1); + OperatorMinus(*this, one, *this); + return *this; +} + +inline int128_t int128_t::operator++(int) +{ + int128_t prev = *this; + int128_t temp((uint32_t)1); + OperatorPlus(*this, temp, *this); + return prev; +} + +inline int128_t int128_t::operator--(int) +{ + int128_t temp((uint32_t)1); + OperatorMinus(*this, temp, temp); + return temp; +} + +inline int128_t int128_t::operator+() const +{ + return *this; +} + +inline int128_t int128_t::operator~() const +{ + return int128_t(~mPart0, ~mPart1); +} + +inline int128_t int128_t::operator+(const int128_t& other) +{ + int128_t temp; + int128_t::OperatorPlus(*this, other, temp); + return temp; +} + +inline int128_t int128_t::operator-(const int128_t& other) +{ + int128_t temp; + int128_t::OperatorMinus(*this, other, temp); + return temp; +} + +// This function forms the basis of all logical comparison functions. +// If value1 < value2, the return value is -1. +// If value1 == value2, the return value is 0. +// If value1 > value2, the return value is 1. +inline int int128_t::compare(const int128_t& other) const +{ + // Cache some values. Positive means >= 0. Negative means < 0 and thus means '!positive'. + const bool bValue1IsPositive( IsPositive()); + const bool bValue2IsPositive(other.IsPositive()); + + // Do positive/negative tests. + if(bValue1IsPositive != bValue2IsPositive) + return bValue1IsPositive ? 1 : -1; + + // Compare individual parts. At this point, the two numbers have the same sign. + if(mPart1 == other.mPart1) + { + if(mPart0 == other.mPart0) + return 0; + else if(mPart0 > other.mPart0) + return 1; + // return -1; //Just fall through to the end. + } + else if(mPart1 > other.mPart1) + return 1; + return -1; +} + +inline bool int128_t::operator==(const int128_t& other) const +{ + return (mPart0 == other.mPart0) && // Check mPart0 first as this will likely yield faster execution. + (mPart1 == other.mPart1); +} + +inline bool int128_t::operator!=(const int128_t& other) const +{ + return (mPart0 != other.mPart0) || // Check mPart0 first as this will likely yield faster execution. + (mPart1 != other.mPart1); +} + +inline bool int128_t::operator>(const int128_t& other) const +{ + return (compare(other) > 0); +} + +inline bool int128_t::operator>=(const int128_t& other) const +{ + return (compare(other) >= 0); +} + +inline bool int128_t::operator<(const int128_t& other) const +{ + return (compare(other) < 0); +} + +inline bool int128_t::operator<=(const int128_t& other) const +{ + return (compare(other) <= 0); +} + +inline bool int128_t::IsNegative() const +{ // True if value < 0 + return ((mPart1 & UINT64_C(0x8000000000000000)) != 0); +} + +inline bool int128_t::IsPositive() const +{ // True of value >= 0 + return ((mPart1 & UINT64_C(0x8000000000000000)) == 0); +} + +inline int128_t int128_t::operator*(const int128_t& other) +{ + int128_t a(*this); + int128_t b(other); + int128_t returnValue; + + // Correctly handle negative values + bool bANegative(false); + bool bBNegative(false); + + if(a.IsNegative()) + { + bANegative = true; + a.Negate(); + } + + if(b.IsNegative()) + { + bBNegative = true; + b.Negate(); + } + + int128_t_base::OperatorMul(a, b, returnValue); + + // Do negation as needed. + if(bANegative != bBNegative) + returnValue.Negate(); + + return returnValue; +} + +inline int128_t int128_t::operator/(const int128_t& other) +{ + int128_t remainder; + int128_t quotient; + this->Modulus(other, quotient, remainder); + return quotient; +} + +inline int128_t int128_t::operator<<(int nShift) const +{ + int128_t temp; + OperatorShiftLeft(*this, nShift, temp); + return temp; +} + +inline int128_t& int128_t::operator+=(const int128_t& value) +{ + OperatorPlus(*this, value, *this); + return *this; +} + +inline int128_t& int128_t::operator-=(const int128_t& value) +{ + OperatorMinus(*this, value, *this); + return *this; +} + +inline int128_t& int128_t::operator<<=(int nShift) +{ + int128_t temp; + OperatorShiftLeft(*this, nShift, temp); + *this = temp; + return *this; +} + +inline int128_t& int128_t::operator*=(const int128_t& value) +{ + *this = *this * value; + return *this; +} + +inline int128_t& int128_t::operator%=(const int128_t& value) +{ + *this = *this % value; + return *this; +} + +inline int128_t int128_t::operator%(const int128_t& other) +{ + int128_t remainder; + int128_t quotient; + this->Modulus(other, quotient, remainder); + return remainder; +} + +inline int128_t& int128_t::operator/=(const int128_t& value) +{ + *this = *this / value; + return *this; +} + +// With rightward shifts of negative numbers, shift in zero from the left side. +inline int128_t int128_t::operator>>(int nShift) const +{ + int128_t temp; + OperatorShiftRight(*this, nShift, temp); + return temp; +} + +inline int128_t& int128_t::operator>>=(int nShift) +{ + int128_t temp; + OperatorShiftRight(*this, nShift, temp); + *this = temp; + return *this; +} + +inline int128_t int128_t::operator^(const int128_t& other) const +{ + int128_t temp; + int128_t::OperatorXOR(*this, other, temp); + return temp; +} + +inline int128_t int128_t::operator|(const int128_t& other) const +{ + int128_t temp; + int128_t::OperatorOR(*this, other, temp); + return temp; +} + + +inline int128_t int128_t::operator&(const int128_t& other) const +{ + int128_t temp; + int128_t::OperatorAND(*this, other, temp); + return temp; +} + +inline int128_t& int128_t::operator^=(const int128_t& value) +{ + OperatorXOR(*this, value, *this); + return *this; +} + +inline int128_t& int128_t::operator|=(const int128_t& value) +{ + OperatorOR(*this, value, *this); + return *this; +} + +inline int128_t& int128_t::operator&=(const int128_t& value) +{ + OperatorAND(*this, value, *this); + return *this; +} + +EA_DISABLE_VC_WARNING(4723) // warning C4723: potential divide by 0 +inline void int128_t::Modulus(const int128_t& divisor, int128_t& quotient, int128_t& remainder) const +{ + int128_t tempDividend(*this); + int128_t tempDivisor(divisor); + + bool bDividendNegative = false; + bool bDivisorNegative = false; + + if(tempDividend.IsNegative()) + { + bDividendNegative = true; + tempDividend.Negate(); + } + if(tempDivisor.IsNegative()) + { + bDivisorNegative = true; + tempDivisor.Negate(); + } + + // Handle the special cases + if(tempDivisor.IsZero()) + { + // Force a divide by zero exception. + // We know that tempDivisor.mPart0 is zero. + quotient.mPart0 /= tempDivisor.mPart0; + } + else if(tempDividend.IsZero()) + { + quotient = int128_t((uint32_t)0); + remainder = int128_t((uint32_t)0); + } + else + { + remainder.SetZero(); + + for(int i(0); i < 128; i++) + { + remainder += (uint32_t)tempDividend.GetBit(127 - i); + const bool bBit(remainder >= tempDivisor); + quotient.SetBit(127 - i, bBit); + + if(bBit) + remainder -= tempDivisor; + + if((i != 127) && !remainder.IsZero()) + remainder <<= 1; + } + } + + if((bDividendNegative && !bDivisorNegative) || (!bDividendNegative && bDivisorNegative)) + { + // Ensure the following formula applies for negative dividends + // dividend = divisor * quotient + remainder + quotient.Negate(); + } +} +EA_RESTORE_VC_WARNING() + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// INT128_C / UINT128_C +// +// The C99 language defines macros for portably defining constants of +// sized numeric types. For example, there might be: +// #define UINT64_C(x) x##ULL +// Since our int128 data type is not a built-in type, we can't define a +// UINT128_C macro as something that pastes ULLL at the end of the digits. +// Instead we define it to create a temporary that is constructed from a +// string of the digits. This will work in most cases that suffix pasting +// would work. +// +/* EA_CONSTEXPR */ inline uint128_t UINT128_C(uint64_t nPart1, uint64_t nPart0) { return uint128_t(nPart0, nPart1); } +/* EA_CONSTEXPR */ inline int128_t INT128_C(int64_t nPart1, int64_t nPart0) { return int128_t(static_cast(nPart0), static_cast(nPart1)); } + + + + +#endif // INCLUDED_int128_h + diff --git a/UnknownVersion/include/EABase/version.h b/UnknownVersion/include/EABase/version.h new file mode 100644 index 0000000..e591d01 --- /dev/null +++ b/UnknownVersion/include/EABase/version.h @@ -0,0 +1,36 @@ +/*----------------------------------------------------------------------------- + * version.h + * + * Copyright (c) Electronic Arts Inc. All rights reserved. + *---------------------------------------------------------------------------*/ + +#ifndef INCLUDED_EABASE_VERSION_H +#define INCLUDED_EABASE_VERSION_H + +/////////////////////////////////////////////////////////////////////////////// +// EABASE_VERSION +// +// We more or less follow the conventional EA packaging approach to versioning +// here. A primary distinction here is that minor versions are defined as two +// digit entities (e.g. .03") instead of minimal digit entities ".3"). The logic +// here is that the value is a counter and not a floating point fraction. +// Note that the major version doesn't have leading zeros. +// +// Example version strings: +// "0.91.00" // Major version 0, minor version 91, patch version 0. +// "1.00.00" // Major version 1, minor and patch version 0. +// "3.10.02" // Major version 3, minor version 10, patch version 02. +// "12.03.01" // Major version 12, minor version 03, patch version +// +// Example usage: +// printf("EABASE version: %s", EABASE_VERSION); +// printf("EABASE version: %d.%d.%d", EABASE_VERSION_N / 10000 % 100, EABASE_VERSION_N / 100 % 100, EABASE_VERSION_N % 100); +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef EABASE_VERSION +#define EABASE_VERSION "2.09.12" +#define EABASE_VERSION_N 20912 +#endif + +#endif -- cgit v1.2.3