Pair.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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 <AzCore/std/containers/compressed_pair.h>
  9. #include "UserTypes.h"
  10. namespace UnitTest
  11. {
  12. //////////////////////////////////////////////////////////////////////////
  13. // Fixtures
  14. // Fixture for non-typed tests
  15. template<typename TestConfig>
  16. class CompressedPairTest
  17. : public LeakDetectionFixture
  18. {
  19. };
  20. template<typename TestConfig>
  21. class CompressedPairSizeTest
  22. : public CompressedPairTest<TestConfig>
  23. {};
  24. namespace CompressedPairInternal
  25. {
  26. struct EmptyStruct
  27. {};
  28. struct EmptyStructNonDerived
  29. {};
  30. struct FinalEmptyStruct final
  31. {};
  32. struct DerivedFromEmptyStruct
  33. : EmptyStruct
  34. {
  35. };
  36. struct DerivedWithDataFromEmptyStruct
  37. : EmptyStruct
  38. {
  39. uint32_t m_value{};
  40. };
  41. }
  42. template<typename T1, typename T2, size_t MaxExpectedSize>
  43. struct CompressedPairTestConfig
  44. {
  45. using first_type = T1;
  46. using second_type = T2;
  47. static constexpr size_t max_expected_size = MaxExpectedSize;
  48. };
  49. using CompressedPairTestConfigs = ::testing::Types<
  50. CompressedPairTestConfig<CompressedPairInternal::EmptyStruct, CompressedPairInternal::FinalEmptyStruct, 1>
  51. , CompressedPairTestConfig<CompressedPairInternal::EmptyStruct, int32_t, 4>
  52. , CompressedPairTestConfig<CompressedPairInternal::EmptyStruct, CompressedPairInternal::EmptyStructNonDerived, 1>
  53. , CompressedPairTestConfig<int32_t, CompressedPairInternal::EmptyStruct, 4>
  54. , CompressedPairTestConfig<int32_t, int32_t, 8>
  55. >;
  56. TYPED_TEST_SUITE(CompressedPairTest, CompressedPairTestConfigs);
  57. using CompressedPairSizeTestConfigs = ::testing::Types<
  58. CompressedPairTestConfig<CompressedPairInternal::EmptyStruct, CompressedPairInternal::FinalEmptyStruct, 1>
  59. , CompressedPairTestConfig<CompressedPairInternal::EmptyStruct, CompressedPairInternal::EmptyStructNonDerived, 1>
  60. , CompressedPairTestConfig<CompressedPairInternal::EmptyStruct, int32_t, 4>
  61. , CompressedPairTestConfig<CompressedPairInternal::EmptyStructNonDerived, CompressedPairInternal::FinalEmptyStruct, 1>
  62. , CompressedPairTestConfig<CompressedPairInternal::EmptyStructNonDerived, CompressedPairInternal::DerivedFromEmptyStruct, 1>
  63. , CompressedPairTestConfig<CompressedPairInternal::FinalEmptyStruct, int32_t, 8>
  64. , CompressedPairTestConfig<CompressedPairInternal::FinalEmptyStruct, CompressedPairInternal::FinalEmptyStruct, 2>
  65. , CompressedPairTestConfig<CompressedPairInternal::FinalEmptyStruct, CompressedPairInternal::DerivedWithDataFromEmptyStruct, 8>
  66. , CompressedPairTestConfig<CompressedPairInternal::DerivedWithDataFromEmptyStruct, CompressedPairInternal::EmptyStructNonDerived, 4>
  67. , CompressedPairTestConfig<CompressedPairInternal::DerivedWithDataFromEmptyStruct, CompressedPairInternal::DerivedWithDataFromEmptyStruct, 8>
  68. , CompressedPairTestConfig<int32_t, int32_t, 8>
  69. >;
  70. TYPED_TEST_SUITE(CompressedPairSizeTest, CompressedPairSizeTestConfigs);
  71. TYPED_TEST(CompressedPairTest, CompressedPairDefaultConstructorSucceeds)
  72. {
  73. AZStd::compressed_pair<typename TypeParam::first_type, typename TypeParam::second_type> testPair;
  74. (void)testPair;
  75. }
  76. TYPED_TEST(CompressedPairTest, CompressedPairFirstElementConstructorSucceeds)
  77. {
  78. AZStd::compressed_pair<typename TypeParam::first_type, typename TypeParam::second_type> testPair(typename TypeParam::first_type{});
  79. (void)testPair;
  80. }
  81. TYPED_TEST(CompressedPairTest, CompressedPairSecondElementConstructorSucceeds)
  82. {
  83. AZStd::compressed_pair<typename TypeParam::first_type, typename TypeParam::second_type> testPair(AZStd::skip_element_tag{}, typename TypeParam::second_type{});
  84. (void)testPair;
  85. }
  86. TYPED_TEST(CompressedPairTest, CompressedPairPiecewiseElementConstructorSucceeds)
  87. {
  88. AZStd::compressed_pair<typename TypeParam::first_type, typename TypeParam::second_type> testPair(AZStd::piecewise_construct_t{}, std::tuple<>{}, std::tuple<>{});
  89. (void)testPair;
  90. }
  91. TYPED_TEST(CompressedPairSizeTest, CompressedPairUsesEmptyBaseOptimizationForClassSize)
  92. {
  93. static_assert(sizeof(TypeParam) <= TypeParam::max_expected_size, "Compressed Pair is not expected size");
  94. }
  95. class PairTestFixture
  96. : public LeakDetectionFixture
  97. {};
  98. TEST_F(PairTestFixture, StructuredBinding_ToConstAutoVar_CompilesSuccessfully)
  99. {
  100. constexpr AZStd::pair<int, int> testPair{ 3, 4 };
  101. const auto [firstElement, secondElement] = testPair;
  102. static_assert(AZStd::is_same_v<const int, decltype(firstElement)>);
  103. static_assert(AZStd::is_same_v<const int, decltype(secondElement)>);
  104. EXPECT_EQ(3, firstElement);
  105. EXPECT_EQ(4, secondElement);
  106. }
  107. TEST_F(PairTestFixture, CanGetFromAPairRValue)
  108. {
  109. {
  110. int myValue = 42;
  111. AZStd::pair<int&, int> myPair(myValue, 0);
  112. int& valueRef = AZStd::get<0>(AZStd::move(myPair));
  113. EXPECT_EQ(&myValue, &valueRef);
  114. static_assert(AZStd::is_same_v<decltype(AZStd::get<0>(AZStd::move(myPair))), int&>,
  115. "Invoking AZStd::get on an lvalue reference element in a pair should return an lvalue reference");
  116. }
  117. {
  118. struct MoveOnlyType
  119. {
  120. MoveOnlyType() = default;
  121. MoveOnlyType(const MoveOnlyType&) = delete;
  122. MoveOnlyType(MoveOnlyType&&) = default;
  123. };
  124. MoveOnlyType myValue;
  125. const AZStd::pair<MoveOnlyType&&, int> myPair(AZStd::move(myValue), 42);
  126. MoveOnlyType&& valueRef = AZStd::get<0>(AZStd::move(myPair));
  127. EXPECT_EQ(&myValue, &valueRef);
  128. static_assert(AZStd::is_same_v<decltype(AZStd::get<0>(AZStd::move(myPair))), MoveOnlyType&&>,
  129. "Invoking AZStd::get on an rvalue reference element in a pair should return an rvalue reference");
  130. }
  131. }
  132. }