Any.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940
  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. // Written with help from libcxx's any tests
  9. // https://github.com/llvm-mirror/libcxx/tree/7175a079211ec78c8232d9d55fa4c1f9eeae803d/test/std/experimental/any
  10. #include <AzCore/std/any.h>
  11. #include "UserTypes.h"
  12. using AZStd::any;
  13. using AZStd::any_cast;
  14. using AZStd::any_numeric_cast;
  15. namespace UnitTest
  16. {
  17. using Small0 = CreationCounter<8, 0>;
  18. using Small1 = CreationCounter<8, 1>;
  19. using Large0 = CreationCounter<256, 0>;
  20. using Large1 = CreationCounter<256, 1>;
  21. using Align0 = CreationCounter<8, 0, 64>;
  22. using Align1 = CreationCounter<8, 1, 64>;
  23. }
  24. // Specialize for the type's we're using to get comprehensible output
  25. namespace testing
  26. {
  27. namespace internal
  28. {
  29. #define DEF_GTN_SINGLE(Struct) template<> std::string GetTypeName<::UnitTest::Struct>() { return #Struct; }
  30. #define DEF_GTN_PAIR(Struct1, Struct2) template<> std::string GetTypeName<AZStd::pair<::UnitTest::Struct1, ::UnitTest::Struct2>>() { return #Struct1 ", " #Struct2; }
  31. DEF_GTN_SINGLE(Small0);
  32. DEF_GTN_SINGLE(Large0);
  33. DEF_GTN_SINGLE(Align0);
  34. DEF_GTN_PAIR(Small0, Small1);
  35. DEF_GTN_PAIR(Large0, Large1);
  36. DEF_GTN_PAIR(Align0, Align1);
  37. DEF_GTN_PAIR(Small0, Large0);
  38. DEF_GTN_PAIR(Small0, Align0);
  39. DEF_GTN_PAIR(Large0, Small0);
  40. DEF_GTN_PAIR(Large0, Align0);
  41. DEF_GTN_PAIR(Align0, Small0);
  42. DEF_GTN_PAIR(Align0, Large0);
  43. #undef DEF_GTN_SINGLE
  44. #undef DEF_GTN_PAIR
  45. }
  46. }
  47. namespace UnitTest
  48. {
  49. //////////////////////////////////////////////////////////////////////////
  50. // Fixtures
  51. // Fixture for non-typed tests
  52. class AnyTest
  53. : public LeakDetectionFixture
  54. { };
  55. // Fixture for tests with 1 type
  56. template<typename TestStruct>
  57. class AnySizedTest
  58. : public LeakDetectionFixture
  59. {
  60. protected:
  61. void SetUp() override
  62. {
  63. LeakDetectionFixture::SetUp();
  64. TestStruct::Reset();
  65. }
  66. };
  67. using AnySizedTestTypes = ::testing::Types<Small0, Large0, Align0>;
  68. TYPED_TEST_SUITE(AnySizedTest, AnySizedTestTypes);
  69. // Fixture for tests with 2 types (for converting between types)
  70. template <typename StructPair>
  71. class AnyConversionTest
  72. : public LeakDetectionFixture
  73. {
  74. public:
  75. using LHS = typename StructPair::first_type;
  76. using RHS = typename StructPair::second_type;
  77. void SetUp() override
  78. {
  79. LeakDetectionFixture::SetUp();
  80. LHS::Reset();
  81. RHS::Reset();
  82. }
  83. };
  84. using AnyConversionTestTypes = ::testing::Types <
  85. AZStd::pair<Small0, Small1>, // Small -> Small
  86. AZStd::pair<Large0, Large1>, // Large -> Large
  87. AZStd::pair<Align0, Align1>, // Align -> Align
  88. AZStd::pair<Small0, Large0>, // Small -> Large
  89. AZStd::pair<Small0, Align0>, // Small -> Align
  90. AZStd::pair<Large0, Small0>, // Large -> Small
  91. AZStd::pair<Large0, Align0>, // Large -> Align
  92. AZStd::pair<Align0, Small0>, // Align -> Small
  93. AZStd::pair<Align0, Large0> // Align -> Large
  94. >;
  95. TYPED_TEST_SUITE(AnyConversionTest, AnyConversionTestTypes);
  96. //////////////////////////////////////////////////////////////////////////
  97. // Tests for constructors
  98. namespace Constructor
  99. {
  100. // Construct empty
  101. TEST_F(AnyTest, Any_EmptyConstruct_IsEmpty)
  102. {
  103. const any a;
  104. ASSERT_TRUE(a.empty());
  105. }
  106. // Construct via copy value
  107. TYPED_TEST(AnySizedTest, Any_ConstructFromData_Copy)
  108. {
  109. {
  110. TypeParam t;
  111. EXPECT_EQ(TypeParam::s_count, 1);
  112. any any1(t);
  113. EXPECT_EQ(TypeParam::s_count, 2);
  114. EXPECT_EQ(TypeParam::s_copied, 1);
  115. EXPECT_EQ(TypeParam::s_moved, 0);
  116. }
  117. }
  118. // Construct via move value
  119. TYPED_TEST(AnySizedTest, Any_ConstructFromData_Move)
  120. {
  121. {
  122. TypeParam t;
  123. EXPECT_EQ(TypeParam::s_count, 1);
  124. any any1(AZStd::move(t));
  125. EXPECT_EQ(TypeParam::s_count, 2);
  126. EXPECT_EQ(TypeParam::s_copied, 0);
  127. EXPECT_EQ(TypeParam::s_moved, 1);
  128. }
  129. EXPECT_EQ(TypeParam::s_count, 0);
  130. }
  131. // Copy empty
  132. TEST_F(AnyTest, Any_CopyConstructEmpty_IsEmpty)
  133. {
  134. const any any1;
  135. const any any2(any1);
  136. EXPECT_TRUE(any1.empty());
  137. EXPECT_TRUE(any2.empty());
  138. }
  139. // Copy with data
  140. TYPED_TEST(AnySizedTest, Any_CopyConstructValid_IsValid)
  141. {
  142. any any1(TypeParam(36));
  143. EXPECT_EQ(TypeParam::s_count, 1);
  144. EXPECT_EQ(TypeParam::s_copied, 0);
  145. EXPECT_EQ(TypeParam::s_moved, 1);
  146. EXPECT_EQ(any_cast<TypeParam&>(any1).val(), 36);
  147. any any2(any1);
  148. EXPECT_EQ(TypeParam::s_copied, 1);
  149. EXPECT_EQ(TypeParam::s_count, 2);
  150. EXPECT_EQ(TypeParam::s_moved, 1);
  151. // Modify a and check that any2 is unchanged
  152. any_cast<TypeParam&>(any1).val() = -1;
  153. EXPECT_EQ(any_cast<TypeParam&>(any1).val(), -1);
  154. EXPECT_EQ(any_cast<TypeParam&>(any2).val(), 36);
  155. // modify any2 and check that any1 is unchanged
  156. any_cast<TypeParam&>(any2).val() = 75;
  157. EXPECT_EQ(any_cast<TypeParam&>(any1).val(), -1);
  158. EXPECT_EQ(any_cast<TypeParam&>(any2).val(), 75);
  159. // clear a and check that a2 is unchanged
  160. any1.clear();
  161. EXPECT_TRUE(any1.empty());
  162. EXPECT_EQ(any_cast<TypeParam&>(any2).val(), 75);
  163. }
  164. // Move empty
  165. TEST_F(AnyTest, Any_MoveConstructEmpty_IsEmpty)
  166. {
  167. const any any1;
  168. const any any2(AZStd::move(any1));
  169. EXPECT_TRUE(any1.empty());
  170. EXPECT_TRUE(any2.empty());
  171. }
  172. // Move with data
  173. TYPED_TEST(AnySizedTest, Any_MoveConstructValid_IsValid)
  174. {
  175. any any1(TypeParam(42));
  176. EXPECT_EQ(TypeParam::s_count, 1);
  177. EXPECT_EQ(TypeParam::s_copied, 0);
  178. EXPECT_EQ(TypeParam::s_moved, 1);
  179. any any2(std::move(any1));
  180. EXPECT_GT(TypeParam::s_moved, 1); // zero or more move operations can be performed.
  181. EXPECT_EQ(TypeParam::s_copied, 0); // no copies can be performed.
  182. EXPECT_EQ(TypeParam::s_count, 1); // Only one instance may remain.
  183. EXPECT_TRUE(any1.empty()); // Moves are always destructive.
  184. EXPECT_EQ(any_cast<TypeParam&>(any2).val(), 42);
  185. }
  186. // Forward with data
  187. TYPED_TEST(AnySizedTest, Any_ForwardConstructValid_IsValid)
  188. {
  189. any any1(AZStd::in_place_type_t<TypeParam>(), 55);
  190. EXPECT_EQ(1, TypeParam::s_count);
  191. EXPECT_EQ(0, TypeParam::s_copied);
  192. EXPECT_EQ(0, TypeParam::s_moved);
  193. any any2(AZStd::in_place_type_t<TypeParam>(), AZStd::initializer_list<int>{ 55 });
  194. EXPECT_EQ(2, TypeParam::s_count);
  195. EXPECT_EQ(0, TypeParam::s_moved);
  196. EXPECT_EQ(0, TypeParam::s_copied);
  197. EXPECT_EQ(any_cast<TypeParam&>(any1).val(), any_cast<TypeParam&>(any2).val());
  198. }
  199. // make_any helper forward functions
  200. TYPED_TEST(AnySizedTest, Any_MakeAnyForwarder_IsValid)
  201. {
  202. any any1 = AZStd::make_any<TypeParam>(24);
  203. EXPECT_EQ(1, TypeParam::s_count);
  204. EXPECT_EQ(0, TypeParam::s_copied);
  205. EXPECT_EQ(0, TypeParam::s_moved);
  206. any any2 = AZStd::make_any<TypeParam, int>({ 24 });
  207. EXPECT_EQ(2, TypeParam::s_count);
  208. EXPECT_EQ(0, TypeParam::s_moved);
  209. EXPECT_EQ(0, TypeParam::s_copied);
  210. EXPECT_EQ(any_cast<TypeParam&>(any1).val(), any_cast<TypeParam&>(any2).val());
  211. }
  212. template <typename ValueType>
  213. void InplaceAnyTypeInfo(AZStd::any::Action action, any* dest, const any*)
  214. {
  215. switch (action)
  216. {
  217. case any::Action::Reserve:
  218. // If doing small buffer optimization, no need to validate anything
  219. if (dest->get_type_info().m_useHeap)
  220. {
  221. // Allocate space for object on heap
  222. AZStd::allocator systemAllocator;
  223. *reinterpret_cast<void**>(dest) = systemAllocator.allocate(sizeof(ValueType), alignof(ValueType));
  224. }
  225. break;
  226. case any::Action::Construct:
  227. break;
  228. case any::Action::Copy:
  229. case any::Action::Move:
  230. ADD_FAILURE() << "Copy/Move Constructor should not be getting invoke in the InPlace test";
  231. break;
  232. case any::Action::Destruct:
  233. break;
  234. case any::Action::Destroy:
  235. // Call the destructor
  236. reinterpret_cast<ValueType*>(AZStd::any_cast<void>(dest))->~ValueType();
  237. // Clear memory
  238. if (dest->get_type_info().m_useHeap)
  239. {
  240. AZStd::allocator systemAllocator;
  241. systemAllocator.deallocate(AZStd::any_cast<void>(dest), sizeof(ValueType), alignof(ValueType));
  242. }
  243. break;
  244. default:
  245. ADD_FAILURE() << "Default case should never get invoked";
  246. }
  247. }
  248. TEST_F(AnyTest, Any_CustomTypeInfoConstructorWithInplace_IsValid)
  249. {
  250. using VectorType = AZStd::vector<int>;
  251. AZStd::any::type_info vectorTypeInfo;
  252. vectorTypeInfo.m_id = azrtti_typeid<VectorType>();
  253. vectorTypeInfo.m_isPointer = false;
  254. vectorTypeInfo.m_useHeap = sizeof(VectorType) > AZStd::Internal::ANY_SBO_BUF_SIZE;
  255. vectorTypeInfo.m_handler = &InplaceAnyTypeInfo<VectorType>;
  256. any vectorAny(vectorTypeInfo, AZStd::in_place_type_t<VectorType>{}, 3, 17);
  257. EXPECT_TRUE(vectorAny.is<VectorType>());
  258. VectorType& vectorRef = AZStd::any_cast<VectorType&>(vectorAny);
  259. EXPECT_EQ(3, vectorRef.size());
  260. EXPECT_EQ(17, vectorRef[0]);
  261. EXPECT_EQ(17, vectorRef[1]);
  262. EXPECT_EQ(17, vectorRef[2]);
  263. }
  264. TEST_F(AnyTest, Any_CustomTypeInfoConstructorWithInitializerListAndInplace_IsValid)
  265. {
  266. using VectorType = AZStd::vector<int>;
  267. AZStd::any::type_info vectorTypeInfo;
  268. vectorTypeInfo.m_id = azrtti_typeid<VectorType>();
  269. vectorTypeInfo.m_isPointer = false;
  270. vectorTypeInfo.m_useHeap = sizeof(VectorType) > AZStd::Internal::ANY_SBO_BUF_SIZE;
  271. vectorTypeInfo.m_handler = &InplaceAnyTypeInfo<VectorType>;
  272. any vectorAny(vectorTypeInfo, AZStd::in_place_type_t<VectorType>{}, { 1, 2, 3, 4 });
  273. EXPECT_TRUE(vectorAny.is<VectorType>());
  274. VectorType& vectorRef = AZStd::any_cast<VectorType&>(vectorAny);
  275. EXPECT_EQ(4, vectorRef.size());
  276. EXPECT_EQ(1, vectorRef[0]);
  277. EXPECT_EQ(2, vectorRef[1]);
  278. EXPECT_EQ(3, vectorRef[2]);
  279. EXPECT_EQ(4, vectorRef[3]);
  280. }
  281. }
  282. //////////////////////////////////////////////////////////////////////////
  283. // Tests for assignment operator
  284. namespace Assignment
  285. {
  286. // Test copy assign other any
  287. TYPED_TEST(AnyConversionTest, Any_CopyAssignAny_IsValid)
  288. {
  289. using LHS = typename TestFixture::LHS;
  290. using RHS = typename TestFixture::RHS;
  291. {
  292. any lhs(LHS(1));
  293. any const rhs(RHS(2));
  294. EXPECT_EQ(LHS::s_count, 1);
  295. EXPECT_EQ(RHS::s_count, 1);
  296. EXPECT_EQ(RHS::s_copied, 0);
  297. lhs = rhs;
  298. EXPECT_EQ(RHS::s_copied, 1);
  299. EXPECT_EQ(LHS::s_count, 0);
  300. EXPECT_EQ(RHS::s_count, 2);
  301. EXPECT_EQ(any_cast<const RHS&>(lhs).val(), 2);
  302. EXPECT_EQ(any_cast<const RHS&>(rhs).val(), 2);
  303. }
  304. EXPECT_EQ(LHS::s_count, 0);
  305. EXPECT_EQ(RHS::s_count, 0);
  306. }
  307. // Test move assign other any
  308. TYPED_TEST(AnyConversionTest, Any_MoveAssignAny_IsValid)
  309. {
  310. using LHS = typename TestFixture::LHS;
  311. using RHS = typename TestFixture::RHS;
  312. {
  313. any lhs(LHS(1));
  314. any rhs(RHS(2));
  315. EXPECT_EQ(LHS::s_count, 1);
  316. EXPECT_EQ(RHS::s_count, 1);
  317. EXPECT_EQ(RHS::s_moved, 1);
  318. lhs = AZStd::move(rhs);
  319. EXPECT_GT(RHS::s_moved, 1);
  320. EXPECT_EQ(RHS::s_copied, 0);
  321. EXPECT_EQ(LHS::s_count, 0);
  322. EXPECT_EQ(RHS::s_count, 1);
  323. EXPECT_EQ(any_cast<RHS&>(lhs).val(), 2);
  324. EXPECT_TRUE(rhs.empty());
  325. }
  326. EXPECT_EQ(LHS::s_count, 0);
  327. EXPECT_EQ(RHS::s_count, 0);
  328. }
  329. // Test copy assign other any
  330. TYPED_TEST(AnySizedTest, Any_CopyAssignValue_IsValid)
  331. {
  332. {
  333. any lhs;
  334. TypeParam rhs(42);
  335. EXPECT_EQ(TypeParam::s_count, 1);
  336. EXPECT_EQ(TypeParam::s_copied, 0);
  337. lhs = rhs;
  338. EXPECT_EQ(TypeParam::s_count, 2);
  339. EXPECT_EQ(TypeParam::s_copied, 1);
  340. EXPECT_GT(TypeParam::s_moved, 0);
  341. EXPECT_EQ(any_cast<const TypeParam&>(lhs).val(), 42);
  342. }
  343. EXPECT_EQ(TypeParam::s_count, 0);
  344. }
  345. // Test move assign other any
  346. TYPED_TEST(AnySizedTest, Any_MoveAssignValue_IsValid)
  347. {
  348. {
  349. any lhs;
  350. TypeParam rhs(42);
  351. EXPECT_EQ(TypeParam::s_count, 1);
  352. EXPECT_EQ(TypeParam::s_moved, 0);
  353. lhs = AZStd::move(rhs);
  354. EXPECT_EQ(TypeParam::s_count, 2);
  355. EXPECT_EQ(TypeParam::s_copied, 0);
  356. EXPECT_GT(TypeParam::s_moved, 1);
  357. EXPECT_EQ(any_cast<TypeParam&>(lhs).val(), 42);
  358. }
  359. EXPECT_EQ(TypeParam::s_count, 0);
  360. }
  361. // Test copy assign other any, and that old value is destroyed
  362. TYPED_TEST(AnyConversionTest, Any_CopyAssignAny_OldIsDestroyed)
  363. {
  364. using LHS = typename TestFixture::LHS;
  365. using RHS = typename TestFixture::RHS;
  366. {
  367. any lhs(LHS(1));
  368. any const rhs(RHS(2));
  369. EXPECT_EQ(LHS::s_count, 1);
  370. EXPECT_EQ(RHS::s_count, 1);
  371. EXPECT_EQ(RHS::s_copied, 0);
  372. lhs = rhs;
  373. EXPECT_EQ(RHS::s_copied, 1);
  374. EXPECT_EQ(LHS::s_count, 0);
  375. EXPECT_EQ(RHS::s_count, 2);
  376. EXPECT_EQ(any_cast<const RHS&>(lhs).val(), 2);
  377. EXPECT_EQ(any_cast<const RHS&>(rhs).val(), 2);
  378. }
  379. EXPECT_EQ(LHS::s_count, 0);
  380. EXPECT_EQ(RHS::s_count, 0);
  381. }
  382. // Test copy assign empty any, and that old value is destroyed
  383. TYPED_TEST(AnySizedTest, Any_CopyAssignEmptyAny_OldIsDestroyed)
  384. {
  385. {
  386. any lhs(TypeParam(1));
  387. any const rhs;
  388. EXPECT_EQ(TypeParam::s_count, 1);
  389. EXPECT_EQ(TypeParam::s_copied, 0);
  390. lhs = rhs;
  391. EXPECT_EQ(TypeParam::s_copied, 0);
  392. EXPECT_EQ(TypeParam::s_count, 0);
  393. EXPECT_TRUE(lhs.empty());
  394. EXPECT_TRUE(rhs.empty());
  395. }
  396. EXPECT_EQ(TypeParam::s_count, 0);
  397. }
  398. // Test copy assign empty self any
  399. TEST_F(AnyTest, Any_CopyAssignSelfEmpty_IsEmpty)
  400. {
  401. any a;
  402. AZ_PUSH_DISABLE_WARNING(, "-Wself-assign-overloaded")
  403. a = a;
  404. AZ_POP_DISABLE_WARNING
  405. EXPECT_TRUE(a.empty());
  406. }
  407. // Test copy assign self any
  408. TYPED_TEST(AnySizedTest, Any_CopyAssignSelf_IsNoop)
  409. {
  410. {
  411. any a((TypeParam(1)));
  412. EXPECT_EQ(TypeParam::s_count, 1);
  413. AZ_PUSH_DISABLE_WARNING(, "-Wself-assign-overloaded")
  414. a = a;
  415. AZ_POP_DISABLE_WARNING
  416. EXPECT_EQ(TypeParam::s_count, 1);
  417. EXPECT_EQ(any_cast<const TypeParam&>(a).val(), 1);
  418. }
  419. EXPECT_EQ(TypeParam::s_count, 0);
  420. }
  421. // Test move assign other any, and that the old value is destroyed
  422. TYPED_TEST(AnyConversionTest, Any_MoveAssignAny_OldIsDestroyed)
  423. {
  424. using LHS = typename TestFixture::LHS;
  425. using RHS = typename TestFixture::RHS;
  426. {
  427. LHS const s1(1);
  428. any a(s1);
  429. RHS const s2(2);
  430. any a2(s2);
  431. EXPECT_EQ(LHS::s_count, 2);
  432. EXPECT_EQ(RHS::s_count, 2);
  433. a = AZStd::move(a2);
  434. EXPECT_EQ(LHS::s_count, 1);
  435. EXPECT_EQ(RHS::s_count, 2);
  436. EXPECT_EQ(any_cast<const RHS&>(a).val(), 2);
  437. EXPECT_TRUE(a2.empty());
  438. }
  439. EXPECT_EQ(LHS::s_count, 0);
  440. EXPECT_EQ(RHS::s_count, 0);
  441. }
  442. // Test move assign other any over empty
  443. TYPED_TEST(AnySizedTest, Any_MoveAssignAny_IsValid)
  444. {
  445. {
  446. any a;
  447. any a2((TypeParam(1)));
  448. EXPECT_EQ(TypeParam::s_count, 1);
  449. a = std::move(a2);
  450. EXPECT_EQ(TypeParam::s_count, 1);
  451. EXPECT_EQ(any_cast<const TypeParam&>(a).val(), 1);
  452. EXPECT_TRUE(a2.empty());
  453. }
  454. EXPECT_EQ(TypeParam::s_count, 0);
  455. }
  456. // Test move assign other empty any
  457. TYPED_TEST(AnySizedTest, Any_MoveAssignEmptyAny_OldIsDestroyed)
  458. {
  459. {
  460. any a((TypeParam(1)));
  461. any a2;
  462. EXPECT_EQ(TypeParam::s_count, 1);
  463. a = std::move(a2);
  464. EXPECT_EQ(TypeParam::s_count, 0);
  465. EXPECT_TRUE(a.empty());
  466. EXPECT_TRUE(a2.empty());
  467. }
  468. EXPECT_EQ(TypeParam::s_count, 0);
  469. }
  470. }
  471. namespace Modifiers
  472. {
  473. // Test clear empty any
  474. TEST_F(AnyTest, Any_ClearEmptyAny_IsEmpty)
  475. {
  476. any a;
  477. a.clear();
  478. EXPECT_TRUE(a.empty());
  479. }
  480. // Test clear valid any
  481. TYPED_TEST(AnySizedTest, Any_ClearValidAny_OldIsDestroyed)
  482. {
  483. {
  484. any a((TypeParam(1)));
  485. EXPECT_EQ(TypeParam::s_count, 1);
  486. EXPECT_EQ(any_cast<const TypeParam&>(a).val(), 1);
  487. a.clear();
  488. EXPECT_TRUE(a.empty());
  489. }
  490. EXPECT_EQ(TypeParam::s_count, 0);
  491. }
  492. // Test swap 2 valid anys
  493. TYPED_TEST(AnyConversionTest, Any_SwapValidAnys_IsValid)
  494. {
  495. using LHS = typename TestFixture::LHS;
  496. using RHS = typename TestFixture::RHS;
  497. {
  498. any a1((LHS(1)));
  499. any a2(RHS(2));
  500. EXPECT_EQ(LHS::s_count, 1);
  501. EXPECT_EQ(RHS::s_count, 1);
  502. a1.swap(a2);
  503. EXPECT_EQ(LHS::s_count, 1);
  504. EXPECT_EQ(RHS::s_count, 1);
  505. EXPECT_EQ(any_cast<const RHS&>(a1).val(), 2);
  506. EXPECT_EQ(any_cast<const RHS&>(a2).val(), 1);
  507. }
  508. EXPECT_EQ(LHS::s_count, 0);
  509. EXPECT_EQ(RHS::s_count, 0);
  510. }
  511. // Test swap valid any with empty any
  512. TYPED_TEST(AnySizedTest, Any_SwapEmptyAndValidAny_IsValid)
  513. {
  514. {
  515. any a1((TypeParam(1)));
  516. any a2;
  517. EXPECT_EQ(TypeParam::s_count, 1);
  518. a1.swap(a2);
  519. EXPECT_EQ(TypeParam::s_count, 1);
  520. EXPECT_EQ(any_cast<const TypeParam&>(a2).val(), 1);
  521. EXPECT_TRUE(a1.empty());
  522. }
  523. EXPECT_EQ(TypeParam::s_count, 0);
  524. }
  525. // Test swap empty any with valid any
  526. TYPED_TEST(AnySizedTest, Any_SwapValidAndEmptyAny_IsValid)
  527. {
  528. {
  529. any a1((TypeParam(1)));
  530. any a2;
  531. EXPECT_EQ(TypeParam::s_count, 1);
  532. a2.swap(a1);
  533. EXPECT_EQ(TypeParam::s_count, 1);
  534. EXPECT_EQ(any_cast<const TypeParam&>(a2).val(), 1);
  535. EXPECT_TRUE(a1.empty());
  536. }
  537. EXPECT_EQ(TypeParam::s_count, 0);
  538. }
  539. }
  540. namespace Observers
  541. {
  542. // Test empty any is empty
  543. TEST_F(AnyTest, Any_EmptyAny_IsEmpty)
  544. {
  545. any a;
  546. EXPECT_TRUE(a.empty());
  547. }
  548. // Test valid any is not empty
  549. TYPED_TEST(AnySizedTest, Any_ValidAny_NotIsEmpty)
  550. {
  551. TypeParam const s(1);
  552. any a(s);
  553. EXPECT_FALSE(a.empty());
  554. }
  555. // Test empty any is empty
  556. TEST_F(AnyTest, Any_EmptyAny_IsTypeEmpty)
  557. {
  558. any const a;
  559. EXPECT_TRUE(a.type().IsNull());
  560. }
  561. // Test empty any is empty
  562. TYPED_TEST(AnySizedTest, Any_ValidAny_IsTypeValid)
  563. {
  564. TypeParam const s(1);
  565. any const a(s);
  566. EXPECT_EQ(a.type(), azrtti_typeid<TypeParam>());
  567. }
  568. namespace NonMembers
  569. {
  570. // Test swapping anys works
  571. TEST_F(AnyTest, Any_AzstdSwapAnys_IsValid)
  572. {
  573. any a1(1);
  574. any a2(2);
  575. AZStd::swap(a1, a2);
  576. EXPECT_EQ(any_cast<int>(a1), 2);
  577. EXPECT_EQ(any_cast<int>(a2), 1);
  578. }
  579. namespace AnyCast
  580. {
  581. // Test return types match
  582. TEST_F(AnyTest, Any_PointerAnyCast_IsReturnTypeValid)
  583. {
  584. any a;
  585. static_assert((AZStd::is_same<decltype(any_cast<int>(&a)), int*>::value), "Return type mismatch");
  586. static_assert((AZStd::is_same<decltype(any_cast<int const>(&a)), int const*>::value), "Return type mismatch");
  587. any const& ca = a;
  588. (void)ca;
  589. static_assert((AZStd::is_same<decltype(any_cast<int>(&ca)), int const*>::value), "Return type mismatch");
  590. static_assert((AZStd::is_same<decltype(any_cast<int const>(&ca)), int const*>::value), "Return type mismatch");
  591. }
  592. // Test any_cast<...>(nullptr) always returns nullptr
  593. TEST_F(AnyTest, Any_PointerAnyCastNullptr_ReturnsNullptr)
  594. {
  595. any* a = nullptr;
  596. EXPECT_EQ(nullptr, any_cast<int>(a));
  597. EXPECT_EQ(nullptr, any_cast<int const>(a));
  598. any const* ca = nullptr;
  599. EXPECT_EQ(nullptr, any_cast<int>(ca));
  600. EXPECT_EQ(nullptr, any_cast<int const>(ca));
  601. }
  602. // Test any_cast(&emptyAny) always returns nullptr
  603. TEST_F(AnyTest, Any_PointerAnyCastEmptyAny_ReturnsNullptr)
  604. {
  605. {
  606. any a;
  607. EXPECT_EQ(nullptr, any_cast<int>(&a));
  608. EXPECT_EQ(nullptr, any_cast<int const>(&a));
  609. any const& ca = a;
  610. EXPECT_EQ(nullptr, any_cast<int>(&ca));
  611. EXPECT_EQ(nullptr, any_cast<int const>(&ca));
  612. }
  613. // Create as non-empty, then make empty and run test.
  614. {
  615. any a(42);
  616. a.clear();
  617. EXPECT_EQ(nullptr, any_cast<int>(&a));
  618. EXPECT_EQ(nullptr, any_cast<int const>(&a));
  619. any const& ca = a;
  620. EXPECT_EQ(nullptr, any_cast<int>(&ca));
  621. EXPECT_EQ(nullptr, any_cast<int const>(&ca));
  622. }
  623. }
  624. // Test any_cast(&validAny) always returns proper value
  625. TYPED_TEST(AnySizedTest, Any_PointerAnyCastValidAny_ReturnsValue)
  626. {
  627. {
  628. any a((TypeParam(42)));
  629. any const& ca = a;
  630. EXPECT_EQ(TypeParam::s_count, 1);
  631. EXPECT_EQ(TypeParam::s_copied, 0);
  632. EXPECT_EQ(TypeParam::s_moved, 1);
  633. // Try a cast to a bad type.
  634. // NOTE: Type cannot be an int.
  635. EXPECT_EQ(any_cast<int>(&a), nullptr);
  636. EXPECT_EQ(any_cast<int const>(&a), nullptr);
  637. // Try a cast to the right type, but as a pointer.
  638. EXPECT_EQ(any_cast<TypeParam*>(&a), nullptr);
  639. EXPECT_EQ(any_cast<TypeParam const*>(&a), nullptr);
  640. // Check getting a unqualified type from a non-const any.
  641. TypeParam* v = any_cast<TypeParam>(&a);
  642. EXPECT_NE(v, nullptr);
  643. EXPECT_EQ(v->val(), 42);
  644. // change the stored value and later check for the new value.
  645. v->val() = 999;
  646. // Check getting a const qualified type from a non-const any.
  647. TypeParam const* cv = any_cast<TypeParam const>(&a);
  648. EXPECT_NE(cv, nullptr);
  649. EXPECT_EQ(cv, v);
  650. EXPECT_EQ(cv->val(), 999);
  651. // Check getting a unqualified type from a const any.
  652. cv = any_cast<TypeParam>(&ca);
  653. EXPECT_NE(cv, nullptr);
  654. EXPECT_EQ(cv, v);
  655. EXPECT_EQ(cv->val(), 999);
  656. // Check getting a const-qualified type from a const any.
  657. cv = any_cast<TypeParam const>(&ca);
  658. EXPECT_NE(cv, nullptr);
  659. EXPECT_EQ(cv, v);
  660. EXPECT_EQ(cv->val(), 999);
  661. // Check that no more objects were created, copied or moved.
  662. EXPECT_EQ(TypeParam::s_count, 1);
  663. EXPECT_EQ(TypeParam::s_copied, 0);
  664. EXPECT_EQ(TypeParam::s_moved, 1);
  665. }
  666. EXPECT_EQ(TypeParam::s_count, 0);
  667. }
  668. }
  669. namespace AnyNumericCast
  670. {
  671. TEST_F(AnyTest, AnyNumericCast_Nullptr_ReturnsNullptr)
  672. {
  673. {
  674. any* a = nullptr;
  675. int i;
  676. EXPECT_FALSE(any_numeric_cast(a, i));
  677. }
  678. {
  679. const any* a = nullptr;
  680. int i;
  681. EXPECT_FALSE(any_numeric_cast(a, i));
  682. }
  683. }
  684. #define EXPECT_ANY_IS(any_ptr, Type, value) do { Type _r; EXPECT_TRUE(any_numeric_cast<Type>(any_ptr, _r)); EXPECT_EQ(value, _r); } while(false)
  685. TEST_F(AnyTest, AnyNumericCast_SameType_ReturnsValid)
  686. {
  687. any a;
  688. a = 10.0f;
  689. EXPECT_ANY_IS(&a, float, 10.0f);
  690. a = 10.0;
  691. EXPECT_ANY_IS(&a, double, 10.0);
  692. a = int(10);
  693. EXPECT_ANY_IS(&a, int, 10);
  694. }
  695. TEST_F(AnyTest, AnyNumericCast_FloatingPoint_ConversionsWork)
  696. {
  697. any a;
  698. a = 10.0f;
  699. EXPECT_ANY_IS(&a, float, 10.0f);
  700. EXPECT_ANY_IS(&a, double, 10.0);
  701. }
  702. TEST_F(AnyTest, AnyNumericCast_Integral_ConversionsWork)
  703. {
  704. any a;
  705. a = int(10);
  706. EXPECT_ANY_IS(&a, int, 10);
  707. EXPECT_ANY_IS(&a, long, 10);
  708. EXPECT_ANY_IS(&a, char, 10);
  709. EXPECT_ANY_IS(&a, unsigned int, 10u);
  710. EXPECT_ANY_IS(&a, unsigned long, 10u);
  711. EXPECT_ANY_IS(&a, unsigned char, 10u);
  712. }
  713. TEST_F(AnyTest, AnyNumericCast_Integral_AssertsOnDataLoss)
  714. {
  715. any a;
  716. {
  717. // Test assert on signed -> unsigned conversion
  718. a = -1;
  719. AZ_TEST_START_TRACE_SUPPRESSION;
  720. unsigned int v;
  721. any_numeric_cast(&a, v);
  722. AZ_TEST_STOP_TRACE_SUPPRESSION(1);
  723. }
  724. {
  725. // Test assert on out of range
  726. a = std::numeric_limits<int>::max();
  727. AZ_TEST_START_TRACE_SUPPRESSION;
  728. char v;
  729. any_numeric_cast(&a, v);
  730. AZ_TEST_STOP_TRACE_SUPPRESSION(1);
  731. }
  732. }
  733. TEST_F(AnyTest, AnyNumericCast_IntegralToFloatingPoint_ConversionsWork)
  734. {
  735. any a;
  736. a = int(10);
  737. EXPECT_ANY_IS(&a, int, 10);
  738. EXPECT_ANY_IS(&a, float, 10.0f);
  739. EXPECT_ANY_IS(&a, double, 10.0);
  740. }
  741. TEST_F(AnyTest, AnyNumericCast_FloatingPointToIntegral_ConversionsWork)
  742. {
  743. any a;
  744. a = 10.0f;
  745. EXPECT_ANY_IS(&a, float, 10.0f);
  746. EXPECT_ANY_IS(&a, int, 10);
  747. EXPECT_ANY_IS(&a, long, 10);
  748. EXPECT_ANY_IS(&a, char, 10);
  749. EXPECT_ANY_IS(&a, unsigned int, 10u);
  750. EXPECT_ANY_IS(&a, unsigned long, 10u);
  751. EXPECT_ANY_IS(&a, unsigned char, 10u);
  752. }
  753. TEST_F(AnyTest, AnyNumericCast_FloatingPointToIntegral_AssertsOnDataLoss)
  754. {
  755. any a;
  756. // Test assert on out of range
  757. a = DBL_MAX;
  758. AZ_TEST_START_TRACE_SUPPRESSION;
  759. float f;
  760. any_numeric_cast(&a, f);
  761. AZ_TEST_STOP_TRACE_SUPPRESSION(1);
  762. }
  763. #undef EXPECT_ANY_IS
  764. }
  765. }
  766. }
  767. }