CreateDestroy.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "UserTypes.h"
  9. #include <AzCore/std/containers/array.h>
  10. #include <AzCore/std/string/string.h>
  11. #include <AzCore/std/string/fixed_string.h>
  12. #include <array>
  13. namespace UnitTest
  14. {
  15. using namespace UnitTestInternal;
  16. TEST(CreateDestroy, UninitializedFill_StdArray_IntType_AllEight)
  17. {
  18. const int intArraySize = 5;
  19. const int fillValue = 8;
  20. std::array<int, intArraySize> intArray;
  21. AZStd::uninitialized_fill(intArray.begin(), intArray.end(), fillValue, std::false_type());
  22. for (auto itr : intArray)
  23. {
  24. EXPECT_EQ(itr, fillValue);
  25. }
  26. }
  27. TEST(CreateDestroy, UninitializedFill_AZStdArray_IntType_AllEight)
  28. {
  29. const int intArraySize = 5;
  30. const int fillValue = 8;
  31. AZStd::array<int, intArraySize> intArray;
  32. AZStd::uninitialized_fill(intArray.begin(), intArray.end(), fillValue, std::false_type());
  33. for (auto itr : intArray)
  34. {
  35. EXPECT_EQ(itr, fillValue);
  36. }
  37. }
  38. TEST(CreateDestroy, UninitializedFill_StdArray_StringType_AllEight)
  39. {
  40. const int stringArraySize = 5;
  41. const AZStd::string fillValue = "hello, world";
  42. std::array<AZStd::string, stringArraySize> stringArray;
  43. AZStd::uninitialized_fill(stringArray.begin(), stringArray.end(), fillValue, std::false_type());
  44. for (auto itr : stringArray)
  45. {
  46. EXPECT_EQ(0, strcmp(itr.c_str(), fillValue.c_str()));
  47. }
  48. }
  49. TEST(CreateDestroy, UninitializedFill_AZStdArray_StringType_AllEight)
  50. {
  51. const int stringArraySize = 5;
  52. const AZStd::string fillValue = "hello, world";
  53. AZStd::array<AZStd::string, stringArraySize> stringArray;
  54. AZStd::uninitialized_fill(stringArray.begin(), stringArray.end(), fillValue, std::false_type());
  55. for (auto itr : stringArray)
  56. {
  57. EXPECT_EQ(0, strcmp(itr.c_str(), fillValue.c_str()));
  58. }
  59. }
  60. TEST(CreateDestroy, Destroy_Compile_WhenUsedInConstexpr)
  61. {
  62. auto TestDestroyFunc = []() constexpr -> int
  63. {
  64. AZStd::string_view testValue("Test");
  65. AZStd::Internal::destroy<decltype(testValue)*>::single(&testValue);
  66. AZStd::string_view testArray[] = { AZStd::string_view("Test"), AZStd::string_view("World") };
  67. AZStd::Internal::destroy<decltype(testValue)*>::range(AZStd::begin(testArray), AZStd::end(testArray));
  68. return 73;
  69. };
  70. static_assert(AZStd::is_trivially_destructible_v<AZStd::string_view>);
  71. static_assert(TestDestroyFunc() == 73);
  72. }
  73. TEST(CreateDestroy, IsFastCopyTraits_SucceedForContiguousIteratorTypes)
  74. {
  75. using list_type = AZStd::list<int>;
  76. using vector_type = AZStd::vector<int>;
  77. using string_type = AZStd::string;
  78. static_assert(AZStd::Internal::is_fast_copy<const char*, const char*>::value);
  79. static_assert(!AZStd::Internal::is_fast_copy<typename list_type::iterator, int*>::value);
  80. static_assert(!AZStd::Internal::is_fast_copy<int*, typename list_type::iterator>::value);
  81. static_assert(AZStd::Internal::is_fast_copy<typename vector_type::iterator, int*>::value);
  82. static_assert(AZStd::Internal::is_fast_copy<int*, typename vector_type::iterator>::value);
  83. static_assert(AZStd::Internal::is_fast_copy<typename string_type::iterator, char*>::value);
  84. static_assert(AZStd::Internal::is_fast_copy<char*, typename string_type::iterator>::value);
  85. static_assert(!AZStd::Internal::is_fast_copy<typename vector_type::iterator, typename list_type::iterator>::value);
  86. }
  87. TEST(CreateDestroy, IsFastFillTraits_TrueForContiguousIteratorTypes)
  88. {
  89. using list_type = AZStd::list<int>;
  90. using vector_type = AZStd::vector<int>;
  91. using string_type = AZStd::string;
  92. using fixed_string_type = AZStd::fixed_string<128>;
  93. static_assert(!AZStd::Internal::is_fast_fill<typename list_type::iterator>::value);
  94. static_assert(!AZStd::Internal::is_fast_fill<typename vector_type::iterator>::value);
  95. // Fast fill requires the type to be of size 1
  96. static_assert(AZStd::Internal::is_fast_fill<const char*>::value);
  97. static_assert(AZStd::Internal::is_fast_fill<typename string_type::iterator>::value);
  98. static_assert(AZStd::Internal::is_fast_fill<typename fixed_string_type::iterator>::value);
  99. }
  100. TEST(CreateDestroy, ConstructAt_IsAbleToConstructReferenceTypes_Success)
  101. {
  102. struct TestConstructAt
  103. {
  104. TestConstructAt(int& intRef, float&& floatRef)
  105. : m_intRef(intRef)
  106. , m_floatValue(floatRef)
  107. {}
  108. int& m_intRef;
  109. float m_floatValue;
  110. };
  111. int testValue = 32;
  112. AZStd::aligned_storage_for_t<TestConstructAt> constructStorage;
  113. auto constructAddress = &reinterpret_cast<TestConstructAt&>(constructStorage);
  114. auto resultAddress = AZStd::construct_at(constructAddress, testValue, 4.0f);
  115. resultAddress->m_intRef = 22;
  116. EXPECT_EQ(22, testValue);
  117. EXPECT_FLOAT_EQ(4.0f, resultAddress->m_floatValue);
  118. AZStd::destroy_at(resultAddress);
  119. }
  120. TEST(CreateDestroy, UninitializedDefaultConstruct_IsAbleToConstructMultipleElements_Succeeds)
  121. {
  122. struct RefWrapper
  123. {
  124. RefWrapper()
  125. {}
  126. int m_intValue{ 2 };
  127. };
  128. constexpr size_t ArraySize = 2;
  129. AZStd::aligned_storage_for_t<RefWrapper> testArray[ArraySize];
  130. RefWrapper(&uninitializedAddress)[2] = reinterpret_cast<RefWrapper(&)[2]>(testArray);
  131. AZStd::uninitialized_default_construct(AZStd::begin(uninitializedAddress), AZStd::end(uninitializedAddress));
  132. EXPECT_EQ(2, uninitializedAddress[0].m_intValue);
  133. EXPECT_EQ(2, uninitializedAddress[1].m_intValue);
  134. // Reset uninitializedAddress to Debug pattern
  135. memset(uninitializedAddress, 0xCD, ArraySize * sizeof(RefWrapper));
  136. AZStd::uninitialized_default_construct_n(AZStd::data(uninitializedAddress), AZStd::size(uninitializedAddress));
  137. EXPECT_EQ(2, uninitializedAddress[0].m_intValue);
  138. EXPECT_EQ(2, uninitializedAddress[1].m_intValue);
  139. }
  140. TEST(CreateDestroy, UninitializedValueConstruct_IsAbleToConstructMultipleElements_Succeeds)
  141. {
  142. struct RefWrapper
  143. {
  144. int m_intValue;
  145. };
  146. constexpr size_t ArraySize = 2;
  147. AZStd::aligned_storage_for_t<RefWrapper> testArray[ArraySize];
  148. RefWrapper(&uninitializedAddress)[2] = reinterpret_cast<RefWrapper(&)[2]>(testArray);
  149. AZStd::uninitialized_value_construct(AZStd::begin(uninitializedAddress), AZStd::end(uninitializedAddress));
  150. EXPECT_EQ(0, uninitializedAddress[0].m_intValue);
  151. EXPECT_EQ(0, uninitializedAddress[1].m_intValue);
  152. // Reset uninitializedAddress to Debug pattern
  153. memset(uninitializedAddress, 0xCD, ArraySize * sizeof(RefWrapper));
  154. AZStd::uninitialized_value_construct_n(AZStd::data(uninitializedAddress), AZStd::size(uninitializedAddress));
  155. EXPECT_EQ(0, uninitializedAddress[0].m_intValue);
  156. EXPECT_EQ(0, uninitializedAddress[1].m_intValue);
  157. }
  158. }