summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomi Korpipää <tomi.korpipaa@qt.io>2020-06-05 08:12:03 +0300
committerTomi Korpipää <tomi.korpipaa@qt.io>2020-06-08 03:42:19 +0000
commit48e7789645cbf93102738f0da0f4181919d102a5 (patch)
tree80de28851082c66fdc48567320e8517a4956909e
parent31697c758f2ed19bd7c6bbe61f1b91f9e12035b5 (diff)
Update EABase for EASTL
Add support for missing mips64 architecture. Task-number: QT3DS-4129 Change-Id: I03f306bf842a43fc686093fc0df693189b8a1452 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Antti Määttä <antti.maatta@qt.io>
-rw-r--r--UnknownVersion/include/EABase/config/eacompiler.h1934
-rw-r--r--UnknownVersion/include/EABase/config/eacompilertraits.h3357
-rw-r--r--UnknownVersion/include/EABase/config/eaplatform.h1165
-rw-r--r--UnknownVersion/include/EABase/eabase.h1524
-rw-r--r--UnknownVersion/include/EABase/earesult.h70
-rw-r--r--UnknownVersion/include/EABase/eaunits.h54
-rw-r--r--UnknownVersion/include/EABase/int128.h1268
-rw-r--r--UnknownVersion/include/EABase/version.h36
8 files changed, 6894 insertions, 2514 deletions
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 = <integer>
* EA_COMPILER_NAME = <string>
* EA_COMPILER_STRING = <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<class U> 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 <class T> 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
- * <exception> is in namespace std. Some std libraries fail to
- * put the contents of <exception> in namespace std. The following
+ * <exception> is in namespace std. Some std libraries fail to
+ * put the contents of <exception> 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 <int i>
* 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 <EABase/config/eaplatform.h>
- // 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()
+// <code>
+// 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 <cstddef> // Need to trigger the compilation of yvals.h without directly using <yvals.h> 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 <android/api-level.h>
+//
+//#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 <iterator> for range-based for loops to work.
+// Example usage:
+// #include <iterator>
+// #include <vector>
+// std::vector<float> 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 <cstddef>.
+// Note that <EABase/nullptr.h> 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 <typename T>
+// using Dictionary = eastl::map<eastl::string, T>;
+//
+// Dictionary<int> 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<class T>
+// 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<eastl::list<int>> 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 = <n bytes>
@@ -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 <EABase/config/eaplatform.h>
+#include <EABase/config/eacompiler.h>
-#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 <stddef.h>
+
+// 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
-#if defined(__SNC__) || defined(EA_PLATFORM_PS3) || defined(__S3E__)
-# ifndef __STDC_LIMIT_MACROS
-# define __STDC_LIMIT_MACROS
-# 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
-# ifndef __STDC_CONSTANT_MACROS
-# define __STDC_CONSTANT_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
-# include <stdint.h>
+// 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
-# if !defined(EA_COMPILER_HAS_INTTYPES)
-# if !defined(__S3E__)
-# define EA_COMPILER_HAS_INTTYPES
-# endif
-# endif
+#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.
+
+#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<int EA_COMMA() int EACOMMA() char>);
+//
+#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<const volatile char&>((((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 <typename T> struct EAAlignOf1 { enum { s = sizeof (T), value = s ^ (s & (s - 1)) }; };
- template <typename T> struct EAAlignOf2;
- template <int size_diff> struct helper { template <typename T> struct Val { enum { value = size_diff }; }; };
- template <> struct helper<0> { template <typename T> struct Val { enum { value = EAAlignOf2<T>::value }; }; };
- template <typename T> struct EAAlignOf2 { struct Big { T x; char c; };
- enum { diff = sizeof (Big) - sizeof (T), value = helper<diff>::template Val<Big>::value }; };
- template <typename T> struct EAAlignof3 { enum { x = EAAlignOf2<T>::value, y = EAAlignOf1<T>::value, value = x < y ? x : y }; };
-# define EA_ALIGN_OF(type) ((size_t)EAAlignof3<type>::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 <typename T> struct EAAlignOf1 { enum { s = sizeof (T), value = s ^ (s & (s - 1)) }; };
+template <typename T> struct EAAlignOf2;
+template <int size_diff> struct helper { template <typename T> struct Val { enum { value = size_diff }; }; };
+template <> struct helper<0> { template <typename T> struct Val { enum { value = EAAlignOf2<T>::value }; }; };
+template <typename T> struct EAAlignOf2 { struct Big { T x; char c; };
+ enum { diff = sizeof (Big) - sizeof (T), value = helper<diff>::template Val<Big>::value }; };
+template <typename T> struct EAAlignof3 { enum { x = EAAlignOf2<T>::value, y = EAAlignOf1<T>::value, value = x < y ? x : y }; };
+#define EA_ALIGN_OF(type) ((size_t)EAAlignof3<type>::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(<myinclude.h>)
+// #include <myinclude.h>
+// #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();
- //
+#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
+
+
+
+// ------------------------------------------------------------------------
+// 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
+
+
+
+// ------------------------------------------------------------------------
+// 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)
+// <code>
+// 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
+
+#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
+
+
+// ------------------------------------------------------------------------
+// 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)
+// <code>
+// 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_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)
+// <code>
+// 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
+
+#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_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)
+// <code>
+// 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
+
+
+// ------------------------------------------------------------------------
+// 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)
+// <code>
+// 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)
+// <code>
+// 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)
+// <code>
+// 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()
+// <code>
+// 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)
+// <code>
+// 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)
+// <code>
+// 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)
+// <code>
+// 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_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();
- //
+#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 (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 = <sizeof(wchar_t)>
- //
+#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 <typename T>
+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 = <sizeof(wchar_t)>
+//
#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
+// 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(_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);
- //
+#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_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;
- //
+#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_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
+#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_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.
- //
+#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)
-# 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.
- //
+#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
+#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
+#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();
- // };
- //
+#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)){}
- //
+#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
+#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
-# 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
+#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(__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.
+#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
+#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.
+// ------------------------------------------------------------------------
+// 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
- //
- // <user code>
- //
- // #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.
- //
+#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
+//
+// <user code>
+//
+// #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()
+//
+// <user code>
+//
+// #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_MSVC) && (EA_COMPILER_VERSION >= 1400) // VS2005 (VC8) and later
-# define EA_OVERRIDE override
-# else
-# define EA_OVERRIDE
-# endif
+#if defined(EA_COMPILER_NO_OVERRIDE)
+#define EA_OVERRIDE
+#else
+#define EA_OVERRIDE override
+#endif
#endif
- // ------------------------------------------------------------------------
- // EA_SEALED
- //
- // See http://msdn.microsoft.com/en-us/library/49k3w2fx%28VS.71%29.aspx for more information.
- //
+// ------------------------------------------------------------------------
+// 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
+#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
- //
- // See http://msdn.microsoft.com/en-us/library/49k3w2fx%28VS.71%29.aspx for more information.
- //
+// ------------------------------------------------------------------------
+// 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
+#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<T>)
+// { ... }
+//
+#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<char>);
+//
+#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 <class T>
+// 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.
+//
+// <No current platform fails to propogate sign bits on right signed shifts>
+
#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 = <string>
- * EA_PLATFORM_DESCRIPTION = <string>
- * 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 = <integer size in bytes>
- * EA_PLATFORM_WORD_SIZE = <integer size in bytes>
- *
- *---------------------------------------------------------------------------*/
+ */
+#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 = <string>
+// EA_PLATFORM_DESCRIPTION = <string>
+// 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 = <integer size in bytes>
+// EA_PLATFORM_WORD_SIZE = <integer size in bytes>
+// EA_CACHE_LINE_SIZE = <integer size in bytes>
+//---------------------------------------------------------------------------
+
+/*
+ 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 <winapifamily.h>
+#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 <TargetConditionals.h>
-
- // 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 <TargetConditionals.h>
+
+// 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 <winapifamily.h>
+#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 <winapifamily.h>
+#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 <EABase/config/eacompiler.h>
// Identify traits which this compiler supports, or does not support
-#ifndef INCLUDED_eacompilertraits_H
-# include "EABase/config/eacompilertraits.h"
-#endif
+#include <EABase/config/eacompilertraits.h>
// Identify the platform and declare the EA_xxxx defines
-#ifndef INCLUDED_eaplatform_H
-# include "EABase/config/eaplatform.h"
-#endif
+#include <EABase/config/eaplatform.h>
-# if defined(_MSC_VER) && (_MSC_VER >= 1600)
-#include <yvals.h>
+#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.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.00.22"
-# define EABASE_VERSION_N 20022
-#endif
-
+// Define common SI unit macros
+#include <EABase/eaunits.h>
// ------------------------------------------------------------------------
@@ -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 <stddef.h>
+#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 <stddef.h>
+#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 <stddef.h>
+#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 <assert.h>(p : 186)
+#if !defined(__cplusplus) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201100L
+#include <assert.h>
#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 "<inttypes.h> 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 <inttypes.h> // PRId8, SCNd8, etc.
-# endif
-# include <stdint.h> // int32_t, INT64_C, UINT8_MAX, etc.
-# include <math.h> // float_t, double_t, etc.
-# include <float.h> // 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 <inttypes.h> // PRId8, SCNd8, etc.
+#endif
+#if defined(_MSC_VER)
+#pragma warning(push, 0)
+#endif
+#include <stdint.h> // int32_t, INT64_C, UINT8_MAX, etc.
+#include <math.h> // float_t, double_t, etc.
+#include <float.h> // 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 <sys/types.h>
+// 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 <sys/types.h>
+#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 <wchar.h>
-# 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 <wchar.h>
+#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 <typename T, size_t N>
+char (&EAArraySizeHelper(T (&x)[N]))[N];
+
+template <typename T, size_t N>
+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 <EABase/int128.h>
+#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 <EABase/eabase.h>
+
+#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 <EABase/eabase.h>
+
+#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<char>(Low()); }
+#if EA_WCHAR_UNIQUE
+// EA_CONSTEXPR inline int128_t_base::operator char16_t() const { return static_cast<char16_t>(Low()); }
+// EA_CONSTEXPR inline int128_t_base::operator char32_t() const { return static_cast<char32_t>(Low()); }
+// EA_CONSTEXPR inline int128_t_base::operator wchar_t() const { return static_cast<wchar_t>(Low()); }
+#endif
+EA_CONSTEXPR inline int128_t_base::operator int() const { return static_cast<int>(Low()); }
+EA_CONSTEXPR inline int128_t_base::operator long() const { return static_cast<long>(Low()); }
+EA_CONSTEXPR inline int128_t_base::operator long long() const { return static_cast<long long>(Low()); }
+EA_CONSTEXPR inline int128_t_base::operator short() const { return static_cast<short>(Low()); }
+EA_CONSTEXPR inline int128_t_base::operator signed char() const { return static_cast<signed char>(Low()); }
+EA_CONSTEXPR inline int128_t_base::operator unsigned char() const { return static_cast<unsigned char>(Low()); }
+EA_CONSTEXPR inline int128_t_base::operator unsigned int() const { return static_cast<unsigned int>(Low()); }
+EA_CONSTEXPR inline int128_t_base::operator unsigned long long() const { return static_cast<unsigned long long>(Low()); }
+EA_CONSTEXPR inline int128_t_base::operator unsigned long() const { return static_cast<unsigned long>(Low()); }
+EA_CONSTEXPR inline int128_t_base::operator unsigned short() const { return static_cast<unsigned short>(Low()); }
+EA_CONSTEXPR inline int128_t_base::operator float() const { return static_cast<float>(Low()); }
+EA_CONSTEXPR inline int128_t_base::operator double() const { return static_cast<double>(Low()); }
+EA_CONSTEXPR inline int128_t_base::operator long double() const { return static_cast<long double>(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<unsigned __int128>(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<uint64_t>(nPart0), static_cast<uint64_t>(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