diff --git a/doc/EASTL.natvis b/doc/EASTL.natvis index e04f2d57..39b3dba1 100644 --- a/doc/EASTL.natvis +++ b/doc/EASTL.natvis @@ -78,6 +78,23 @@ + + + {mPair.mFirst.heap.mpBegin,su} + {mPair.mFirst.sso.mData,su} + + mPair.mFirst.heap.mnSize + (mPair.mFirst.heap.mnCapacity & ~kHeapMask) + mPair.mFirst.heap.mpBegin,su + + mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize + SSOLayout::SSO_CAPACITY + mPair.mFirst.sso.mData,su + + !!(mPair.mFirst.sso.mRemainingSizeField.mnRemainingSize & kSSOMask) + + + ({first}, {second}) diff --git a/include/EASTL/allocator_malloc.h b/include/EASTL/allocator_malloc.h index fe59b706..31f8deca 100644 --- a/include/EASTL/allocator_malloc.h +++ b/include/EASTL/allocator_malloc.h @@ -32,14 +32,20 @@ #include // memalign, posix_memalign. #define EASTL_ALIGNED_MALLOC_AVAILABLE 1 - #if defined(__clang__) - #if __has_include() + #if EA_HAS_INCLUDE_AVAILABLE + #if EA_HAS_INCLUDE() #include - #elif __has_include() + #elif EA_HAS_INCLUDE() #include #endif #elif defined(EA_PLATFORM_BSD) #include + #elif defined(EA_COMPILER_CLANG) + #if __has_include() + #include + #elif __has_include() + #include + #endif #else #include #endif diff --git a/include/EASTL/finally.h b/include/EASTL/finally.h index f027e07a..b4ed5803 100644 --- a/include/EASTL/finally.h +++ b/include/EASTL/finally.h @@ -32,6 +32,8 @@ #endif #include +#include +#include namespace eastl { diff --git a/include/EASTL/internal/config.h b/include/EASTL/internal/config.h index f9c4b001..4138af49 100644 --- a/include/EASTL/internal/config.h +++ b/include/EASTL/internal/config.h @@ -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 diff --git a/include/EASTL/memory.h b/include/EASTL/memory.h index 933cbd0a..6d6b8a3b 100644 --- a/include/EASTL/memory.h +++ b/include/EASTL/memory.h @@ -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 + template class late_constructed { public: - using this_type = late_constructed; + using this_type = late_constructed; using value_type = T; using storage_type = eastl::aligned_storage_t>; @@ -212,16 +216,16 @@ namespace eastl ~late_constructed() { - if(mpValue) + if (autoDestruct && mpValue) (*mpValue).~value_type(); - } + } template void construct(Args&&... args) { if(!mpValue) - mpValue = new(&mStorage) value_type(eastl::forward(args)...); - } + mpValue = new (&mStorage) value_type(eastl::forward(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 - class late_constructed : public late_constructed + template + class late_constructed : public late_constructed { public: - typedef late_constructed base_type; + typedef late_constructed base_type; typename base_type::value_type& operator*() EA_NOEXCEPT { EASTL_ASSERT(base_type::mpValue); return *base_type::mpValue; } diff --git a/include/EASTL/string.h b/include/EASTL/string.h index babf708a..ce83df3d 100644 --- a/include/EASTL/string.h +++ b/include/EASTL/string.h @@ -3900,12 +3900,12 @@ namespace eastl typedef basic_string string; typedef basic_string wstring; - /// string8 / string16 / string32 - typedef basic_string string8; + /// custom string8 / string16 / string32 + typedef basic_string string8; typedef basic_string string16; typedef basic_string string32; - // C++11 string types + /// ISO mandated string types typedef basic_string u8string; // Actually not a C++11 type, but added for consistency. typedef basic_string u16string; typedef basic_string u32string; @@ -3934,20 +3934,22 @@ namespace eastl } }; - #if defined(EA_CHAR8_UNIQUE) && EA_CHAR8_UNIQUE - template <> - struct hash - { - 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 + // { + // 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 diff --git a/include/EASTL/vector_multimap.h b/include/EASTL/vector_multimap.h index 25a0a4ac..235f6718 100644 --- a/include/EASTL/vector_multimap.h +++ b/include/EASTL/vector_multimap.h @@ -304,7 +304,9 @@ namespace eastl inline vector_multimap::vector_multimap() : base_type(), mValueCompare(C()) { + #if EASTL_NAME_ENABLED get_allocator().set_name(EASTL_VECTOR_MULTIMAP_DEFAULT_NAME); + #endif } diff --git a/test/packages/EABase b/test/packages/EABase index edbafca8..af4ae274 160000 --- a/test/packages/EABase +++ b/test/packages/EABase @@ -1 +1 @@ -Subproject commit edbafca82e4c4e73302e0b5144c5d1f4710db9fa +Subproject commit af4ae274795f4c40829428a2c4058c6f512530f4 diff --git a/test/packages/EAStdC b/test/packages/EAStdC index dcbf2665..8dc9e314 160000 --- a/test/packages/EAStdC +++ b/test/packages/EAStdC @@ -1 +1 @@ -Subproject commit dcbf266509e8e30a4d9f974d06916d2d103e66ac +Subproject commit 8dc9e314fdbe09d0627c613ae2eb6543859e995d diff --git a/test/packages/EATest b/test/packages/EATest index 9a712b9c..a59b372f 160000 --- a/test/packages/EATest +++ b/test/packages/EATest @@ -1 +1 @@ -Subproject commit 9a712b9c368baf37c4bc6be21e88c5830f4e6100 +Subproject commit a59b372fc9cba517283ad6d060d2ab96e0ba34ac diff --git a/test/source/TestFixedVector.cpp b/test/source/TestFixedVector.cpp index bad3c445..aeb3ba2b 100644 --- a/test/source/TestFixedVector.cpp +++ b/test/source/TestFixedVector.cpp @@ -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); diff --git a/test/source/TestMap.cpp b/test/source/TestMap.cpp index cce6cc1d..df4a195e 100644 --- a/test/source/TestMap.cpp +++ b/test/source/TestMap.cpp @@ -115,8 +115,8 @@ int TestMap() { // User reports that EASTL_VALIDATE_COMPARE_ENABLED / EASTL_COMPARE_VALIDATE isn't compiling for this case. - eastl::map m; - m.find_as(EA_CHAR8("some string"), eastl::equal_to_2()); + eastl::map m; + m.find_as(EA_CHAR8("some string"), eastl::equal_to_2()); } { diff --git a/test/source/TestMemory.cpp b/test/source/TestMemory.cpp index e088d611..4e257382 100644 --- a/test/source/TestMemory.cpp +++ b/test/source/TestMemory.cpp @@ -128,8 +128,10 @@ int64_t LCTestObject::sTOCtorCount = 0; int64_t LCTestObject::sTODtorCount = 0; -eastl::late_constructed gLCTestObjectTrue; -eastl::late_constructed gLCTestObjectFalse; +eastl::late_constructed gLCTestObjectTrueTrue; +eastl::late_constructed gLCTestObjectFalseTrue; +eastl::late_constructed gLCTestObjectFalseFalse; +eastl::late_constructed gLCTestObjectTrueFalse; /////////////////////////////////////////////////////////////////////////////// @@ -163,84 +165,192 @@ int TestMemory() { 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::value_type>::value == 64, "late_constructed alignment failure."); + static_assert(eastl::alignment_of::storage_type>::value == 64, "late_constructed alignment failure."); + static_assert(eastl::alignment_of >::value >= 64, "late_constructed alignment failure."); + + + // late_constructed / gLCTestObjectTrueTrue + EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0)); + EATEST_VERIFY(!gLCTestObjectTrueTrue.is_constructed()); + + pLCTO = gLCTestObjectTrueTrue.get(); // This will auto-construct LCTestObject. + EATEST_VERIFY(pLCTO != NULL); + EATEST_VERIFY(gLCTestObjectTrueTrue.is_constructed()); + EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); + + gLCTestObjectTrueTrue->mX = 17; + EATEST_VERIFY(gLCTestObjectTrueTrue->mX == 17); + EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); + + gLCTestObjectTrueTrue.destruct(); + EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 1)); + EATEST_VERIFY(!gLCTestObjectTrueTrue.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)); + + gLCTestObjectTrueTrue.destruct(); + (*gLCTestObjectTrueTrue).mX = 19; + EATEST_VERIFY(gLCTestObjectTrueTrue->mX == 19); + EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 3) && (LCTestObject::sTODtorCount == 2)); + + gLCTestObjectTrueTrue.destruct(); + LCTestObject::sTOCount = 0; + LCTestObject::sTOCtorCount = 0; + LCTestObject::sTODtorCount = 0; + + // late_constructed / gLCTestObjectFalseTrue + EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0)); + EATEST_VERIFY(!gLCTestObjectFalseTrue.is_constructed()); + + pLCTO = gLCTestObjectFalseTrue.get(); // This will not auto-construct LCTestObject. + EATEST_VERIFY(pLCTO == NULL); + EATEST_VERIFY(!gLCTestObjectFalseTrue.is_constructed()); + EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0)); + + gLCTestObjectFalseTrue.construct(); + pLCTO = gLCTestObjectFalseTrue.get(); + EATEST_VERIFY(pLCTO != NULL); + EATEST_VERIFY(gLCTestObjectFalseTrue.is_constructed()); + EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); + + gLCTestObjectFalseTrue->mX = 17; + EATEST_VERIFY(gLCTestObjectFalseTrue->mX == 17); + EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); + + gLCTestObjectFalseTrue.destruct(); + EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 1)); + EATEST_VERIFY(!gLCTestObjectFalseTrue.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)); + + 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)); + + gLCTestObjectFalseTrue.destruct(); + } + + { + 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::value_type>::value == 64, "late_constructed alignment failure."); static_assert(eastl::alignment_of::storage_type>::value == 64, "late_constructed alignment failure."); static_assert(eastl::alignment_of >::value >= 64, "late_constructed alignment failure."); - // late_constructed / gLCTestObjectTrue + // late_constructed / gLCTestObjectTrueFalse EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0)); - EATEST_VERIFY(!gLCTestObjectTrue.is_constructed()); + EATEST_VERIFY(!gLCTestObjectTrueFalse.is_constructed()); - pLCTO = gLCTestObjectTrue.get(); // This will auto-construct LCTestObject. + pLCTO = gLCTestObjectTrueFalse.get(); // This will auto-construct LCTestObject. EATEST_VERIFY(pLCTO != NULL); - EATEST_VERIFY(gLCTestObjectTrue.is_constructed()); + EATEST_VERIFY(gLCTestObjectTrueFalse.is_constructed()); EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); - gLCTestObjectTrue->mX = 17; - EATEST_VERIFY(gLCTestObjectTrue->mX == 17); + gLCTestObjectTrueFalse->mX = 17; + EATEST_VERIFY(gLCTestObjectTrueFalse->mX == 17); EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); - gLCTestObjectTrue.destruct(); + gLCTestObjectTrueFalse.destruct(); EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 1)); - EATEST_VERIFY(!gLCTestObjectTrue.is_constructed()); + EATEST_VERIFY(!gLCTestObjectTrueFalse.is_constructed()); - gLCTestObjectTrue->mX = 18; - EATEST_VERIFY(gLCTestObjectTrue->mX == 18); - EATEST_VERIFY(gLCTestObjectTrue.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)); - gLCTestObjectTrue.destruct(); - (*gLCTestObjectTrue).mX = 19; - EATEST_VERIFY(gLCTestObjectTrue->mX == 19); + gLCTestObjectTrueFalse.destruct(); + (*gLCTestObjectTrueFalse).mX = 19; + EATEST_VERIFY(gLCTestObjectTrueFalse->mX == 19); EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 3) && (LCTestObject::sTODtorCount == 2)); - gLCTestObjectTrue.destruct(); + gLCTestObjectTrueFalse.destruct(); LCTestObject::sTOCount = 0; LCTestObject::sTOCtorCount = 0; LCTestObject::sTODtorCount = 0; - // late_constructed / gLCTestObjectFalse + // late_constructed / gLCTestObjectFalseFalse EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0)); - EATEST_VERIFY(!gLCTestObjectFalse.is_constructed()); + EATEST_VERIFY(!gLCTestObjectFalseFalse.is_constructed()); - pLCTO = gLCTestObjectFalse.get(); // This will not auto-construct LCTestObject. + pLCTO = gLCTestObjectFalseFalse.get(); // This will not auto-construct LCTestObject. EATEST_VERIFY(pLCTO == NULL); - EATEST_VERIFY(!gLCTestObjectFalse.is_constructed()); + EATEST_VERIFY(!gLCTestObjectFalseFalse.is_constructed()); EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0)); - gLCTestObjectFalse.construct(); - pLCTO = gLCTestObjectFalse.get(); + gLCTestObjectFalseFalse.construct(); + pLCTO = gLCTestObjectFalseFalse.get(); EATEST_VERIFY(pLCTO != NULL); - EATEST_VERIFY(gLCTestObjectFalse.is_constructed()); + EATEST_VERIFY(gLCTestObjectFalseFalse.is_constructed()); EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); - gLCTestObjectFalse->mX = 17; - EATEST_VERIFY(gLCTestObjectFalse->mX == 17); + gLCTestObjectFalseFalse->mX = 17; + EATEST_VERIFY(gLCTestObjectFalseFalse->mX == 17); EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); - gLCTestObjectFalse.destruct(); + gLCTestObjectFalseFalse.destruct(); EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 1)); - EATEST_VERIFY(!gLCTestObjectFalse.is_constructed()); + EATEST_VERIFY(!gLCTestObjectFalseFalse.is_constructed()); - gLCTestObjectFalse.construct(14); - EATEST_VERIFY(gLCTestObjectFalse->mX == 14); - gLCTestObjectFalse->mX = 18; - EATEST_VERIFY(gLCTestObjectFalse->mX == 18); - EATEST_VERIFY(gLCTestObjectFalse.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)); - gLCTestObjectFalse.destruct(); - gLCTestObjectFalse.construct(10, 20, 30); - EATEST_VERIFY(gLCTestObjectFalse->mX == 10+20+30); - (*gLCTestObjectFalse).mX = 19; - EATEST_VERIFY(gLCTestObjectFalse->mX == 19); + 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)); - gLCTestObjectFalse.destruct(); + gLCTestObjectFalseFalse.destruct(); + } + + LCTestObject::sTOCount = 0; + LCTestObject::sTOCtorCount = 0; + LCTestObject::sTODtorCount = 0; + { + eastl::late_constructed 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 lc; + lc.construct(); } + EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0)); // We use the vector container to supply a RandomAccessIterator. diff --git a/test/source/TestString.inl b/test/source/TestString.inl index a370c246..2c9fd404 100644 --- a/test/source/TestString.inl +++ b/test/source/TestString.inl @@ -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