Variant.cpp 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349
  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/variant.h>
  9. #include "UserTypes.h"
  10. namespace UnitTest
  11. {
  12. //////////////////////////////////////////////////////////////////////////
  13. // Fixtures
  14. // Fixture for non-typed tests
  15. class VariantTest
  16. : public LeakDetectionFixture
  17. {
  18. };
  19. template<typename TestConfig>
  20. class VariantSizeTest
  21. : public LeakDetectionFixture
  22. {
  23. };
  24. template<typename VariantType, size_t ExpectedSize>
  25. struct VariantSizeTestConfig
  26. {
  27. using type = VariantType;
  28. static constexpr size_t expected_size = ExpectedSize;
  29. };
  30. using VariantSizeTestConfigs = ::testing::Types<
  31. VariantSizeTestConfig<AZStd::variant<AZStd::monostate>, 1>
  32. , VariantSizeTestConfig<AZStd::variant<void*, const void*>, 2>
  33. , VariantSizeTestConfig<AZStd::variant<uint64_t, AZStd::string, uint64_t, double>, 4>
  34. >;
  35. TYPED_TEST_SUITE(VariantSizeTest, VariantSizeTestConfigs);
  36. template<typename TestConfig>
  37. class VariantAlternativeTest
  38. : public LeakDetectionFixture
  39. {
  40. };
  41. template<typename VariantType, size_t Index, typename AlternativeType>
  42. struct VariantAlternativeTestConfig
  43. {
  44. using type = VariantType;
  45. using expected_type = AlternativeType;
  46. static constexpr size_t expected_index = Index;
  47. };
  48. using Variant6AltType = AZStd::variant<AZStd::monostate, void*, const void*, double, int32_t, uintptr_t>;
  49. using VariantAlternativeTestConfigs = ::testing::Types<
  50. VariantAlternativeTestConfig<Variant6AltType, 0, AZStd::monostate>
  51. , VariantAlternativeTestConfig<Variant6AltType, 1, void*>
  52. , VariantAlternativeTestConfig<Variant6AltType, 2, const void*>
  53. , VariantAlternativeTestConfig<Variant6AltType, 3, double>
  54. , VariantAlternativeTestConfig<Variant6AltType, 4, int32_t>
  55. , VariantAlternativeTestConfig<Variant6AltType, 5, uintptr_t>
  56. >;
  57. TYPED_TEST_SUITE(VariantAlternativeTest, VariantAlternativeTestConfigs);
  58. namespace VariantTestInternal
  59. {
  60. struct TrivialAlt
  61. {};
  62. struct NonDefaultConstructible
  63. {
  64. constexpr NonDefaultConstructible(bool)
  65. {}
  66. };
  67. struct MoveConstructorOnly
  68. {
  69. MoveConstructorOnly() = default;
  70. MoveConstructorOnly(const MoveConstructorOnly&) = delete;
  71. MoveConstructorOnly(MoveConstructorOnly&& other)
  72. {
  73. memcpy(m_alignedBuffer, other.m_alignedBuffer, sizeof(m_alignedBuffer));
  74. memset(other.m_alignedBuffer, 0, sizeof(other.m_alignedBuffer));
  75. }
  76. alignas(16) uint8_t m_alignedBuffer[32];
  77. };
  78. struct MoveOnly
  79. {
  80. MoveOnly() = default;
  81. MoveOnly(const MoveOnly&) = delete;
  82. MoveOnly& operator=(const MoveOnly&) = delete;
  83. MoveOnly(MoveOnly&& other)
  84. {
  85. m_value = other.m_value;
  86. other.m_value = {};
  87. m_moveConstructed = true;
  88. }
  89. MoveOnly& operator=(MoveOnly&& rhs)
  90. {
  91. m_value = rhs.m_value;
  92. rhs.m_value = {};
  93. ++m_moveAssignmentCounter;
  94. return *this;
  95. }
  96. int32_t m_value{};
  97. int32_t m_moveAssignmentCounter{};
  98. bool m_moveConstructed{};
  99. };
  100. struct CopyConstructorOnly
  101. {
  102. CopyConstructorOnly() = default;
  103. CopyConstructorOnly(const CopyConstructorOnly& other)
  104. {
  105. memcpy(m_alignedBuffer, other.m_alignedBuffer, sizeof(m_alignedBuffer));
  106. }
  107. CopyConstructorOnly(CopyConstructorOnly&& other) = delete;
  108. alignas(16) uint8_t m_alignedBuffer[32];
  109. };
  110. struct ConstexprVisitorHelper
  111. {
  112. template <typename... Args>
  113. constexpr int64_t operator()(int64_t numAlt, Args&&...) const
  114. {
  115. return numAlt;
  116. }
  117. };
  118. struct VariadicVariantSizeof
  119. {
  120. template <typename... Args>
  121. constexpr size_t operator()(Args&&...) const
  122. {
  123. return sizeof...(Args);
  124. }
  125. };
  126. enum class MemberFuncQualifiers : uint32_t
  127. {
  128. const_ = 1,
  129. lvalue_ref = 2,
  130. rvalue_ref = 4,
  131. const_lvalue_ref = const_ | lvalue_ref,
  132. const_rvalue_ref = const_ | rvalue_ref,
  133. };
  134. struct MemberFuncQualifierCallable
  135. {
  136. template <typename... Args>
  137. MemberFuncQualifiers operator()(Args&&...) &
  138. {
  139. return MemberFuncQualifiers::lvalue_ref;
  140. }
  141. template <typename... Args>
  142. MemberFuncQualifiers operator()(Args&&...) const &
  143. {
  144. return MemberFuncQualifiers::const_lvalue_ref;
  145. }
  146. template <typename... Args>
  147. MemberFuncQualifiers operator()(Args&&...) &&
  148. {
  149. return MemberFuncQualifiers::rvalue_ref;
  150. }
  151. template <typename... Args>
  152. MemberFuncQualifiers operator()(Args&&...) const &&
  153. {
  154. return MemberFuncQualifiers::const_rvalue_ref;
  155. }
  156. };
  157. struct ParameterQualifierCallable
  158. {
  159. template <typename... Args>
  160. MemberFuncQualifiers operator()(Args&&...)
  161. {
  162. constexpr bool lvalueArg = AZStd::conjunction<AZStd::is_lvalue_reference<Args>...>::value;
  163. constexpr bool constArg = AZStd::conjunction<AZStd::is_const<AZStd::remove_reference_t<Args>>...>::value;
  164. AZ_PUSH_DISABLE_WARNING(4127, "-Wunknown-warning-option") // conditional expression is constant
  165. if (lvalueArg && !constArg)
  166. {
  167. return MemberFuncQualifiers::lvalue_ref;
  168. }
  169. else if (lvalueArg && constArg)
  170. {
  171. return MemberFuncQualifiers::const_lvalue_ref;
  172. }
  173. else if (!lvalueArg && !constArg)
  174. {
  175. return MemberFuncQualifiers::rvalue_ref;
  176. }
  177. else if (!lvalueArg && constArg)
  178. {
  179. return MemberFuncQualifiers::const_rvalue_ref;
  180. }
  181. AZ_POP_DISABLE_WARNING
  182. return MemberFuncQualifiers{};
  183. }
  184. };
  185. template <typename Sequence>
  186. struct make_heterogeneous_variant;
  187. template <size_t... Indices>
  188. struct make_heterogeneous_variant<AZStd::index_sequence<Indices...>>
  189. {
  190. template <size_t Index>
  191. using alternative_t = uint64_t;
  192. using type = AZStd::variant<alternative_t<Indices>...>;
  193. };
  194. template <size_t NumAlternatives>
  195. using make_heterogeneous_variant_t = typename make_heterogeneous_variant<AZStd::make_index_sequence<NumAlternatives>>::type;
  196. }
  197. // variant_size test
  198. TYPED_TEST(VariantSizeTest, variant_sizeReturnsCorrectSizeWithConstVolatileQualifiers)
  199. {
  200. static_assert(TypeParam::expected_size == AZStd::variant_size<typename TypeParam::type>::value, "Variant size is not equal to expected result");
  201. static_assert(TypeParam::expected_size == AZStd::variant_size<const typename TypeParam::type>::value, "Variant size is not equal to expected result");
  202. static_assert(TypeParam::expected_size == AZStd::variant_size<volatile typename TypeParam::type>::value, "Variant size is not equal to expected result");
  203. static_assert(TypeParam::expected_size == AZStd::variant_size<const volatile typename TypeParam::type>::value, "Variant size is not equal to expected result");
  204. static_assert(TypeParam::expected_size == AZStd::variant_size_v<typename TypeParam::type>, "Variant size is not equal to expected result");
  205. static_assert(TypeParam::expected_size == AZStd::variant_size_v<const typename TypeParam::type>, "Variant size is not equal to expected result");
  206. static_assert(TypeParam::expected_size == AZStd::variant_size_v<volatile typename TypeParam::type>, "Variant size is not equal to expected result");
  207. static_assert(TypeParam::expected_size == AZStd::variant_size_v<const volatile typename TypeParam::type>, "Variant size is not equal to expected result");
  208. }
  209. TEST_F(VariantTest, variant_sizeReturnsNumberOfAlternatives)
  210. {
  211. using TestVariant1 = AZStd::variant<int, float, bool, AZStd::string_view>;
  212. static_assert(AZStd::variant_size_v<TestVariant1> == 4, "Variant size should be equal to the number of alternatives");
  213. using TestVariant2 = AZStd::variant<int, float, bool, AZStd::string, float>;
  214. static_assert(AZStd::variant_size_v<TestVariant2> == 5, "Variant size should be equal to the number of alternatives");
  215. }
  216. // variant_alternative test
  217. TYPED_TEST(VariantAlternativeTest, variant_alternativeReturnsCorrectTypeForIndex)
  218. {
  219. static_assert(AZStd::is_same_v<typename TypeParam::expected_type, typename AZStd::variant_alternative<TypeParam::expected_index, typename TypeParam::type>::type>, "Variant size is not equal to expected result");
  220. static_assert(AZStd::is_same_v<const typename TypeParam::expected_type, typename AZStd::variant_alternative<TypeParam::expected_index, const typename TypeParam::type>::type>, "Variant size is not equal to expected result");
  221. static_assert(AZStd::is_same_v<volatile typename TypeParam::expected_type, typename AZStd::variant_alternative<TypeParam::expected_index, volatile typename TypeParam::type>::type>, "Variant size is not equal to expected result");
  222. static_assert(AZStd::is_same_v<const volatile typename TypeParam::expected_type, typename AZStd::variant_alternative<TypeParam::expected_index, const volatile typename TypeParam::type>::type>, "Variant size is not equal to expected result");
  223. static_assert(AZStd::is_same_v<typename TypeParam::expected_type, AZStd::variant_alternative_t<TypeParam::expected_index, typename TypeParam::type>>, "Variant size is not equal to expected result");
  224. static_assert(AZStd::is_same_v<const typename TypeParam::expected_type, AZStd::variant_alternative_t<TypeParam::expected_index, const typename TypeParam::type>>, "Variant size is not equal to expected result");
  225. static_assert(AZStd::is_same_v<volatile typename TypeParam::expected_type, AZStd::variant_alternative_t<TypeParam::expected_index, volatile typename TypeParam::type>>, "Variant size is not equal to expected result");
  226. static_assert(AZStd::is_same_v<const volatile typename TypeParam::expected_type, AZStd::variant_alternative_t<TypeParam::expected_index, const volatile typename TypeParam::type>>, "Variant size is not equal to expected result");
  227. }
  228. TEST_F(VariantTest, sizeof_VariantIsGreaterThanLargestElementSize)
  229. {
  230. // Largest Element is string_view
  231. using TestVariant1 = AZStd::variant<int, float, bool, AZStd::string_view>;
  232. static_assert(sizeof(AZStd::string_view) < sizeof(TestVariant1), "using the sizeof operator on a std::variant should return a size larger than all the alternatives");
  233. // Largest Element is MoveOnly
  234. using TestVariant2 = AZStd::variant<double, AZStd::string_view, VariantTestInternal::MoveConstructorOnly, bool, float>;
  235. static_assert(sizeof(VariantTestInternal::MoveConstructorOnly) < sizeof(TestVariant2), "using the sizeof operator on a std::variant should return a size larger than all the alternatives");
  236. }
  237. TEST_F(VariantTest, sizeof_VariantIsLessThanCombinedAlternativeSize)
  238. {
  239. // Largest Element is string_view
  240. using TestVariant1 = AZStd::variant<int, float, bool, AZStd::string_view, AZStd::string_view>;
  241. // For a variant with less than 255 alternatives the index type is an uint8_t
  242. constexpr size_t variantAlignment = alignof(TestVariant1);
  243. constexpr size_t maxExpectedVariantByteSize = (sizeof(AZStd::string_view) + sizeof(uint8_t) + variantAlignment - 1) & ~(variantAlignment - 1);
  244. constexpr size_t testVariantByteSize = sizeof(TestVariant1);
  245. static_assert(testVariantByteSize <= maxExpectedVariantByteSize, "using the sizeof operator on a std::variant should return a size smaller"
  246. " than the sizeof(largest type) + padding + sizeof(index type)");
  247. }
  248. TEST_F(VariantTest, DifferentPermutationsOfVariantHasSameSize)
  249. {
  250. constexpr size_t alignedStorageSize = 144;
  251. using TestAlignedStorage = AZStd::aligned_storage_t<alignedStorageSize, 16>;
  252. // Largest Element is string_view
  253. using TestVariant1 = AZStd::variant<int, float, bool, TestAlignedStorage>;
  254. using TestVariant2 = AZStd::variant<TestAlignedStorage, float, bool, int>;
  255. static_assert(sizeof(TestVariant1) == sizeof(TestVariant2), "with different permutations variants of same types should be the same size");
  256. using UnorderedVariant3 = AZStd::variant<AZStd::unordered_map<AZStd::string, AZStd::string>, TestAlignedStorage>;
  257. static_assert(sizeof(TestVariant1) == sizeof(UnorderedVariant3), "with different permutations variants of same types should be the same size");
  258. }
  259. TEST_F(VariantTest, VariantIndexTypeIsLessSizeIfLessThan255Alternatives)
  260. {
  261. constexpr size_t indexSizeWithOneAlternatives = sizeof(AZStd::variant_index_t<1>);
  262. constexpr size_t indexSizeWithOneByteMaxAlternatives = sizeof(AZStd::variant_index_t<std::numeric_limits<uint8_t>::max() - 1>);
  263. constexpr size_t indexSizeWithTwoByteMinAlternatives = sizeof(AZStd::variant_index_t<std::numeric_limits<uint8_t>::max()>);
  264. static_assert(indexSizeWithOneAlternatives == indexSizeWithOneByteMaxAlternatives, "the index type for a variant with 1 alternative should be the same size for a variant with 254 alternatives");
  265. static_assert(indexSizeWithOneByteMaxAlternatives < indexSizeWithTwoByteMinAlternatives, "the index type for a variant with 254 alternatives should be smaller for a variant with 255 alternatives");
  266. }
  267. namespace Constructors
  268. {
  269. TEST_F(VariantTest, DefaultConstructorVariantSetsIndexZero)
  270. {
  271. constexpr AZStd::variant<AZStd::monostate> monostateVariant;
  272. static_assert(monostateVariant.index() == 0U, "Default Constructed variant should be constructed to first alternative");
  273. EXPECT_EQ(0U, monostateVariant.index());
  274. }
  275. TEST_F(VariantTest, DefaultConstructorSucceedsWhenOnlyFirstAlternativeIsDefaultConstructible)
  276. {
  277. AZStd::variant<AZStd::string_view, VariantTestInternal::NonDefaultConstructible> testVariant;
  278. EXPECT_EQ(0U, testVariant.index());
  279. EXPECT_TRUE(AZStd::get<0>(testVariant).empty());
  280. }
  281. TEST_F(VariantTest, ConvertingConstructorSucceeds)
  282. {
  283. const AZStd::variant<AZStd::string> stringVariant{ AZStd::string("Test String") };
  284. const AZStd::variant<AZStd::string> convertToStringVariant{ "Test String" };
  285. EXPECT_EQ(stringVariant, convertToStringVariant);
  286. }
  287. TEST_F(VariantTest, CopyConstructorSucceeds)
  288. {
  289. AZStd::variant<uint32_t, AZStd::string> numberStringUnion{ 5U };
  290. AZStd::variant<uint32_t, AZStd::string> copiedUnion(numberStringUnion);
  291. EXPECT_EQ(copiedUnion, numberStringUnion);
  292. const AZStd::variant<AZStd::string, int32_t> testVariant3{ AZStd::in_place_index_t<1>{}, 6 };
  293. const AZStd::variant<AZStd::string, int32_t > copyVariant(testVariant3);
  294. EXPECT_EQ(testVariant3, copyVariant);
  295. ASSERT_EQ(1, copyVariant.index());
  296. EXPECT_EQ(6, AZStd::get<1>(copyVariant));
  297. }
  298. TEST_F(VariantTest, MoveConstructorSucceeds)
  299. {
  300. AZStd::variant<AZStd::string> sourceStringUnion("Hello World");
  301. AZStd::variant<AZStd::string> moveUnion(AZStd::move(sourceStringUnion));
  302. EXPECT_NE(moveUnion, sourceStringUnion);
  303. // Moved from Variant should have default value
  304. EXPECT_TRUE(AZStd::get<0>(sourceStringUnion).empty());
  305. AZStd::variant<AZStd::string, AZStd::string_view> testVariant3{ AZStd::in_place_index_t<1>{}, "Hello" };
  306. AZStd::variant<AZStd::string, AZStd::string_view > moveVariant(AZStd::move(testVariant3));
  307. EXPECT_NE(testVariant3, moveVariant);
  308. ASSERT_EQ(1, moveVariant.index());
  309. EXPECT_EQ("Hello", AZStd::get<1>(moveVariant));
  310. // Moved from Variant should have default value
  311. ASSERT_EQ(1, moveVariant.index());
  312. EXPECT_TRUE(AZStd::get<1>(testVariant3).empty());
  313. }
  314. TEST_F(VariantTest, InPlaceTypeConstructorSucceeds)
  315. {
  316. AZStd::variant<bool, int32_t, AZStd::tuple<int32_t, bool>> inplaceIndexVariant(AZStd::in_place_type_t<int32_t>{}, 108);
  317. EXPECT_EQ(1, inplaceIndexVariant.index());
  318. auto& int32Alt = AZStd::get<1>(inplaceIndexVariant);
  319. EXPECT_EQ(108, int32Alt);
  320. }
  321. TEST_F(VariantTest, InPlaceTypeConstructorWithInitializerListSucceeds)
  322. {
  323. AZStd::variant<int32_t, double, AZStd::vector<int32_t>, bool> inplaceIndexVariant(AZStd::in_place_type_t<AZStd::vector<int32_t>>{}, { 1, 2, 3 }, AZStd::allocator("Variant in_place_type allocator "));
  324. EXPECT_EQ(2, inplaceIndexVariant.index());
  325. auto& vectorAlt = AZStd::get<2>(inplaceIndexVariant);
  326. ASSERT_EQ(3, vectorAlt.size());
  327. EXPECT_EQ(1, vectorAlt[0]);
  328. EXPECT_EQ(2, vectorAlt[1]);
  329. EXPECT_EQ(3, vectorAlt[2]);
  330. }
  331. TEST_F(VariantTest, InPlaceIndexConstructorSucceeds)
  332. {
  333. AZStd::variant<bool, int32_t, AZStd::tuple<int32_t, bool>> inplaceIndexVariant(AZStd::in_place_index_t<2>{}, 55, true);
  334. EXPECT_EQ(2, inplaceIndexVariant.index());
  335. auto& tupleAlt= AZStd::get<2>(inplaceIndexVariant);
  336. EXPECT_EQ(55, AZStd::get<0>(tupleAlt));
  337. EXPECT_EQ(true, AZStd::get<1>(tupleAlt));
  338. }
  339. TEST_F(VariantTest, InPlaceIndexConstructorWithInitializerListSucceeds)
  340. {
  341. AZStd::variant<float, AZStd::vector<int32_t>> inplaceIndexVariant(AZStd::in_place_index_t<1>{}, { 1, 2, 3 }, AZStd::allocator("Variant in_place_index allocator "));
  342. EXPECT_EQ(1, inplaceIndexVariant.index());
  343. auto& vectorAlt = AZStd::get<1>(inplaceIndexVariant);
  344. ASSERT_EQ(3, vectorAlt.size());
  345. EXPECT_EQ(1, vectorAlt[0]);
  346. EXPECT_EQ(2, vectorAlt[1]);
  347. EXPECT_EQ(3, vectorAlt[2]);
  348. }
  349. }
  350. namespace Emplace
  351. {
  352. // emplace<Type>
  353. TEST_F(VariantTest, TypeEmplaceUpdateCurrentAlternativeSucceeds)
  354. {
  355. AZStd::variant<bool, int32_t, AZStd::tuple<int32_t, bool>> emplaceIndexVariant(AZStd::in_place_type_t<int32_t>{}, 110);
  356. EXPECT_EQ(1, emplaceIndexVariant.index());
  357. EXPECT_EQ(110, AZStd::get<1>(emplaceIndexVariant));
  358. // Update current alternative
  359. int32_t& updatedInt = emplaceIndexVariant.emplace<int32_t>(252);
  360. EXPECT_EQ(1, emplaceIndexVariant.index());
  361. EXPECT_EQ(252, updatedInt);
  362. }
  363. TEST_F(VariantTest, TypeEmplaceUpdateDifferentAlternativeSucceeds)
  364. {
  365. AZStd::variant<bool, int32_t, AZStd::tuple<int32_t, bool>> emplaceIndexVariant(AZStd::in_place_type_t<int32_t>{}, 110);
  366. EXPECT_EQ(1, emplaceIndexVariant.index());
  367. EXPECT_EQ(110, AZStd::get<1>(emplaceIndexVariant));
  368. // Update different alternative
  369. auto& updatedTuple = emplaceIndexVariant.emplace<AZStd::tuple<int32_t, bool>>(410, true);
  370. EXPECT_EQ(2, emplaceIndexVariant.index());
  371. EXPECT_EQ(410, AZStd::get<0>(updatedTuple));
  372. EXPECT_TRUE(AZStd::get<1>(updatedTuple));
  373. }
  374. TEST_F(VariantTest, TypeEmplaceWithInitializerListUpdateCurrentAlternativeSucceeds)
  375. {
  376. AZStd::variant<int32_t, double, AZStd::vector<int32_t>, bool> emplaceIndexVariant(AZStd::in_place_type_t<AZStd::vector<int32_t>>{});
  377. EXPECT_EQ(2, emplaceIndexVariant.index());
  378. EXPECT_TRUE(AZStd::get<2>(emplaceIndexVariant).empty());
  379. // Update current alternative
  380. auto& updatedVector= emplaceIndexVariant.emplace<AZStd::vector<int32_t>>({ 2, 4, 6 }, AZStd::allocator("Variant emplace allocator"));
  381. EXPECT_EQ(2, emplaceIndexVariant.index());
  382. EXPECT_EQ(3, updatedVector.size());
  383. EXPECT_EQ(2, updatedVector[0]);
  384. EXPECT_EQ(4, updatedVector[1]);
  385. EXPECT_EQ(6, updatedVector[2]);
  386. }
  387. TEST_F(VariantTest, TypeEmplaceWithInitializerListUpdateDifferentAlternativeSucceeds)
  388. {
  389. AZStd::variant<int32_t, double, AZStd::vector<int32_t>, bool> emplaceIndexVariant(AZStd::in_place_type_t<int32_t>{}, 110);
  390. EXPECT_EQ(0, emplaceIndexVariant.index());
  391. EXPECT_EQ(110, AZStd::get<0>(emplaceIndexVariant));
  392. // Update different alternative
  393. auto& updatedVector = emplaceIndexVariant.emplace<AZStd::vector<int32_t>>({ 1, 2, 3 }, AZStd::allocator("Variant emplace allocator"));
  394. EXPECT_EQ(2, emplaceIndexVariant.index());
  395. ASSERT_EQ(3, updatedVector.size());
  396. EXPECT_EQ(1, updatedVector[0]);
  397. EXPECT_EQ(2, updatedVector[1]);
  398. EXPECT_EQ(3, updatedVector[2]);
  399. }
  400. // emplace<Index>
  401. TEST_F(VariantTest, IndexEmplaceUpdateCurrentAlternativeSucceeds)
  402. {
  403. AZStd::variant<bool, int32_t, AZStd::tuple<int32_t, bool>> emplaceIndexVariant(AZStd::in_place_type_t<int32_t>{}, 110);
  404. EXPECT_EQ(1, emplaceIndexVariant.index());
  405. EXPECT_EQ(110, AZStd::get<1>(emplaceIndexVariant));
  406. // Update current alternative
  407. int32_t& updatedInt = emplaceIndexVariant.emplace<1>(252);
  408. EXPECT_EQ(1, emplaceIndexVariant.index());
  409. EXPECT_EQ(252, updatedInt);
  410. }
  411. TEST_F(VariantTest, IndexEmplaceUpdateDifferentAlternativeSucceeds)
  412. {
  413. AZStd::variant<bool, int32_t, AZStd::tuple<int32_t, bool>> emplaceIndexVariant(AZStd::in_place_type_t<int32_t>{}, 110);
  414. EXPECT_EQ(1, emplaceIndexVariant.index());
  415. EXPECT_EQ(110, AZStd::get<1>(emplaceIndexVariant));
  416. // Update different alternative
  417. auto& updatedTuple = emplaceIndexVariant.emplace<2>(410, true);
  418. EXPECT_EQ(2, emplaceIndexVariant.index());
  419. EXPECT_EQ(410, AZStd::get<0>(updatedTuple));
  420. EXPECT_TRUE(AZStd::get<1>(updatedTuple));
  421. }
  422. TEST_F(VariantTest, IndexEmplaceWithInitializerListUpdateCurrentAlternativeSucceeds)
  423. {
  424. AZStd::variant<int32_t, double, AZStd::vector<int32_t>, bool> emplaceIndexVariant(AZStd::in_place_type_t<AZStd::vector<int32_t>>{}, { 336 });
  425. EXPECT_EQ(2, emplaceIndexVariant.index());
  426. EXPECT_EQ(1, AZStd::get<2>(emplaceIndexVariant).size());
  427. EXPECT_EQ(336, AZStd::get<2>(emplaceIndexVariant).at(0));
  428. // Update current alternative
  429. auto& updatedVector = emplaceIndexVariant.emplace<2>({ 17, -54 });
  430. EXPECT_EQ(2, emplaceIndexVariant.index());
  431. EXPECT_EQ(2, updatedVector.size());
  432. EXPECT_EQ(17, updatedVector[0]);
  433. EXPECT_EQ(-54, updatedVector[1]);
  434. }
  435. TEST_F(VariantTest, IndexEmplaceWithInitializerListUpdateDifferentAlternativeSucceeds)
  436. {
  437. AZStd::variant<int32_t, double, AZStd::vector<int32_t>, bool> emplaceIndexVariant(AZStd::in_place_type_t<int32_t>{}, 110);
  438. EXPECT_EQ(0, emplaceIndexVariant.index());
  439. EXPECT_EQ(110, AZStd::get<0>(emplaceIndexVariant));
  440. // Update different alternative
  441. auto& updatedVector = emplaceIndexVariant.emplace<2>({ 1, 2, 3 }, AZStd::allocator("Variant emplace allocator"));
  442. EXPECT_EQ(2, emplaceIndexVariant.index());
  443. ASSERT_EQ(3, updatedVector.size());
  444. EXPECT_EQ(1, updatedVector[0]);
  445. EXPECT_EQ(2, updatedVector[1]);
  446. EXPECT_EQ(3, updatedVector[2]);
  447. }
  448. }
  449. namespace GetAlternative
  450. {
  451. //get_if<Index>
  452. TEST_F(VariantTest, HoldsAlternativeSucceeds)
  453. {
  454. AZStd::variant<double, int32_t> testVariant(AZStd::in_place_type_t<int32_t>{}, 17);
  455. EXPECT_FALSE(AZStd::holds_alternative<double>(testVariant));
  456. EXPECT_TRUE(AZStd::holds_alternative<int32_t>(testVariant));
  457. testVariant = 8.0;
  458. EXPECT_TRUE(AZStd::holds_alternative<double>(testVariant));
  459. EXPECT_FALSE(AZStd::holds_alternative<int32_t>(testVariant));
  460. }
  461. TEST_F(VariantTest, IndexGetIfWithConstVariantSingleAlternativeSucceeds)
  462. {
  463. const AZStd::variant<int32_t> testVariant(17);
  464. const int32_t* testAlt = AZStd::get_if<0>(&testVariant);
  465. ASSERT_NE(nullptr, testAlt);
  466. EXPECT_EQ(17, *testAlt);
  467. }
  468. TEST_F(VariantTest, IndexGetIfWithConstVariantMultipleAlternativeSucceeds)
  469. {
  470. const AZStd::variant<int32_t, double> testVariant(32.0);
  471. const double* testAlt = AZStd::get_if<1>(&testVariant);
  472. ASSERT_NE(nullptr, testAlt);
  473. EXPECT_DOUBLE_EQ(32.0, *testAlt);
  474. }
  475. TEST_F(VariantTest, IndexGetIfWithConstVariantMultipleAlternativeFails)
  476. {
  477. const AZStd::variant<int32_t, double> testVariant(32.0);
  478. const int32_t* testAlt = AZStd::get_if<0>(&testVariant);
  479. EXPECT_EQ(nullptr, testAlt);
  480. }
  481. TEST_F(VariantTest, IndexGetIfWithVariantSingleAlternativeSucceeds)
  482. {
  483. AZStd::variant<int32_t> testVariant(17);
  484. int32_t* testAlt = AZStd::get_if<0>(&testVariant);
  485. ASSERT_NE(nullptr, testAlt);
  486. EXPECT_EQ(17, *testAlt);
  487. }
  488. TEST_F(VariantTest, IndexGetIfWithVariantMultipleAlternativeSucceeds)
  489. {
  490. AZStd::variant<int32_t, double> testVariant(32.0);
  491. double* testAlt = AZStd::get_if<1>(&testVariant);
  492. ASSERT_NE(nullptr, testAlt);
  493. EXPECT_DOUBLE_EQ(32.0, *testAlt);
  494. }
  495. // get_if<Type>
  496. TEST_F(VariantTest, IndexGetIfWithVariantMultipleAlternativeFails)
  497. {
  498. AZStd::variant<int32_t, double> testVariant(32.0);
  499. int32_t* testAlt = AZStd::get_if<0>(&testVariant);
  500. EXPECT_EQ(nullptr, testAlt);
  501. }
  502. TEST_F(VariantTest, TypeGetIfWithConstVariantSingleAlternativeSucceeds)
  503. {
  504. const AZStd::variant<int32_t> testVariant(17);
  505. const int32_t* testAlt = AZStd::get_if<int32_t>(&testVariant);
  506. ASSERT_NE(nullptr, testAlt);
  507. EXPECT_EQ(17, *testAlt);
  508. }
  509. TEST_F(VariantTest, TypeGetIfWithConstVariantMultipleAlternativeSucceeds)
  510. {
  511. const AZStd::variant<int32_t, double> testVariant(32.0);
  512. const auto testAlt = AZStd::get_if<double>(&testVariant);
  513. ASSERT_NE(nullptr, testAlt);
  514. EXPECT_DOUBLE_EQ(32.0, *testAlt);
  515. }
  516. TEST_F(VariantTest, TypeGetIfWithConstVariantMultipleAlternativeFails)
  517. {
  518. const AZStd::variant<int32_t, double> testVariant(32.0);
  519. const auto testAlt = AZStd::get_if<int32_t>(&testVariant);
  520. EXPECT_EQ(nullptr, testAlt);
  521. }
  522. TEST_F(VariantTest, TypeGetIfWithVariantSingleAlternativeSucceeds)
  523. {
  524. AZStd::variant<int32_t> testVariant(17);
  525. auto testAlt = AZStd::get_if<int32_t>(&testVariant);
  526. ASSERT_NE(nullptr, testAlt);
  527. EXPECT_EQ(17, *testAlt);
  528. }
  529. TEST_F(VariantTest, TypeGetIfWithVariantMultipleAlternativeSucceeds)
  530. {
  531. AZStd::variant<int32_t, double> testVariant(32.0);
  532. auto testAlt = AZStd::get_if<double>(&testVariant);
  533. ASSERT_NE(nullptr, testAlt);
  534. EXPECT_DOUBLE_EQ(32.0, *testAlt);
  535. }
  536. TEST_F(VariantTest, TypeGetIfWithVariantMultipleAlternativeFails)
  537. {
  538. AZStd::variant<int32_t, double> testVariant(32.0);
  539. auto testAlt = AZStd::get_if<int32_t>(&testVariant);
  540. EXPECT_EQ(nullptr, testAlt);
  541. }
  542. // get<Index>
  543. TEST_F(VariantTest, IndexGetLValueVariantNonConstAlternativeSucceeds)
  544. {
  545. AZStd::variant<int32_t, const int64_t> testVariant(6);
  546. ASSERT_EQ(0, testVariant.index());
  547. EXPECT_EQ(6, AZStd::get<0>(testVariant));
  548. static_assert(AZStd::is_same<decltype(AZStd::get<0>(testVariant)), int32_t&>::value,
  549. "AZStd::get should return lvalue reference to non-const alternative for non-const variant");
  550. }
  551. TEST_F(VariantTest, IndexGetLValueVariantConstAlternativeSucceeds)
  552. {
  553. // Set const alternative on construct
  554. AZStd::variant<int32_t, const int64_t> testVariant(static_cast<int64_t>(23LL));
  555. ASSERT_EQ(1, testVariant.index());
  556. EXPECT_EQ(23LL, AZStd::get<1>(testVariant));
  557. static_assert(AZStd::is_same<decltype(AZStd::get<1>(testVariant)), const int64_t&>::value,
  558. "AZStd::get should return const lvalue reference to const alternativefor non-const variant");
  559. }
  560. TEST_F(VariantTest, IndexGetConstLValueVariantNonConstAlternativeSucceeds)
  561. {
  562. const AZStd::variant<int32_t, const int64_t> testVariant(6);
  563. ASSERT_EQ(0, testVariant.index());
  564. EXPECT_EQ(6, AZStd::get<0>(testVariant));
  565. static_assert(AZStd::is_same<decltype(AZStd::get<0>(testVariant)), const int32_t&>::value,
  566. "AZStd::get should return const lvalue reference to non-const alternative for const variant");
  567. }
  568. TEST_F(VariantTest, IndexGetConstLValueVariantConstAlternativeSucceeds)
  569. {
  570. // Set const alternative on construct
  571. const AZStd::variant<int32_t, const int64_t> testVariant(static_cast<int64_t>(23LL));
  572. ASSERT_EQ(1, testVariant.index());
  573. EXPECT_EQ(23LL, AZStd::get<1>(testVariant));
  574. static_assert(AZStd::is_same<decltype(AZStd::get<1>(testVariant)), const int64_t&>::value,
  575. "AZStd::get should return const lvalue reference to const alternative for const variant");
  576. }
  577. TEST_F(VariantTest, IndexGetRValueVariantNonConstAlternativeSucceeds)
  578. {
  579. AZStd::variant<int32_t, const int64_t> testVariant(6);
  580. ASSERT_EQ(0, testVariant.index());
  581. static_assert(AZStd::is_same<decltype(AZStd::get<0>(AZStd::move(testVariant))), int32_t&&>::value,
  582. "AZStd::get should return rvalue reference to non-const alternative for non-const variant");
  583. EXPECT_EQ(6, AZStd::get<0>(AZStd::move(testVariant)));
  584. }
  585. TEST_F(VariantTest, IndexGetRValueVariantConstAlternativeSucceeds)
  586. {
  587. // Set const alternative on construct
  588. AZStd::variant<int32_t, const int64_t> testVariant(static_cast<int64_t>(23LL));
  589. ASSERT_EQ(1, testVariant.index());
  590. static_assert(AZStd::is_same<decltype(AZStd::get<1>(AZStd::move(testVariant))), const int64_t&&>::value,
  591. "AZStd::get should return const rvalue reference to const alternative for non-const variant");
  592. EXPECT_EQ(23LL, AZStd::get<1>(AZStd::move(testVariant)));
  593. }
  594. TEST_F(VariantTest, IndexGetConstRValueVariantNonConstAlternativeSucceeds)
  595. {
  596. const AZStd::variant<int32_t, const int64_t> testVariant(6);
  597. ASSERT_EQ(0, testVariant.index());
  598. static_assert(AZStd::is_same<decltype(AZStd::get<0>(AZStd::move(testVariant))), const int32_t&&>::value,
  599. "AZStd::get should return const rvalue reference to non-const alternative for const variant");
  600. EXPECT_EQ(6, AZStd::get<0>(AZStd::move(testVariant)));
  601. }
  602. TEST_F(VariantTest, IndexGetConstRValueVariantConstAlternativeSucceeds)
  603. {
  604. // Set const alternative on construct
  605. const AZStd::variant<int32_t, const int64_t> testVariant(static_cast<int64_t>(23LL));
  606. ASSERT_EQ(1, testVariant.index());
  607. static_assert(AZStd::is_same<decltype(AZStd::get<1>(AZStd::move(testVariant))), const int64_t&&>::value,
  608. "AZStd::get should return const rvalue reference to const alternative for const variant");
  609. EXPECT_EQ(23LL, AZStd::get<1>(AZStd::move(testVariant)));
  610. }
  611. // get<Type>
  612. TEST_F(VariantTest, TypeGetLValueVariantNonConstAlternativeSucceeds)
  613. {
  614. AZStd::variant<int32_t, const int64_t> testVariant(6);
  615. ASSERT_EQ(0, testVariant.index());
  616. EXPECT_EQ(6, AZStd::get<int32_t>(testVariant));
  617. static_assert(AZStd::is_same<decltype(AZStd::get<int32_t>(testVariant)), int32_t&>::value,
  618. "AZStd::get should return lvalue reference to non-const alternative for non-const variant");
  619. }
  620. TEST_F(VariantTest, TypeGetLValueVariantConstAlternativeSucceeds)
  621. {
  622. // Set const alternative on construct
  623. AZStd::variant<int32_t, const int64_t> testVariant(static_cast<int64_t>(23LL));
  624. ASSERT_EQ(1, testVariant.index());
  625. EXPECT_EQ(23LL, AZStd::get<const int64_t>(testVariant));
  626. static_assert(AZStd::is_same<decltype(AZStd::get<const int64_t>(testVariant)), const int64_t&>::value,
  627. "AZStd::get should return const lvalue reference to const alternativefor non-const variant");
  628. }
  629. TEST_F(VariantTest, TypeGetConstLValueVariantNonConstAlternativeSucceeds)
  630. {
  631. const AZStd::variant<int32_t, const int64_t> testVariant(6);
  632. ASSERT_EQ(0, testVariant.index());
  633. EXPECT_EQ(6, AZStd::get<int32_t>(testVariant));
  634. static_assert(AZStd::is_same<decltype(AZStd::get<int32_t>(testVariant)), const int32_t&>::value,
  635. "AZStd::get should return const lvalue reference to non-const alternative for const variant");
  636. }
  637. TEST_F(VariantTest, TypeGetConstLValueVariantConstAlternativeSucceeds)
  638. {
  639. // Set const alternative on construct
  640. const AZStd::variant<int32_t, const int64_t> testVariant(static_cast<int64_t>(23LL));
  641. ASSERT_EQ(1, testVariant.index());
  642. EXPECT_EQ(23LL, AZStd::get<const int64_t>(testVariant));
  643. static_assert(AZStd::is_same<decltype(AZStd::get<const int64_t>(testVariant)), const int64_t&>::value,
  644. "AZStd::get should return const lvalue reference to const alternative for const variant");
  645. }
  646. TEST_F(VariantTest, TypeGetRValueVariantNonConstAlternativeSucceeds)
  647. {
  648. AZStd::variant<int32_t, const int64_t> testVariant(6);
  649. ASSERT_EQ(0, testVariant.index());
  650. static_assert(AZStd::is_same<decltype(AZStd::get<int32_t>(AZStd::move(testVariant))), int32_t&&>::value,
  651. "AZStd::get should return rvalue reference to non-const alternative for non-const variant");
  652. EXPECT_EQ(6, AZStd::get<int32_t>(AZStd::move(testVariant)));
  653. }
  654. TEST_F(VariantTest, TypeGetRValueVariantConstAlternativeSucceeds)
  655. {
  656. // Set const alternative on construct
  657. AZStd::variant<int32_t, const int64_t> testVariant(static_cast<int64_t>(23LL));
  658. ASSERT_EQ(1, testVariant.index());
  659. static_assert(AZStd::is_same<decltype(AZStd::get<const int64_t>(AZStd::move(testVariant))), const int64_t&&>::value,
  660. "AZStd::get should return const rvalue reference to const alternative for non-const variant");
  661. EXPECT_EQ(23LL, AZStd::get<const int64_t>(AZStd::move(testVariant)));
  662. }
  663. TEST_F(VariantTest, TypeGetConstRValueVariantNonConstAlternativeSucceeds)
  664. {
  665. const AZStd::variant<int32_t, const int64_t> testVariant(6);
  666. ASSERT_EQ(0, testVariant.index());
  667. static_assert(AZStd::is_same<decltype(AZStd::get<int32_t>(AZStd::move(testVariant))), const int32_t&&>::value,
  668. "AZStd::get should return const rvalue reference to non-const alternative for const variant");
  669. EXPECT_EQ(6, AZStd::get<int32_t>(AZStd::move(testVariant)));
  670. }
  671. TEST_F(VariantTest, TypeGetConstRValueVariantConstAlternativeSucceeds)
  672. {
  673. // Set const alternative on construct
  674. const AZStd::variant<int32_t, const int64_t> testVariant(static_cast<int64_t>(23LL));
  675. ASSERT_EQ(1, testVariant.index());
  676. static_assert(AZStd::is_same<decltype(AZStd::get<const int64_t>(AZStd::move(testVariant))), const int64_t&&>::value,
  677. "AZStd::get should return const rvalue reference to const alternative for const variant");
  678. EXPECT_EQ(23LL, AZStd::get<const int64_t>(AZStd::move(testVariant)));
  679. }
  680. }
  681. namespace VisitorQualifier
  682. {
  683. // non-const lvalue visitor
  684. TEST_F(VariantTest, VisitForwardsLValueMemberVisitorCorrectly_WithSingleAlternativeVariant)
  685. {
  686. VariantTestInternal::MemberFuncQualifierCallable callable{};
  687. AZStd::variant<int16_t> testVariant(static_cast<int16_t>(7));
  688. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, testVariant);
  689. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::lvalue_ref, calledFunc);
  690. }
  691. TEST_F(VariantTest, VisitForwardsLValueMemberVisitorCorrectly_WithMultipleAlternativeVariant)
  692. {
  693. VariantTestInternal::MemberFuncQualifierCallable callable{};
  694. AZStd::variant<int16_t, AZStd::string> testVariant2("ConstMember");
  695. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, testVariant2);
  696. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::lvalue_ref, calledFunc);
  697. }
  698. TEST_F(VariantTest, VisitForwardsLValueMemberVisitorCorrectly_WithMultipleVariants)
  699. {
  700. VariantTestInternal::MemberFuncQualifierCallable callable{};
  701. AZStd::variant<float, double> testVariant3(2.0);
  702. AZStd::variant<AZStd::string_view, const char*> testVariant4("ConstMember");
  703. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, testVariant3, testVariant4);
  704. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::lvalue_ref, calledFunc);
  705. }
  706. // const lvalue visitor
  707. TEST_F(VariantTest, VisitForwardsConstLValueMemberVisitorCorrectly_WithSingleAlternativeVariant)
  708. {
  709. const VariantTestInternal::MemberFuncQualifierCallable callable{};
  710. AZStd::variant<int16_t> testVariant(static_cast<int16_t>(7));
  711. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, testVariant);
  712. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::const_lvalue_ref, calledFunc);
  713. }
  714. TEST_F(VariantTest, VisitForwardsConstLValueMemberVisitorCorrectly_WithMultipleAlternativeVariant)
  715. {
  716. const VariantTestInternal::MemberFuncQualifierCallable callable{};
  717. AZStd::variant<int16_t, AZStd::string> testVariant2("ConstMember");
  718. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, testVariant2);
  719. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::const_lvalue_ref, calledFunc);
  720. }
  721. TEST_F(VariantTest, VisitForwardsConstLValueMemberVisitorCorrectly_WithMultipleVariants)
  722. {
  723. const VariantTestInternal::MemberFuncQualifierCallable callable{};
  724. AZStd::variant<float, double> testVariant3(2.0);
  725. AZStd::variant<AZStd::string_view, const char*> testVariant4("ConstMember");
  726. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, testVariant3, testVariant4);
  727. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::const_lvalue_ref, calledFunc);
  728. }
  729. // non-const rvalue visitor
  730. TEST_F(VariantTest, VisitForwardsRValueMemberVisitorCorrectly_WithSingleAlternativeVariant)
  731. {
  732. VariantTestInternal::MemberFuncQualifierCallable callable{};
  733. AZStd::variant<int16_t> testVariant(static_cast<int16_t>(7));
  734. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(AZStd::move(callable), testVariant);
  735. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::rvalue_ref, calledFunc);
  736. }
  737. TEST_F(VariantTest, VisitForwardsRValueMemberVisitorCorrectly_WithMultipleAlternativeVariant)
  738. {
  739. VariantTestInternal::MemberFuncQualifierCallable callable{};
  740. AZStd::variant<int16_t, AZStd::string> testVariant2("ConstMember");
  741. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(AZStd::move(callable), testVariant2);
  742. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::rvalue_ref, calledFunc);
  743. }
  744. TEST_F(VariantTest, VisitForwardsRValueMemberVisitorCorrectly_WithMultipleVariants)
  745. {
  746. VariantTestInternal::MemberFuncQualifierCallable callable{};
  747. AZStd::variant<float, double> testVariant3(2.0);
  748. AZStd::variant<AZStd::string_view, const char*> testVariant4("ConstMember");
  749. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(AZStd::move(callable), testVariant3, testVariant4);
  750. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::rvalue_ref, calledFunc);
  751. }
  752. // const rvalue visitor
  753. TEST_F(VariantTest, VisitForwardsConstRValueMemberVisitorCorrectly_WithSingleAlternativeVariant)
  754. {
  755. const VariantTestInternal::MemberFuncQualifierCallable callable{};
  756. AZStd::variant<int16_t> testVariant(static_cast<int16_t>(7));
  757. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(AZStd::move(callable), testVariant);
  758. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::const_rvalue_ref, calledFunc);
  759. }
  760. TEST_F(VariantTest, VisitForwardsConstRValueMemberVisitorCorrectly_WithMultiAlternativeVariant)
  761. {
  762. const VariantTestInternal::MemberFuncQualifierCallable callable{};
  763. AZStd::variant<int16_t, AZStd::string> testVariant2("ConstMember");
  764. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(AZStd::move(callable), testVariant2);
  765. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::const_rvalue_ref, calledFunc);
  766. }
  767. TEST_F(VariantTest, VisitForwardsConstRValueMemberVisitorCorrectly_WithMultipleVariants)
  768. {
  769. const VariantTestInternal::MemberFuncQualifierCallable callable{};
  770. AZStd::variant<float, double> testVariant3(2.0);
  771. AZStd::variant<AZStd::string_view, const char*> testVariant4("ConstMember");
  772. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(AZStd::move(callable), testVariant3, testVariant4);
  773. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::const_rvalue_ref, calledFunc);
  774. }
  775. TEST_F(VariantTest, VisitWithExplicitReturnTypeSucceeds)
  776. {
  777. auto returnConstCharPtrVisitor = [](auto&& variantAlt) -> const char*
  778. {
  779. (void)variantAlt;
  780. return AZStd::is_same<AZStd::remove_cvref_t<decltype(variantAlt)>, const char*>::value ? "Boat" : "Willy";
  781. };
  782. AZStd::variant<float, const char*> testVariant1(static_cast<const char*>("Steam"));
  783. auto testResultData = AZStd::visit<AZStd::string_view>(returnConstCharPtrVisitor, testVariant1);
  784. EXPECT_FALSE(testResultData.empty());
  785. EXPECT_EQ("Boat", testResultData);
  786. }
  787. }
  788. namespace VariantQualifier
  789. {
  790. // non-const lvalue variant
  791. TEST_F(VariantTest, VisitForwardsLValueVariantCorrectly_WithSingleAlternativeVariant)
  792. {
  793. VariantTestInternal::ParameterQualifierCallable callable{};
  794. AZStd::variant<int16_t> testVariant(static_cast<int16_t>(7));
  795. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, testVariant);
  796. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::lvalue_ref, calledFunc);
  797. }
  798. TEST_F(VariantTest, VisitForwardsLValueVariantCorrectly_WithMultipleAlternativeVariant)
  799. {
  800. VariantTestInternal::ParameterQualifierCallable callable{};
  801. AZStd::variant<int16_t, AZStd::string> testVariant2("ConstMember");
  802. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, testVariant2);
  803. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::lvalue_ref, calledFunc);
  804. }
  805. TEST_F(VariantTest, VisitForwardsLValueVariantCorrectly_WithMultipleVariants)
  806. {
  807. VariantTestInternal::ParameterQualifierCallable callable{};
  808. AZStd::variant<float, double> testVariant3(2.0);
  809. AZStd::variant<AZStd::string_view, const char*> testVariant4("ConstMember");
  810. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, testVariant3, testVariant4);
  811. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::lvalue_ref, calledFunc);
  812. }
  813. // const lvalue variant
  814. TEST_F(VariantTest, VisitForwardsConstLValueVariantCorrectly_WithSingleAlternativeVariant)
  815. {
  816. VariantTestInternal::ParameterQualifierCallable callable{};
  817. const AZStd::variant<int16_t> testVariant(static_cast<int16_t>(7));
  818. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, testVariant);
  819. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::const_lvalue_ref, calledFunc);
  820. }
  821. TEST_F(VariantTest, VisitForwardsConstLValueVariantCorrectly_WithMultipleAlternativeVariant)
  822. {
  823. VariantTestInternal::ParameterQualifierCallable callable{};
  824. const AZStd::variant<int16_t, AZStd::string> testVariant2("ConstMember");
  825. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, testVariant2);
  826. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::const_lvalue_ref, calledFunc);
  827. }
  828. TEST_F(VariantTest, VisitForwardsConstLValueVariantCorrectly_WithMultipleVariants)
  829. {
  830. VariantTestInternal::ParameterQualifierCallable callable{};
  831. const AZStd::variant<float, double> testVariant3(2.0);
  832. const AZStd::variant<AZStd::string_view, const char*> testVariant4("ConstMember");
  833. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, testVariant3, testVariant4);
  834. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::const_lvalue_ref, calledFunc);
  835. }
  836. // non-const rvalue variant
  837. TEST_F(VariantTest, VisitForwardsRValueVariantCorrectly_WithSingleAlternativeVariant)
  838. {
  839. VariantTestInternal::ParameterQualifierCallable callable{};
  840. AZStd::variant<int16_t> testVariant(static_cast<int16_t>(7));
  841. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, AZStd::move(testVariant));
  842. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::rvalue_ref, calledFunc);
  843. }
  844. TEST_F(VariantTest, VisitForwardsRValueVariantCorrectly_WithMultipleAlternativeVariant)
  845. {
  846. VariantTestInternal::ParameterQualifierCallable callable{};
  847. AZStd::variant<int16_t, AZStd::string> testVariant2("ConstMember");
  848. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, AZStd::move(testVariant2));
  849. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::rvalue_ref, calledFunc);
  850. }
  851. TEST_F(VariantTest, VisitForwardsRValueVariantCorrectly_WithMultipleVariants)
  852. {
  853. VariantTestInternal::ParameterQualifierCallable callable{};
  854. AZStd::variant<float, double> testVariant3(2.0);
  855. const AZStd::variant<AZStd::string_view, const char*> testVariant4("ConstMember");
  856. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, AZStd::move(testVariant3), AZStd::move(testVariant4));
  857. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::rvalue_ref, calledFunc);
  858. }
  859. // const rvalue variant
  860. TEST_F(VariantTest, VisitForwardsConstRValueVariantCorrectly_WithSingleAlternativeVariant)
  861. {
  862. VariantTestInternal::ParameterQualifierCallable callable{};
  863. const AZStd::variant<int16_t> testVariant(static_cast<int16_t>(7));
  864. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, AZStd::move(testVariant));
  865. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::const_rvalue_ref, calledFunc);
  866. }
  867. TEST_F(VariantTest, VisitForwardsConstRValueVariantCorrectly_WithMultipleAlternativeVariant)
  868. {
  869. VariantTestInternal::ParameterQualifierCallable callable{};
  870. const AZStd::variant<int16_t, AZStd::string> testVariant2("ConstMember");
  871. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, AZStd::move(testVariant2));
  872. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::const_rvalue_ref, calledFunc);
  873. }
  874. TEST_F(VariantTest, VisitForwardsConstRValueVariantCorrectly_WithMultipleVariants)
  875. {
  876. VariantTestInternal::ParameterQualifierCallable callable{};
  877. const AZStd::variant<float, double> testVariant3(2.0);
  878. const AZStd::variant<AZStd::string_view, const char*> testVariant4("ConstMember");
  879. VariantTestInternal::MemberFuncQualifiers calledFunc = AZStd::visit(callable, AZStd::move(testVariant3), AZStd::move(testVariant4));
  880. EXPECT_EQ(VariantTestInternal::MemberFuncQualifiers::const_rvalue_ref, calledFunc);
  881. }
  882. }
  883. TEST_F(VariantTest, VisitIsEvaluatedInConstexprContextSucceeds)
  884. {
  885. constexpr VariantTestInternal::ConstexprVisitorHelper constexprHelper{};
  886. using TestVariant = AZStd::variant<uint32_t>;
  887. // variant visiting ends up calling array operator [] which is constexpr but calls AZ_Assert which is not constexpr, so it cannot be solved in a static_assert
  888. constexpr TestVariant testVariant(21);
  889. static_assert(AZStd::visit(constexprHelper, testVariant) == 21, "Constexpr Variant not equal to expected result");
  890. EXPECT_EQ(21, AZStd::visit(constexprHelper, testVariant));
  891. }
  892. TEST_F(VariantTest, VisitWithMultipleAlternativeEvaluatedInConstexprContextSucceeds)
  893. {
  894. constexpr VariantTestInternal::ConstexprVisitorHelper constexprHelper{};
  895. using TestVariant = AZStd::variant<int16_t, int64_t, char>;
  896. // variant visiting ends up calling array operator [] which is constexpr but calls AZ_Assert which is not constexpr, so it cannot be solved in a static_assert
  897. constexpr TestVariant testVariant(static_cast<int64_t>(42LL));
  898. static_assert(AZStd::visit(constexprHelper, testVariant) == 42, "Constexpr Variant not equal to expected result");
  899. EXPECT_EQ(42, AZStd::visit(constexprHelper, testVariant));
  900. }
  901. TEST_F(VariantTest, VisitWithMultipleVariantEvaluatedInConstexprContextSucceeds)
  902. {
  903. using TestVariant1 = AZStd::variant<int32_t>;
  904. using TestVariant2 = AZStd::variant<int32_t, char*, int64_t>;
  905. using TestVariant3 = AZStd::variant<bool, uint32_t, int32_t>;
  906. // variant visiting ends up calling array operator [] which is constexpr but calls AZ_Assert which is not constexpr, so it cannot be solved in a static_assert
  907. constexpr TestVariant1 testVariant1;
  908. constexpr TestVariant2 testVariant2(nullptr);
  909. constexpr TestVariant3 testVariant3;
  910. static_assert(AZStd::visit(VariantTestInternal::VariadicVariantSizeof{}, testVariant1, testVariant2, testVariant3) == 3,
  911. "Sizeof visitor should return the same number of variants supplied to it");
  912. EXPECT_EQ(3, AZStd::visit(VariantTestInternal::VariadicVariantSizeof{}, testVariant1, testVariant2, testVariant3));
  913. }
  914. TEST_F(VariantTest, VisitorAcceptsNonConstLValueReferenceSucceeds)
  915. {
  916. AZStd::variant<VariantTestInternal::TrivialAlt> variantAlt;
  917. auto nonConstLRefVisitor = [](VariantTestInternal::TrivialAlt&)
  918. {
  919. };
  920. AZStd::visit(nonConstLRefVisitor, variantAlt);
  921. }
  922. TEST_F(VariantTest, VisitorAcceptsNonConstRValueReferenceSucceeds)
  923. {
  924. AZStd::variant<VariantTestInternal::TrivialAlt> variantAlt;
  925. auto nonConstRRefVisitor = [](VariantTestInternal::TrivialAlt&&)
  926. {
  927. };
  928. AZStd::visit(nonConstRRefVisitor, AZStd::move(variantAlt));
  929. }
  930. namespace HashFunctions
  931. {
  932. TEST_F(VariantTest, HashMonostateSucceeds)
  933. {
  934. AZStd::monostate testMonostate1;
  935. size_t resultHash1 = AZStd::hash<AZStd::monostate>{}(testMonostate1);
  936. const AZStd::monostate testMonostate2 {};
  937. size_t resultHash2 = AZStd::hash<AZStd::monostate>{}(testMonostate2);
  938. EXPECT_EQ(resultHash1, resultHash2);
  939. }
  940. TEST_F(VariantTest, HashVariantAlternativeOfSameTypeHashesToDifferentResults)
  941. {
  942. using TestVariant = AZStd::variant<AZStd::monostate, AZStd::monostate>;
  943. TestVariant testVariant1(AZStd::in_place_index_t<0>{});
  944. TestVariant testVariant2(AZStd::in_place_index_t<1>{});
  945. size_t resultHash1 = AZStd::hash<TestVariant>{}(testVariant1);
  946. size_t resultHash2 = AZStd::hash<TestVariant>{}(testVariant2);
  947. EXPECT_NE(resultHash1, resultHash2);
  948. }
  949. TEST_F(VariantTest, HashVariantDifferentValuesForSameAlternativeHashesToDifferentResults)
  950. {
  951. using TestVariant = AZStd::variant<int64_t, int32_t, int64_t>;
  952. TestVariant testVariant1(AZStd::in_place_index_t<0>{}, 42);
  953. TestVariant testVariant2(AZStd::in_place_index_t<1>{}, 43);
  954. size_t resultHash1 = AZStd::hash<TestVariant>{}(testVariant1);
  955. size_t resultHash2 = AZStd::hash<TestVariant>{}(testVariant2);
  956. EXPECT_NE(resultHash1, resultHash2);
  957. }
  958. TEST_F(VariantTest, HashVariantCopyOfVariantHashesToSameResult)
  959. {
  960. using TestVariant = AZStd::variant<int64_t, int32_t, int64_t>;
  961. TestVariant testVariant1(AZStd::in_place_index_t<0>{}, 47);
  962. TestVariant copyVariant(testVariant1);
  963. size_t resultHash1 = AZStd::hash<TestVariant>{}(testVariant1);
  964. size_t resultHash2 = AZStd::hash<TestVariant>{}(copyVariant);
  965. EXPECT_EQ(resultHash1, resultHash2);
  966. }
  967. TEST_F(VariantTest, HashVariantDefaultConstructedVariantHashesToSameValue)
  968. {
  969. using TestVariant = AZStd::variant<int64_t, int32_t, int64_t>;
  970. TestVariant testVariant1;
  971. TestVariant testVariant2;
  972. size_t resultHash1 = AZStd::hash<TestVariant>{}(testVariant1);
  973. size_t resultHash2 = AZStd::hash<TestVariant>{}(testVariant2);
  974. EXPECT_EQ(resultHash1, resultHash2);
  975. }
  976. TEST_F(VariantTest, HashVariantHashRemainsStableForSameValue)
  977. {
  978. using TestVariant = AZStd::variant<int64_t, int32_t, int64_t>;
  979. constexpr int64_t initialValue = 84;
  980. TestVariant testVariant1(AZStd::in_place_index_t<2>{}, initialValue);
  981. size_t expectedHash = AZStd::hash<TestVariant>{}(testVariant1);
  982. AZStd::get<2>(testVariant1) = 74;
  983. size_t resultHash = AZStd::hash<TestVariant>{}(testVariant1);
  984. EXPECT_NE(expectedHash, resultHash);
  985. AZStd::get<2>(testVariant1) = initialValue;
  986. resultHash = AZStd::hash<TestVariant>{}(testVariant1);
  987. EXPECT_EQ(expectedHash, resultHash);
  988. }
  989. }
  990. namespace RelationalOperators
  991. {
  992. // equal
  993. TEST_F(VariantTest, OperatorEqualForVariantWithSameAlternativeAndValueSucceeds)
  994. {
  995. using TestVariant = AZStd::variant<int64_t, int32_t>;
  996. TestVariant testVariant1(AZStd::in_place_index_t<0>{}, 7);
  997. TestVariant testVariant2(AZStd::in_place_index_t<0>{}, 7);
  998. EXPECT_TRUE(testVariant1 == testVariant2);
  999. }
  1000. TEST_F(VariantTest, OperatorEqualForVariantWithSameAlternativeAndDifferentValueFails)
  1001. {
  1002. using TestVariant = AZStd::variant<int64_t, int32_t>;
  1003. TestVariant testVariant1(AZStd::in_place_index_t<0>{}, 7);
  1004. TestVariant testVariant2(AZStd::in_place_index_t<0>{}, 8);
  1005. EXPECT_FALSE(testVariant1 == testVariant2);
  1006. }
  1007. TEST_F(VariantTest, OperatorEqualForVariantWithDifferentAlternativeFails)
  1008. {
  1009. using TestVariant = AZStd::variant<int64_t, int32_t>;
  1010. TestVariant testVariant1(AZStd::in_place_index_t<0>{}, 7);
  1011. TestVariant testVariant2(AZStd::in_place_index_t<1>{}, 7);
  1012. EXPECT_FALSE(testVariant1 == testVariant2);
  1013. }
  1014. // not-equal
  1015. TEST_F(VariantTest, OperatorNotEqualForVariantWithSameAlternativeAndValueFails)
  1016. {
  1017. using TestVariant = AZStd::variant<int64_t, int32_t>;
  1018. TestVariant testVariant1(AZStd::in_place_index_t<0>{}, 7);
  1019. TestVariant testVariant2(AZStd::in_place_index_t<0>{}, 7);
  1020. EXPECT_FALSE(testVariant1 != testVariant2);
  1021. }
  1022. TEST_F(VariantTest, OperatorNotEqualForVariantWithSameAlternativeAndDifferentValueSucceeds)
  1023. {
  1024. using TestVariant = AZStd::variant<int64_t, int32_t>;
  1025. TestVariant testVariant1(AZStd::in_place_index_t<0>{}, 7);
  1026. TestVariant testVariant2(AZStd::in_place_index_t<0>{}, 8);
  1027. EXPECT_TRUE(testVariant1 != testVariant2);
  1028. }
  1029. TEST_F(VariantTest, OperatorNotEqualForVariantWithDifferentAlternativeSucceeds)
  1030. {
  1031. using TestVariant = AZStd::variant<int8_t, int32_t>;
  1032. TestVariant testVariant1(AZStd::in_place_index_t<0>{}, static_cast<int8_t>(7));
  1033. TestVariant testVariant2(AZStd::in_place_index_t<1>{}, 7);
  1034. EXPECT_TRUE(testVariant1 != testVariant2);
  1035. }
  1036. // less
  1037. TEST_F(VariantTest, OperatorLessForVariantWithSameAlternativeAndValueFails)
  1038. {
  1039. using TestVariant = AZStd::variant<int64_t, int32_t>;
  1040. TestVariant testVariant1(AZStd::in_place_index_t<0>{}, 7);
  1041. TestVariant testVariant2(AZStd::in_place_index_t<0>{}, 7);
  1042. EXPECT_FALSE(testVariant1 < testVariant2);
  1043. }
  1044. TEST_F(VariantTest, OperatorLessForVariantWithSameAlternativeAndDifferentValueSucceeds)
  1045. {
  1046. using TestVariant = AZStd::variant<int64_t, int32_t>;
  1047. TestVariant testVariant1(AZStd::in_place_index_t<1>{}, 7);
  1048. TestVariant testVariant2(AZStd::in_place_index_t<1>{}, 8);
  1049. EXPECT_TRUE(testVariant1 < testVariant2);
  1050. EXPECT_FALSE(testVariant2 < testVariant1);
  1051. }
  1052. TEST_F(VariantTest, OperatorLessForVariantWithDifferentAlternativeSucceeds)
  1053. {
  1054. using TestVariant = AZStd::variant<int64_t, int32_t>;
  1055. TestVariant testVariant1(AZStd::in_place_index_t<0>{}, 10000);
  1056. TestVariant testVariant2(AZStd::in_place_index_t<1>{}, 7);
  1057. EXPECT_TRUE(testVariant1 < testVariant2);
  1058. EXPECT_FALSE(testVariant2 < testVariant1);
  1059. }
  1060. // greater
  1061. TEST_F(VariantTest, OperatorGreaterForVariantWithSameAlternativeAndValueFails)
  1062. {
  1063. using TestVariant = AZStd::variant<int64_t, int32_t>;
  1064. TestVariant testVariant1(AZStd::in_place_index_t<0>{}, 7);
  1065. TestVariant testVariant2(AZStd::in_place_index_t<0>{}, 7);
  1066. EXPECT_FALSE(testVariant1 > testVariant2);
  1067. }
  1068. TEST_F(VariantTest, OperatorGreaterForVariantWithSameAlternativeAndDifferentValueSucceeds)
  1069. {
  1070. using TestVariant = AZStd::variant<int8_t, int32_t>;
  1071. TestVariant testVariant1(AZStd::in_place_index_t<1>{}, 427);
  1072. TestVariant testVariant2(AZStd::in_place_index_t<1>{}, 321);
  1073. EXPECT_TRUE(testVariant1 > testVariant2);
  1074. EXPECT_FALSE(testVariant2 > testVariant1);
  1075. }
  1076. TEST_F(VariantTest, OperatorGreaterForVariantWithDifferentAlternativeSucceeds)
  1077. {
  1078. using TestVariant = AZStd::variant<int64_t, int32_t>;
  1079. TestVariant testVariant1(AZStd::in_place_index_t<1>{}, -5000);
  1080. TestVariant testVariant2(AZStd::in_place_index_t<0>{}, 17);
  1081. EXPECT_TRUE(testVariant1 > testVariant2);
  1082. EXPECT_FALSE(testVariant2 > testVariant1);
  1083. }
  1084. // less equal
  1085. TEST_F(VariantTest, OperatorLessEqualForVariantWithSameAlternativeAndValueSucceeds)
  1086. {
  1087. using TestVariant = AZStd::variant<int64_t, int32_t>;
  1088. TestVariant testVariant1(AZStd::in_place_index_t<0>{}, 7);
  1089. TestVariant testVariant2(AZStd::in_place_index_t<0>{}, 7);
  1090. EXPECT_TRUE(testVariant1 <= testVariant2);
  1091. }
  1092. TEST_F(VariantTest, OperatorLessEqualForVariantWithSameAlternativeAndDifferentValueSucceeds)
  1093. {
  1094. using TestVariant = AZStd::variant<int8_t, int32_t>;
  1095. TestVariant testVariant1(AZStd::in_place_index_t<1>{}, 19);
  1096. TestVariant testVariant2(AZStd::in_place_index_t<1>{}, 21);
  1097. TestVariant testVariant3(AZStd::in_place_index_t<1>{}, 21);
  1098. EXPECT_TRUE(testVariant1 <= testVariant2);
  1099. EXPECT_FALSE(testVariant2 <= testVariant1);
  1100. EXPECT_TRUE(testVariant2 <= testVariant3);
  1101. }
  1102. TEST_F(VariantTest, OperatorLessEqualForVariantWithDifferentAlternativeSucceeds)
  1103. {
  1104. using TestVariant = AZStd::variant<bool, float>;
  1105. TestVariant testVariant1(AZStd::in_place_index_t<0>{}, false);
  1106. TestVariant testVariant2(AZStd::in_place_index_t<1>{}, 16.0f);
  1107. EXPECT_TRUE(testVariant1 <= testVariant2);
  1108. EXPECT_FALSE(testVariant2 <= testVariant1);
  1109. }
  1110. // greater equal
  1111. TEST_F(VariantTest, OperatorGreaterEqualForVariantWithSameAlternativeAndValueSucceeds)
  1112. {
  1113. using TestVariant = AZStd::variant<AZStd::string, int32_t>;
  1114. TestVariant testVariant1(AZStd::in_place_index_t<0>{}, "Hello");
  1115. TestVariant testVariant2(AZStd::in_place_index_t<0>{}, "Hello");
  1116. EXPECT_TRUE(testVariant1 >= testVariant2);
  1117. }
  1118. TEST_F(VariantTest, OperatorGreaterEqualForVariantWithSameAlternativeAndDifferentValueSucceeds)
  1119. {
  1120. using TestVariant = AZStd::variant<int16_t, AZStd::string>;
  1121. TestVariant testVariant1(AZStd::in_place_index_t<1>{}, "World");
  1122. TestVariant testVariant2(AZStd::in_place_index_t<1>{}, "Worlc");
  1123. TestVariant testVariant3(AZStd::in_place_index_t<1>{}, "Worlc");
  1124. EXPECT_TRUE(testVariant1 >= testVariant2);
  1125. EXPECT_FALSE(testVariant2 >= testVariant1);
  1126. EXPECT_TRUE(testVariant2 >= testVariant3);
  1127. }
  1128. TEST_F(VariantTest, OperatorGreaterEqualForVariantWithDifferentAlternativeSucceeds)
  1129. {
  1130. using TestVariant = AZStd::variant<void*, float>;
  1131. TestVariant testVariant1(AZStd::in_place_index_t<1>{}, 34.5f);
  1132. TestVariant testVariant2(AZStd::in_place_index_t<0>{}, nullptr);
  1133. EXPECT_TRUE(testVariant1 >= testVariant2);
  1134. EXPECT_FALSE(testVariant2 >= testVariant1);
  1135. }
  1136. }
  1137. namespace VariantSwap
  1138. {
  1139. TEST_F(VariantTest, SwapSameAlternativeSucceeds)
  1140. {
  1141. using TestVariant = AZStd::variant<AZStd::string, int32_t>;
  1142. TestVariant testVariant1(AZStd::in_place_index_t<0>{}, "Hello");
  1143. TestVariant testVariant2(AZStd::in_place_index_t<0>{}, "World");
  1144. testVariant1.swap(testVariant2);
  1145. EXPECT_EQ("World", AZStd::get<0>(testVariant1));
  1146. EXPECT_EQ("Hello", AZStd::get<0>(testVariant2));
  1147. }
  1148. TEST_F(VariantTest, SwapDifferentAlternativeSucceeds)
  1149. {
  1150. using TestVariant = AZStd::variant<AZStd::string, int32_t>;
  1151. TestVariant testVariant1(AZStd::in_place_index_t<1>{}, 501);
  1152. TestVariant testVariant2(AZStd::in_place_index_t<0>{}, "TestCode");
  1153. testVariant1.swap(testVariant2);
  1154. ASSERT_EQ(0, testVariant1.index());
  1155. EXPECT_EQ("TestCode", AZStd::get<0>(testVariant1));
  1156. ASSERT_EQ(1, testVariant2.index());
  1157. EXPECT_EQ(501, AZStd::get<1>(testVariant2));
  1158. }
  1159. TEST_F(VariantTest, SwapWithMoveOnlyTypeSucceeds)
  1160. {
  1161. using TestVariant = AZStd::variant<VariantTestInternal::MoveOnly>;
  1162. TestVariant testVariant1;
  1163. AZStd::get<0>(testVariant1).m_value = 10;
  1164. TestVariant testVariant2;
  1165. AZStd::get<0>(testVariant2).m_value = 20;
  1166. testVariant1.swap(testVariant2);
  1167. EXPECT_EQ(20, AZStd::get<0>(testVariant1).m_value);
  1168. EXPECT_EQ(10, AZStd::get<0>(testVariant2).m_value);
  1169. EXPECT_NE(0, AZStd::get<0>(testVariant1).m_moveAssignmentCounter);
  1170. EXPECT_NE(0, AZStd::get<0>(testVariant2).m_moveAssignmentCounter);
  1171. }
  1172. }
  1173. }