SpanTests.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  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/UnitTest/TestTypes.h>
  9. #include <AzCore/std/containers/span.h>
  10. namespace UnitTest
  11. {
  12. class SpanTestFixture
  13. : public LeakDetectionFixture
  14. {};
  15. // range access
  16. TEST_F(SpanTestFixture, IsConstructibleWithContiguousRangeLikeContainers)
  17. {
  18. constexpr AZStd::string_view testStringView{ "Foo" };
  19. AZStd::string testString{ "Foo" };
  20. AZStd::vector testVector{ 'F', 'o', 'o' };
  21. AZStd::fixed_vector testFixedVector{ 'F', 'o', 'o' };
  22. AZStd::array testStdArray{ 'F', 'o', 'o' };
  23. const char testCArray[]{ 'F', 'o', 'o' };
  24. constexpr AZStd::span stringViewSpan(testStringView);
  25. static_assert(stringViewSpan.data() == testStringView.data());
  26. AZStd::span testStringSpan(testString);
  27. EXPECT_EQ(testStringSpan.data(), testString.data());
  28. AZStd::span testVectorSpan(testVector);
  29. EXPECT_EQ(testVectorSpan.data(), testVector.data());
  30. AZStd::span testFixedVectorSpan(testFixedVector);
  31. EXPECT_EQ(testFixedVectorSpan.data(), testFixedVector.data());
  32. AZStd::span testStdArraySpan(testStdArray);
  33. EXPECT_EQ(testStdArraySpan.data(), testStdArray.data());
  34. AZStd::span testCArraySpan(testCArray);
  35. EXPECT_EQ(AZStd::data(testCArray), testCArraySpan.data());
  36. }
  37. TEST_F(SpanTestFixture, IsConstructibleWithContiguousIterators)
  38. {
  39. constexpr AZStd::string_view testStringView{ "Foo" };
  40. AZStd::string testString{ "Foo" };
  41. AZStd::vector testVector{ 'F', 'o', 'o' };
  42. AZStd::fixed_vector testFixedVector{ 'F', 'o', 'o' };
  43. AZStd::array testStdArray{ 'F', 'o', 'o' };
  44. const char testCArray[]{ 'F', 'o', 'o' };
  45. constexpr AZStd::span stringViewSpan(testStringView.begin(), testStringView.end());
  46. static_assert(stringViewSpan.data() == testStringView.data());
  47. AZStd::span testStringSpan(testString.begin(), testString.end());
  48. EXPECT_EQ(testStringSpan.data(), testString.data());
  49. AZStd::span testVectorSpan(testVector.begin(), testVector.end());
  50. EXPECT_EQ(testVectorSpan.data(), testVector.data());
  51. AZStd::span testFixedVectorSpan(testFixedVector.begin(), testFixedVector.end());
  52. EXPECT_EQ(testFixedVectorSpan.data(), testFixedVector.data());
  53. AZStd::span testStdArraySpan(testStdArray.begin(), testStdArray.end());
  54. EXPECT_EQ(testStdArraySpan.data(), testStdArray.data());
  55. AZStd::span testCArraySpan(AZStd::begin(testCArray), AZStd::end(testCArray));
  56. EXPECT_EQ(AZStd::data(testCArray), testCArraySpan.data());
  57. }
  58. TEST_F(SpanTestFixture, ObserverMethods_ReturnsCorrectValues)
  59. {
  60. AZStd::vector<int> intVector{ 4, 5, 6, 1, 7 };
  61. AZStd::span intSpan(intVector);
  62. EXPECT_FALSE(intSpan.empty());
  63. EXPECT_EQ(intVector.size(), intSpan.size());
  64. EXPECT_EQ(intSpan.size() * sizeof(int), intSpan.size_bytes());
  65. intSpan = {};
  66. EXPECT_TRUE(intSpan.empty());
  67. EXPECT_EQ(0, intSpan.size());
  68. EXPECT_EQ(0, intSpan.size_bytes());
  69. }
  70. TEST_F(SpanTestFixture, ElementAccessorMethods_Succeeds)
  71. {
  72. AZStd::vector<int> intVector{ 4, 5, 6, 1, 7 };
  73. AZStd::span intSpan(intVector);
  74. EXPECT_EQ(intVector.data(), intSpan.data());
  75. EXPECT_EQ(4, intSpan.front());
  76. EXPECT_EQ(7, intSpan.back());
  77. EXPECT_EQ(6, intSpan[2]);
  78. // Create subspan from elements 1 .. end - 1
  79. intSpan = intSpan.subspan(1, intSpan.size() - 2);
  80. EXPECT_NE(intVector.data(), intSpan.data());
  81. EXPECT_EQ(5, intSpan.front());
  82. EXPECT_EQ(1, intSpan.back());
  83. EXPECT_EQ(6, intSpan[1]);
  84. }
  85. TEST_F(SpanTestFixture, Supspan_Returns_Subview_Succeeds)
  86. {
  87. AZStd::vector<int> intVector{ 4, 5, 6, 1, 7 };
  88. AZStd::span intSpan(intVector);
  89. // dynamic_extent subspan with count
  90. auto dynamicIntSubSpan = intSpan.subspan(1, 2);
  91. ASSERT_EQ(2, dynamicIntSubSpan.size());
  92. EXPECT_EQ(5, dynamicIntSubSpan[0]);
  93. EXPECT_EQ(6, dynamicIntSubSpan[1]);
  94. // dynamic_extent subspan without count
  95. dynamicIntSubSpan = intSpan.subspan(1);
  96. ASSERT_EQ(4, dynamicIntSubSpan.size());
  97. EXPECT_EQ(5, dynamicIntSubSpan[0]);
  98. EXPECT_EQ(6, dynamicIntSubSpan[1]);
  99. EXPECT_EQ(1, dynamicIntSubSpan[2]);
  100. EXPECT_EQ(7, dynamicIntSubSpan[3]);
  101. // template subspan with count
  102. auto templateIntSubSpan1 = intSpan.subspan<1, 3>();
  103. static_assert(decltype(templateIntSubSpan1)::extent == 3);
  104. ASSERT_EQ(3, templateIntSubSpan1.size());
  105. EXPECT_EQ(5, templateIntSubSpan1[0]);
  106. EXPECT_EQ(6, templateIntSubSpan1[1]);
  107. EXPECT_EQ(1, templateIntSubSpan1[2]);
  108. // template subspan without count
  109. auto templateIntSubSpan2 = intSpan.subspan<1>();
  110. static_assert(decltype(templateIntSubSpan2)::extent == AZStd::dynamic_extent);
  111. ASSERT_EQ(4, templateIntSubSpan2.size());
  112. EXPECT_EQ(5, templateIntSubSpan2[0]);
  113. EXPECT_EQ(6, templateIntSubSpan2[1]);
  114. EXPECT_EQ(1, templateIntSubSpan2[2]);
  115. EXPECT_EQ(7, templateIntSubSpan2[3]);
  116. // get subspan of fixed extent span without count
  117. auto subSpanOfSubSpan = templateIntSubSpan1.subspan<1>();
  118. static_assert(decltype(subSpanOfSubSpan)::extent == 2);
  119. ASSERT_EQ(2, subSpanOfSubSpan.size());
  120. EXPECT_EQ(6, subSpanOfSubSpan[0]);
  121. EXPECT_EQ(1, subSpanOfSubSpan[1]);
  122. }
  123. TEST_F(SpanTestFixture, FirstMethod_Returns_FirstCountElementsOfSpan)
  124. {
  125. constexpr size_t vectorElementCount = 5;
  126. AZStd::vector<int> intVector{ 4, 5, 6, 1, 7 };
  127. AZStd::span intSpan(intVector);
  128. {
  129. // No templated first function
  130. auto prefixSpan = intSpan.first(3);
  131. ASSERT_EQ(3, prefixSpan.size());
  132. EXPECT_EQ(4, prefixSpan[0]);
  133. EXPECT_EQ(5, prefixSpan[1]);
  134. EXPECT_EQ(6, prefixSpan[2]);
  135. auto prefixSpanRedux = prefixSpan.first(1);
  136. ASSERT_EQ(1, prefixSpanRedux.size());
  137. EXPECT_EQ(4, prefixSpanRedux[0]);
  138. // Test failure of preconditions by requesting more
  139. // elements thant stored in the span
  140. AZ_TEST_START_TRACE_SUPPRESSION;
  141. intSpan.first(intSpan.size() + 1);
  142. AZ_TEST_STOP_TRACE_SUPPRESSION(1);
  143. }
  144. {
  145. // templated first function
  146. auto prefixSpan = intSpan.first<3>();
  147. static_assert(decltype(prefixSpan)::extent == 3);
  148. ASSERT_EQ(3, prefixSpan.size());
  149. EXPECT_EQ(4, prefixSpan[0]);
  150. EXPECT_EQ(5, prefixSpan[1]);
  151. EXPECT_EQ(6, prefixSpan[2]);
  152. auto prefixSpanRedux = prefixSpan.first<1>();
  153. ASSERT_EQ(1, prefixSpanRedux.size());
  154. EXPECT_EQ(4, prefixSpanRedux[0]);
  155. // Test failure of preconditions by requesting more
  156. // elements thant stored in the span
  157. AZ_TEST_START_TRACE_SUPPRESSION;
  158. intSpan.first<vectorElementCount + 1>();
  159. AZ_TEST_STOP_TRACE_SUPPRESSION(1);
  160. }
  161. }
  162. TEST_F(SpanTestFixture, LastCountElementsOfSpan)
  163. {
  164. constexpr size_t vectorElementCount = 5;
  165. AZStd::vector<int> intVector{ 4, 5, 6, 1, 7 };
  166. AZStd::span intSpan(intVector);
  167. {
  168. // No templated last function
  169. auto suffixSpan = intSpan.last(3);
  170. ASSERT_EQ(3, suffixSpan.size());
  171. EXPECT_EQ(6, suffixSpan[0]);
  172. EXPECT_EQ(1, suffixSpan[1]);
  173. EXPECT_EQ(7, suffixSpan[2]);
  174. auto suffixSpanRedux = suffixSpan.last(1);
  175. ASSERT_EQ(1, suffixSpanRedux.size());
  176. EXPECT_EQ(7, suffixSpanRedux[0]);
  177. // Test failure of preconditions by requesting more
  178. // elements thant stored in the span
  179. AZ_TEST_START_TRACE_SUPPRESSION;
  180. intSpan.last(intSpan.size() + 1);
  181. AZ_TEST_STOP_TRACE_SUPPRESSION(1);
  182. }
  183. {
  184. // templated last function
  185. auto suffixSpan = intSpan.last<3>();
  186. static_assert(decltype(suffixSpan)::extent == 3);
  187. ASSERT_EQ(3, suffixSpan.size());
  188. EXPECT_EQ(6, suffixSpan[0]);
  189. EXPECT_EQ(1, suffixSpan[1]);
  190. EXPECT_EQ(7, suffixSpan[2]);
  191. auto suffixSpanRedux = suffixSpan.last<1>();
  192. ASSERT_EQ(1, suffixSpanRedux.size());
  193. EXPECT_EQ(7, suffixSpanRedux[0]);
  194. // Test failure of preconditions by requesting more
  195. // elements thant stored in the span
  196. AZ_TEST_START_TRACE_SUPPRESSION;
  197. intSpan.last<vectorElementCount + 1>();
  198. AZ_TEST_STOP_TRACE_SUPPRESSION(1);
  199. }
  200. }
  201. TEST_F(SpanTestFixture, CanInitializeFixedArrayToDynamicExtentSpan)
  202. {
  203. constexpr size_t arrayElementCount = 5;
  204. static constexpr AZStd::array<int, arrayElementCount> intArray{ 4, 5, 6, 1, 7 };
  205. constexpr AZStd::span<const int, AZStd::dynamic_extent> arraySpan(intArray);
  206. static_assert(intArray.data() == arraySpan.data());
  207. constexpr AZStd::span<const int, arrayElementCount> arraySpanFixedExtent(intArray);
  208. static_assert(intArray.data() == arraySpanFixedExtent.data());
  209. }
  210. }