/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #include "UserTypes.h" #include #include #include #include namespace UnitTest { using namespace UnitTestInternal; TEST(CreateDestroy, UninitializedFill_StdArray_IntType_AllEight) { const int intArraySize = 5; const int fillValue = 8; std::array intArray; AZStd::uninitialized_fill(intArray.begin(), intArray.end(), fillValue, std::false_type()); for (auto itr : intArray) { EXPECT_EQ(itr, fillValue); } } TEST(CreateDestroy, UninitializedFill_AZStdArray_IntType_AllEight) { const int intArraySize = 5; const int fillValue = 8; AZStd::array intArray; AZStd::uninitialized_fill(intArray.begin(), intArray.end(), fillValue, std::false_type()); for (auto itr : intArray) { EXPECT_EQ(itr, fillValue); } } TEST(CreateDestroy, UninitializedFill_StdArray_StringType_AllEight) { const int stringArraySize = 5; const AZStd::string fillValue = "hello, world"; std::array stringArray; AZStd::uninitialized_fill(stringArray.begin(), stringArray.end(), fillValue, std::false_type()); for (auto itr : stringArray) { EXPECT_EQ(0, strcmp(itr.c_str(), fillValue.c_str())); } } TEST(CreateDestroy, UninitializedFill_AZStdArray_StringType_AllEight) { const int stringArraySize = 5; const AZStd::string fillValue = "hello, world"; AZStd::array stringArray; AZStd::uninitialized_fill(stringArray.begin(), stringArray.end(), fillValue, std::false_type()); for (auto itr : stringArray) { EXPECT_EQ(0, strcmp(itr.c_str(), fillValue.c_str())); } } TEST(CreateDestroy, Destroy_Compile_WhenUsedInConstexpr) { auto TestDestroyFunc = []() constexpr -> int { AZStd::string_view testValue("Test"); AZStd::Internal::destroy::single(&testValue); AZStd::string_view testArray[] = { AZStd::string_view("Test"), AZStd::string_view("World") }; AZStd::Internal::destroy::range(AZStd::begin(testArray), AZStd::end(testArray)); return 73; }; static_assert(AZStd::is_trivially_destructible_v); static_assert(TestDestroyFunc() == 73); } TEST(CreateDestroy, IsFastCopyTraits_SucceedForContiguousIteratorTypes) { using list_type = AZStd::list; using vector_type = AZStd::vector; using string_type = AZStd::string; static_assert(AZStd::Internal::is_fast_copy::value); static_assert(!AZStd::Internal::is_fast_copy::value); static_assert(!AZStd::Internal::is_fast_copy::value); static_assert(AZStd::Internal::is_fast_copy::value); static_assert(AZStd::Internal::is_fast_copy::value); static_assert(AZStd::Internal::is_fast_copy::value); static_assert(AZStd::Internal::is_fast_copy::value); static_assert(!AZStd::Internal::is_fast_copy::value); } TEST(CreateDestroy, IsFastFillTraits_TrueForContiguousIteratorTypes) { using list_type = AZStd::list; using vector_type = AZStd::vector; using string_type = AZStd::string; using fixed_string_type = AZStd::fixed_string<128>; static_assert(!AZStd::Internal::is_fast_fill::value); static_assert(!AZStd::Internal::is_fast_fill::value); // Fast fill requires the type to be of size 1 static_assert(AZStd::Internal::is_fast_fill::value); static_assert(AZStd::Internal::is_fast_fill::value); static_assert(AZStd::Internal::is_fast_fill::value); } TEST(CreateDestroy, ConstructAt_IsAbleToConstructReferenceTypes_Success) { struct TestConstructAt { TestConstructAt(int& intRef, float&& floatRef) : m_intRef(intRef) , m_floatValue(floatRef) {} int& m_intRef; float m_floatValue; }; int testValue = 32; AZStd::aligned_storage_for_t constructStorage; auto constructAddress = &reinterpret_cast(constructStorage); auto resultAddress = AZStd::construct_at(constructAddress, testValue, 4.0f); resultAddress->m_intRef = 22; EXPECT_EQ(22, testValue); EXPECT_FLOAT_EQ(4.0f, resultAddress->m_floatValue); AZStd::destroy_at(resultAddress); } TEST(CreateDestroy, UninitializedDefaultConstruct_IsAbleToConstructMultipleElements_Succeeds) { struct RefWrapper { RefWrapper() {} int m_intValue{ 2 }; }; constexpr size_t ArraySize = 2; AZStd::aligned_storage_for_t testArray[ArraySize]; RefWrapper(&uninitializedAddress)[2] = reinterpret_cast(testArray); AZStd::uninitialized_default_construct(AZStd::begin(uninitializedAddress), AZStd::end(uninitializedAddress)); EXPECT_EQ(2, uninitializedAddress[0].m_intValue); EXPECT_EQ(2, uninitializedAddress[1].m_intValue); // Reset uninitializedAddress to Debug pattern memset(uninitializedAddress, 0xCD, ArraySize * sizeof(RefWrapper)); AZStd::uninitialized_default_construct_n(AZStd::data(uninitializedAddress), AZStd::size(uninitializedAddress)); EXPECT_EQ(2, uninitializedAddress[0].m_intValue); EXPECT_EQ(2, uninitializedAddress[1].m_intValue); } TEST(CreateDestroy, UninitializedValueConstruct_IsAbleToConstructMultipleElements_Succeeds) { struct RefWrapper { int m_intValue; }; constexpr size_t ArraySize = 2; AZStd::aligned_storage_for_t testArray[ArraySize]; RefWrapper(&uninitializedAddress)[2] = reinterpret_cast(testArray); AZStd::uninitialized_value_construct(AZStd::begin(uninitializedAddress), AZStd::end(uninitializedAddress)); EXPECT_EQ(0, uninitializedAddress[0].m_intValue); EXPECT_EQ(0, uninitializedAddress[1].m_intValue); // Reset uninitializedAddress to Debug pattern memset(uninitializedAddress, 0xCD, ArraySize * sizeof(RefWrapper)); AZStd::uninitialized_value_construct_n(AZStd::data(uninitializedAddress), AZStd::size(uninitializedAddress)); EXPECT_EQ(0, uninitializedAddress[0].m_intValue); EXPECT_EQ(0, uninitializedAddress[1].m_intValue); } }