First
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) Electronic Arts Inc. All rights reserved.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include <EASTL/internal/config.h>
|
||||
#include <EASTL/allocator.h>
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// ReadMe
|
||||
//
|
||||
// This file implements the default application allocator.
|
||||
// You can replace this allocator.cpp file with a different one,
|
||||
// you can define EASTL_USER_DEFINED_ALLOCATOR below to ignore this file,
|
||||
// or you can modify the EASTL config.h file to redefine how allocators work.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef EASTL_USER_DEFINED_ALLOCATOR // If the user hasn't declared that he has defined an allocator implementation elsewhere...
|
||||
|
||||
namespace eastl
|
||||
{
|
||||
|
||||
/// gDefaultAllocator
|
||||
/// Default global allocator instance.
|
||||
EASTL_API allocator gDefaultAllocator;
|
||||
EASTL_API allocator* gpDefaultAllocator = &gDefaultAllocator;
|
||||
|
||||
EASTL_API allocator* GetDefaultAllocator()
|
||||
{
|
||||
return gpDefaultAllocator;
|
||||
}
|
||||
|
||||
EASTL_API allocator* SetDefaultAllocator(allocator* pAllocator)
|
||||
{
|
||||
allocator* const pPrevAllocator = gpDefaultAllocator;
|
||||
gpDefaultAllocator = pAllocator;
|
||||
return pPrevAllocator;
|
||||
}
|
||||
|
||||
} // namespace eastl
|
||||
|
||||
|
||||
#endif // EASTL_USER_DEFINED_ALLOCATOR
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) Electronic Arts Inc. All rights reserved.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include <EASTL/internal/config.h>
|
||||
#include <EASTL/string.h>
|
||||
#include <EABase/eabase.h>
|
||||
|
||||
#if defined(EA_PLATFORM_WINDOWS_KERNEL)
|
||||
#include <Wdm.h>
|
||||
#elif defined(EA_PLATFORM_MICROSOFT)
|
||||
EA_DISABLE_ALL_VC_WARNINGS();
|
||||
#if defined(EA_COMPILER_MSVC)
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
EA_RESTORE_ALL_VC_WARNINGS();
|
||||
#elif defined(EA_PLATFORM_ANDROID)
|
||||
#include <android/log.h>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
namespace eastl
|
||||
{
|
||||
|
||||
/// gpAssertionFailureFunction
|
||||
///
|
||||
/// Global assertion failure function pointer. Set by SetAssertionFailureFunction.
|
||||
///
|
||||
EASTL_API EASTL_AssertionFailureFunction gpAssertionFailureFunction = AssertionFailureFunctionDefault;
|
||||
EASTL_API void* gpAssertionFailureFunctionContext = NULL;
|
||||
|
||||
|
||||
|
||||
/// SetAssertionFailureFunction
|
||||
///
|
||||
/// Sets the function called when an assertion fails. If this function is not called
|
||||
/// by the user, a default function will be used. The user may supply a context parameter
|
||||
/// which will be passed back to the user in the function call. This is typically used
|
||||
/// to store a C++ 'this' pointer, though other things are possible.
|
||||
///
|
||||
/// There is no thread safety here, so the user needs to externally make sure that
|
||||
/// this function is not called in a thread-unsafe way. The easiest way to do this is
|
||||
/// to just call this function once from the main thread on application startup.
|
||||
///
|
||||
EASTL_API void SetAssertionFailureFunction(EASTL_AssertionFailureFunction pAssertionFailureFunction, void* pContext)
|
||||
{
|
||||
gpAssertionFailureFunction = pAssertionFailureFunction;
|
||||
gpAssertionFailureFunctionContext = pContext;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// AssertionFailureFunctionDefault
|
||||
///
|
||||
EASTL_API void AssertionFailureFunctionDefault(const char* pExpression, void* /*pContext*/)
|
||||
{
|
||||
#if EASTL_ASSERT_ENABLED
|
||||
#if defined(EA_PLATFORM_WINDOWS_KERNEL)
|
||||
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "%s", pExpression);
|
||||
#elif defined(EA_PLATFORM_MICROSOFT)
|
||||
printf("%s\n", pExpression); // Write the message to stdout
|
||||
if( ::IsDebuggerPresent())
|
||||
{
|
||||
OutputDebugStringA(pExpression);
|
||||
}
|
||||
#elif defined(EA_PLATFORM_ANDROID)
|
||||
__android_log_print(ANDROID_LOG_INFO, "PRINTF", "%s\n", pExpression);
|
||||
#else
|
||||
printf("%s\n", pExpression); // Write the message to stdout, which happens to be the trace view for many console debug machines.
|
||||
#endif
|
||||
#else
|
||||
EA_UNUSED(pExpression);
|
||||
#endif
|
||||
|
||||
EASTL_DEBUG_BREAK();
|
||||
}
|
||||
|
||||
|
||||
/// AssertionFailure
|
||||
///
|
||||
EASTL_API void AssertionFailure(const char* pExpression)
|
||||
{
|
||||
if(gpAssertionFailureFunction)
|
||||
gpAssertionFailureFunction(pExpression, gpAssertionFailureFunctionContext);
|
||||
}
|
||||
|
||||
|
||||
} // namespace eastl
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) Electronic Arts Inc. All rights reserved.
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include <EASTL/atomic.h>
|
||||
|
||||
|
||||
namespace eastl
|
||||
{
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
|
||||
static void EastlCompilerBarrierDataDependencyFunc(void*)
|
||||
{
|
||||
}
|
||||
|
||||
volatile CompilerBarrierDataDependencyFuncPtr gCompilerBarrierDataDependencyFunc = &EastlCompilerBarrierDataDependencyFunc;
|
||||
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace eastl
|
||||
@@ -0,0 +1,70 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) Electronic Arts Inc. All rights reserved.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include <EASTL/internal/fixed_pool.h>
|
||||
#include <EASTL/fixed_allocator.h>
|
||||
|
||||
|
||||
|
||||
namespace eastl
|
||||
{
|
||||
|
||||
|
||||
EASTL_API void fixed_pool_base::init(void* pMemory, size_t memorySize, size_t nodeSize,
|
||||
size_t alignment, size_t /*alignmentOffset*/)
|
||||
{
|
||||
// To do: Support alignmentOffset.
|
||||
|
||||
#if EASTL_FIXED_SIZE_TRACKING_ENABLED
|
||||
mnCurrentSize = 0;
|
||||
mnPeakSize = 0;
|
||||
#endif
|
||||
|
||||
if(pMemory)
|
||||
{
|
||||
// Assert that alignment is a power of 2 value (e.g. 1, 2, 4, 8, 16, etc.)
|
||||
EASTL_ASSERT((alignment & (alignment - 1)) == 0);
|
||||
|
||||
// Make sure alignment is a valid value.
|
||||
if(alignment < 1)
|
||||
alignment = 1;
|
||||
|
||||
mpNext = (Link*)(((uintptr_t)pMemory + (alignment - 1)) & ~(alignment - 1));
|
||||
memorySize -= (uintptr_t)mpNext - (uintptr_t)pMemory;
|
||||
pMemory = mpNext;
|
||||
|
||||
// The node size must be at least as big as a Link, which itself is sizeof(void*).
|
||||
if(nodeSize < sizeof(Link))
|
||||
nodeSize = ((sizeof(Link) + (alignment - 1))) & ~(alignment - 1);
|
||||
|
||||
// If the user passed in a memory size that wasn't a multiple of the node size,
|
||||
// we need to chop down the memory size so that the last node is not a whole node.
|
||||
memorySize = (memorySize / nodeSize) * nodeSize;
|
||||
|
||||
mpCapacity = (Link*)((uintptr_t)pMemory + memorySize);
|
||||
mpHead = NULL;
|
||||
mnNodeSize = nodeSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace eastl
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) Electronic Arts Inc. All rights reserved.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include <EASTL/internal/hashtable.h>
|
||||
#include <EASTL/utility.h>
|
||||
#include <math.h> // Not all compilers support <cmath> and std::ceilf(), which we need below.
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
EA_DISABLE_VC_WARNING(4267); // 'argument' : conversion from 'size_t' to 'const uint32_t', possible loss of data. This is a bogus warning resulting from a bug in VC++.
|
||||
|
||||
|
||||
namespace eastl
|
||||
{
|
||||
|
||||
/// gpEmptyBucketArray
|
||||
///
|
||||
/// A shared representation of an empty hash table. This is present so that
|
||||
/// a new empty hashtable allocates no memory. It has two entries, one for
|
||||
/// the first lone empty (NULL) bucket, and one for the non-NULL trailing sentinel.
|
||||
///
|
||||
EASTL_API void* gpEmptyBucketArray[2] = { NULL, (void*)uintptr_t(~0) };
|
||||
|
||||
|
||||
|
||||
/// gPrimeNumberArray
|
||||
///
|
||||
/// This is an array of prime numbers. This is the same set of prime
|
||||
/// numbers suggested by the C++ standard proposal. These are numbers
|
||||
/// which are separated by 8% per entry.
|
||||
///
|
||||
/// To consider: Allow the user to specify their own prime number array.
|
||||
///
|
||||
const uint32_t gPrimeNumberArray[] =
|
||||
{
|
||||
2u, 3u, 5u, 7u, 11u, 13u, 17u, 19u, 23u, 29u, 31u,
|
||||
37u, 41u, 43u, 47u, 53u, 59u, 61u, 67u, 71u, 73u, 79u,
|
||||
83u, 89u, 97u, 103u, 109u, 113u, 127u, 137u, 139u, 149u,
|
||||
157u, 167u, 179u, 193u, 199u, 211u, 227u, 241u, 257u,
|
||||
277u, 293u, 313u, 337u, 359u, 383u, 409u, 439u, 467u,
|
||||
503u, 541u, 577u, 619u, 661u, 709u, 761u, 823u, 887u,
|
||||
953u, 1031u, 1109u, 1193u, 1289u, 1381u, 1493u, 1613u,
|
||||
1741u, 1879u, 2029u, 2179u, 2357u, 2549u, 2753u, 2971u,
|
||||
3209u, 3469u, 3739u, 4027u, 4349u, 4703u, 5087u, 5503u,
|
||||
5953u, 6427u, 6949u, 7517u, 8123u, 8783u, 9497u, 10273u,
|
||||
11113u, 12011u, 12983u, 14033u, 15173u, 16411u, 17749u,
|
||||
19183u, 20753u, 22447u, 24281u, 26267u, 28411u, 30727u,
|
||||
33223u, 35933u, 38873u, 42043u, 45481u, 49201u, 53201u,
|
||||
57557u, 62233u, 67307u, 72817u, 78779u, 85229u, 92203u,
|
||||
99733u, 107897u, 116731u, 126271u, 136607u, 147793u,
|
||||
159871u, 172933u, 187091u, 202409u, 218971u, 236897u,
|
||||
256279u, 277261u, 299951u, 324503u, 351061u, 379787u,
|
||||
410857u, 444487u, 480881u, 520241u, 562841u, 608903u,
|
||||
658753u, 712697u, 771049u, 834181u, 902483u, 976369u,
|
||||
1056323u, 1142821u, 1236397u, 1337629u, 1447153u, 1565659u,
|
||||
1693859u, 1832561u, 1982627u, 2144977u, 2320627u, 2510653u,
|
||||
2716249u, 2938679u, 3179303u, 3439651u, 3721303u, 4026031u,
|
||||
4355707u, 4712381u, 5098259u, 5515729u, 5967347u, 6456007u,
|
||||
6984629u, 7556579u, 8175383u, 8844859u, 9569143u, 10352717u,
|
||||
11200489u, 12117689u, 13109983u, 14183539u, 15345007u,
|
||||
16601593u, 17961079u, 19431899u, 21023161u, 22744717u,
|
||||
24607243u, 26622317u, 28802401u, 31160981u, 33712729u,
|
||||
36473443u, 39460231u, 42691603u, 46187573u, 49969847u,
|
||||
54061849u, 58488943u, 63278561u, 68460391u, 74066549u,
|
||||
80131819u, 86693767u, 93793069u, 101473717u, 109783337u,
|
||||
118773397u, 128499677u, 139022417u, 150406843u, 162723577u,
|
||||
176048909u, 190465427u, 206062531u, 222936881u, 241193053u,
|
||||
260944219u, 282312799u, 305431229u, 330442829u, 357502601u,
|
||||
386778277u, 418451333u, 452718089u, 489790921u, 529899637u,
|
||||
573292817u, 620239453u, 671030513u, 725980837u, 785430967u,
|
||||
849749479u, 919334987u, 994618837u, 1076067617u, 1164186217u,
|
||||
1259520799u, 1362662261u, 1474249943u, 1594975441u,
|
||||
1725587117u, 1866894511u, 2019773507u, 2185171673u,
|
||||
2364114217u, 2557710269u, 2767159799u, 2993761039u,
|
||||
3238918481u, 3504151727u, 3791104843u, 4101556399u,
|
||||
4294967291u,
|
||||
4294967291u // Sentinel so we don't have to test result of lower_bound
|
||||
};
|
||||
|
||||
|
||||
/// kPrimeCount
|
||||
///
|
||||
/// The number of prime numbers in gPrimeNumberArray.
|
||||
///
|
||||
const uint32_t kPrimeCount = (sizeof(gPrimeNumberArray) / sizeof(gPrimeNumberArray[0]) - 1);
|
||||
|
||||
|
||||
/// GetPrevBucketCountOnly
|
||||
/// Return a bucket count no greater than nBucketCountHint.
|
||||
///
|
||||
uint32_t prime_rehash_policy::GetPrevBucketCountOnly(uint32_t nBucketCountHint)
|
||||
{
|
||||
const uint32_t nPrime = *(eastl::upper_bound(gPrimeNumberArray, gPrimeNumberArray + kPrimeCount, nBucketCountHint) - 1);
|
||||
return nPrime;
|
||||
}
|
||||
|
||||
|
||||
/// GetPrevBucketCount
|
||||
/// Return a bucket count no greater than nBucketCountHint.
|
||||
/// This function has a side effect of updating mnNextResize.
|
||||
///
|
||||
uint32_t prime_rehash_policy::GetPrevBucketCount(uint32_t nBucketCountHint) const
|
||||
{
|
||||
const uint32_t nPrime = *(eastl::upper_bound(gPrimeNumberArray, gPrimeNumberArray + kPrimeCount, nBucketCountHint) - 1);
|
||||
|
||||
mnNextResize = (uint32_t)ceilf(nPrime * mfMaxLoadFactor);
|
||||
return nPrime;
|
||||
}
|
||||
|
||||
|
||||
/// GetNextBucketCount
|
||||
/// Return a prime no smaller than nBucketCountHint.
|
||||
/// This function has a side effect of updating mnNextResize.
|
||||
///
|
||||
uint32_t prime_rehash_policy::GetNextBucketCount(uint32_t nBucketCountHint) const
|
||||
{
|
||||
const uint32_t nPrime = *eastl::lower_bound(gPrimeNumberArray, gPrimeNumberArray + kPrimeCount, nBucketCountHint);
|
||||
|
||||
mnNextResize = (uint32_t)ceilf(nPrime * mfMaxLoadFactor);
|
||||
return nPrime;
|
||||
}
|
||||
|
||||
|
||||
/// GetBucketCount
|
||||
/// Return the smallest prime p such that alpha p >= nElementCount, where alpha
|
||||
/// is the load factor. This function has a side effect of updating mnNextResize.
|
||||
///
|
||||
uint32_t prime_rehash_policy::GetBucketCount(uint32_t nElementCount) const
|
||||
{
|
||||
const uint32_t nMinBucketCount = (uint32_t)(nElementCount / mfMaxLoadFactor);
|
||||
const uint32_t nPrime = *eastl::lower_bound(gPrimeNumberArray, gPrimeNumberArray + kPrimeCount, nMinBucketCount);
|
||||
|
||||
mnNextResize = (uint32_t)ceilf(nPrime * mfMaxLoadFactor);
|
||||
return nPrime;
|
||||
}
|
||||
|
||||
|
||||
/// GetRehashRequired
|
||||
/// Finds the smallest prime p such that alpha p > nElementCount + nElementAdd.
|
||||
/// If p > nBucketCount, return pair<bool, uint32_t>(true, p); otherwise return
|
||||
/// pair<bool, uint32_t>(false, 0). In principle this isn't very different from GetBucketCount.
|
||||
/// This function has a side effect of updating mnNextResize.
|
||||
///
|
||||
eastl::pair<bool, uint32_t>
|
||||
prime_rehash_policy::GetRehashRequired(uint32_t nBucketCount, uint32_t nElementCount, uint32_t nElementAdd) const
|
||||
{
|
||||
if((nElementCount + nElementAdd) > mnNextResize) // It is significant that we specify > next resize and not >= next resize.
|
||||
{
|
||||
if(nBucketCount == 1) // We force rehashing to occur if the bucket count is < 2.
|
||||
nBucketCount = 0;
|
||||
|
||||
float fMinBucketCount = (nElementCount + nElementAdd) / mfMaxLoadFactor;
|
||||
|
||||
if(fMinBucketCount > (float)nBucketCount)
|
||||
{
|
||||
fMinBucketCount = eastl::max_alt(fMinBucketCount, mfGrowthFactor * nBucketCount);
|
||||
const uint32_t nPrime = *eastl::lower_bound(gPrimeNumberArray, gPrimeNumberArray + kPrimeCount, (uint32_t)fMinBucketCount);
|
||||
mnNextResize = (uint32_t)ceilf(nPrime * mfMaxLoadFactor);
|
||||
|
||||
return eastl::pair<bool, uint32_t>(true, nPrime);
|
||||
}
|
||||
else
|
||||
{
|
||||
mnNextResize = (uint32_t)ceilf(nBucketCount * mfMaxLoadFactor);
|
||||
return eastl::pair<bool, uint32_t>(false, (uint32_t)0);
|
||||
}
|
||||
}
|
||||
|
||||
return eastl::pair<bool, uint32_t>(false, (uint32_t)0);
|
||||
}
|
||||
|
||||
|
||||
} // namespace eastl
|
||||
|
||||
EA_RESTORE_VC_WARNING();
|
||||
@@ -0,0 +1,87 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) Electronic Arts Inc. All rights reserved.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <EASTL/intrusive_list.h>
|
||||
|
||||
|
||||
namespace eastl
|
||||
{
|
||||
|
||||
|
||||
EASTL_API void intrusive_list_base::reverse() EA_NOEXCEPT
|
||||
{
|
||||
intrusive_list_node* pNode = &mAnchor;
|
||||
do {
|
||||
intrusive_list_node* const pTemp = pNode->mpNext;
|
||||
pNode->mpNext = pNode->mpPrev;
|
||||
pNode->mpPrev = pTemp;
|
||||
pNode = pNode->mpPrev;
|
||||
}
|
||||
while(pNode != &mAnchor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
EASTL_API bool intrusive_list_base::validate() const
|
||||
{
|
||||
const intrusive_list_node *p = &mAnchor;
|
||||
const intrusive_list_node *q = p;
|
||||
|
||||
// We do two tests below:
|
||||
//
|
||||
// 1) Prev and next pointers are symmetric. We check (p->next->prev == p)
|
||||
// for each node, which is enough to verify all links.
|
||||
//
|
||||
// 2) Loop check. We bump the q pointer at one-half rate compared to the
|
||||
// p pointer; (p == q) if and only if we are at the start (which we
|
||||
// don't check) or if there is a loop somewhere in the list.
|
||||
|
||||
do {
|
||||
// validate node (even phase)
|
||||
if (p->mpNext->mpPrev != p)
|
||||
return false; // broken linkage detected
|
||||
|
||||
// bump only fast pointer
|
||||
p = p->mpNext;
|
||||
if (p == &mAnchor)
|
||||
break;
|
||||
|
||||
if (p == q)
|
||||
return false; // loop detected
|
||||
|
||||
// validate node (odd phase)
|
||||
if (p->mpNext->mpPrev != p)
|
||||
return false; // broken linkage detected
|
||||
|
||||
// bump both pointers
|
||||
p = p->mpNext;
|
||||
q = q->mpNext;
|
||||
|
||||
if (p == q)
|
||||
return false; // loop detected
|
||||
|
||||
} while(p != &mAnchor);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace eastl
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,598 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) Electronic Arts Inc. All rights reserved.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include <EASTL/numeric_limits.h>
|
||||
|
||||
|
||||
#if EASTL_CUSTOM_FLOAT_CONSTANTS_REQUIRED
|
||||
#include <limits> // See notes below about usage of this header.
|
||||
|
||||
namespace eastl
|
||||
{
|
||||
namespace Internal
|
||||
{
|
||||
// For this platformc/compiler combination we fall back to using std::numeric_limits,
|
||||
// which is available for with most compilers and platforms, though it doesn't necessarily
|
||||
// support the C++11 functionality that we do. However, we need it just for the four
|
||||
// floating point types. Note that this code isn't used for most EA platforms, as
|
||||
// most platforms use GCC, clang, VC++ (yvals), or Dinkumware (yvals).
|
||||
// To do: Initialize these values via a means that doesn't depend on std::numeric_limits.
|
||||
|
||||
EASTL_API float gFloatInfinity = std::numeric_limits<float>::infinity();
|
||||
EASTL_API float gFloatNaN = std::numeric_limits<float>::quiet_NaN();
|
||||
EASTL_API float gFloatSNaN = std::numeric_limits<float>::signaling_NaN();
|
||||
EASTL_API float gFloatDenorm = std::numeric_limits<float>::denorm_min();
|
||||
|
||||
EASTL_API double gDoubleInfinity = std::numeric_limits<double>::infinity();
|
||||
EASTL_API double gDoubleNaN = std::numeric_limits<double>::quiet_NaN();
|
||||
EASTL_API double gDoubleSNaN = std::numeric_limits<double>::signaling_NaN();
|
||||
EASTL_API double gDoubleDenorm = std::numeric_limits<double>::denorm_min();
|
||||
|
||||
EASTL_API long double gLongDoubleInfinity = std::numeric_limits<long double>::infinity();
|
||||
EASTL_API long double gLongDoubleNaN = std::numeric_limits<long double>::quiet_NaN();
|
||||
EASTL_API long double gLongDoubleSNaN = std::numeric_limits<long double>::signaling_NaN();
|
||||
EASTL_API long double gLongDoubleDenorm = std::numeric_limits<long double>::denorm_min();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_MSC_VER) && !defined(EA_COMPILER_CLANG_CL)
|
||||
// VC++ has a long-standing bug: it fails to allow the definition of static const member variables
|
||||
// outside the declaration within the class. The C++ Standard actually requires that they be defined
|
||||
// and some other compilers fail to link if they aren't. So we simply don't define the members for VC++.
|
||||
// See the C++ Standard Sec. 9.4.2 paragraph 4, which makes this clear.
|
||||
// http://bytes.com/topic/c/answers/710704-const-static-initialization-visual-studio
|
||||
#else
|
||||
|
||||
namespace eastl
|
||||
{
|
||||
namespace Internal
|
||||
{
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits_base::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits_base::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits_base::digits10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits_base::max_digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits_base::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits_base::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits_base::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits_base::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits_base::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits_base::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits_base::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits_base::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits_base::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits_base::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits_base::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits_base::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits_base::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits_base::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits_base::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits_base::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits_base::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits_base::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits_base::is_iec559;
|
||||
}
|
||||
|
||||
// bool
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<bool>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<bool>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<bool>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<bool>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<bool>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<bool>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<bool>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<bool>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<bool>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<bool>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<bool>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<bool>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<bool>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<bool>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<bool>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<bool>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<bool>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<bool>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<bool>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<bool>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<bool>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<bool>::is_iec559;
|
||||
|
||||
// char
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<char>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<char>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char>::is_iec559;
|
||||
|
||||
// unsigned char
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned char>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned char>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned char>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned char>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned char>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned char>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned char>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned char>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned char>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned char>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned char>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned char>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned char>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned char>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned char>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<unsigned char>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned char>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned char>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned char>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<unsigned char>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned char>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned char>::is_iec559;
|
||||
|
||||
// signed char
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<signed char>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<signed char>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<signed char>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<signed char>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<signed char>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<signed char>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<signed char>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<signed char>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<signed char>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<signed char>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<signed char>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<signed char>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<signed char>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<signed char>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<signed char>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<signed char>::round_style;
|
||||
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<signed char>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<signed char>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<signed char>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<signed char>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<signed char>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<signed char>::is_iec559;
|
||||
|
||||
// wchar_t
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<wchar_t>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<wchar_t>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<wchar_t>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<wchar_t>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<wchar_t>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<wchar_t>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<wchar_t>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<wchar_t>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<wchar_t>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<wchar_t>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<wchar_t>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<wchar_t>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<wchar_t>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<wchar_t>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<wchar_t>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<wchar_t>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<wchar_t>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<wchar_t>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<wchar_t>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<wchar_t>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<wchar_t>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<wchar_t>::is_iec559;
|
||||
|
||||
// char8_t
|
||||
#if defined(EA_CHAR8_UNIQUE) && EA_CHAR8_UNIQUE // If char8_t is a true unique type (as called for by the C++20 Standard)
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char8_t>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char8_t>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char8_t>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char8_t>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char8_t>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char8_t>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char8_t>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char8_t>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char8_t>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char8_t>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char8_t>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char8_t>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char8_t>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char8_t>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char8_t>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<char8_t>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char8_t>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char8_t>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char8_t>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<char8_t>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char8_t>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char8_t>::is_iec559;
|
||||
#endif
|
||||
|
||||
// char16_t
|
||||
#if EA_CHAR16_NATIVE // If char16_t is a true unique type (as called for by the C++11 Standard)...
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char16_t>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char16_t>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char16_t>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char16_t>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char16_t>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char16_t>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char16_t>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char16_t>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char16_t>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char16_t>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char16_t>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char16_t>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char16_t>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char16_t>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char16_t>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<char16_t>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char16_t>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char16_t>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char16_t>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<char16_t>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char16_t>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char16_t>::is_iec559;
|
||||
#endif
|
||||
|
||||
// char32_t
|
||||
#if EA_CHAR32_NATIVE // If char32_t is a true unique type (as called for by the C++11 Standard)...
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char32_t>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char32_t>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char32_t>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char32_t>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char32_t>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char32_t>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char32_t>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char32_t>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char32_t>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char32_t>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<char32_t>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char32_t>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char32_t>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char32_t>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char32_t>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<char32_t>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char32_t>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char32_t>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char32_t>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<char32_t>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char32_t>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<char32_t>::is_iec559;
|
||||
#endif
|
||||
|
||||
// unsigned short
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned short>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned short>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned short>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned short>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned short>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned short>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned short>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned short>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned short>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned short>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned short>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned short>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned short>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned short>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned short>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<unsigned short>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned short>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned short>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned short>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<unsigned short>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned short>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned short>::is_iec559;
|
||||
|
||||
// short
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<short>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<short>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<short>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<short>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<short>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<short>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<short>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<short>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<short>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<short>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<short>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<short>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<short>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<short>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<short>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<short>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<short>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<short>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<short>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<short>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<short>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<short>::is_iec559;
|
||||
|
||||
// unsigned int
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned int>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned int>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned int>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned int>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned int>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned int>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned int>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned int>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned int>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned int>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned int>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned int>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned int>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned int>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned int>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<unsigned int>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned int>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned int>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned int>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<unsigned int>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned int>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned int>::is_iec559;
|
||||
|
||||
// int
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<int>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<int>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<int>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<int>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<int>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<int>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<int>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<int>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<int>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<int>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<int>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<int>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<int>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<int>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<int>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<int>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<int>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<int>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<int>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<int>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<int>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<int>::is_iec559;
|
||||
|
||||
// unsigned long
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned long>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned long>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned long>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned long>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned long>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned long>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned long>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<unsigned long>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<unsigned long>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long>::is_iec559;
|
||||
|
||||
// long
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<long>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<long>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long>::is_iec559;
|
||||
|
||||
// unsigned long long
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long long>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned long long>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned long long>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long long>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long long>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long long>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned long long>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned long long>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned long long>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned long long>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<unsigned long long>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long long>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long long>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long long>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long long>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<unsigned long long>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long long>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long long>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long long>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<unsigned long long>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long long>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<unsigned long long>::is_iec559;
|
||||
|
||||
// long long
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long long>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long long>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long long>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long long>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long long>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long long>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long long>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long long>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long long>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long long>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long long>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long long>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long long>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long long>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long long>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<long long>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long long>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long long>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long long>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<long long>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long long>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long long>::is_iec559;
|
||||
|
||||
// __uint128_t
|
||||
#if (EA_COMPILER_INTMAX_SIZE >= 16) && (defined(EA_COMPILER_GNUC) || defined(__clang__)) // If __int128_t/__uint128_t is supported...
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__uint128_t>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<__uint128_t>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<__uint128_t>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__uint128_t>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__uint128_t>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__uint128_t>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<__uint128_t>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<__uint128_t>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<__uint128_t>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<__uint128_t>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<__uint128_t>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__uint128_t>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__uint128_t>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__uint128_t>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__uint128_t>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<__uint128_t>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__uint128_t>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__uint128_t>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__uint128_t>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<__uint128_t>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__uint128_t>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__uint128_t>::is_iec559;
|
||||
#endif
|
||||
|
||||
// __int128_t
|
||||
#if (EA_COMPILER_INTMAX_SIZE >= 16) && (defined(EA_COMPILER_GNUC) || defined(__clang__)) // If __int128_t/__uint128_t is supported...
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__int128_t>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<__int128_t>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<__int128_t>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__int128_t>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__int128_t>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__int128_t>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<__int128_t>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<__int128_t>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<__int128_t>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<__int128_t>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<__int128_t>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__int128_t>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__int128_t>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__int128_t>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__int128_t>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<__int128_t>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__int128_t>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__int128_t>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__int128_t>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<__int128_t>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__int128_t>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<__int128_t>::is_iec559;
|
||||
#endif
|
||||
|
||||
// float
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<float>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<float>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<float>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<float>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<float>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<float>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<float>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<float>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<float>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<float>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<float>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<float>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<float>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<float>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<float>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<float>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<float>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<float>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<float>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<float>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<float>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<float>::is_iec559;
|
||||
|
||||
// double
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<double>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<double>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<double>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<double>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<double>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<double>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<double>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<double>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<double>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<double>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<double>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<double>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<double>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<double>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<double>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<double>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<double>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<double>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<double>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<double>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<double>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<double>::is_iec559;
|
||||
|
||||
// long double
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long double>::is_specialized;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long double>::digits;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long double>::digits10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long double>::is_signed;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long double>::is_integer;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long double>::is_exact;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long double>::radix;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long double>::min_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long double>::min_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long double>::max_exponent;
|
||||
EA_CONSTEXPR_OR_CONST int numeric_limits<long double>::max_exponent10;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long double>::is_bounded;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long double>::is_modulo;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long double>::traps;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long double>::tinyness_before;
|
||||
EA_CONSTEXPR_OR_CONST float_round_style numeric_limits<long double>::round_style;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long double>::has_infinity;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long double>::has_quiet_NaN;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long double>::has_signaling_NaN;
|
||||
EA_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<long double>::has_denorm;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long double>::has_denorm_loss;
|
||||
EA_CONSTEXPR_OR_CONST bool numeric_limits<long double>::is_iec559;
|
||||
|
||||
} // namespace eastl
|
||||
|
||||
#endif // (VC++ 2010 or earlier)
|
||||
|
||||
|
||||
@@ -0,0 +1,518 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) Electronic Arts Inc. All rights reserved.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// The tree insert and erase functions below are based on the original
|
||||
// HP STL tree functions. Use of these functions was been approved by
|
||||
// EA legal on November 4, 2005 and the approval documentation is available
|
||||
// from the EASTL maintainer or from the EA legal deparatment on request.
|
||||
//
|
||||
// Copyright (c) 1994
|
||||
// Hewlett-Packard Company
|
||||
//
|
||||
// Permission to use, copy, modify, distribute and sell this software
|
||||
// and its documentation for any purpose is hereby granted without fee,
|
||||
// provided that the above copyright notice appear in all copies and
|
||||
// that both that copyright notice and this permission notice appear
|
||||
// in supporting documentation. Hewlett-Packard Company makes no
|
||||
// representations about the suitability of this software for any
|
||||
// purpose. It is provided "as is" without express or implied warranty.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
#include <EASTL/internal/config.h>
|
||||
#include <EASTL/internal/red_black_tree.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
|
||||
namespace eastl
|
||||
{
|
||||
// Forward declarations
|
||||
rbtree_node_base* RBTreeRotateLeft(rbtree_node_base* pNode, rbtree_node_base* pNodeRoot);
|
||||
rbtree_node_base* RBTreeRotateRight(rbtree_node_base* pNode, rbtree_node_base* pNodeRoot);
|
||||
|
||||
|
||||
|
||||
/// RBTreeIncrement
|
||||
/// Returns the next item in a sorted red-black tree.
|
||||
///
|
||||
EASTL_API rbtree_node_base* RBTreeIncrement(const rbtree_node_base* pNode)
|
||||
{
|
||||
if(pNode->mpNodeRight)
|
||||
{
|
||||
pNode = pNode->mpNodeRight;
|
||||
|
||||
while(pNode->mpNodeLeft)
|
||||
pNode = pNode->mpNodeLeft;
|
||||
}
|
||||
else
|
||||
{
|
||||
rbtree_node_base* pNodeTemp = pNode->mpNodeParent;
|
||||
|
||||
while(pNode == pNodeTemp->mpNodeRight)
|
||||
{
|
||||
pNode = pNodeTemp;
|
||||
pNodeTemp = pNodeTemp->mpNodeParent;
|
||||
}
|
||||
|
||||
if(pNode->mpNodeRight != pNodeTemp)
|
||||
pNode = pNodeTemp;
|
||||
}
|
||||
|
||||
return const_cast<rbtree_node_base*>(pNode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// RBTreeIncrement
|
||||
/// Returns the previous item in a sorted red-black tree.
|
||||
///
|
||||
EASTL_API rbtree_node_base* RBTreeDecrement(const rbtree_node_base* pNode)
|
||||
{
|
||||
if((pNode->mpNodeParent->mpNodeParent == pNode) && (pNode->mColor == kRBTreeColorRed))
|
||||
return pNode->mpNodeRight;
|
||||
else if(pNode->mpNodeLeft)
|
||||
{
|
||||
rbtree_node_base* pNodeTemp = pNode->mpNodeLeft;
|
||||
|
||||
while(pNodeTemp->mpNodeRight)
|
||||
pNodeTemp = pNodeTemp->mpNodeRight;
|
||||
|
||||
return pNodeTemp;
|
||||
}
|
||||
|
||||
rbtree_node_base* pNodeTemp = pNode->mpNodeParent;
|
||||
|
||||
while(pNode == pNodeTemp->mpNodeLeft)
|
||||
{
|
||||
pNode = pNodeTemp;
|
||||
pNodeTemp = pNodeTemp->mpNodeParent;
|
||||
}
|
||||
|
||||
return const_cast<rbtree_node_base*>(pNodeTemp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// RBTreeGetBlackCount
|
||||
/// Counts the number of black nodes in an red-black tree, from pNode down to the given bottom node.
|
||||
/// We don't count red nodes because red-black trees don't really care about
|
||||
/// red node counts; it is black node counts that are significant in the
|
||||
/// maintenance of a balanced tree.
|
||||
///
|
||||
EASTL_API size_t RBTreeGetBlackCount(const rbtree_node_base* pNodeTop, const rbtree_node_base* pNodeBottom)
|
||||
{
|
||||
size_t nCount = 0;
|
||||
|
||||
for(; pNodeBottom; pNodeBottom = pNodeBottom->mpNodeParent)
|
||||
{
|
||||
if(pNodeBottom->mColor == kRBTreeColorBlack)
|
||||
++nCount;
|
||||
|
||||
if(pNodeBottom == pNodeTop)
|
||||
break;
|
||||
}
|
||||
|
||||
return nCount;
|
||||
}
|
||||
|
||||
|
||||
/// RBTreeRotateLeft
|
||||
/// Does a left rotation about the given node.
|
||||
/// If you want to understand tree rotation, any book on algorithms will
|
||||
/// discuss the topic in detail.
|
||||
///
|
||||
rbtree_node_base* RBTreeRotateLeft(rbtree_node_base* pNode, rbtree_node_base* pNodeRoot)
|
||||
{
|
||||
rbtree_node_base* const pNodeTemp = pNode->mpNodeRight;
|
||||
|
||||
pNode->mpNodeRight = pNodeTemp->mpNodeLeft;
|
||||
|
||||
if(pNodeTemp->mpNodeLeft)
|
||||
pNodeTemp->mpNodeLeft->mpNodeParent = pNode;
|
||||
pNodeTemp->mpNodeParent = pNode->mpNodeParent;
|
||||
|
||||
if(pNode == pNodeRoot)
|
||||
pNodeRoot = pNodeTemp;
|
||||
else if(pNode == pNode->mpNodeParent->mpNodeLeft)
|
||||
pNode->mpNodeParent->mpNodeLeft = pNodeTemp;
|
||||
else
|
||||
pNode->mpNodeParent->mpNodeRight = pNodeTemp;
|
||||
|
||||
pNodeTemp->mpNodeLeft = pNode;
|
||||
pNode->mpNodeParent = pNodeTemp;
|
||||
|
||||
return pNodeRoot;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// RBTreeRotateRight
|
||||
/// Does a right rotation about the given node.
|
||||
/// If you want to understand tree rotation, any book on algorithms will
|
||||
/// discuss the topic in detail.
|
||||
///
|
||||
rbtree_node_base* RBTreeRotateRight(rbtree_node_base* pNode, rbtree_node_base* pNodeRoot)
|
||||
{
|
||||
rbtree_node_base* const pNodeTemp = pNode->mpNodeLeft;
|
||||
|
||||
pNode->mpNodeLeft = pNodeTemp->mpNodeRight;
|
||||
|
||||
if(pNodeTemp->mpNodeRight)
|
||||
pNodeTemp->mpNodeRight->mpNodeParent = pNode;
|
||||
pNodeTemp->mpNodeParent = pNode->mpNodeParent;
|
||||
|
||||
if(pNode == pNodeRoot)
|
||||
pNodeRoot = pNodeTemp;
|
||||
else if(pNode == pNode->mpNodeParent->mpNodeRight)
|
||||
pNode->mpNodeParent->mpNodeRight = pNodeTemp;
|
||||
else
|
||||
pNode->mpNodeParent->mpNodeLeft = pNodeTemp;
|
||||
|
||||
pNodeTemp->mpNodeRight = pNode;
|
||||
pNode->mpNodeParent = pNodeTemp;
|
||||
|
||||
return pNodeRoot;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// RBTreeInsert
|
||||
/// Insert a node into the tree and rebalance the tree as a result of the
|
||||
/// disturbance the node introduced.
|
||||
///
|
||||
EASTL_API void RBTreeInsert(rbtree_node_base* pNode,
|
||||
rbtree_node_base* pNodeParent,
|
||||
rbtree_node_base* pNodeAnchor,
|
||||
RBTreeSide insertionSide)
|
||||
{
|
||||
rbtree_node_base*& pNodeRootRef = pNodeAnchor->mpNodeParent;
|
||||
|
||||
// Initialize fields in new node to insert.
|
||||
pNode->mpNodeParent = pNodeParent;
|
||||
pNode->mpNodeRight = NULL;
|
||||
pNode->mpNodeLeft = NULL;
|
||||
pNode->mColor = kRBTreeColorRed;
|
||||
|
||||
// Insert the node.
|
||||
if(insertionSide == kRBTreeSideLeft)
|
||||
{
|
||||
pNodeParent->mpNodeLeft = pNode; // Also makes (leftmost = pNode) when (pNodeParent == pNodeAnchor)
|
||||
|
||||
if(pNodeParent == pNodeAnchor)
|
||||
{
|
||||
pNodeAnchor->mpNodeParent = pNode;
|
||||
pNodeAnchor->mpNodeRight = pNode;
|
||||
}
|
||||
else if(pNodeParent == pNodeAnchor->mpNodeLeft)
|
||||
pNodeAnchor->mpNodeLeft = pNode; // Maintain leftmost pointing to min node
|
||||
}
|
||||
else
|
||||
{
|
||||
pNodeParent->mpNodeRight = pNode;
|
||||
|
||||
if(pNodeParent == pNodeAnchor->mpNodeRight)
|
||||
pNodeAnchor->mpNodeRight = pNode; // Maintain rightmost pointing to max node
|
||||
}
|
||||
|
||||
// Rebalance the tree.
|
||||
while((pNode != pNodeRootRef) && (pNode->mpNodeParent->mColor == kRBTreeColorRed))
|
||||
{
|
||||
EA_ANALYSIS_ASSUME(pNode->mpNodeParent != NULL);
|
||||
rbtree_node_base* const pNodeParentParent = pNode->mpNodeParent->mpNodeParent;
|
||||
|
||||
if(pNode->mpNodeParent == pNodeParentParent->mpNodeLeft)
|
||||
{
|
||||
rbtree_node_base* const pNodeTemp = pNodeParentParent->mpNodeRight;
|
||||
|
||||
if(pNodeTemp && (pNodeTemp->mColor == kRBTreeColorRed))
|
||||
{
|
||||
pNode->mpNodeParent->mColor = kRBTreeColorBlack;
|
||||
pNodeTemp->mColor = kRBTreeColorBlack;
|
||||
pNodeParentParent->mColor = kRBTreeColorRed;
|
||||
pNode = pNodeParentParent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pNode->mpNodeParent && pNode == pNode->mpNodeParent->mpNodeRight)
|
||||
{
|
||||
pNode = pNode->mpNodeParent;
|
||||
pNodeRootRef = RBTreeRotateLeft(pNode, pNodeRootRef);
|
||||
}
|
||||
|
||||
EA_ANALYSIS_ASSUME(pNode->mpNodeParent != NULL);
|
||||
pNode->mpNodeParent->mColor = kRBTreeColorBlack;
|
||||
pNodeParentParent->mColor = kRBTreeColorRed;
|
||||
pNodeRootRef = RBTreeRotateRight(pNodeParentParent, pNodeRootRef);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rbtree_node_base* const pNodeTemp = pNodeParentParent->mpNodeLeft;
|
||||
|
||||
if(pNodeTemp && (pNodeTemp->mColor == kRBTreeColorRed))
|
||||
{
|
||||
pNode->mpNodeParent->mColor = kRBTreeColorBlack;
|
||||
pNodeTemp->mColor = kRBTreeColorBlack;
|
||||
pNodeParentParent->mColor = kRBTreeColorRed;
|
||||
pNode = pNodeParentParent;
|
||||
}
|
||||
else
|
||||
{
|
||||
EA_ANALYSIS_ASSUME(pNode != NULL && pNode->mpNodeParent != NULL);
|
||||
|
||||
if(pNode == pNode->mpNodeParent->mpNodeLeft)
|
||||
{
|
||||
pNode = pNode->mpNodeParent;
|
||||
pNodeRootRef = RBTreeRotateRight(pNode, pNodeRootRef);
|
||||
}
|
||||
|
||||
pNode->mpNodeParent->mColor = kRBTreeColorBlack;
|
||||
pNodeParentParent->mColor = kRBTreeColorRed;
|
||||
pNodeRootRef = RBTreeRotateLeft(pNodeParentParent, pNodeRootRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EA_ANALYSIS_ASSUME(pNodeRootRef != NULL);
|
||||
pNodeRootRef->mColor = kRBTreeColorBlack;
|
||||
|
||||
} // RBTreeInsert
|
||||
|
||||
|
||||
|
||||
|
||||
/// RBTreeErase
|
||||
/// Erase a node from the tree.
|
||||
///
|
||||
EASTL_API void RBTreeErase(rbtree_node_base* pNode, rbtree_node_base* pNodeAnchor)
|
||||
{
|
||||
rbtree_node_base*& pNodeRootRef = pNodeAnchor->mpNodeParent;
|
||||
rbtree_node_base*& pNodeLeftmostRef = pNodeAnchor->mpNodeLeft;
|
||||
rbtree_node_base*& pNodeRightmostRef = pNodeAnchor->mpNodeRight;
|
||||
rbtree_node_base* pNodeSuccessor = pNode;
|
||||
rbtree_node_base* pNodeChild = NULL;
|
||||
rbtree_node_base* pNodeChildParent = NULL;
|
||||
|
||||
if(pNodeSuccessor->mpNodeLeft == NULL) // pNode has at most one non-NULL child.
|
||||
pNodeChild = pNodeSuccessor->mpNodeRight; // pNodeChild might be null.
|
||||
else if(pNodeSuccessor->mpNodeRight == NULL) // pNode has exactly one non-NULL child.
|
||||
pNodeChild = pNodeSuccessor->mpNodeLeft; // pNodeChild is not null.
|
||||
else
|
||||
{
|
||||
// pNode has two non-null children. Set pNodeSuccessor to pNode's successor. pNodeChild might be NULL.
|
||||
pNodeSuccessor = pNodeSuccessor->mpNodeRight;
|
||||
|
||||
while(pNodeSuccessor->mpNodeLeft)
|
||||
pNodeSuccessor = pNodeSuccessor->mpNodeLeft;
|
||||
|
||||
pNodeChild = pNodeSuccessor->mpNodeRight;
|
||||
}
|
||||
|
||||
// Here we remove pNode from the tree and fix up the node pointers appropriately around it.
|
||||
if(pNodeSuccessor == pNode) // If pNode was a leaf node (had both NULL children)...
|
||||
{
|
||||
pNodeChildParent = pNodeSuccessor->mpNodeParent; // Assign pNodeReplacement's parent.
|
||||
|
||||
if(pNodeChild)
|
||||
pNodeChild->mpNodeParent = pNodeSuccessor->mpNodeParent;
|
||||
|
||||
if(pNode == pNodeRootRef) // If the node being deleted is the root node...
|
||||
pNodeRootRef = pNodeChild; // Set the new root node to be the pNodeReplacement.
|
||||
else
|
||||
{
|
||||
if(pNode == pNode->mpNodeParent->mpNodeLeft) // If pNode is a left node...
|
||||
pNode->mpNodeParent->mpNodeLeft = pNodeChild; // Make pNode's replacement node be on the same side.
|
||||
else
|
||||
pNode->mpNodeParent->mpNodeRight = pNodeChild;
|
||||
// Now pNode is disconnected from the bottom of the tree (recall that in this pathway pNode was determined to be a leaf).
|
||||
}
|
||||
|
||||
if(pNode == pNodeLeftmostRef) // If pNode is the tree begin() node...
|
||||
{
|
||||
// Because pNode is the tree begin(), pNode->mpNodeLeft must be NULL.
|
||||
// Here we assign the new begin() (first node).
|
||||
if(pNode->mpNodeRight && pNodeChild)
|
||||
{
|
||||
EASTL_ASSERT(pNodeChild != NULL); // Logically pNodeChild should always be valid.
|
||||
pNodeLeftmostRef = RBTreeGetMinChild(pNodeChild);
|
||||
}
|
||||
else
|
||||
pNodeLeftmostRef = pNode->mpNodeParent; // This makes (pNodeLeftmostRef == end()) if (pNode == root node)
|
||||
}
|
||||
|
||||
if(pNode == pNodeRightmostRef) // If pNode is the tree last (rbegin()) node...
|
||||
{
|
||||
// Because pNode is the tree rbegin(), pNode->mpNodeRight must be NULL.
|
||||
// Here we assign the new rbegin() (last node)
|
||||
if(pNode->mpNodeLeft && pNodeChild)
|
||||
{
|
||||
EASTL_ASSERT(pNodeChild != NULL); // Logically pNodeChild should always be valid.
|
||||
pNodeRightmostRef = RBTreeGetMaxChild(pNodeChild);
|
||||
}
|
||||
else // pNodeChild == pNode->mpNodeLeft
|
||||
pNodeRightmostRef = pNode->mpNodeParent; // makes pNodeRightmostRef == &mAnchor if pNode == pNodeRootRef
|
||||
}
|
||||
}
|
||||
else // else (pNodeSuccessor != pNode)
|
||||
{
|
||||
// Relink pNodeSuccessor in place of pNode. pNodeSuccessor is pNode's successor.
|
||||
// We specifically set pNodeSuccessor to be on the right child side of pNode, so fix up the left child side.
|
||||
pNode->mpNodeLeft->mpNodeParent = pNodeSuccessor;
|
||||
pNodeSuccessor->mpNodeLeft = pNode->mpNodeLeft;
|
||||
|
||||
if(pNodeSuccessor == pNode->mpNodeRight) // If pNode's successor was at the bottom of the tree... (yes that's effectively what this statement means)
|
||||
pNodeChildParent = pNodeSuccessor; // Assign pNodeReplacement's parent.
|
||||
else
|
||||
{
|
||||
pNodeChildParent = pNodeSuccessor->mpNodeParent;
|
||||
|
||||
if(pNodeChild)
|
||||
pNodeChild->mpNodeParent = pNodeChildParent;
|
||||
|
||||
pNodeChildParent->mpNodeLeft = pNodeChild;
|
||||
|
||||
pNodeSuccessor->mpNodeRight = pNode->mpNodeRight;
|
||||
pNode->mpNodeRight->mpNodeParent = pNodeSuccessor;
|
||||
}
|
||||
|
||||
if(pNode == pNodeRootRef)
|
||||
pNodeRootRef = pNodeSuccessor;
|
||||
else if(pNode == pNode->mpNodeParent->mpNodeLeft)
|
||||
pNode->mpNodeParent->mpNodeLeft = pNodeSuccessor;
|
||||
else
|
||||
pNode->mpNodeParent->mpNodeRight = pNodeSuccessor;
|
||||
|
||||
// Now pNode is disconnected from the tree.
|
||||
|
||||
pNodeSuccessor->mpNodeParent = pNode->mpNodeParent;
|
||||
eastl::swap(pNodeSuccessor->mColor, pNode->mColor);
|
||||
}
|
||||
|
||||
// Here we do tree balancing as per the conventional red-black tree algorithm.
|
||||
if(pNode->mColor == kRBTreeColorBlack)
|
||||
{
|
||||
while((pNodeChild != pNodeRootRef) && ((pNodeChild == NULL) || (pNodeChild->mColor == kRBTreeColorBlack)))
|
||||
{
|
||||
if(pNodeChild == pNodeChildParent->mpNodeLeft)
|
||||
{
|
||||
rbtree_node_base* pNodeTemp = pNodeChildParent->mpNodeRight;
|
||||
|
||||
if(pNodeTemp->mColor == kRBTreeColorRed)
|
||||
{
|
||||
pNodeTemp->mColor = kRBTreeColorBlack;
|
||||
pNodeChildParent->mColor = kRBTreeColorRed;
|
||||
pNodeRootRef = RBTreeRotateLeft(pNodeChildParent, pNodeRootRef);
|
||||
pNodeTemp = pNodeChildParent->mpNodeRight;
|
||||
}
|
||||
|
||||
if(((pNodeTemp->mpNodeLeft == NULL) || (pNodeTemp->mpNodeLeft->mColor == kRBTreeColorBlack)) &&
|
||||
((pNodeTemp->mpNodeRight == NULL) || (pNodeTemp->mpNodeRight->mColor == kRBTreeColorBlack)))
|
||||
{
|
||||
pNodeTemp->mColor = kRBTreeColorRed;
|
||||
pNodeChild = pNodeChildParent;
|
||||
pNodeChildParent = pNodeChildParent->mpNodeParent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((pNodeTemp->mpNodeRight == NULL) || (pNodeTemp->mpNodeRight->mColor == kRBTreeColorBlack))
|
||||
{
|
||||
pNodeTemp->mpNodeLeft->mColor = kRBTreeColorBlack;
|
||||
pNodeTemp->mColor = kRBTreeColorRed;
|
||||
pNodeRootRef = RBTreeRotateRight(pNodeTemp, pNodeRootRef);
|
||||
pNodeTemp = pNodeChildParent->mpNodeRight;
|
||||
}
|
||||
|
||||
pNodeTemp->mColor = pNodeChildParent->mColor;
|
||||
pNodeChildParent->mColor = kRBTreeColorBlack;
|
||||
|
||||
if(pNodeTemp->mpNodeRight)
|
||||
pNodeTemp->mpNodeRight->mColor = kRBTreeColorBlack;
|
||||
|
||||
pNodeRootRef = RBTreeRotateLeft(pNodeChildParent, pNodeRootRef);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The following is the same as above, with mpNodeRight <-> mpNodeLeft.
|
||||
rbtree_node_base* pNodeTemp = pNodeChildParent->mpNodeLeft;
|
||||
|
||||
if(pNodeTemp->mColor == kRBTreeColorRed)
|
||||
{
|
||||
pNodeTemp->mColor = kRBTreeColorBlack;
|
||||
pNodeChildParent->mColor = kRBTreeColorRed;
|
||||
|
||||
pNodeRootRef = RBTreeRotateRight(pNodeChildParent, pNodeRootRef);
|
||||
pNodeTemp = pNodeChildParent->mpNodeLeft;
|
||||
}
|
||||
|
||||
if(((pNodeTemp->mpNodeRight == NULL) || (pNodeTemp->mpNodeRight->mColor == kRBTreeColorBlack)) &&
|
||||
((pNodeTemp->mpNodeLeft == NULL) || (pNodeTemp->mpNodeLeft->mColor == kRBTreeColorBlack)))
|
||||
{
|
||||
pNodeTemp->mColor = kRBTreeColorRed;
|
||||
pNodeChild = pNodeChildParent;
|
||||
pNodeChildParent = pNodeChildParent->mpNodeParent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((pNodeTemp->mpNodeLeft == NULL) || (pNodeTemp->mpNodeLeft->mColor == kRBTreeColorBlack))
|
||||
{
|
||||
pNodeTemp->mpNodeRight->mColor = kRBTreeColorBlack;
|
||||
pNodeTemp->mColor = kRBTreeColorRed;
|
||||
|
||||
pNodeRootRef = RBTreeRotateLeft(pNodeTemp, pNodeRootRef);
|
||||
pNodeTemp = pNodeChildParent->mpNodeLeft;
|
||||
}
|
||||
|
||||
pNodeTemp->mColor = pNodeChildParent->mColor;
|
||||
pNodeChildParent->mColor = kRBTreeColorBlack;
|
||||
|
||||
if(pNodeTemp->mpNodeLeft)
|
||||
pNodeTemp->mpNodeLeft->mColor = kRBTreeColorBlack;
|
||||
|
||||
pNodeRootRef = RBTreeRotateRight(pNodeChildParent, pNodeRootRef);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(pNodeChild)
|
||||
pNodeChild->mColor = kRBTreeColorBlack;
|
||||
}
|
||||
|
||||
} // RBTreeErase
|
||||
|
||||
|
||||
|
||||
} // namespace eastl
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,464 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) Electronic Arts Inc. All rights reserved.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include <EASTL/internal/config.h>
|
||||
#include <EASTL/string.h>
|
||||
#include <EABase/eabase.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
namespace eastl
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Converters for DecodePart
|
||||
//
|
||||
// For some decent documentation about conversions, see:
|
||||
// http://tidy.sourceforge.net/cgi-bin/lxr/source/src/utf8.c
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Requires that pDest have a capacity of at least 6 chars.
|
||||
// Sets pResult to '\1' in the case that c is an invalid UCS4 char.
|
||||
inline bool UCS4ToUTF8(uint32_t c, char*& pResult)
|
||||
{
|
||||
if(c < 0x00000080)
|
||||
*pResult++ = (char)(uint8_t)c;
|
||||
else if(c < 0x0800)
|
||||
{
|
||||
*pResult++ = (char)(uint8_t)(0xC0 | (c >> 6));
|
||||
*pResult++ = (char)(uint8_t)(0x80 | (c & 0x3F));
|
||||
}
|
||||
else if(c <= 0x0000FFFF)
|
||||
{
|
||||
*pResult++ = (char)(uint8_t)(0xE0 | (c >> 12));
|
||||
*pResult++ = (char)(uint8_t)(0x80 | ((c >> 6) & 0x3F));
|
||||
*pResult++ = (char)(uint8_t)(0x80 | (c & 0x3F));
|
||||
}
|
||||
else if(c <= 0x001FFFFF)
|
||||
{
|
||||
*pResult++ = (char)(uint8_t)(0xF0 | (c >> 18));
|
||||
*pResult++ = (char)(uint8_t)(0x80 | ((c >> 12) & 0x3F));
|
||||
*pResult++ = (char)(uint8_t)(0x80 | ((c >> 6) & 0x3F));
|
||||
*pResult++ = (char)(uint8_t)(0x80 | (c & 0x3F));
|
||||
}
|
||||
else if(c <= 0x003FFFFFF)
|
||||
{
|
||||
*pResult++ = (char)(uint8_t)(0xF8 | (c >> 24));
|
||||
*pResult++ = (char)(uint8_t)(0x80 | (c >> 18));
|
||||
*pResult++ = (char)(uint8_t)(0x80 | ((c >> 12) & 0x3F));
|
||||
*pResult++ = (char)(uint8_t)(0x80 | ((c >> 6) & 0x3F));
|
||||
*pResult++ = (char)(uint8_t)(0x80 | (c & 0x3F));
|
||||
}
|
||||
else if(c <= 0x7FFFFFFF)
|
||||
{
|
||||
*pResult++ = (char)(uint8_t)(0xFC | (c >> 30));
|
||||
*pResult++ = (char)(uint8_t)(0x80 | ((c >> 24) & 0x3F));
|
||||
*pResult++ = (char)(uint8_t)(0x80 | ((c >> 18) & 0x3F));
|
||||
*pResult++ = (char)(uint8_t)(0x80 | ((c >> 12) & 0x3F));
|
||||
*pResult++ = (char)(uint8_t)(0x80 | ((c >> 6) & 0x3F));
|
||||
*pResult++ = (char)(uint8_t)(0x80 | (c & 0x3F));
|
||||
}
|
||||
else
|
||||
{
|
||||
// values >= 0x80000000 can't be converted to UTF8.
|
||||
*pResult++ = '\1';
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Requires that pResult have a capacity of at least 3 chars.
|
||||
// Sets pResult to '\1' in the case that c is an invalid UCS4 char.
|
||||
inline bool UCS2ToUTF8(uint16_t c, char*& pResult)
|
||||
{
|
||||
return UCS4ToUTF8(c, pResult);
|
||||
}
|
||||
|
||||
|
||||
// Sets result to 0xffff in the case that the input UTF8 sequence is bad.
|
||||
// 32 bit 0xffffffff is an invalid UCS4 code point, so we can't use that as an error return value.
|
||||
inline bool UTF8ToUCS4(const char*& p, const char* pEnd, uint32_t& result)
|
||||
{
|
||||
// This could likely be implemented in a faster-executing way that uses tables.
|
||||
|
||||
bool success = true;
|
||||
uint32_t c = 0xffff;
|
||||
const char* pNext = NULL;
|
||||
|
||||
if(p < pEnd)
|
||||
{
|
||||
uint8_t cChar0((uint8_t)*p), cChar1, cChar2, cChar3;
|
||||
|
||||
// Asserts are disabled because we don't necessarily want to interrupt runtime execution due to this.
|
||||
// EASTL_ASSERT((cChar0 != 0xFE) && (cChar0 != 0xFF)); // No byte can be 0xFE or 0xFF
|
||||
// Code below will effectively catch this error as it goes.
|
||||
|
||||
if(cChar0 < 0x80)
|
||||
{
|
||||
pNext = p + 1;
|
||||
c = cChar0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//EASTL_ASSERT((cChar0 & 0xC0) == 0xC0); // The top two bits need to be equal to 1
|
||||
if((cChar0 & 0xC0) != 0xC0)
|
||||
{
|
||||
success = false;
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
if((cChar0 & 0xE0) == 0xC0)
|
||||
{
|
||||
pNext = p + 2;
|
||||
|
||||
if(pNext <= pEnd)
|
||||
{
|
||||
c = (uint32_t)((cChar0 & 0x1F) << 6);
|
||||
cChar1 = static_cast<uint8_t>(p[1]);
|
||||
c |= cChar1 & 0x3F;
|
||||
|
||||
//EASTL_ASSERT((cChar1 & 0xC0) == 0x80); // All subsequent code should be b10xxxxxx
|
||||
//EASTL_ASSERT(c >= 0x0080 && c < 0x0800); // Check that we have the smallest coding
|
||||
if(!((cChar1 & 0xC0) == 0x80) ||
|
||||
!(c >= 0x0080 && c < 0x0800))
|
||||
{
|
||||
success = false;
|
||||
goto Failure;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
success = false;
|
||||
goto Failure;
|
||||
}
|
||||
}
|
||||
else if((cChar0 & 0xF0) == 0xE0)
|
||||
{
|
||||
pNext = p + 3;
|
||||
|
||||
if(pNext <= pEnd)
|
||||
{
|
||||
c = (uint32_t)((cChar0 & 0xF) << 12);
|
||||
cChar1 = static_cast<uint8_t>(p[1]);
|
||||
c |= (cChar1 & 0x3F) << 6;
|
||||
cChar2 = static_cast<uint8_t>(p[2]);
|
||||
c |= cChar2 & 0x3F;
|
||||
|
||||
//EASTL_ASSERT((cChar1 & 0xC0) == 0x80); // All subsequent code should be b10xxxxxx
|
||||
//EASTL_ASSERT((cChar2 & 0xC0) == 0x80); // All subsequent code should be b10xxxxxx
|
||||
//EASTL_ASSERT(c >= 0x00000800 && c < 0x00010000); // Check that we have the smallest coding
|
||||
if(!((cChar1 & 0xC0) == 0x80) ||
|
||||
!((cChar2 & 0xC0) == 0x80) ||
|
||||
!(c >= 0x00000800 && c < 0x00010000))
|
||||
{
|
||||
success = false;
|
||||
goto Failure;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
success = false;
|
||||
goto Failure;
|
||||
}
|
||||
}
|
||||
else if((cChar0 & 0xF8) == 0xF0)
|
||||
{
|
||||
pNext = p + 4;
|
||||
|
||||
if(pNext <= pEnd)
|
||||
{
|
||||
c = (uint32_t)((cChar0 & 0x7) << 18);
|
||||
cChar1 = static_cast<uint8_t>(p[1]);
|
||||
c |= (uint32_t)((cChar1 & 0x3F) << 12);
|
||||
cChar2 = static_cast<uint8_t>(p[2]);
|
||||
c |= (cChar2 & 0x3F) << 6;
|
||||
cChar3 = static_cast<uint8_t>(p[3]);
|
||||
c |= cChar3 & 0x3F;
|
||||
|
||||
//EASTL_ASSERT((cChar0 & 0xf8) == 0xf0); // We handle the unicode but not UCS-4
|
||||
//EASTL_ASSERT((cChar1 & 0xC0) == 0x80); // All subsequent code should be b10xxxxxx
|
||||
//EASTL_ASSERT((cChar2 & 0xC0) == 0x80); // All subsequent code should be b10xxxxxx
|
||||
//EASTL_ASSERT((cChar3 & 0xC0) == 0x80); // All subsequent code should be b10xxxxxx
|
||||
//EASTL_ASSERT(c >= 0x00010000 && c <= 0x0010FFFF); // Check that we have the smallest coding, Unicode and not ucs-4
|
||||
if(!((cChar0 & 0xf8) == 0xf0) ||
|
||||
!((cChar1 & 0xC0) == 0x80) ||
|
||||
!((cChar2 & 0xC0) == 0x80) ||
|
||||
!(c >= 0x00010000 && c <= 0x0010FFFF))
|
||||
{
|
||||
success = false;
|
||||
goto Failure;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
success = false;
|
||||
goto Failure;
|
||||
}
|
||||
}
|
||||
else if((cChar0 & 0xFC) == 0xF8)
|
||||
{
|
||||
pNext = p + 4;
|
||||
|
||||
if(pNext <= pEnd)
|
||||
{
|
||||
// To do. We don't currently support extended UCS4 characters.
|
||||
}
|
||||
else
|
||||
{
|
||||
success = false;
|
||||
goto Failure;
|
||||
}
|
||||
}
|
||||
else if((cChar0 & 0xFE) == 0xFC)
|
||||
{
|
||||
pNext = p + 5;
|
||||
|
||||
if(pNext <= pEnd)
|
||||
{
|
||||
// To do. We don't currently support extended UCS4 characters.
|
||||
}
|
||||
else
|
||||
{
|
||||
success = false;
|
||||
goto Failure;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
success = false;
|
||||
goto Failure;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
success = false;
|
||||
|
||||
Failure:
|
||||
if(success)
|
||||
{
|
||||
p = pNext;
|
||||
result = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = p + 1;
|
||||
result = 0xffff;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// Sets result to 0xffff in the case that the input UTF8 sequence is bad.
|
||||
// The effect of converting UTF8 codepoints > 0xffff to UCS2 (char16_t) is to set all
|
||||
// such codepoints to 0xffff. EASTL doesn't have a concept of setting or maintaining
|
||||
// error state for string conversions, though it does have a policy of converting
|
||||
// impossible values to something without generating invalid strings or throwing exceptions.
|
||||
inline bool UTF8ToUCS2(const char*& p, const char* pEnd, uint16_t& result)
|
||||
{
|
||||
uint32_t u32;
|
||||
|
||||
if(UTF8ToUCS4(p, pEnd, u32))
|
||||
{
|
||||
if(u32 <= 0xffff)
|
||||
{
|
||||
result = (uint16_t)u32;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
result = 0xffff;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// DecodePart
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
EASTL_API bool DecodePart(const char*& pSrc, const char* pSrcEnd, char*& pDest, char* pDestEnd)
|
||||
{
|
||||
size_t sourceSize = (size_t)(pSrcEnd - pSrc);
|
||||
size_t destSize = (size_t)(pDestEnd - pDest);
|
||||
|
||||
if(sourceSize > destSize)
|
||||
sourceSize = destSize;
|
||||
|
||||
memmove(pDest, pSrc, sourceSize * sizeof(*pSrcEnd));
|
||||
|
||||
pSrc += sourceSize;
|
||||
pDest += sourceSize; // Intentionally add sourceSize here.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
EASTL_API bool DecodePart(const char*& pSrc, const char* pSrcEnd, char16_t*& pDest, char16_t* pDestEnd)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
while(success && (pSrc < pSrcEnd) && (pDest < pDestEnd))
|
||||
success = UTF8ToUCS2(pSrc, pSrcEnd, (uint16_t&)*pDest++);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
EASTL_API bool DecodePart(const char*& pSrc, const char* pSrcEnd, char32_t*& pDest, char32_t* pDestEnd)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
while(success && (pSrc < pSrcEnd) && (pDest < pDestEnd))
|
||||
success = UTF8ToUCS4(pSrc, pSrcEnd, (uint32_t&)*pDest++);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
EASTL_API bool DecodePart(const char16_t*& pSrc, const char16_t* pSrcEnd, char*& pDest, char* pDestEnd)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
EASTL_ASSERT((pDest + 6) < pDestEnd); // The user must provide ample buffer space, preferably 256 chars or more.
|
||||
pDestEnd -= 6; // Do this so that we can avoid dest buffer size checking in the loop below and the function it calls.
|
||||
|
||||
while(success && (pSrc < pSrcEnd) && (pDest < pDestEnd))
|
||||
success = UCS2ToUTF8(*pSrc++, pDest);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
EASTL_API bool DecodePart(const char16_t*& pSrc, const char16_t* pSrcEnd, char16_t*& pDest, char16_t* pDestEnd)
|
||||
{
|
||||
size_t sourceSize = (size_t)(pSrcEnd - pSrc);
|
||||
size_t destSize = (size_t)(pDestEnd - pDest);
|
||||
|
||||
if(sourceSize > destSize)
|
||||
sourceSize = destSize;
|
||||
|
||||
memmove(pDest, pSrc, sourceSize * sizeof(*pSrcEnd));
|
||||
|
||||
pSrc += sourceSize;
|
||||
pDest += sourceSize; // Intentionally add sourceSize here.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
EASTL_API bool DecodePart(const char16_t*& pSrc, const char16_t* pSrcEnd, char32_t*& pDest, char32_t* pDestEnd)
|
||||
{
|
||||
size_t sourceSize = (size_t)(pSrcEnd - pSrc);
|
||||
size_t destSize = (size_t)(pDestEnd - pDest);
|
||||
|
||||
if(sourceSize > destSize)
|
||||
pSrcEnd = pSrc + destSize;
|
||||
|
||||
while(pSrc != pSrcEnd) // To consider: Improve this by unrolling this loop. Other tricks can improve its speed as well.
|
||||
*pDest++ = (char32_t)*pSrc++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
EASTL_API bool DecodePart(const char32_t*& pSrc, const char32_t* pSrcEnd, char*& pDest, char* pDestEnd)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
EASTL_ASSERT((pDest + 6) < pDestEnd); // The user must provide ample buffer space, preferably 256 chars or more.
|
||||
pDestEnd -= 6; // Do this so that we can avoid dest buffer size checking in the loop below and the function it calls.
|
||||
|
||||
while(success && (pSrc < pSrcEnd) && (pDest < pDestEnd))
|
||||
success = UCS4ToUTF8(*pSrc++, pDest);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
EASTL_API bool DecodePart(const char32_t*& pSrc, const char32_t* pSrcEnd, char16_t*& pDest, char16_t* pDestEnd)
|
||||
{
|
||||
size_t sourceSize = (size_t)(pSrcEnd - pSrc);
|
||||
size_t destSize = (size_t)(pDestEnd - pDest);
|
||||
|
||||
if(sourceSize > destSize)
|
||||
pSrcEnd = pSrc + destSize;
|
||||
|
||||
while(pSrc != pSrcEnd) // To consider: Improve this by unrolling this loop. Other tricks can improve its speed as well.
|
||||
*pDest++ = (char16_t)*pSrc++; // This is potentially losing data. We are not converting to UTF16; we are converting to UCS2.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
EASTL_API bool DecodePart(const char32_t*& pSrc, const char32_t* pSrcEnd, char32_t*& pDest, char32_t* pDestEnd)
|
||||
{
|
||||
size_t sourceSize = (size_t)(pSrcEnd - pSrc);
|
||||
size_t destSize = (size_t)(pDestEnd - pDest);
|
||||
|
||||
if(sourceSize > destSize)
|
||||
sourceSize = destSize;
|
||||
|
||||
memmove(pDest, pSrc, sourceSize * sizeof(*pSrcEnd));
|
||||
|
||||
pSrc += sourceSize;
|
||||
pDest += sourceSize; // Intentionally add sourceSize here.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
EASTL_API bool DecodePart(const int*& pSrc, const int* pSrcEnd, char*& pDest, char* pDestEnd)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
EASTL_ASSERT((pDest + 6) < pDestEnd); // The user must provide ample buffer space, preferably 256 chars or more.
|
||||
pDestEnd -= 6; // Do this so that we can avoid dest buffer size checking in the loop below and the function it calls.
|
||||
|
||||
while(success && (pSrc < pSrcEnd) && (pDest < pDestEnd))
|
||||
success = UCS4ToUTF8((uint32_t)(unsigned)*pSrc++, pDest);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
EASTL_API bool DecodePart(const int*& pSrc, const int* pSrcEnd, char16_t*& pDest, char16_t* pDestEnd)
|
||||
{
|
||||
size_t sourceSize = (size_t)(pSrcEnd - pSrc);
|
||||
size_t destSize = (size_t)(pDestEnd - pDest);
|
||||
|
||||
if(sourceSize > destSize)
|
||||
pSrcEnd = pSrc + destSize;
|
||||
|
||||
while(pSrc != pSrcEnd) // To consider: Improve this by unrolling this loop. Other tricks can improve its speed as well.
|
||||
*pDest++ = (char16_t)*pSrc++; // This is potentially losing data. We are not converting to UTF16; we are converting to UCS2.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
EASTL_API bool DecodePart(const int*& pSrc, const int* pSrcEnd, char32_t*& pDest, char32_t* pDestEnd)
|
||||
{
|
||||
size_t sourceSize = (size_t)(pSrcEnd - pSrc);
|
||||
size_t destSize = (size_t)(pDestEnd - pDest);
|
||||
|
||||
if(sourceSize > destSize)
|
||||
pSrcEnd = pSrc + destSize;
|
||||
|
||||
while(pSrc != pSrcEnd) // To consider: Improve this by unrolling this loop. Other tricks can improve its speed as well.
|
||||
*pDest++ = (char32_t)*pSrc++; // This is potentially losing data. We are not converting to UTF16; we are converting to UCS2.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace eastl
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) Electronic Arts Inc. All rights reserved.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include <EASTL/internal/config.h>
|
||||
#include <EASTL/internal/thread_support.h>
|
||||
#include <EASTL/type_traits.h>
|
||||
#include <EASTL/memory.h>
|
||||
|
||||
#if defined(EA_PLATFORM_MICROSOFT)
|
||||
EA_DISABLE_ALL_VC_WARNINGS();
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
EA_RESTORE_ALL_VC_WARNINGS();
|
||||
#endif
|
||||
|
||||
|
||||
namespace eastl
|
||||
{
|
||||
namespace Internal
|
||||
{
|
||||
#if EASTL_CPP11_MUTEX_ENABLED
|
||||
// We use the C++11 Standard Library mutex as-is.
|
||||
#else
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// mutex
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
mutex::mutex()
|
||||
{
|
||||
#if defined(EA_PLATFORM_MICROSOFT)
|
||||
static_assert(sizeof(mMutexBuffer) == sizeof(CRITICAL_SECTION), "mMutexBuffer size failure");
|
||||
//static_assert(EA_ALIGN_OF(mMutexBuffer) >= EA_ALIGN_OF(CRITICAL_SECTION), "mMutexBuffer alignment failure"); // Enabling this causes the VS2012 compiler to crash.
|
||||
|
||||
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0403)
|
||||
InitializeCriticalSection((CRITICAL_SECTION*)mMutexBuffer);
|
||||
#elif !EA_WINAPI_FAMILY_PARTITION(EA_WINAPI_PARTITION_DESKTOP)
|
||||
BOOL result = InitializeCriticalSectionEx((CRITICAL_SECTION*)mMutexBuffer, 10, 0);
|
||||
EASTL_ASSERT(result != 0); EA_UNUSED(result);
|
||||
#else
|
||||
BOOL result = InitializeCriticalSectionAndSpinCount((CRITICAL_SECTION*)mMutexBuffer, 10);
|
||||
EASTL_ASSERT(result != 0); EA_UNUSED(result);
|
||||
#endif
|
||||
|
||||
#elif defined(EA_PLATFORM_POSIX)
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
pthread_mutexattr_init(&attr);
|
||||
|
||||
#if defined(EA_HAVE_pthread_mutexattr_setpshared_DECL)
|
||||
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
|
||||
#endif
|
||||
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&mMutex, &attr);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
#endif
|
||||
}
|
||||
|
||||
mutex::~mutex()
|
||||
{
|
||||
#if defined(EA_PLATFORM_MICROSOFT)
|
||||
DeleteCriticalSection((CRITICAL_SECTION*)mMutexBuffer);
|
||||
#elif defined(EA_PLATFORM_POSIX)
|
||||
pthread_mutex_destroy(&mMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void mutex::lock()
|
||||
{
|
||||
#if defined(EA_PLATFORM_MICROSOFT)
|
||||
EnterCriticalSection((CRITICAL_SECTION*)mMutexBuffer);
|
||||
#elif defined(EA_PLATFORM_POSIX)
|
||||
pthread_mutex_lock(&mMutex);
|
||||
#else
|
||||
EASTL_FAIL_MSG("EASTL thread safety is not implemented yet. See EAThread for how to do this for the given platform.");
|
||||
#endif
|
||||
}
|
||||
|
||||
void mutex::unlock()
|
||||
{
|
||||
#if defined(EA_PLATFORM_MICROSOFT)
|
||||
LeaveCriticalSection((CRITICAL_SECTION*)mMutexBuffer);
|
||||
#elif defined(EA_PLATFORM_POSIX)
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// shared_ptr_auto_mutex
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
// We could solve this by having single global mutex for all shared_ptrs, a set of mutexes for shared_ptrs,
|
||||
// a single mutex for every shared_ptr, or have a template parameter that enables mutexes for just some shared_ptrs.
|
||||
eastl::late_constructed<mutex, true> gSharedPtrMutex;
|
||||
|
||||
shared_ptr_auto_mutex::shared_ptr_auto_mutex(const void* /*pSharedPtr*/)
|
||||
: auto_mutex(*gSharedPtrMutex.get())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
} // namespace eastl
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user