This commit is contained in:
Rob Parolin
2020-02-24 12:38:46 -08:00
parent b254863782
commit 05127aebc2
14 changed files with 222 additions and 78 deletions

View File

@@ -78,6 +78,23 @@
</Expand>
</Type>
<Type Name="eastl::basic_string&lt;wchar_t,*&gt;">
<DisplayString Condition="!!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize &amp; kSSOMask)">{mPair.mFirst.heap.mpBegin,su}</DisplayString>
<DisplayString Condition="!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize &amp; kSSOMask)">{mPair.mFirst.sso.mData,su}</DisplayString>
<Expand>
<Item Name="[length]" Condition="!!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize &amp; kSSOMask)">mPair.mFirst.heap.mnSize</Item>
<Item Name="[capacity]" Condition="!!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize &amp; kSSOMask)">(mPair.mFirst.heap.mnCapacity &amp; ~kHeapMask)</Item>
<Item Name="[value]" Condition="!!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize &amp; kSSOMask)">mPair.mFirst.heap.mpBegin,su</Item>
<Item Name="[length]" Condition="!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize &amp; kSSOMask)">mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize</Item>
<Item Name="[capacity]" Condition="!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize &amp; kSSOMask)">SSOLayout::SSO_CAPACITY</Item>
<Item Name="[value]" Condition="!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize &amp; kSSOMask)">mPair.mFirst.sso.mData,su</Item>
<Item Name="[uses heap]">!!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize &amp; kSSOMask)</Item>
</Expand>
</Type>
<Type Name="eastl::pair&lt;*&gt;">
<DisplayString>({first}, {second})</DisplayString>
<Expand>

View File

@@ -32,14 +32,20 @@
#include <stdlib.h> // memalign, posix_memalign.
#define EASTL_ALIGNED_MALLOC_AVAILABLE 1
#if defined(__clang__)
#if __has_include(<malloc/malloc.h>)
#if EA_HAS_INCLUDE_AVAILABLE
#if EA_HAS_INCLUDE(<malloc/malloc.h>)
#include <malloc/malloc.h>
#elif __has_include(<malloc.h>)
#elif EA_HAS_INCLUDE(<malloc.h>)
#include <malloc.h>
#endif
#elif defined(EA_PLATFORM_BSD)
#include <malloc/malloc.h>
#elif defined(EA_COMPILER_CLANG)
#if __has_include(<malloc/malloc.h>)
#include <malloc/malloc.h>
#elif __has_include(<malloc.h>)
#include <malloc.h>
#endif
#else
#include <malloc.h>
#endif

View File

@@ -32,6 +32,8 @@
#endif
#include <EASTL/internal/config.h>
#include <EASTL/internal/move_help.h>
#include <EASTL/type_traits.h>
namespace eastl
{

View File

@@ -89,8 +89,8 @@
///////////////////////////////////////////////////////////////////////////////
#ifndef EASTL_VERSION
#define EASTL_VERSION "3.16.01"
#define EASTL_VERSION_N 31601
#define EASTL_VERSION "3.16.05"
#define EASTL_VERSION_N 31605
#endif

View File

@@ -169,6 +169,10 @@ namespace eastl
/// operator * or ->. autoConstruct is convenient but it causes * and -> to be slightly slower
/// and may result in construction at an inconvenient time.
///
/// The autoDestruct template parameter controls whether the object, if constructed, is automatically
/// destructed when ~late_constructed() is called or must be manually destructed via a call to
/// destruct().
///
/// While construction can be automatic or manual, automatic destruction support is always present.
/// Thus you aren't required in any case to manually call destruct. However, you may safely manually
/// destruct the object at any time before the late_constructed destructor is executed.
@@ -199,11 +203,11 @@ namespace eastl
/// // You may want to call destruct here, but aren't required to do so unless the Widget type requires it.
/// }
///
template <typename T, bool autoConstruct = true>
template <typename T, bool autoConstruct = true, bool autoDestruct = true>
class late_constructed
{
public:
using this_type = late_constructed<T, autoConstruct>;
using this_type = late_constructed<T, autoConstruct, autoDestruct>;
using value_type = T;
using storage_type = eastl::aligned_storage_t<sizeof(value_type), eastl::alignment_of_v<value_type>>;
@@ -212,16 +216,16 @@ namespace eastl
~late_constructed()
{
if(mpValue)
if (autoDestruct && mpValue)
(*mpValue).~value_type();
}
}
template <typename... Args>
void construct(Args&&... args)
{
if(!mpValue)
mpValue = new(&mStorage) value_type(eastl::forward<Args>(args)...);
}
mpValue = new (&mStorage) value_type(eastl::forward<Args>(args)...);
}
bool is_constructed() const EA_NOEXCEPT
{ return mpValue != nullptr; }
@@ -288,11 +292,11 @@ namespace eastl
// Specialization that doesn't auto-construct on demand.
template <typename T>
class late_constructed<T, false> : public late_constructed<T, true>
template <typename T, bool autoDestruct>
class late_constructed<T, false, autoDestruct> : public late_constructed<T, true, autoDestruct>
{
public:
typedef late_constructed<T, true> base_type;
typedef late_constructed<T, true, autoDestruct> base_type;
typename base_type::value_type& operator*() EA_NOEXCEPT
{ EASTL_ASSERT(base_type::mpValue); return *base_type::mpValue; }

View File

@@ -3900,12 +3900,12 @@ namespace eastl
typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring;
/// string8 / string16 / string32
typedef basic_string<char8_t> string8;
/// custom string8 / string16 / string32
typedef basic_string<char> string8;
typedef basic_string<char16_t> string16;
typedef basic_string<char32_t> string32;
// C++11 string types
/// ISO mandated string types
typedef basic_string<char8_t> u8string; // Actually not a C++11 type, but added for consistency.
typedef basic_string<char16_t> u16string;
typedef basic_string<char32_t> u32string;
@@ -3934,20 +3934,22 @@ namespace eastl
}
};
#if defined(EA_CHAR8_UNIQUE) && EA_CHAR8_UNIQUE
template <>
struct hash<string8>
{
size_t operator()(const string8& x) const
{
const char8_t* p = (const char8_t*)x.c_str();
unsigned int c, result = 2166136261U;
while((c = *p++) != 0)
result = (result * 16777619) ^ c;
return (size_t)result;
}
};
#endif
// NOTE(rparolin): no longer required.
//
// #if defined(EA_CHAR8_UNIQUE) && EA_CHAR8_UNIQUE
// template <>
// struct hash<string8>
// {
// size_t operator()(const string8& x) const
// {
// const char8_t* p = (const char8_t*)x.c_str();
// unsigned int c, result = 2166136261U;
// while((c = *p++) != 0)
// result = (result * 16777619) ^ c;
// return (size_t)result;
// }
// };
// #endif
template <>
struct hash<string16>

View File

@@ -304,7 +304,9 @@ namespace eastl
inline vector_multimap<K, T, C, A, RAC>::vector_multimap()
: base_type(), mValueCompare(C())
{
#if EASTL_NAME_ENABLED
get_allocator().set_name(EASTL_VECTOR_MULTIMAP_DEFAULT_NAME);
#endif
}

View File

@@ -143,7 +143,8 @@ int TestFixedVector()
EATEST_VERIFY(fv88.capacity() >= (capacity * 2));
// void swap(this_type& x);
FixedVectorInt8 fv7(5, 3);
// FixedVectorInt8 fv7(5, 3); // MSVC-ARM64 generated an internal compiler error on this line.
FixedVectorInt8 fv7 = {3, 3, 3, 3, 3};
FixedVectorInt8 fv8(intArray, intArray + 8);
swap(fv7, fv8);

View File

@@ -115,8 +115,8 @@ int TestMap()
{
// User reports that EASTL_VALIDATE_COMPARE_ENABLED / EASTL_COMPARE_VALIDATE isn't compiling for this case.
eastl::map<eastl::string8, int> m;
m.find_as(EA_CHAR8("some string"), eastl::equal_to_2<eastl::string8, const char8_t*>());
eastl::map<eastl::u8string, int> m;
m.find_as(EA_CHAR8("some string"), eastl::equal_to_2<eastl::u8string, const char8_t*>());
}
{

View File

@@ -128,8 +128,10 @@ int64_t LCTestObject::sTOCtorCount = 0;
int64_t LCTestObject::sTODtorCount = 0;
eastl::late_constructed<LCTestObject, true> gLCTestObjectTrue;
eastl::late_constructed<LCTestObject, false> gLCTestObjectFalse;
eastl::late_constructed<LCTestObject, true, true> gLCTestObjectTrueTrue;
eastl::late_constructed<LCTestObject, false, true> gLCTestObjectFalseTrue;
eastl::late_constructed<LCTestObject, false, false> gLCTestObjectFalseFalse;
eastl::late_constructed<LCTestObject, true, false> gLCTestObjectTrueFalse;
///////////////////////////////////////////////////////////////////////////////
@@ -163,85 +165,193 @@ int TestMemory()
{
LCTestObject* pLCTO;
LCTestObject::sTOCount = 0;
LCTestObject::sTOCtorCount = 0;
LCTestObject::sTODtorCount = 0;
// Verify alignment requirements.
// We don't verify that gLCTestObjectTrue.get() is aligned for all platforms because some platforms can't do that with global memory.
// We don't verify that gLCTestObjectTrueTrue.get() is aligned for all platforms because some platforms can't do that with global memory.
static_assert(eastl::alignment_of<typename late_constructed<LCTestObject>::value_type>::value == 64, "late_constructed alignment failure.");
static_assert(eastl::alignment_of<typename late_constructed<LCTestObject>::storage_type>::value == 64, "late_constructed alignment failure.");
static_assert(eastl::alignment_of<late_constructed<LCTestObject> >::value >= 64, "late_constructed alignment failure.");
// late_constructed / gLCTestObjectTrue
// late_constructed / gLCTestObjectTrueTrue
EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0));
EATEST_VERIFY(!gLCTestObjectTrue.is_constructed());
EATEST_VERIFY(!gLCTestObjectTrueTrue.is_constructed());
pLCTO = gLCTestObjectTrue.get(); // This will auto-construct LCTestObject.
pLCTO = gLCTestObjectTrueTrue.get(); // This will auto-construct LCTestObject.
EATEST_VERIFY(pLCTO != NULL);
EATEST_VERIFY(gLCTestObjectTrue.is_constructed());
EATEST_VERIFY(gLCTestObjectTrueTrue.is_constructed());
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0));
gLCTestObjectTrue->mX = 17;
EATEST_VERIFY(gLCTestObjectTrue->mX == 17);
gLCTestObjectTrueTrue->mX = 17;
EATEST_VERIFY(gLCTestObjectTrueTrue->mX == 17);
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0));
gLCTestObjectTrue.destruct();
gLCTestObjectTrueTrue.destruct();
EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 1));
EATEST_VERIFY(!gLCTestObjectTrue.is_constructed());
EATEST_VERIFY(!gLCTestObjectTrueTrue.is_constructed());
gLCTestObjectTrue->mX = 18;
EATEST_VERIFY(gLCTestObjectTrue->mX == 18);
EATEST_VERIFY(gLCTestObjectTrue.is_constructed());
gLCTestObjectTrueTrue->mX = 18;
EATEST_VERIFY(gLCTestObjectTrueTrue->mX == 18);
EATEST_VERIFY(gLCTestObjectTrueTrue.is_constructed());
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 2) && (LCTestObject::sTODtorCount == 1));
gLCTestObjectTrue.destruct();
(*gLCTestObjectTrue).mX = 19;
EATEST_VERIFY(gLCTestObjectTrue->mX == 19);
gLCTestObjectTrueTrue.destruct();
(*gLCTestObjectTrueTrue).mX = 19;
EATEST_VERIFY(gLCTestObjectTrueTrue->mX == 19);
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 3) && (LCTestObject::sTODtorCount == 2));
gLCTestObjectTrue.destruct();
gLCTestObjectTrueTrue.destruct();
LCTestObject::sTOCount = 0;
LCTestObject::sTOCtorCount = 0;
LCTestObject::sTODtorCount = 0;
// late_constructed / gLCTestObjectFalse
// late_constructed / gLCTestObjectFalseTrue
EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0));
EATEST_VERIFY(!gLCTestObjectFalse.is_constructed());
EATEST_VERIFY(!gLCTestObjectFalseTrue.is_constructed());
pLCTO = gLCTestObjectFalse.get(); // This will not auto-construct LCTestObject.
pLCTO = gLCTestObjectFalseTrue.get(); // This will not auto-construct LCTestObject.
EATEST_VERIFY(pLCTO == NULL);
EATEST_VERIFY(!gLCTestObjectFalse.is_constructed());
EATEST_VERIFY(!gLCTestObjectFalseTrue.is_constructed());
EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0));
gLCTestObjectFalse.construct();
pLCTO = gLCTestObjectFalse.get();
gLCTestObjectFalseTrue.construct();
pLCTO = gLCTestObjectFalseTrue.get();
EATEST_VERIFY(pLCTO != NULL);
EATEST_VERIFY(gLCTestObjectFalse.is_constructed());
EATEST_VERIFY(gLCTestObjectFalseTrue.is_constructed());
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0));
gLCTestObjectFalse->mX = 17;
EATEST_VERIFY(gLCTestObjectFalse->mX == 17);
gLCTestObjectFalseTrue->mX = 17;
EATEST_VERIFY(gLCTestObjectFalseTrue->mX == 17);
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0));
gLCTestObjectFalse.destruct();
gLCTestObjectFalseTrue.destruct();
EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 1));
EATEST_VERIFY(!gLCTestObjectFalse.is_constructed());
EATEST_VERIFY(!gLCTestObjectFalseTrue.is_constructed());
gLCTestObjectFalse.construct(14);
EATEST_VERIFY(gLCTestObjectFalse->mX == 14);
gLCTestObjectFalse->mX = 18;
EATEST_VERIFY(gLCTestObjectFalse->mX == 18);
EATEST_VERIFY(gLCTestObjectFalse.is_constructed());
gLCTestObjectFalseTrue.construct(14);
EATEST_VERIFY(gLCTestObjectFalseTrue->mX == 14);
gLCTestObjectFalseTrue->mX = 18;
EATEST_VERIFY(gLCTestObjectFalseTrue->mX == 18);
EATEST_VERIFY(gLCTestObjectFalseTrue.is_constructed());
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 2) && (LCTestObject::sTODtorCount == 1));
gLCTestObjectFalse.destruct();
gLCTestObjectFalse.construct(10, 20, 30);
EATEST_VERIFY(gLCTestObjectFalse->mX == 10+20+30);
(*gLCTestObjectFalse).mX = 19;
EATEST_VERIFY(gLCTestObjectFalse->mX == 19);
gLCTestObjectFalseTrue.destruct();
gLCTestObjectFalseTrue.construct(10, 20, 30);
EATEST_VERIFY(gLCTestObjectFalseTrue->mX == 10+20+30);
(*gLCTestObjectFalseTrue).mX = 19;
EATEST_VERIFY(gLCTestObjectFalseTrue->mX == 19);
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 3) && (LCTestObject::sTODtorCount == 2));
gLCTestObjectFalse.destruct();
gLCTestObjectFalseTrue.destruct();
}
{
LCTestObject* pLCTO;
LCTestObject::sTOCount = 0;
LCTestObject::sTOCtorCount = 0;
LCTestObject::sTODtorCount = 0;
// Verify alignment requirements.
// We don't verify that gLCTestObjectTrueTrue.get() is aligned for all platforms because some platforms can't do that with global memory.
static_assert(eastl::alignment_of<typename late_constructed<LCTestObject>::value_type>::value == 64, "late_constructed alignment failure.");
static_assert(eastl::alignment_of<typename late_constructed<LCTestObject>::storage_type>::value == 64, "late_constructed alignment failure.");
static_assert(eastl::alignment_of<late_constructed<LCTestObject> >::value >= 64, "late_constructed alignment failure.");
// late_constructed / gLCTestObjectTrueFalse
EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0));
EATEST_VERIFY(!gLCTestObjectTrueFalse.is_constructed());
pLCTO = gLCTestObjectTrueFalse.get(); // This will auto-construct LCTestObject.
EATEST_VERIFY(pLCTO != NULL);
EATEST_VERIFY(gLCTestObjectTrueFalse.is_constructed());
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0));
gLCTestObjectTrueFalse->mX = 17;
EATEST_VERIFY(gLCTestObjectTrueFalse->mX == 17);
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0));
gLCTestObjectTrueFalse.destruct();
EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 1));
EATEST_VERIFY(!gLCTestObjectTrueFalse.is_constructed());
gLCTestObjectTrueFalse->mX = 18;
EATEST_VERIFY(gLCTestObjectTrueFalse->mX == 18);
EATEST_VERIFY(gLCTestObjectTrueFalse.is_constructed());
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 2) && (LCTestObject::sTODtorCount == 1));
gLCTestObjectTrueFalse.destruct();
(*gLCTestObjectTrueFalse).mX = 19;
EATEST_VERIFY(gLCTestObjectTrueFalse->mX == 19);
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 3) && (LCTestObject::sTODtorCount == 2));
gLCTestObjectTrueFalse.destruct();
LCTestObject::sTOCount = 0;
LCTestObject::sTOCtorCount = 0;
LCTestObject::sTODtorCount = 0;
// late_constructed / gLCTestObjectFalseFalse
EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0));
EATEST_VERIFY(!gLCTestObjectFalseFalse.is_constructed());
pLCTO = gLCTestObjectFalseFalse.get(); // This will not auto-construct LCTestObject.
EATEST_VERIFY(pLCTO == NULL);
EATEST_VERIFY(!gLCTestObjectFalseFalse.is_constructed());
EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0));
gLCTestObjectFalseFalse.construct();
pLCTO = gLCTestObjectFalseFalse.get();
EATEST_VERIFY(pLCTO != NULL);
EATEST_VERIFY(gLCTestObjectFalseFalse.is_constructed());
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0));
gLCTestObjectFalseFalse->mX = 17;
EATEST_VERIFY(gLCTestObjectFalseFalse->mX == 17);
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0));
gLCTestObjectFalseFalse.destruct();
EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 1));
EATEST_VERIFY(!gLCTestObjectFalseFalse.is_constructed());
gLCTestObjectFalseFalse.construct(14);
EATEST_VERIFY(gLCTestObjectFalseFalse->mX == 14);
gLCTestObjectFalseFalse->mX = 18;
EATEST_VERIFY(gLCTestObjectFalseFalse->mX == 18);
EATEST_VERIFY(gLCTestObjectFalseFalse.is_constructed());
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 2) && (LCTestObject::sTODtorCount == 1));
gLCTestObjectFalseFalse.destruct();
gLCTestObjectFalseFalse.construct(10, 20, 30);
EATEST_VERIFY(gLCTestObjectFalseFalse->mX == 10+20+30);
(*gLCTestObjectFalseFalse).mX = 19;
EATEST_VERIFY(gLCTestObjectFalseFalse->mX == 19);
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 3) && (LCTestObject::sTODtorCount == 2));
gLCTestObjectFalseFalse.destruct();
}
LCTestObject::sTOCount = 0;
LCTestObject::sTOCtorCount = 0;
LCTestObject::sTODtorCount = 0;
{
eastl::late_constructed<LCTestObject, true, false> lc;
lc.construct();
}
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0));
LCTestObject::sTOCount = 0;
LCTestObject::sTOCtorCount = 0;
LCTestObject::sTODtorCount = 0;
{
eastl::late_constructed<LCTestObject, false, false> lc;
lc.construct();
}
EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0));
// We use the vector container to supply a RandomAccessIterator.
// We use the list container to supply a BidirectionalIterator.

View File

@@ -1340,7 +1340,7 @@ int TEST_STRING_NAME()
{
#if defined(EA_CHAR8)
StringType str;
str.append_convert(eastl::string8(EA_CHAR8("123456789")));
str.append_convert(eastl::u8string(EA_CHAR8("123456789")));
VERIFY(str == LITERAL("123456789"));
VERIFY(str.validate());
#endif