Ordered.cpp 74 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "UserTypes.h"
  9. #include <AzCore/std/containers/set.h>
  10. #include <AzCore/std/containers/map.h>
  11. #include <AzCore/std/containers/intrusive_set.h>
  12. #include <AzCore/std/containers/array.h>
  13. #include <AzCore/std/containers/fixed_vector.h>
  14. #include <AzCore/std/containers/span.h>
  15. #include <AzCore/std/ranges/transform_view.h>
  16. #define AZ_TEST_VALIDATE_EMPTY_TREE(_Tree_) \
  17. EXPECT_EQ(0, _Tree_.size()); \
  18. EXPECT_TRUE(_Tree_.empty()); \
  19. EXPECT_TRUE(_Tree_.begin() == _Tree_.end());
  20. #define AZ_TEST_VALIDATE_TREE(_Tree_, _NumElements) \
  21. EXPECT_EQ(_NumElements, _Tree_.size()); \
  22. EXPECT_TRUE((_Tree_.size() > 0) ? !_Tree_.empty() : _Tree_.empty()); \
  23. EXPECT_TRUE((_NumElements > 0) ? _Tree_.begin() != _Tree_.end() : _Tree_.begin() == _Tree_.end()); \
  24. EXPECT_FALSE(_Tree_.empty());
  25. namespace UnitTest
  26. {
  27. using namespace AZStd;
  28. using namespace UnitTestInternal;
  29. /**
  30. * Setup the red-black tree. To achieve fixed_rbtree all you need is to use \ref AZStd::static_pool_allocator with
  31. * the node (Internal::rb_tree_node<T>).
  32. */
  33. template<class T, class KeyEq = AZStd::less<T>, class Allocator = AZStd::allocator >
  34. struct RedBlackTree_SetTestTraits
  35. {
  36. typedef T key_type;
  37. typedef KeyEq key_equal;
  38. typedef T value_type;
  39. typedef Allocator allocator_type;
  40. static AZ_FORCE_INLINE const key_type& key_from_value(const value_type& value) { return value; }
  41. };
  42. class Tree_RedBlack
  43. : public LeakDetectionFixture
  44. {
  45. };
  46. TEST_F(Tree_RedBlack, Test)
  47. {
  48. array<int, 5> elements = {
  49. {1, 5, 8, 8, 4}
  50. };
  51. AZStd::size_t num;
  52. typedef rbtree<RedBlackTree_SetTestTraits<int> > rbtree_set_type;
  53. rbtree_set_type tree;
  54. AZ_TEST_VALIDATE_EMPTY_TREE(tree);
  55. rbtree_set_type copy_tree = tree;
  56. AZ_TEST_VALIDATE_EMPTY_TREE(copy_tree);
  57. // insert unique element
  58. bool isInsert = tree.insert_unique(10).second;
  59. AZ_TEST_VALIDATE_TREE(tree, 1);
  60. AZ_TEST_ASSERT(isInsert == true);
  61. // insert unique element, which we already have.
  62. isInsert = tree.insert_unique(10).second;
  63. AZ_TEST_VALIDATE_TREE(tree, 1);
  64. AZ_TEST_ASSERT(isInsert == false);
  65. // insert equal element.
  66. tree.insert_equal(11);
  67. AZ_TEST_VALIDATE_TREE(tree, 2);
  68. // insert equal element, which we already have.
  69. tree.insert_equal(11);
  70. AZ_TEST_VALIDATE_TREE(tree, 3);
  71. tree.insert_unique(elements.begin(), elements.end());
  72. AZ_TEST_VALIDATE_TREE(tree, 7); /// there are 4 unique elements in the list.
  73. tree.insert_equal(elements.begin(), elements.end());
  74. AZ_TEST_VALIDATE_TREE(tree, 12);
  75. AZ_TEST_ASSERT(*tree.begin() == 1);
  76. rbtree_set_type::iterator iterNext = tree.erase(tree.begin()); // we have 2 elements with value (1)
  77. AZ_TEST_ASSERT(*iterNext == 1);
  78. tree.erase(tree.begin());
  79. AZ_TEST_VALIDATE_TREE(tree, 10);
  80. AZ_TEST_ASSERT(*tree.begin() == 4);
  81. AZ_TEST_ASSERT(*prev(tree.end()) == 11);
  82. iterNext = tree.erase(prev(tree.end()));
  83. AZ_TEST_ASSERT(iterNext == tree.end());
  84. AZ_TEST_VALIDATE_TREE(tree, 9);
  85. AZ_TEST_ASSERT(*prev(tree.end()) == 11); // we have 2 elements with value(11) at the end
  86. num = tree.erase(8);
  87. AZ_TEST_VALIDATE_TREE(tree, 6);
  88. AZ_TEST_ASSERT(num == 3);
  89. tree.clear();
  90. AZ_TEST_VALIDATE_EMPTY_TREE(tree);
  91. tree.insert_equal(elements.begin(), elements.end());
  92. tree.erase(elements.begin(), elements.end());
  93. AZ_TEST_ASSERT(iterNext == tree.end());
  94. AZ_TEST_VALIDATE_EMPTY_TREE(tree);
  95. tree.insert_equal(elements.begin(), elements.end());
  96. tree.insert_equal(elements.begin(), elements.end());
  97. AZ_TEST_VALIDATE_TREE(tree, 10);
  98. rbtree_set_type::iterator iter, iter1;
  99. iter = tree.find(8);
  100. AZ_TEST_ASSERT(iter != tree.end());
  101. iter1 = tree.lower_bound(8);
  102. AZ_TEST_ASSERT(iter == iter1);
  103. iter1 = tree.upper_bound(8);
  104. AZ_TEST_ASSERT(iter1 == tree.end());
  105. AZ_TEST_ASSERT(iter1 != iter);
  106. num = tree.count(8);
  107. AZ_TEST_ASSERT(num == 4);
  108. AZStd::pair<rbtree_set_type::iterator, rbtree_set_type::iterator> range;
  109. range = tree.equal_range(8);
  110. AZ_TEST_ASSERT(range.first != tree.end());
  111. AZ_TEST_ASSERT(range.second == tree.end());
  112. AZ_TEST_ASSERT(AZStd::distance(range.first, range.second) == 4);
  113. // check the order
  114. int prevValue = *tree.begin();
  115. for (iter = next(tree.begin()); iter != tree.end(); ++iter)
  116. {
  117. AZ_TEST_ASSERT(prevValue <= *iter);
  118. prevValue = *iter;
  119. }
  120. // rbtree with different key equal function
  121. typedef rbtree<RedBlackTree_SetTestTraits<int, AZStd::greater<int> > > rbtree_set_type1;
  122. rbtree_set_type1 tree1;
  123. tree1.insert_equal(elements.begin(), elements.end());
  124. tree1.insert_equal(elements.begin(), elements.end());
  125. AZ_TEST_VALIDATE_TREE(tree1, 10);
  126. // check the order
  127. prevValue = *tree1.begin();
  128. for (rbtree_set_type1::iterator it = next(tree1.begin()); it != tree1.end(); ++it)
  129. {
  130. AZ_TEST_ASSERT(prevValue >= *it);
  131. prevValue = *it;
  132. }
  133. }
  134. class Tree_IntrusiveMultiSet
  135. : public LeakDetectionFixture
  136. {
  137. public:
  138. struct Node
  139. : public AZStd::intrusive_multiset_node<Node>
  140. {
  141. Node(int order)
  142. : m_order(order) {}
  143. operator int() {
  144. return m_order;
  145. }
  146. int m_order;
  147. };
  148. typedef AZStd::intrusive_multiset<Node, AZStd::intrusive_multiset_base_hook<Node>, AZStd::less<> > IntrusiveSetIntKeyType;
  149. };
  150. TEST_F(Tree_IntrusiveMultiSet, Test)
  151. {
  152. IntrusiveSetIntKeyType tree;
  153. // make sure the tree is empty
  154. AZ_TEST_VALIDATE_EMPTY_TREE(tree);
  155. // insert node
  156. Node n1(1);
  157. tree.insert(&n1);
  158. AZ_TEST_ASSERT(!tree.empty());
  159. AZ_TEST_ASSERT(tree.size() == 1);
  160. AZ_TEST_ASSERT(tree.begin() != tree.end());
  161. AZ_TEST_ASSERT(tree.begin()->m_order == 1);
  162. // insert node and sort
  163. Node n2(0);
  164. tree.insert(&n2);
  165. AZ_TEST_ASSERT(!tree.empty());
  166. AZ_TEST_ASSERT(tree.size() == 2);
  167. AZ_TEST_ASSERT(tree.begin() != tree.end());
  168. AZ_TEST_ASSERT(tree.begin()->m_order == 0);
  169. AZ_TEST_ASSERT((++tree.begin())->m_order == 1);
  170. // erase the first node
  171. IntrusiveSetIntKeyType::iterator it = tree.erase(tree.begin());
  172. AZ_TEST_ASSERT(it != tree.end());
  173. AZ_TEST_ASSERT(tree.size() == 1);
  174. AZ_TEST_ASSERT(it->m_order == 1);
  175. // insert via reference (a pointer to it will be taken)
  176. it = tree.insert(n2);
  177. AZ_TEST_ASSERT(it->m_order == n2.m_order);
  178. AZ_TEST_ASSERT(tree.size() == 2);
  179. AZStd::fixed_vector<Node, 5> elements;
  180. elements.push_back(Node(2));
  181. elements.push_back(Node(5));
  182. elements.push_back(Node(8));
  183. elements.push_back(Node(8));
  184. elements.push_back(Node(4));
  185. // insert from input iterator
  186. tree.insert(elements.begin(), elements.end());
  187. AZ_TEST_ASSERT(!tree.empty());
  188. AZ_TEST_ASSERT(tree.size() == 7);
  189. AZ_TEST_ASSERT(tree.begin() != tree.end());
  190. it = tree.begin();
  191. AZ_TEST_ASSERT((it++)->m_order == 0);
  192. AZ_TEST_ASSERT((it++)->m_order == 1);
  193. AZ_TEST_ASSERT((it++)->m_order == 2);
  194. AZ_TEST_ASSERT((it++)->m_order == 4);
  195. AZ_TEST_ASSERT((it++)->m_order == 5);
  196. AZ_TEST_ASSERT((it++)->m_order == 8);
  197. AZ_TEST_ASSERT((it++)->m_order == 8);
  198. // lower bound
  199. it = tree.lower_bound(8);
  200. AZ_TEST_ASSERT(it != tree.end());
  201. AZ_TEST_ASSERT(it->m_order == 8);
  202. AZ_TEST_ASSERT((++it)->m_order == 8);
  203. // upper bound
  204. it = tree.upper_bound(8);
  205. AZ_TEST_ASSERT(it == tree.end());
  206. AZ_TEST_ASSERT((--it)->m_order == 8);
  207. AZ_TEST_ASSERT((--it)->m_order == 8);
  208. // minimum
  209. it = tree.minimum();
  210. AZ_TEST_ASSERT(it != tree.end());
  211. AZ_TEST_ASSERT(it->m_order == 0);
  212. // maximum
  213. it = tree.maximum();
  214. AZ_TEST_ASSERT(it != tree.end());
  215. AZ_TEST_ASSERT(it->m_order == 8);
  216. // erase elements with iterator
  217. tree.erase(elements.begin(), elements.end());
  218. it = tree.begin();
  219. AZ_TEST_ASSERT(tree.size() == 2);
  220. AZ_TEST_ASSERT((it++)->m_order == 0);
  221. AZ_TEST_ASSERT((it++)->m_order == 1);
  222. // clear the entire container
  223. tree.clear();
  224. AZ_TEST_VALIDATE_EMPTY_TREE(tree);
  225. }
  226. // SetContainerTest-Begin
  227. class Tree_Set
  228. : public LeakDetectionFixture
  229. {
  230. };
  231. TEST_F(Tree_Set, Test)
  232. {
  233. array<int, 5> elements = {
  234. {2, 6, 9, 3, 9}
  235. };
  236. array<int, 5> elements2 = {
  237. {11, 4, 13, 6, 1}
  238. };
  239. AZStd::size_t num;
  240. typedef set<int> int_set_type;
  241. int_set_type set;
  242. AZ_TEST_VALIDATE_EMPTY_TREE(set);
  243. int_set_type set1(elements.begin(), elements.end());
  244. AZ_TEST_ASSERT(set1 > set);
  245. AZ_TEST_VALIDATE_TREE(set1, 4);
  246. AZ_TEST_ASSERT(*set1.begin() == 2);
  247. AZ_TEST_ASSERT(*prev(set1.end()) == 9);
  248. int_set_type set2(set1);
  249. AZ_TEST_ASSERT(set1 == set2);
  250. AZ_TEST_VALIDATE_TREE(set2, 4);
  251. AZ_TEST_ASSERT(*set2.begin() == 2);
  252. AZ_TEST_ASSERT(*prev(set2.end()) == 9);
  253. set = set2;
  254. AZ_TEST_VALIDATE_TREE(set, 4);
  255. AZ_TEST_ASSERT(*set.begin() == 2);
  256. AZ_TEST_ASSERT(*prev(set.end()) == 9);
  257. set.clear();
  258. AZ_TEST_VALIDATE_EMPTY_TREE(set);
  259. set.swap(set2);
  260. AZ_TEST_VALIDATE_TREE(set, 4);
  261. AZ_TEST_ASSERT(*set.begin() == 2);
  262. AZ_TEST_ASSERT(*prev(set.end()) == 9);
  263. AZ_TEST_VALIDATE_EMPTY_TREE(set2);
  264. bool isInsert = set.insert(6).second;
  265. AZ_TEST_VALIDATE_TREE(set, 4);
  266. AZ_TEST_ASSERT(isInsert == false);
  267. isInsert = set.insert(10).second;
  268. AZ_TEST_VALIDATE_TREE(set, 5);
  269. AZ_TEST_ASSERT(isInsert == true);
  270. AZ_TEST_ASSERT(*prev(set.end()) == 10);
  271. set.insert(elements2.begin(), elements2.end());
  272. AZ_TEST_VALIDATE_TREE(set, 9);
  273. AZ_TEST_ASSERT(*set.begin() == 1);
  274. AZ_TEST_ASSERT(*prev(set.end()) == 13);
  275. set.erase(set.begin());
  276. AZ_TEST_VALIDATE_TREE(set, 8);
  277. AZ_TEST_ASSERT(*set.begin() == 2);
  278. set.erase(prev(set.end()));
  279. AZ_TEST_VALIDATE_TREE(set, 7);
  280. AZ_TEST_ASSERT(*prev(set.end()) == 11);
  281. num = set.erase(6);
  282. AZ_TEST_VALIDATE_TREE(set, 6);
  283. AZ_TEST_ASSERT(num == 1);
  284. num = set.erase(100);
  285. AZ_TEST_VALIDATE_TREE(set, 6);
  286. AZ_TEST_ASSERT(num == 0);
  287. int_set_type::iterator iter = set.find(9);
  288. AZ_TEST_ASSERT(iter != set.end());
  289. iter = set.find(99);
  290. AZ_TEST_ASSERT(iter == set.end());
  291. num = set.count(9);
  292. AZ_TEST_ASSERT(num == 1);
  293. num = set.count(88);
  294. AZ_TEST_ASSERT(num == 0);
  295. iter = set.lower_bound(11);
  296. AZ_TEST_ASSERT(iter != set.end());
  297. AZ_TEST_ASSERT(*iter == 11);
  298. iter = set.lower_bound(111);
  299. AZ_TEST_ASSERT(iter == set.end());
  300. iter = set.upper_bound(11);
  301. AZ_TEST_ASSERT(iter == set.end()); // this is the last element
  302. iter = set.upper_bound(4);
  303. AZ_TEST_ASSERT(iter != set.end()); // this is NOT the last element
  304. iter = set.upper_bound(44);
  305. AZ_TEST_ASSERT(iter == set.end());
  306. AZStd::pair<int_set_type::iterator, int_set_type::iterator> range = set.equal_range(11);
  307. num = distance(range.first, range.second);
  308. AZ_TEST_ASSERT(num == 1);
  309. AZ_TEST_ASSERT(range.first != set.end());
  310. AZ_TEST_ASSERT(*range.first == 11);
  311. AZ_TEST_ASSERT(range.second == set.end()); // this is the last element
  312. range = set.equal_range(91);
  313. num = distance(range.first, range.second);
  314. AZ_TEST_ASSERT(num == 0);
  315. AZ_TEST_ASSERT(range.first == set.end());
  316. AZ_TEST_ASSERT(range.second == set.end());
  317. }
  318. TEST_F(Tree_Set, ExplicitAllocatorSucceeds)
  319. {
  320. AZ::OSAllocator customAllocator;
  321. AZStd::set<int, AZStd::less<int>, AZ::AZStdIAllocator> setWithCustomAllocator{ AZ::AZStdIAllocator(&customAllocator) };
  322. auto insertIter = setWithCustomAllocator.emplace(1);
  323. EXPECT_TRUE(insertIter.second);
  324. insertIter = setWithCustomAllocator.emplace(1);
  325. EXPECT_FALSE(insertIter.second);
  326. EXPECT_EQ(1, setWithCustomAllocator.size());
  327. }
  328. class Tree_MultiSet
  329. : public LeakDetectionFixture
  330. {
  331. };
  332. TEST_F(Tree_MultiSet, Test)
  333. {
  334. array<int, 5> elements = {
  335. {2, 6, 9, 3, 9}
  336. };
  337. array<int, 5> elements2 = {
  338. {11, 4, 13, 6, 1}
  339. };
  340. AZStd::size_t num;
  341. typedef multiset<int> int_multiset_type;
  342. int_multiset_type set;
  343. AZ_TEST_VALIDATE_EMPTY_TREE(set);
  344. int_multiset_type set1(elements.begin(), elements.end());
  345. AZ_TEST_ASSERT(set1 > set);
  346. AZ_TEST_VALIDATE_TREE(set1, 5);
  347. AZ_TEST_ASSERT(*set1.begin() == 2);
  348. AZ_TEST_ASSERT(*prev(set1.end()) == 9);
  349. int_multiset_type set2(set1);
  350. AZ_TEST_ASSERT(set1 == set2);
  351. AZ_TEST_VALIDATE_TREE(set2, 5);
  352. AZ_TEST_ASSERT(*set2.begin() == 2);
  353. AZ_TEST_ASSERT(*prev(set2.end()) == 9);
  354. set = set2;
  355. AZ_TEST_VALIDATE_TREE(set, 5);
  356. AZ_TEST_ASSERT(*set.begin() == 2);
  357. AZ_TEST_ASSERT(*prev(set.end()) == 9);
  358. set.clear();
  359. AZ_TEST_VALIDATE_EMPTY_TREE(set);
  360. set.swap(set2);
  361. AZ_TEST_VALIDATE_TREE(set, 5);
  362. AZ_TEST_ASSERT(*set.begin() == 2);
  363. AZ_TEST_ASSERT(*prev(set.end()) == 9);
  364. AZ_TEST_VALIDATE_EMPTY_TREE(set2);
  365. set.insert(10);
  366. AZ_TEST_VALIDATE_TREE(set, 6);
  367. AZ_TEST_ASSERT(*prev(set.end()) == 10);
  368. set.insert(elements2.begin(), elements2.end());
  369. AZ_TEST_VALIDATE_TREE(set, 11);
  370. AZ_TEST_ASSERT(*set.begin() == 1);
  371. AZ_TEST_ASSERT(*prev(set.end()) == 13);
  372. set.erase(set.begin());
  373. AZ_TEST_VALIDATE_TREE(set, 10);
  374. AZ_TEST_ASSERT(*set.begin() == 2);
  375. set.erase(prev(set.end()));
  376. AZ_TEST_VALIDATE_TREE(set, 9);
  377. AZ_TEST_ASSERT(*prev(set.end()) == 11);
  378. num = set.erase(6);
  379. AZ_TEST_VALIDATE_TREE(set, 7);
  380. AZ_TEST_ASSERT(num == 2);
  381. num = set.erase(100);
  382. AZ_TEST_VALIDATE_TREE(set, 7);
  383. AZ_TEST_ASSERT(num == 0);
  384. int_multiset_type::iterator iter = set.find(9);
  385. AZ_TEST_ASSERT(iter != set.end());
  386. iter = set.find(99);
  387. AZ_TEST_ASSERT(iter == set.end());
  388. num = set.count(9);
  389. AZ_TEST_ASSERT(num == 2);
  390. num = set.count(88);
  391. AZ_TEST_ASSERT(num == 0);
  392. iter = set.lower_bound(11);
  393. AZ_TEST_ASSERT(iter != set.end());
  394. AZ_TEST_ASSERT(*iter == 11);
  395. iter = set.lower_bound(111);
  396. AZ_TEST_ASSERT(iter == set.end());
  397. iter = set.upper_bound(11);
  398. AZ_TEST_ASSERT(iter == set.end()); // this is the last element
  399. iter = set.upper_bound(4);
  400. AZ_TEST_ASSERT(iter != set.end()); // this is NOT the last element
  401. iter = set.upper_bound(44);
  402. AZ_TEST_ASSERT(iter == set.end());
  403. AZStd::pair<int_multiset_type::iterator, int_multiset_type::iterator> range = set.equal_range(9);
  404. num = distance(range.first, range.second);
  405. AZ_TEST_ASSERT(num == 2);
  406. AZ_TEST_ASSERT(range.first != set.end());
  407. AZ_TEST_ASSERT(*range.first == 9);
  408. AZ_TEST_ASSERT(range.second != set.end());
  409. range = set.equal_range(91);
  410. num = distance(range.first, range.second);
  411. AZ_TEST_ASSERT(num == 0);
  412. AZ_TEST_ASSERT(range.first == set.end());
  413. AZ_TEST_ASSERT(range.second == set.end());
  414. }
  415. TEST_F(Tree_MultiSet, ExplicitAllocatorSucceeds)
  416. {
  417. AZ::OSAllocator customAllocator;
  418. AZStd::multiset<int, AZStd::less<int>, AZ::AZStdIAllocator> setWithCustomAllocator{ AZ::AZStdIAllocator(&customAllocator) };
  419. setWithCustomAllocator.emplace(1);
  420. setWithCustomAllocator.emplace(1);
  421. EXPECT_EQ(2, setWithCustomAllocator.size());
  422. }
  423. class Tree_Map
  424. : public LeakDetectionFixture
  425. {
  426. };
  427. TEST_F(Tree_Map, Test)
  428. {
  429. fixed_vector<AZStd::pair<int, int>, 5> elements;
  430. elements.push_back(AZStd::make_pair(2, 100));
  431. elements.push_back(AZStd::make_pair(6, 101));
  432. elements.push_back(AZStd::make_pair(9, 102));
  433. elements.push_back(AZStd::make_pair(3, 103));
  434. elements.push_back(AZStd::make_pair(9, 104));
  435. fixed_vector<AZStd::pair<int, int>, 5> elements2;
  436. elements2.push_back(AZStd::make_pair(11, 200));
  437. elements2.push_back(AZStd::make_pair(4, 201));
  438. elements2.push_back(AZStd::make_pair(13, 202));
  439. elements2.push_back(AZStd::make_pair(6, 203));
  440. elements2.push_back(AZStd::make_pair(1, 204));
  441. AZStd::size_t num;
  442. typedef map<int, int> int_map_type;
  443. int_map_type map;
  444. AZ_TEST_VALIDATE_EMPTY_TREE(map);
  445. int_map_type map1(elements.begin(), elements.end());
  446. AZ_TEST_ASSERT(map1 > map);
  447. AZ_TEST_VALIDATE_TREE(map1, 4);
  448. AZ_TEST_ASSERT((*map1.begin()).first == 2);
  449. AZ_TEST_ASSERT((*prev(map1.end())).first == 9);
  450. int_map_type map2(map1);
  451. AZ_TEST_ASSERT(map1 == map2);
  452. AZ_TEST_VALIDATE_TREE(map2, 4);
  453. AZ_TEST_ASSERT((*map2.begin()).first == 2);
  454. AZ_TEST_ASSERT((*prev(map2.end())).first == 9);
  455. map = map2;
  456. AZ_TEST_VALIDATE_TREE(map, 4);
  457. AZ_TEST_ASSERT((*map.begin()).first == 2);
  458. AZ_TEST_ASSERT((*prev(map.end())).first == 9);
  459. map.clear();
  460. AZ_TEST_VALIDATE_EMPTY_TREE(map);
  461. map.swap(map2);
  462. AZ_TEST_VALIDATE_TREE(map, 4);
  463. AZ_TEST_ASSERT((*map.begin()).first == 2);
  464. AZ_TEST_ASSERT((*prev(map.end())).first == 9);
  465. AZ_TEST_VALIDATE_EMPTY_TREE(map2);
  466. bool isInsert = map.insert(6).second;
  467. AZ_TEST_VALIDATE_TREE(map, 4);
  468. AZ_TEST_ASSERT(isInsert == false);
  469. isInsert = map.insert(10).second;
  470. AZ_TEST_VALIDATE_TREE(map, 5);
  471. AZ_TEST_ASSERT(isInsert == true);
  472. AZ_TEST_ASSERT((*prev(map.end())).first == 10);
  473. map.insert(elements2.begin(), elements2.end());
  474. AZ_TEST_VALIDATE_TREE(map, 9);
  475. AZ_TEST_ASSERT((*map.begin()).first == 1);
  476. AZ_TEST_ASSERT((*prev(map.end())).first == 13);
  477. map.erase(map.begin());
  478. AZ_TEST_VALIDATE_TREE(map, 8);
  479. AZ_TEST_ASSERT(map.begin()->first == 2);
  480. map.erase(prev(map.end()));
  481. AZ_TEST_VALIDATE_TREE(map, 7);
  482. AZ_TEST_ASSERT(prev(map.end())->first == 11);
  483. num = map.erase(6);
  484. AZ_TEST_VALIDATE_TREE(map, 6);
  485. AZ_TEST_ASSERT(num == 1);
  486. num = map.erase(100);
  487. AZ_TEST_VALIDATE_TREE(map, 6);
  488. AZ_TEST_ASSERT(num == 0);
  489. int_map_type::iterator iter = map.find(9);
  490. AZ_TEST_ASSERT(iter != map.end());
  491. iter = map.find(99);
  492. AZ_TEST_ASSERT(iter == map.end());
  493. num = map.count(9);
  494. AZ_TEST_ASSERT(num == 1);
  495. num = map.count(88);
  496. AZ_TEST_ASSERT(num == 0);
  497. iter = map.lower_bound(11);
  498. AZ_TEST_ASSERT(iter != map.end());
  499. AZ_TEST_ASSERT(iter->first == 11);
  500. iter = map.lower_bound(111);
  501. AZ_TEST_ASSERT(iter == map.end());
  502. iter = map.upper_bound(11);
  503. AZ_TEST_ASSERT(iter == map.end()); // this is the last element
  504. iter = map.upper_bound(4);
  505. AZ_TEST_ASSERT(iter != map.end()); // this is NOT the last element
  506. iter = map.upper_bound(44);
  507. AZ_TEST_ASSERT(iter == map.end());
  508. AZStd::pair<int_map_type::iterator, int_map_type::iterator> range = map.equal_range(11);
  509. num = distance(range.first, range.second);
  510. AZ_TEST_ASSERT(num == 1);
  511. AZ_TEST_ASSERT(range.first != map.end());
  512. AZ_TEST_ASSERT(range.first->first == 11);
  513. AZ_TEST_ASSERT(range.second == map.end()); // this is the last element
  514. range = map.equal_range(91);
  515. num = distance(range.first, range.second);
  516. AZ_TEST_ASSERT(num == 0);
  517. AZ_TEST_ASSERT(range.first == map.end());
  518. AZ_TEST_ASSERT(range.second == map.end());
  519. AZStd::map<int, MyNoCopyClass> nocopy_map;
  520. MyNoCopyClass& inserted = nocopy_map.insert(3).first->second;
  521. inserted.m_bool = true;
  522. AZ_TEST_ASSERT(nocopy_map.begin()->second.m_bool == true);
  523. int_map_type map3({
  524. {1, 2}, {3, 4}, {5, 6}
  525. });
  526. AZ_TEST_VALIDATE_TREE(map3, 3);
  527. AZ_TEST_ASSERT((*map3.begin()).first == 1);
  528. AZ_TEST_ASSERT((*map3.begin()).second == 2);
  529. AZ_TEST_ASSERT((*prev(map3.end())).first == 5);
  530. AZ_TEST_ASSERT((*prev(map3.end())).second == 6);
  531. }
  532. TEST_F(Tree_Map, ExplicitAllocatorSucceeds)
  533. {
  534. AZ::OSAllocator customAllocator;
  535. AZStd::map<int, int, AZStd::less<int>, AZ::AZStdIAllocator> mapWithCustomAllocator{ AZ::AZStdIAllocator(&customAllocator) };
  536. auto insertIter = mapWithCustomAllocator.emplace(1, 1);
  537. EXPECT_TRUE(insertIter.second);
  538. insertIter = mapWithCustomAllocator.emplace(1, 2);
  539. EXPECT_FALSE(insertIter.second);
  540. EXPECT_EQ(1, mapWithCustomAllocator.size());
  541. }
  542. TEST_F(Tree_Map, IndexOperatorCompilesWithMoveOnlyType)
  543. {
  544. AZStd::map<int, AZStd::unique_ptr<int>> uniquePtrIntMap;
  545. uniquePtrIntMap[4] = AZStd::make_unique<int>(74);
  546. auto findIter = uniquePtrIntMap.find(4);
  547. EXPECT_NE(uniquePtrIntMap.end(), findIter);
  548. EXPECT_EQ(74, *findIter->second);
  549. }
  550. class Tree_MultiMap
  551. : public LeakDetectionFixture
  552. {
  553. };
  554. TEST_F(Tree_MultiMap, Test)
  555. {
  556. fixed_vector<AZStd::pair<int, int>, 5> elements;
  557. elements.push_back(AZStd::make_pair(2, 100));
  558. elements.push_back(AZStd::make_pair(6, 101));
  559. elements.push_back(AZStd::make_pair(9, 102));
  560. elements.push_back(AZStd::make_pair(3, 103));
  561. elements.push_back(AZStd::make_pair(9, 104));
  562. fixed_vector<AZStd::pair<int, int>, 5> elements2;
  563. elements2.push_back(AZStd::make_pair(11, 200));
  564. elements2.push_back(AZStd::make_pair(4, 201));
  565. elements2.push_back(AZStd::make_pair(13, 202));
  566. elements2.push_back(AZStd::make_pair(6, 203));
  567. elements2.push_back(AZStd::make_pair(1, 204));
  568. AZStd::size_t num;
  569. typedef multimap<int, int> int_multimap_type;
  570. int_multimap_type map;
  571. AZ_TEST_VALIDATE_EMPTY_TREE(map);
  572. int_multimap_type map1(elements.begin(), elements.end());
  573. AZ_TEST_ASSERT(map1 > map);
  574. AZ_TEST_VALIDATE_TREE(map1, 5);
  575. AZ_TEST_ASSERT(map1.begin()->first == 2);
  576. AZ_TEST_ASSERT(prev(map1.end())->first == 9);
  577. int_multimap_type map2(map1);
  578. AZ_TEST_ASSERT(map1 == map2);
  579. AZ_TEST_VALIDATE_TREE(map2, 5);
  580. AZ_TEST_ASSERT(map2.begin()->first == 2);
  581. AZ_TEST_ASSERT(prev(map2.end())->first == 9);
  582. map = map2;
  583. AZ_TEST_VALIDATE_TREE(map, 5);
  584. AZ_TEST_ASSERT(map.begin()->first == 2);
  585. AZ_TEST_ASSERT(prev(map.end())->first == 9);
  586. map.clear();
  587. AZ_TEST_VALIDATE_EMPTY_TREE(map);
  588. map.swap(map2);
  589. AZ_TEST_VALIDATE_TREE(map, 5);
  590. AZ_TEST_ASSERT(map.begin()->first == 2);
  591. AZ_TEST_ASSERT(prev(map.end())->first == 9);
  592. AZ_TEST_VALIDATE_EMPTY_TREE(map2);
  593. map.insert(10);
  594. AZ_TEST_VALIDATE_TREE(map, 6);
  595. AZ_TEST_ASSERT(prev(map.end())->first == 10);
  596. map.insert(elements2.begin(), elements2.end());
  597. AZ_TEST_VALIDATE_TREE(map, 11);
  598. AZ_TEST_ASSERT(map.begin()->first == 1);
  599. AZ_TEST_ASSERT(prev(map.end())->first == 13);
  600. map.erase(map.begin());
  601. AZ_TEST_VALIDATE_TREE(map, 10);
  602. AZ_TEST_ASSERT(map.begin()->first == 2);
  603. map.erase(prev(map.end()));
  604. AZ_TEST_VALIDATE_TREE(map, 9);
  605. AZ_TEST_ASSERT(prev(map.end())->first == 11);
  606. num = map.erase(6);
  607. AZ_TEST_VALIDATE_TREE(map, 7);
  608. AZ_TEST_ASSERT(num == 2);
  609. num = map.erase(100);
  610. AZ_TEST_VALIDATE_TREE(map, 7);
  611. AZ_TEST_ASSERT(num == 0);
  612. int_multimap_type::iterator iter = map.find(9);
  613. AZ_TEST_ASSERT(iter != map.end());
  614. iter = map.find(99);
  615. AZ_TEST_ASSERT(iter == map.end());
  616. num = map.count(9);
  617. AZ_TEST_ASSERT(num == 2);
  618. num = map.count(88);
  619. AZ_TEST_ASSERT(num == 0);
  620. iter = map.lower_bound(11);
  621. AZ_TEST_ASSERT(iter != map.end());
  622. AZ_TEST_ASSERT(iter->first == 11);
  623. iter = map.lower_bound(111);
  624. AZ_TEST_ASSERT(iter == map.end());
  625. iter = map.upper_bound(11);
  626. AZ_TEST_ASSERT(iter == map.end()); // this is the last element
  627. iter = map.upper_bound(4);
  628. AZ_TEST_ASSERT(iter != map.end()); // this is NOT the last element
  629. iter = map.upper_bound(44);
  630. AZ_TEST_ASSERT(iter == map.end());
  631. AZStd::pair<int_multimap_type::iterator, int_multimap_type::iterator> range = map.equal_range(9);
  632. num = distance(range.first, range.second);
  633. AZ_TEST_ASSERT(num == 2);
  634. AZ_TEST_ASSERT(range.first != map.end());
  635. AZ_TEST_ASSERT(range.first->first == 9);
  636. AZ_TEST_ASSERT(range.second != map.end());
  637. range = map.equal_range(91);
  638. num = distance(range.first, range.second);
  639. AZ_TEST_ASSERT(num == 0);
  640. AZ_TEST_ASSERT(range.first == map.end());
  641. AZ_TEST_ASSERT(range.second == map.end());
  642. int_multimap_type intint_map3({
  643. {1, 10}, {2, 200}, {3, 3000}, {4, 40000}, {4, 40001}, {5, 500000}
  644. });
  645. AZ_TEST_ASSERT(intint_map3.size() == 6);
  646. AZ_TEST_ASSERT(intint_map3.count(1) == 1);
  647. AZ_TEST_ASSERT(intint_map3.count(2) == 1);
  648. AZ_TEST_ASSERT(intint_map3.count(3) == 1);
  649. AZ_TEST_ASSERT(intint_map3.count(4) == 2);
  650. AZ_TEST_ASSERT(intint_map3.count(5) == 1);
  651. AZ_TEST_ASSERT(intint_map3.lower_bound(1)->second == 10);
  652. AZ_TEST_ASSERT(intint_map3.lower_bound(2)->second == 200);
  653. AZ_TEST_ASSERT(intint_map3.lower_bound(3)->second == 3000);
  654. AZ_TEST_ASSERT(intint_map3.lower_bound(4)->second == 40000 || intint_map3.lower_bound(4)->second == 40001);
  655. AZ_TEST_ASSERT((++intint_map3.lower_bound(4))->second == 40000 || (++intint_map3.lower_bound(4))->second == 40001);
  656. AZ_TEST_ASSERT(intint_map3.lower_bound(5)->second == 500000);
  657. }
  658. TEST_F(Tree_MultiMap, ExplicitAllocatorSucceeds)
  659. {
  660. AZ::OSAllocator customAllocator;
  661. AZStd::multimap<int, int, AZStd::less<int>, AZ::AZStdIAllocator> mapWithCustomAllocator{ AZ::AZStdIAllocator(&customAllocator) };
  662. mapWithCustomAllocator.emplace(1, 1);
  663. mapWithCustomAllocator.emplace(1, 2);
  664. EXPECT_EQ(2, mapWithCustomAllocator.size());
  665. }
  666. template<typename ContainerType>
  667. class TreeSetContainers
  668. : public LeakDetectionFixture
  669. {
  670. };
  671. struct MoveOnlyIntType
  672. {
  673. MoveOnlyIntType() = default;
  674. MoveOnlyIntType(int32_t value)
  675. : m_value(value)
  676. {}
  677. MoveOnlyIntType(const MoveOnlyIntType&) = delete;
  678. MoveOnlyIntType& operator=(const MoveOnlyIntType&) = delete;
  679. MoveOnlyIntType(MoveOnlyIntType&& other)
  680. : m_value(other.m_value)
  681. {
  682. }
  683. MoveOnlyIntType& operator=(MoveOnlyIntType&& other)
  684. {
  685. m_value = other.m_value;
  686. other.m_value = {};
  687. return *this;
  688. }
  689. explicit operator int32_t()
  690. {
  691. return m_value;
  692. }
  693. bool operator==(const MoveOnlyIntType& other) const
  694. {
  695. return m_value == other.m_value;
  696. }
  697. int32_t m_value;
  698. };
  699. struct MoveOnlyIntTypeCompare
  700. {
  701. bool operator()(const MoveOnlyIntType& lhs, const MoveOnlyIntType& rhs) const
  702. {
  703. return lhs.m_value < rhs.m_value;
  704. }
  705. };
  706. template<typename ContainerType>
  707. struct TreeSetConfig
  708. {
  709. using SetType = ContainerType;
  710. static SetType Create()
  711. {
  712. SetType testSet;
  713. testSet.emplace(1);
  714. testSet.emplace(2);
  715. testSet.emplace(84075);
  716. testSet.emplace(-73);
  717. testSet.emplace(534);
  718. testSet.emplace(-845920);
  719. testSet.emplace(-42);
  720. testSet.emplace(0b1111'0000);
  721. return testSet;
  722. }
  723. };
  724. using SetContainerConfigs = ::testing::Types<
  725. TreeSetConfig<AZStd::set<int32_t>>
  726. , TreeSetConfig<AZStd::multiset<int32_t>>
  727. , TreeSetConfig<AZStd::set<MoveOnlyIntType, MoveOnlyIntTypeCompare>>
  728. , TreeSetConfig<AZStd::multiset<MoveOnlyIntType, MoveOnlyIntTypeCompare>>
  729. >;
  730. TYPED_TEST_CASE(TreeSetContainers, SetContainerConfigs);
  731. TYPED_TEST(TreeSetContainers, ExtractNodeHandleByKeySucceeds)
  732. {
  733. using SetType = typename TypeParam::SetType;
  734. using node_type = typename SetType::node_type;
  735. SetType testContainer = TypeParam::Create();
  736. node_type extractedNode = testContainer.extract(84075);
  737. EXPECT_EQ(7, testContainer.size());
  738. EXPECT_FALSE(extractedNode.empty());
  739. EXPECT_EQ(84075, static_cast<int32_t>(extractedNode.value()));
  740. }
  741. TYPED_TEST(TreeSetContainers, ExtractNodeHandleByKeyFails)
  742. {
  743. using SetType = typename TypeParam::SetType;
  744. using node_type = typename SetType::node_type;
  745. SetType testContainer = TypeParam::Create();
  746. node_type extractedNode = testContainer.extract(10000001);
  747. EXPECT_EQ(8, testContainer.size());
  748. EXPECT_TRUE(extractedNode.empty());
  749. }
  750. TYPED_TEST(TreeSetContainers, ExtractNodeHandleByIteratorSucceeds)
  751. {
  752. using SetType = typename TypeParam::SetType;
  753. using node_type = typename SetType::node_type;
  754. SetType testContainer = TypeParam::Create();
  755. auto foundIter = testContainer.find(-73);
  756. node_type extractedNode = testContainer.extract(foundIter);
  757. EXPECT_EQ(7, testContainer.size());
  758. EXPECT_FALSE(extractedNode.empty());
  759. EXPECT_EQ(-73, static_cast<int32_t>(extractedNode.value()));
  760. }
  761. TYPED_TEST(TreeSetContainers, ExtractAndReinsertNodeHandleByIteratorSucceeds)
  762. {
  763. using SetType = typename TypeParam::SetType;
  764. using node_type = typename SetType::node_type;
  765. SetType testContainer = TypeParam::Create();
  766. auto foundIter = testContainer.find(-73);
  767. auto nextIter = AZStd::next(foundIter);
  768. node_type extractedNode = testContainer.extract(foundIter);
  769. extractedNode.value() = static_cast<int32_t>(extractedNode.value()) + 1;
  770. testContainer.insert(nextIter, AZStd::move(extractedNode));
  771. // Lookup reinserted node
  772. foundIter = testContainer.find(-72);
  773. ASSERT_NE(testContainer.end(), foundIter);
  774. }
  775. TYPED_TEST(TreeSetContainers, InsertNodeHandleSucceeds)
  776. {
  777. using SetType = AZStd::set<int32_t>;
  778. using node_type = typename SetType::node_type;
  779. using insert_return_type = typename SetType::insert_return_type;
  780. SetType testContainer = TreeSetConfig<SetType>::Create();
  781. node_type extractedNode = testContainer.extract(84075);
  782. EXPECT_EQ(7, testContainer.size());
  783. EXPECT_FALSE(extractedNode.empty());
  784. EXPECT_EQ(84075, static_cast<int32_t>(extractedNode.value()));
  785. extractedNode.value() = -60;
  786. insert_return_type insertResult = testContainer.insert(AZStd::move(extractedNode));
  787. EXPECT_NE(testContainer.end(), insertResult.position);
  788. EXPECT_TRUE(insertResult.inserted);
  789. EXPECT_TRUE(insertResult.node.empty());
  790. EXPECT_NE(0, testContainer.count(-60));
  791. EXPECT_EQ(8, testContainer.size());
  792. }
  793. TEST_F(Tree_Set, SetInsertNodeHandleSucceeds)
  794. {
  795. using SetType = AZStd::set<int32_t>;
  796. using node_type = typename SetType::node_type;
  797. using insert_return_type = typename SetType::insert_return_type;
  798. SetType testContainer = TreeSetConfig<SetType>::Create();
  799. node_type extractedNode;
  800. EXPECT_TRUE(extractedNode.empty());
  801. insert_return_type insertResult = testContainer.insert(AZStd::move(extractedNode));
  802. EXPECT_EQ(testContainer.end(), insertResult.position);
  803. EXPECT_FALSE(insertResult.inserted);
  804. EXPECT_TRUE(insertResult.node.empty());
  805. EXPECT_EQ(8, testContainer.size());
  806. }
  807. TEST_F(Tree_Set, SetInsertNodeHandleWithEmptyNodeHandleFails)
  808. {
  809. using SetType = AZStd::set<int32_t>;
  810. using node_type = typename SetType::node_type;
  811. using insert_return_type = typename SetType::insert_return_type;
  812. SetType testContainer = TreeSetConfig<SetType>::Create();
  813. node_type extractedNode;
  814. EXPECT_TRUE(extractedNode.empty());
  815. insert_return_type insertResult = testContainer.insert(AZStd::move(extractedNode));
  816. EXPECT_EQ(testContainer.end(), insertResult.position);
  817. EXPECT_FALSE(insertResult.inserted);
  818. EXPECT_TRUE(insertResult.node.empty());
  819. EXPECT_EQ(8, testContainer.size());
  820. }
  821. TEST_F(Tree_Set, SetInsertNodeHandleWithDuplicateValueInNodeHandleFails)
  822. {
  823. using SetType = AZStd::set<int32_t>;
  824. using node_type = typename SetType::node_type;
  825. using insert_return_type = typename SetType::insert_return_type;
  826. SetType testContainer = TreeSetConfig<SetType>::Create();
  827. node_type extractedNode = testContainer.extract(2);
  828. EXPECT_EQ(7, testContainer.size());
  829. EXPECT_FALSE(extractedNode.empty());
  830. EXPECT_EQ(2, static_cast<int32_t>(extractedNode.value()));
  831. // Set node handle value to a key that is currently within the container
  832. extractedNode.value() = 534;
  833. insert_return_type insertResult = testContainer.insert(AZStd::move(extractedNode));
  834. EXPECT_NE(testContainer.end(), insertResult.position);
  835. EXPECT_FALSE(insertResult.inserted);
  836. EXPECT_FALSE(insertResult.node.empty());
  837. EXPECT_EQ(7, testContainer.size());
  838. }
  839. TEST_F(Tree_Set, SetExtractedNodeCanBeInsertedIntoMultiset)
  840. {
  841. using SetType = AZStd::set<int32_t>;
  842. using MultisetType = AZStd::multiset<int32_t>;
  843. SetType uniqueSet{ 1, 2, 3 };
  844. MultisetType multiSet{ 1, 4, 1 };
  845. auto extractedNode = uniqueSet.extract(1);
  846. EXPECT_EQ(2, uniqueSet.size());
  847. EXPECT_FALSE(extractedNode.empty());
  848. auto insertIt = multiSet.insert(AZStd::move(extractedNode));
  849. EXPECT_NE(multiSet.end(), insertIt);
  850. EXPECT_EQ(4, multiSet.size());
  851. EXPECT_EQ(3, multiSet.count(1));
  852. }
  853. TEST_F(Tree_Set, MultisetExtractedNodeCanBeInsertedIntoSet)
  854. {
  855. using SetType = AZStd::set<int32_t>;
  856. using MultisetType = AZStd::multiset<int32_t>;
  857. SetType uniqueSet{ 1, 2, 3 };
  858. MultisetType multiSet{ 1, 4, 1 };
  859. auto extractedNode = multiSet.extract(4);
  860. EXPECT_EQ(2, multiSet.size());
  861. EXPECT_FALSE(extractedNode.empty());
  862. auto insertResult = uniqueSet.insert(AZStd::move(extractedNode));
  863. EXPECT_TRUE(insertResult.inserted);
  864. EXPECT_EQ(4, uniqueSet.size());
  865. EXPECT_EQ(1, uniqueSet.count(4));
  866. }
  867. template<template<class...> class SetTemplate>
  868. static void TreeSetRangeConstructorSucceeds()
  869. {
  870. constexpr AZStd::string_view testView = "abc";
  871. SetTemplate testSet(AZStd::from_range, testView);
  872. EXPECT_THAT(testSet, ::testing::ElementsAre('a', 'b', 'c'));
  873. testSet = SetTemplate(AZStd::from_range, AZStd::vector<char>{testView.begin(), testView.end()});
  874. EXPECT_THAT(testSet, ::testing::ElementsAre('a', 'b', 'c'));
  875. testSet = SetTemplate(AZStd::from_range, AZStd::list<char>{testView.begin(), testView.end()});
  876. EXPECT_THAT(testSet, ::testing::ElementsAre('a', 'b', 'c'));
  877. testSet = SetTemplate(AZStd::from_range, AZStd::deque<char>{testView.begin(), testView.end()});
  878. EXPECT_THAT(testSet, ::testing::ElementsAre('a', 'b', 'c'));
  879. testSet = SetTemplate(AZStd::from_range, AZStd::set<char>{testView.begin(), testView.end()});
  880. EXPECT_THAT(testSet, ::testing::ElementsAre('a', 'b', 'c'));
  881. testSet = SetTemplate(AZStd::from_range, AZStd::unordered_set<char>{testView.begin(), testView.end()});
  882. EXPECT_THAT(testSet, ::testing::ElementsAre('a', 'b', 'c'));
  883. testSet = SetTemplate(AZStd::from_range, AZStd::fixed_vector<char, 8>{testView.begin(), testView.end()});
  884. EXPECT_THAT(testSet, ::testing::ElementsAre('a', 'b', 'c'));
  885. testSet = SetTemplate(AZStd::from_range, AZStd::array{ 'a', 'b', 'c' });
  886. EXPECT_THAT(testSet, ::testing::ElementsAre('a', 'b', 'c'));
  887. testSet = SetTemplate(AZStd::from_range, AZStd::span(testView));
  888. EXPECT_THAT(testSet, ::testing::ElementsAre('a', 'b', 'c'));
  889. testSet = SetTemplate(AZStd::from_range, AZStd::span(testView));
  890. EXPECT_THAT(testSet, ::testing::ElementsAre('a', 'b', 'c'));
  891. AZStd::fixed_string<8> testValue(testView);
  892. testSet = SetTemplate(AZStd::from_range, testValue);
  893. EXPECT_THAT(testSet, ::testing::ElementsAre('a', 'b', 'c'));
  894. testSet = SetTemplate(AZStd::from_range, AZStd::string(testView));
  895. EXPECT_THAT(testSet, ::testing::ElementsAre('a', 'b', 'c'));
  896. // Test Range views
  897. testSet = SetTemplate(AZStd::from_range, testValue | AZStd::views::transform([](const char elem) -> char { return elem + 1; }));
  898. EXPECT_THAT(testSet, ::testing::ElementsAre('b', 'c', 'd'));
  899. }
  900. TEST_F(Tree_Set, RangeConstructor_Succeeds)
  901. {
  902. TreeSetRangeConstructorSucceeds<AZStd::set>();
  903. TreeSetRangeConstructorSucceeds<AZStd::multiset>();
  904. }
  905. template<template<class...> class SetTemplate>
  906. static void TreeSetInsertRangeSucceeds()
  907. {
  908. constexpr AZStd::string_view testView = "abc";
  909. SetTemplate testSet{ 'd', 'e', 'f' };
  910. testSet.insert_range(AZStd::vector<char>{testView.begin(), testView.end()});
  911. testSet.insert_range(testView | AZStd::views::transform([](const char elem) -> char { return elem + 6; }));
  912. EXPECT_THAT(testSet, ::testing::ElementsAre('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'));
  913. }
  914. TEST_F(Tree_Set, InsertRange_Succeeds)
  915. {
  916. TreeSetInsertRangeSucceeds<AZStd::set>();
  917. TreeSetInsertRangeSucceeds<AZStd::multiset>();
  918. }
  919. template <typename ContainerType>
  920. class TreeSetDifferentAllocatorFixture
  921. : public LeakDetectionFixture
  922. {
  923. };
  924. template<template <typename, typename, typename> class ContainerTemplate>
  925. struct TreeSetWithCustomAllocatorConfig
  926. {
  927. using ContainerType = ContainerTemplate<int32_t, AZStd::less<int32_t>, AZ::AZStdIAllocator>;
  928. static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocator* allocatorInstance)
  929. {
  930. ContainerType allocatorSet(intList, AZStd::less<int32_t>{}, AZ::AZStdIAllocator{ allocatorInstance });
  931. return allocatorSet;
  932. }
  933. };
  934. using SetTemplateConfigs = ::testing::Types<
  935. TreeSetWithCustomAllocatorConfig<AZStd::set>
  936. , TreeSetWithCustomAllocatorConfig<AZStd::multiset>
  937. >;
  938. TYPED_TEST_CASE(TreeSetDifferentAllocatorFixture, SetTemplateConfigs);
  939. #if GTEST_HAS_DEATH_TEST
  940. #if AZ_TRAIT_DISABLE_FAILED_DEATH_TESTS
  941. TYPED_TEST(TreeSetDifferentAllocatorFixture, DISABLED_InsertNodeHandleWithDifferentAllocatorsLogsTraceMessages)
  942. #else
  943. TYPED_TEST(TreeSetDifferentAllocatorFixture, InsertNodeHandleWithDifferentAllocatorsLogsTraceMessages)
  944. #endif // AZ_TRAIT_DISABLE_FAILED_DEATH_TESTS
  945. {
  946. using ContainerType = typename TypeParam::ContainerType;
  947. ContainerType systemAllocatorSet = TypeParam::Create({ {1}, {2}, {3} }, &AZ::AllocatorInstance<AZ::SystemAllocator>::Get());
  948. auto extractedNode = systemAllocatorSet.extract(1);
  949. ContainerType osAllocatorSet = TypeParam::Create({ {2} }, &AZ::AllocatorInstance<AZ::OSAllocator>::Get());
  950. // Attempt to insert an extracted node from a container using the AZ::SystemAllocator into a container using the AZ::OSAllocator
  951. EXPECT_DEATH(
  952. {
  953. UnitTest::TestRunner::Instance().StartAssertTests();
  954. osAllocatorSet.insert(AZStd::move(extractedNode));
  955. if (UnitTest::TestRunner::Instance().StopAssertTests() > 0)
  956. {
  957. // AZ_Assert does not cause the application to exit in profile_test configuration
  958. // Therefore an exit with a non-zero error code is invoked to trigger the death condition
  959. exit(1);
  960. }
  961. }, ".*");
  962. }
  963. #endif // GTEST_HAS_DEATH_TEST
  964. TYPED_TEST(TreeSetDifferentAllocatorFixture, SwapMovesElementsWhenAllocatorsDiffer)
  965. {
  966. using ContainerType = typename TypeParam::ContainerType;
  967. ContainerType systemAllocatorMap = TypeParam::Create({ {1}, {2}, {3} }, &AZ::AllocatorInstance<AZ::SystemAllocator>::Get());
  968. ContainerType osAllocatorMap = TypeParam::Create({ {2} }, &AZ::AllocatorInstance<AZ::OSAllocator>::Get());
  969. // Swap the container elements around while leave the allocators the same.
  970. systemAllocatorMap.swap(osAllocatorMap);
  971. EXPECT_EQ(1, systemAllocatorMap.size());
  972. EXPECT_EQ(1, systemAllocatorMap.count(2));
  973. EXPECT_EQ(AZ::AZStdIAllocator(&AZ::AllocatorInstance<AZ::SystemAllocator>::Get()), systemAllocatorMap.get_allocator());
  974. EXPECT_EQ(3, osAllocatorMap.size());
  975. EXPECT_EQ(1, osAllocatorMap.count(1));
  976. EXPECT_EQ(1, osAllocatorMap.count(2));
  977. EXPECT_EQ(1, osAllocatorMap.count(3));
  978. EXPECT_EQ(AZ::AZStdIAllocator(&AZ::AllocatorInstance<AZ::OSAllocator>::Get()), osAllocatorMap.get_allocator());
  979. }
  980. template<typename ContainerType>
  981. class TreeMapContainers
  982. : public LeakDetectionFixture
  983. {
  984. };
  985. template<typename ContainerType>
  986. struct TreeMapConfig
  987. {
  988. using MapType = ContainerType;
  989. static MapType Create()
  990. {
  991. MapType testMap;
  992. testMap.emplace(8001, 1337);
  993. testMap.emplace(-200, 31337);
  994. testMap.emplace(-932, 0xbaddf00d);
  995. testMap.emplace(73, 0xfee1badd);
  996. testMap.emplace(1872, 0xCDCDCDCD);
  997. testMap.emplace(0xFF, 7000000);
  998. testMap.emplace(0777, 0b00110000010);
  999. testMap.emplace(0b11010110110000101, 0xDDDDDDDD);
  1000. return testMap;
  1001. }
  1002. };
  1003. using MapContainerConfigs = ::testing::Types<
  1004. TreeMapConfig<AZStd::map<int32_t, int32_t>>
  1005. , TreeMapConfig<AZStd::multimap<int32_t, int32_t>>
  1006. , TreeMapConfig<AZStd::map<MoveOnlyIntType, int32_t, MoveOnlyIntTypeCompare>>
  1007. , TreeMapConfig<AZStd::multimap<MoveOnlyIntType, int32_t, MoveOnlyIntTypeCompare>>
  1008. >;
  1009. TYPED_TEST_CASE(TreeMapContainers, MapContainerConfigs);
  1010. TYPED_TEST(TreeMapContainers, ExtractNodeHandleByKeySucceeds)
  1011. {
  1012. using MapType = typename TypeParam::MapType;
  1013. using node_type = typename MapType::node_type;
  1014. MapType testContainer = TypeParam::Create();
  1015. node_type extractedNode = testContainer.extract(0777);
  1016. EXPECT_EQ(7, testContainer.size());
  1017. EXPECT_FALSE(extractedNode.empty());
  1018. EXPECT_EQ(0777, static_cast<int32_t>(extractedNode.key()));
  1019. EXPECT_EQ(0b00110000010, extractedNode.mapped());
  1020. }
  1021. TYPED_TEST(TreeMapContainers, ExtractNodeHandleByKeyFails)
  1022. {
  1023. using MapType = typename TypeParam::MapType;
  1024. using node_type = typename MapType::node_type;
  1025. MapType testContainer = TypeParam::Create();
  1026. node_type extractedNode = testContainer.extract(3);
  1027. EXPECT_EQ(8, testContainer.size());
  1028. EXPECT_TRUE(extractedNode.empty());
  1029. }
  1030. TYPED_TEST(TreeMapContainers, ExtractNodeHandleByIteratorSucceeds)
  1031. {
  1032. using MapType = typename TypeParam::MapType;
  1033. using node_type = typename MapType::node_type;
  1034. MapType testContainer = TypeParam::Create();
  1035. auto foundIter = testContainer.find(73);
  1036. node_type extractedNode = testContainer.extract(foundIter);
  1037. EXPECT_EQ(7, testContainer.size());
  1038. EXPECT_FALSE(extractedNode.empty());
  1039. EXPECT_EQ(73, static_cast<int32_t>(extractedNode.key()));
  1040. EXPECT_EQ(0xfee1badd, extractedNode.mapped());
  1041. }
  1042. TYPED_TEST(TreeMapContainers, ExtractAndReinsertNodeHandleByIteratorSucceeds)
  1043. {
  1044. using MapType = typename TypeParam::MapType;
  1045. using node_type = typename MapType::node_type;
  1046. MapType testContainer = TypeParam::Create();
  1047. auto foundIter = testContainer.find(73);
  1048. auto nextIter = AZStd::next(foundIter);
  1049. node_type extractedNode = testContainer.extract(foundIter);
  1050. extractedNode.key() = static_cast<int32_t>(extractedNode.key()) + 1;
  1051. testContainer.insert(nextIter, AZStd::move(extractedNode));
  1052. foundIter = testContainer.find(74);
  1053. ASSERT_NE(testContainer.end(), foundIter);
  1054. }
  1055. TYPED_TEST(TreeMapContainers, InsertNodeHandleSucceeds)
  1056. {
  1057. using MapType = typename TypeParam::MapType;
  1058. using node_type = typename MapType::node_type;
  1059. MapType testContainer = TypeParam::Create();
  1060. node_type extractedNode = testContainer.extract(0777);
  1061. EXPECT_EQ(7, testContainer.size());
  1062. EXPECT_FALSE(extractedNode.empty());
  1063. EXPECT_EQ(0777, static_cast<int32_t>(extractedNode.key()));
  1064. extractedNode.key() = 0644;
  1065. extractedNode.mapped() = 1'212;
  1066. testContainer.insert(AZStd::move(extractedNode));
  1067. auto foundIt = testContainer.find(0644);
  1068. EXPECT_NE(testContainer.end(), foundIt);
  1069. EXPECT_EQ(0644, static_cast<int32_t>(foundIt->first));
  1070. EXPECT_EQ(1'212, foundIt->second);
  1071. EXPECT_EQ(8, testContainer.size());
  1072. }
  1073. TEST_F(Tree_Map, MapInsertNodeHandleSucceeds)
  1074. {
  1075. using MapType = AZStd::map<int32_t, int32_t>;
  1076. using node_type = typename MapType::node_type;
  1077. using insert_return_type = typename MapType::insert_return_type;
  1078. MapType testContainer = TreeMapConfig<MapType>::Create();
  1079. node_type extractedNode = testContainer.extract(0b11010110110000101);
  1080. EXPECT_EQ(7, testContainer.size());
  1081. EXPECT_FALSE(extractedNode.empty());
  1082. EXPECT_EQ(0b11010110110000101, extractedNode.key());
  1083. extractedNode.key() = -60;
  1084. extractedNode.mapped() = -1;
  1085. insert_return_type insertResult = testContainer.insert(AZStd::move(extractedNode));
  1086. EXPECT_NE(testContainer.end(), insertResult.position);
  1087. EXPECT_TRUE(insertResult.inserted);
  1088. EXPECT_TRUE(insertResult.node.empty());
  1089. auto foundIt = testContainer.find(-60);
  1090. EXPECT_NE(testContainer.end(), foundIt);
  1091. EXPECT_EQ(-60, foundIt->first);
  1092. EXPECT_EQ(-1, foundIt->second);
  1093. EXPECT_EQ(8, testContainer.size());
  1094. }
  1095. TEST_F(Tree_Map, MapInsertNodeHandleWithEmptyNodeHandleFails)
  1096. {
  1097. using MapType = AZStd::map<int32_t, int32_t>;
  1098. using node_type = typename MapType::node_type;
  1099. using insert_return_type = typename MapType::insert_return_type;
  1100. MapType testContainer = TreeMapConfig<MapType>::Create();
  1101. node_type extractedNode;
  1102. EXPECT_TRUE(extractedNode.empty());
  1103. EXPECT_EQ(8, testContainer.size());
  1104. insert_return_type insertResult = testContainer.insert(AZStd::move(extractedNode));
  1105. EXPECT_EQ(testContainer.end(), insertResult.position);
  1106. EXPECT_FALSE(insertResult.inserted);
  1107. EXPECT_TRUE(insertResult.node.empty());
  1108. EXPECT_EQ(8, testContainer.size());
  1109. }
  1110. TEST_F(Tree_Map, MapInsertNodeHandleWithDuplicateValueInNodeHandleFails)
  1111. {
  1112. using MapType = AZStd::map<int32_t, int32_t>;
  1113. using node_type = typename MapType::node_type;
  1114. using insert_return_type = typename MapType::insert_return_type;
  1115. MapType testContainer = TreeMapConfig<MapType>::Create();
  1116. node_type extractedNode = testContainer.extract(0xFF);
  1117. EXPECT_EQ(7, testContainer.size());
  1118. EXPECT_FALSE(extractedNode.empty());
  1119. EXPECT_EQ(0xFF, static_cast<int32_t>(extractedNode.key()));
  1120. // Update the extracted node to have the same key as one of the elements currently within the container
  1121. extractedNode.key() = -200;
  1122. insert_return_type insertResult = testContainer.insert(AZStd::move(extractedNode));
  1123. EXPECT_NE(testContainer.end(), insertResult.position);
  1124. EXPECT_FALSE(insertResult.inserted);
  1125. EXPECT_FALSE(insertResult.node.empty());
  1126. EXPECT_EQ(7, testContainer.size());
  1127. }
  1128. TEST_F(Tree_Map, MapExtractedNodeCanBeInsertedIntoMultimap)
  1129. {
  1130. using MapType = AZStd::map<int32_t, int32_t>;
  1131. using MultimapType = AZStd::multimap<int32_t, int32_t>;
  1132. MapType uniqueMap{ {1, 2}, {2, 4}, {3, 6} };
  1133. MultimapType multiMap{ {1, 2}, { 4, 8}, {1, 3} };
  1134. auto extractedNode = uniqueMap.extract(1);
  1135. EXPECT_EQ(2, uniqueMap.size());
  1136. EXPECT_FALSE(extractedNode.empty());
  1137. auto insertIt = multiMap.insert(AZStd::move(extractedNode));
  1138. EXPECT_NE(multiMap.end(), insertIt);
  1139. EXPECT_EQ(4, multiMap.size());
  1140. EXPECT_EQ(3, multiMap.count(1));
  1141. }
  1142. TEST_F(Tree_Map, MultimapExtractedNodeCanBeInsertedIntoMap)
  1143. {
  1144. using MapType = AZStd::map<int32_t, int32_t>;
  1145. using MultimapType = AZStd::multimap<int32_t, int32_t>;
  1146. MapType uniqueMap{ {1, 2}, {2, 4}, {3, 6} };
  1147. MultimapType multiMap{ {1, 2}, { 4, 8}, {1, 3} };
  1148. auto extractedNode = multiMap.extract(4);
  1149. EXPECT_EQ(2, multiMap.size());
  1150. EXPECT_FALSE(extractedNode.empty());
  1151. auto insertResult = uniqueMap.insert(AZStd::move(extractedNode));
  1152. EXPECT_TRUE(insertResult.inserted);
  1153. EXPECT_EQ(4, uniqueMap.size());
  1154. EXPECT_EQ(1, uniqueMap.count(4));
  1155. }
  1156. TEST_F(Tree_Map, MapTryEmplace_DoesNotConstruct_OnExistingKey)
  1157. {
  1158. static int s_tryEmplaceConstructorCallCount;
  1159. s_tryEmplaceConstructorCallCount = 0;
  1160. struct TryEmplaceConstructorCalls
  1161. {
  1162. TryEmplaceConstructorCalls()
  1163. {
  1164. ++s_tryEmplaceConstructorCallCount;
  1165. }
  1166. TryEmplaceConstructorCalls(int value)
  1167. : m_value{ value }
  1168. {
  1169. ++s_tryEmplaceConstructorCallCount;
  1170. }
  1171. TryEmplaceConstructorCalls(const TryEmplaceConstructorCalls& other)
  1172. : m_value{ other.m_value }
  1173. {
  1174. ++s_tryEmplaceConstructorCallCount;
  1175. }
  1176. int m_value{};
  1177. };
  1178. using TryEmplaceTestMap = AZStd::map<int, TryEmplaceConstructorCalls>;
  1179. TryEmplaceTestMap testContainer;
  1180. // try_emplace move key
  1181. AZStd::pair<TryEmplaceTestMap::iterator, bool> emplacePairIter = testContainer.try_emplace(1, 5);
  1182. EXPECT_EQ(1, s_tryEmplaceConstructorCallCount);
  1183. EXPECT_TRUE(emplacePairIter.second);
  1184. EXPECT_EQ(5, emplacePairIter.first->second.m_value);
  1185. // try_emplace copy key
  1186. int testKey = 3;
  1187. emplacePairIter = testContainer.try_emplace(testKey, 72);
  1188. EXPECT_EQ(2, s_tryEmplaceConstructorCallCount);
  1189. EXPECT_TRUE(emplacePairIter.second);
  1190. EXPECT_EQ(72, emplacePairIter.first->second.m_value);
  1191. // invoke try_emplace with hint and move key
  1192. TryEmplaceTestMap::iterator emplaceIter = testContainer.try_emplace(testContainer.end(), 5, 4092);
  1193. EXPECT_EQ(3, s_tryEmplaceConstructorCallCount);
  1194. EXPECT_EQ(4092, emplaceIter->second.m_value);
  1195. // invoke try_emplace with hint and copy key
  1196. testKey = 48;
  1197. emplaceIter = testContainer.try_emplace(testContainer.end(), testKey, 824);
  1198. EXPECT_EQ(4, s_tryEmplaceConstructorCallCount);
  1199. EXPECT_EQ(824, emplaceIter->second.m_value);
  1200. // Since the key of '1' exist, nothing should be constructed
  1201. emplacePairIter = testContainer.try_emplace(1, -6354);
  1202. EXPECT_EQ(4, s_tryEmplaceConstructorCallCount);
  1203. EXPECT_FALSE(emplacePairIter.second);
  1204. EXPECT_EQ(5, emplacePairIter.first->second.m_value);
  1205. }
  1206. TEST_F(Tree_Map, MapTryEmplace_DoesNotMoveValue_OnExistingKey)
  1207. {
  1208. AZStd::unordered_map<int, AZStd::unique_ptr<int>> testMap;
  1209. auto testPtr = AZStd::make_unique<int>(5);
  1210. auto [emplaceIter, inserted] = testMap.try_emplace(1, AZStd::move(testPtr));
  1211. EXPECT_TRUE(inserted);
  1212. EXPECT_EQ(nullptr, testPtr);
  1213. testPtr = AZStd::make_unique<int>(7000);
  1214. auto [emplaceIter2, inserted2] = testMap.try_emplace(1, AZStd::move(testPtr));
  1215. EXPECT_FALSE(inserted2);
  1216. ASSERT_NE(nullptr, testPtr);
  1217. EXPECT_EQ(7000, *testPtr);
  1218. }
  1219. TEST_F(Tree_Map, MapInsertOrAssign_PerformsAssignment_OnExistingKey)
  1220. {
  1221. static int s_tryInsertOrAssignConstructorCalls;
  1222. static int s_tryInsertOrAssignAssignmentCalls;
  1223. s_tryInsertOrAssignConstructorCalls = 0;
  1224. s_tryInsertOrAssignAssignmentCalls = 0;
  1225. struct InsertOrAssignInitCalls
  1226. {
  1227. InsertOrAssignInitCalls()
  1228. {
  1229. ++s_tryInsertOrAssignConstructorCalls;
  1230. }
  1231. InsertOrAssignInitCalls(int value)
  1232. : m_value{ value }
  1233. {
  1234. ++s_tryInsertOrAssignConstructorCalls;
  1235. }
  1236. InsertOrAssignInitCalls(const InsertOrAssignInitCalls& other)
  1237. : m_value{ other.m_value }
  1238. {
  1239. ++s_tryInsertOrAssignConstructorCalls;
  1240. }
  1241. InsertOrAssignInitCalls& operator=(int value)
  1242. {
  1243. m_value = value;
  1244. ++s_tryInsertOrAssignAssignmentCalls;
  1245. return *this;
  1246. }
  1247. int m_value{};
  1248. };
  1249. using InsertOrAssignTestMap = AZStd::map<int, InsertOrAssignInitCalls>;
  1250. InsertOrAssignTestMap testContainer;
  1251. // insert_or_assign move key
  1252. AZStd::pair<InsertOrAssignTestMap::iterator, bool> insertOrAssignPairIter = testContainer.insert_or_assign(1, 5);
  1253. EXPECT_EQ(1, s_tryInsertOrAssignConstructorCalls);
  1254. EXPECT_EQ(0, s_tryInsertOrAssignAssignmentCalls);
  1255. EXPECT_TRUE(insertOrAssignPairIter.second);
  1256. EXPECT_EQ(5, insertOrAssignPairIter.first->second.m_value);
  1257. // insert_or_assign copy key
  1258. int testKey = 3;
  1259. insertOrAssignPairIter = testContainer.insert_or_assign(testKey, 72);
  1260. EXPECT_EQ(2, s_tryInsertOrAssignConstructorCalls);
  1261. EXPECT_EQ(0, s_tryInsertOrAssignAssignmentCalls);
  1262. EXPECT_TRUE(insertOrAssignPairIter.second);
  1263. EXPECT_EQ(72, insertOrAssignPairIter.first->second.m_value);
  1264. // invoke insert_or_assign with hint and move key
  1265. InsertOrAssignTestMap::iterator insertOrAssignIter = testContainer.insert_or_assign(testContainer.end(), 5, 4092);
  1266. EXPECT_EQ(3, s_tryInsertOrAssignConstructorCalls);
  1267. EXPECT_EQ(0, s_tryInsertOrAssignAssignmentCalls);
  1268. EXPECT_EQ(4092, insertOrAssignIter->second.m_value);
  1269. // invoke insert_or_assign with hint and copy key
  1270. testKey = 48;
  1271. insertOrAssignIter = testContainer.insert_or_assign(testContainer.end(), testKey, 824);
  1272. EXPECT_EQ(4, s_tryInsertOrAssignConstructorCalls);
  1273. EXPECT_EQ(0, s_tryInsertOrAssignAssignmentCalls);
  1274. EXPECT_EQ(824, insertOrAssignIter->second.m_value);
  1275. // Since the key of '1' exist, only an assignment should take place
  1276. insertOrAssignPairIter = testContainer.insert_or_assign(1, -6354);
  1277. EXPECT_EQ(4, s_tryInsertOrAssignConstructorCalls);
  1278. EXPECT_EQ(1, s_tryInsertOrAssignAssignmentCalls);
  1279. EXPECT_FALSE(insertOrAssignPairIter.second);
  1280. EXPECT_EQ(-6354, insertOrAssignPairIter.first->second.m_value);
  1281. }
  1282. template<template<class...> class MapTemplate>
  1283. static void TreeMapRangeConstructorSucceeds()
  1284. {
  1285. using ValueType = AZStd::pair<char, int>;
  1286. constexpr AZStd::array testArray{ ValueType{'a', 1}, ValueType{'b', 2}, ValueType{'c', 3} };
  1287. MapTemplate testMap(AZStd::from_range, testArray);
  1288. EXPECT_THAT(testMap, ::testing::ElementsAre(ValueType{ 'a', 1 }, ValueType{ 'b', 2 }, ValueType{ 'c', 3 }));
  1289. testMap = MapTemplate(AZStd::from_range, AZStd::vector<ValueType>{testArray.begin(), testArray.end()});
  1290. EXPECT_THAT(testMap, ::testing::ElementsAre(ValueType{ 'a', 1 }, ValueType{ 'b', 2 }, ValueType{ 'c', 3 }));
  1291. testMap = MapTemplate(AZStd::from_range, AZStd::list<ValueType>{testArray.begin(), testArray.end()});
  1292. EXPECT_THAT(testMap, ::testing::ElementsAre(ValueType{ 'a', 1 }, ValueType{ 'b', 2 }, ValueType{ 'c', 3 }));
  1293. testMap = MapTemplate(AZStd::from_range, AZStd::deque<ValueType>{testArray.begin(), testArray.end()});
  1294. EXPECT_THAT(testMap, ::testing::ElementsAre(ValueType{ 'a', 1 }, ValueType{ 'b', 2 }, ValueType{ 'c', 3 }));
  1295. testMap = MapTemplate(AZStd::from_range, AZStd::set<ValueType>{testArray.begin(), testArray.end()});
  1296. EXPECT_THAT(testMap, ::testing::ElementsAre(ValueType{ 'a', 1 }, ValueType{ 'b', 2 }, ValueType{ 'c', 3 }));
  1297. testMap = MapTemplate(AZStd::from_range, AZStd::unordered_set<ValueType>{testArray.begin(), testArray.end()});
  1298. EXPECT_THAT(testMap, ::testing::ElementsAre(ValueType{ 'a', 1 }, ValueType{ 'b', 2 }, ValueType{ 'c', 3 }));
  1299. testMap = MapTemplate(AZStd::from_range, AZStd::fixed_vector<ValueType, 8>{testArray.begin(), testArray.end()});
  1300. EXPECT_THAT(testMap, ::testing::ElementsAre(ValueType{ 'a', 1 }, ValueType{ 'b', 2 }, ValueType{ 'c', 3 }));
  1301. testMap = MapTemplate(AZStd::from_range, AZStd::span(testArray));
  1302. EXPECT_THAT(testMap, ::testing::ElementsAre(ValueType{ 'a', 1 }, ValueType{ 'b', 2 }, ValueType{ 'c', 3 }));
  1303. }
  1304. TEST_F(Tree_Map, RangeConstructor_Succeeds)
  1305. {
  1306. TreeMapRangeConstructorSucceeds<AZStd::map>();
  1307. TreeMapRangeConstructorSucceeds<AZStd::multimap>();
  1308. }
  1309. template<template<class...> class MapTemplate>
  1310. static void TreeMapInsertRangeSucceeds()
  1311. {
  1312. using ValueType = AZStd::pair<char, int>;
  1313. constexpr AZStd::array testArray{ ValueType{'a', 1}, ValueType{'b', 2}, ValueType{'c', 3} };
  1314. MapTemplate testMap(AZStd::from_range, testArray);
  1315. testMap.insert_range(AZStd::vector<ValueType>{ValueType{ 'd', 4 }, ValueType{ 'e', 5 }, ValueType{ 'f', 6 }});
  1316. EXPECT_THAT(testMap, ::testing::ElementsAre(ValueType{ 'a', 1 }, ValueType{ 'b', 2 }, ValueType{ 'c', 3 },
  1317. ValueType{ 'd', 4 }, ValueType{ 'e', 5 }, ValueType{ 'f', 6 }));
  1318. }
  1319. TEST_F(Tree_Map, InsertRange_Succeeds)
  1320. {
  1321. TreeMapInsertRangeSucceeds<AZStd::map>();
  1322. TreeMapInsertRangeSucceeds<AZStd::multimap>();
  1323. }
  1324. template <typename ContainerType>
  1325. class TreeMapDifferentAllocatorFixture
  1326. : public LeakDetectionFixture
  1327. {
  1328. };
  1329. template<template <typename, typename, typename, typename> class ContainerTemplate>
  1330. struct TreeMapWithCustomAllocatorConfig
  1331. {
  1332. using ContainerType = ContainerTemplate<int32_t, int32_t, AZStd::less<int32_t>, AZ::AZStdIAllocator>;
  1333. static ContainerType Create(std::initializer_list<typename ContainerType::value_type> intList, AZ::IAllocator* allocatorInstance)
  1334. {
  1335. ContainerType allocatorMap(intList, AZStd::less<int32_t>{}, AZ::AZStdIAllocator{ allocatorInstance });
  1336. return allocatorMap;
  1337. }
  1338. };
  1339. using MapTemplateConfigs = ::testing::Types<
  1340. TreeMapWithCustomAllocatorConfig<AZStd::map>
  1341. , TreeMapWithCustomAllocatorConfig<AZStd::multimap>
  1342. >;
  1343. TYPED_TEST_CASE(TreeMapDifferentAllocatorFixture, MapTemplateConfigs);
  1344. #if GTEST_HAS_DEATH_TEST
  1345. #if AZ_TRAIT_DISABLE_FAILED_DEATH_TESTS
  1346. TYPED_TEST(TreeMapDifferentAllocatorFixture, DISABLED_InsertNodeHandleWithDifferentAllocatorsLogsTraceMessages)
  1347. #else
  1348. TYPED_TEST(TreeMapDifferentAllocatorFixture, InsertNodeHandleWithDifferentAllocatorsLogsTraceMessages)
  1349. #endif // AZ_TRAIT_DISABLE_FAILED_DEATH_TESTS
  1350. {
  1351. using ContainerType = typename TypeParam::ContainerType;
  1352. ContainerType systemAllocatorMap = TypeParam::Create({ {1, 2}, {2, 4}, {3, 6} }, &AZ::AllocatorInstance<AZ::SystemAllocator>::Get());
  1353. auto extractedNode = systemAllocatorMap.extract(1);
  1354. ContainerType osAllocatorMap = TypeParam::Create({ {2, 4} }, &AZ::AllocatorInstance<AZ::OSAllocator>::Get());
  1355. // Attempt to insert an extracted node from a container using the AZ::SystemAllocator into a container using the AZ::OSAllocator
  1356. EXPECT_DEATH(
  1357. {
  1358. UnitTest::TestRunner::Instance().StartAssertTests();
  1359. osAllocatorMap.insert(AZStd::move(extractedNode));
  1360. if (UnitTest::TestRunner::Instance().StopAssertTests() > 0)
  1361. {
  1362. // AZ_Assert does not cause the application to exit in profile_test configuration
  1363. // Therefore an exit with a non-zero error code is invoked to trigger the death condition
  1364. exit(1);
  1365. }
  1366. }, ".*");
  1367. }
  1368. #endif // GTEST_HAS_DEATH_TEST
  1369. TYPED_TEST(TreeMapDifferentAllocatorFixture, SwapMovesElementsWhenAllocatorsDiffer)
  1370. {
  1371. using ContainerType = typename TypeParam::ContainerType;
  1372. ContainerType systemAllocatorMap = TypeParam::Create({ {1, 2}, {2, 4}, {3, 6} }, &AZ::AllocatorInstance<AZ::SystemAllocator>::Get());
  1373. ContainerType osAllocatorMap = TypeParam::Create({ {2, 4} }, &AZ::AllocatorInstance<AZ::OSAllocator>::Get());
  1374. // Swap the container elements around while leaving the allocators the same.
  1375. systemAllocatorMap.swap(osAllocatorMap);
  1376. EXPECT_EQ(1, systemAllocatorMap.size());
  1377. EXPECT_EQ(1, systemAllocatorMap.count(2));
  1378. EXPECT_EQ(AZ::AZStdIAllocator(&AZ::AllocatorInstance<AZ::SystemAllocator>::Get()), systemAllocatorMap.get_allocator());
  1379. EXPECT_EQ(3, osAllocatorMap.size());
  1380. EXPECT_EQ(1, osAllocatorMap.count(1));
  1381. EXPECT_EQ(1, osAllocatorMap.count(2));
  1382. EXPECT_EQ(1, osAllocatorMap.count(3));
  1383. EXPECT_EQ(AZ::AZStdIAllocator(&AZ::AllocatorInstance<AZ::OSAllocator>::Get()), osAllocatorMap.get_allocator());
  1384. }
  1385. namespace TreeContainerTransparentTestInternal
  1386. {
  1387. static int s_allConstructorCount;
  1388. static int s_allAssignmentCount;
  1389. struct TrackConstructorCalls
  1390. {
  1391. TrackConstructorCalls()
  1392. {
  1393. ++s_allConstructorCount;
  1394. }
  1395. TrackConstructorCalls(int value)
  1396. : m_value(value)
  1397. {
  1398. ++s_allConstructorCount;
  1399. }
  1400. TrackConstructorCalls(const TrackConstructorCalls& other)
  1401. : m_value(other.m_value)
  1402. {
  1403. ++s_allConstructorCount;
  1404. };
  1405. TrackConstructorCalls& operator=(const TrackConstructorCalls& other)
  1406. {
  1407. ++s_allAssignmentCount;
  1408. m_value = other.m_value;
  1409. return *this;
  1410. }
  1411. operator int() const
  1412. {
  1413. return m_value;
  1414. }
  1415. int m_value{}; // Used for comparison
  1416. };
  1417. bool operator<(const TrackConstructorCalls& lhs, const TrackConstructorCalls& rhs)
  1418. {
  1419. return lhs.m_value < rhs.m_value;
  1420. }
  1421. bool operator<(int lhs, const TrackConstructorCalls& rhs)
  1422. {
  1423. return lhs < rhs.m_value;
  1424. }
  1425. bool operator<(const TrackConstructorCalls& lhs, int rhs)
  1426. {
  1427. return lhs.m_value < rhs;
  1428. }
  1429. }
  1430. template<typename Container>
  1431. struct TreeContainerTransparentConfig
  1432. {
  1433. using ContainerType = Container;
  1434. };
  1435. template <typename ContainerType>
  1436. class TreeContainerTransparentFixture
  1437. : public LeakDetectionFixture
  1438. {
  1439. protected:
  1440. void SetUp() override
  1441. {
  1442. TreeContainerTransparentTestInternal::s_allConstructorCount = 0;
  1443. TreeContainerTransparentTestInternal::s_allAssignmentCount = 0;
  1444. }
  1445. void TearDown() override
  1446. {
  1447. TreeContainerTransparentTestInternal::s_allConstructorCount = 0;
  1448. TreeContainerTransparentTestInternal::s_allAssignmentCount = 0;
  1449. }
  1450. };
  1451. using TreeContainerConfigs = ::testing::Types <
  1452. TreeContainerTransparentConfig<AZStd::set<TreeContainerTransparentTestInternal::TrackConstructorCalls, AZStd::less<>>>
  1453. , TreeContainerTransparentConfig<AZStd::multiset<TreeContainerTransparentTestInternal::TrackConstructorCalls, AZStd::less<>>>
  1454. , TreeContainerTransparentConfig<AZStd::map<TreeContainerTransparentTestInternal::TrackConstructorCalls, int, AZStd::less<>>>
  1455. , TreeContainerTransparentConfig<AZStd::multimap<TreeContainerTransparentTestInternal::TrackConstructorCalls, int, AZStd::less<>>>
  1456. >;
  1457. TYPED_TEST_CASE(TreeContainerTransparentFixture, TreeContainerConfigs);
  1458. TYPED_TEST(TreeContainerTransparentFixture, FindDoesNotConstructKeyForTransparentHashEqual_NoKeyConstructed_Succeeds)
  1459. {
  1460. typename TypeParam::ContainerType container;
  1461. container.emplace(1);
  1462. container.emplace(2);
  1463. container.emplace(3);
  1464. container.emplace(4);
  1465. container.emplace(5);
  1466. container.emplace(1);
  1467. // Reset constructor count to zero
  1468. TreeContainerTransparentTestInternal::s_allConstructorCount = 0;
  1469. // The following call will construct a TrackConstructorCalls element
  1470. auto foundIt = container.find(TreeContainerTransparentTestInternal::TrackConstructorCalls{ 2 });
  1471. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1472. EXPECT_NE(container.end(), foundIt);
  1473. // The transparent find function should be invoked and no constructor of TrackConstructorCallsElement should be invoked
  1474. foundIt = container.find(1);
  1475. // The ConstructorCount should still be the same
  1476. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1477. EXPECT_NE(container.end(), foundIt);
  1478. // When find fails to locate an element, TrackConstructorCallsElement shouldn't be construction
  1479. foundIt = container.find(-1);
  1480. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1481. EXPECT_EQ(container.end(), foundIt);
  1482. // No assignments should have taken place from any of the container operations
  1483. EXPECT_EQ(0, TreeContainerTransparentTestInternal::s_allAssignmentCount);
  1484. }
  1485. TYPED_TEST(TreeContainerTransparentFixture, ContainsDoesNotConstructKeyForTransparentHashEqual_NoKeyConstructed_Succeeds)
  1486. {
  1487. typename TypeParam::ContainerType container;
  1488. container.emplace(1);
  1489. container.emplace(2);
  1490. container.emplace(3);
  1491. container.emplace(4);
  1492. container.emplace(5);
  1493. container.emplace(1);
  1494. // Reset constructor count to zero
  1495. TreeContainerTransparentTestInternal::s_allConstructorCount = 0;
  1496. // The following call will construct a TrackConstructorCalls element
  1497. EXPECT_TRUE(container.contains(TreeContainerTransparentTestInternal::TrackConstructorCalls{ 2 }));
  1498. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1499. // The transparent contain function should be invoked and no constructor of TrackConstructorCallsElement should be invoked
  1500. EXPECT_TRUE(container.contains(2));
  1501. // The ConstructorCount should still be the same
  1502. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1503. // In the case when the element isn't found, no constructor shouldn't be invoked as well
  1504. EXPECT_FALSE(container.contains(27));
  1505. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1506. // No assignments should have taken place from any of the container operations
  1507. EXPECT_EQ(0, TreeContainerTransparentTestInternal::s_allAssignmentCount);
  1508. }
  1509. TYPED_TEST(TreeContainerTransparentFixture, CountDoesNotConstructKeyForTransparentHashEqual_NoKeyConstructed_Succeeds)
  1510. {
  1511. typename TypeParam::ContainerType container;
  1512. container.emplace(1);
  1513. container.emplace(2);
  1514. container.emplace(3);
  1515. container.emplace(4);
  1516. container.emplace(5);
  1517. container.emplace(1);
  1518. // Reset constructor count to zero
  1519. TreeContainerTransparentTestInternal::s_allConstructorCount = 0;
  1520. // The following call will construct a TrackConstructorCalls element
  1521. EXPECT_EQ(1, container.count(TreeContainerTransparentTestInternal::TrackConstructorCalls{ 2 }));
  1522. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1523. // The transparent count function should be invoked and no constructor of TrackConstructorCallsElement should be invoked
  1524. EXPECT_EQ(1, container.count(2));
  1525. // The ConstructorCount should still be the same
  1526. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1527. // In the case when the element isn't found, no constructor shouldn't be invoked as well
  1528. EXPECT_EQ(0, container.count(27));
  1529. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1530. // No assignments should have taken place from any of the container operations
  1531. EXPECT_EQ(0, TreeContainerTransparentTestInternal::s_allAssignmentCount);
  1532. }
  1533. TYPED_TEST(TreeContainerTransparentFixture, LowerBoundDoesNotConstructKeyForTransparentHashEqual_NoKeyConstructed_Succeeds)
  1534. {
  1535. typename TypeParam::ContainerType container;
  1536. container.emplace(21);
  1537. container.emplace(4);
  1538. container.emplace(3);
  1539. container.emplace(7);
  1540. container.emplace(15);
  1541. container.emplace(42);
  1542. // Reset constructor count to zero
  1543. TreeContainerTransparentTestInternal::s_allConstructorCount = 0;
  1544. // The following call will construct a TrackConstructorCalls element
  1545. auto foundIt = container.lower_bound(TreeContainerTransparentTestInternal::TrackConstructorCalls{ 2 });
  1546. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1547. EXPECT_NE(container.end(), foundIt);
  1548. // The transparent lower_bound function should be invoked and no constructor of TrackConstructorCallsElement should be invoked
  1549. foundIt = container.lower_bound(26);
  1550. // The ConstructorCount should still be the same
  1551. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1552. EXPECT_NE(container.end(), foundIt);
  1553. // In the case when the element isn't found, no constructor shouldn't be invoked as well
  1554. foundIt = container.lower_bound(562);
  1555. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1556. EXPECT_EQ(container.end(), foundIt);
  1557. // No assignments should have taken place from any of the container operations
  1558. EXPECT_EQ(0, TreeContainerTransparentTestInternal::s_allAssignmentCount);
  1559. }
  1560. TYPED_TEST(TreeContainerTransparentFixture, UpperBoundDoesNotConstructKeyForTransparentHashEqual_NoKeyConstructed_Succeeds)
  1561. {
  1562. typename TypeParam::ContainerType container;
  1563. container.emplace(2);
  1564. container.emplace(4);
  1565. container.emplace(15);
  1566. container.emplace(332);
  1567. container.emplace(5);
  1568. container.emplace(1);
  1569. // Reset constructor count to zero
  1570. TreeContainerTransparentTestInternal::s_allConstructorCount = 0;
  1571. // The following call will construct a TrackConstructorCalls element
  1572. auto foundIt = container.upper_bound(TreeContainerTransparentTestInternal::TrackConstructorCalls{ 3 });
  1573. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1574. EXPECT_NE(container.end(), foundIt);
  1575. // The transparent upper_bound function should be invoked and no constructor of TrackConstructorCallsElement should be invoked
  1576. foundIt = container.upper_bound(278);
  1577. // The ConstructorCount should still be the same
  1578. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1579. EXPECT_NE(container.end(), foundIt);
  1580. // In the case when the element isn't found, no constructor shouldn't be invoked as well
  1581. foundIt = container.upper_bound(1000);
  1582. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1583. EXPECT_EQ(container.end(), foundIt);
  1584. // No assignments should have taken place from any of the container operations
  1585. EXPECT_EQ(0, TreeContainerTransparentTestInternal::s_allAssignmentCount);
  1586. }
  1587. TYPED_TEST(TreeContainerTransparentFixture, EqualRangeDoesNotConstructKeyForTransparentHashEqual_NoKeyConstructed_Succeeds)
  1588. {
  1589. typename TypeParam::ContainerType container;
  1590. container.emplace(-2352);
  1591. container.emplace(3534);
  1592. container.emplace(535408957);
  1593. container.emplace(1310556522);
  1594. container.emplace(55546193);
  1595. container.emplace(1582);
  1596. // Reset constructor count to zero
  1597. TreeContainerTransparentTestInternal::s_allConstructorCount = 0;
  1598. // The following call will construct a TrackConstructorCalls element
  1599. auto foundRange = container.equal_range(TreeContainerTransparentTestInternal::TrackConstructorCalls{ -2352 });
  1600. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1601. EXPECT_NE(foundRange.first, foundRange.second);
  1602. // The transparent upper_bound function should be invoked and no constructor of TrackConstructorCallsElement should be invoked
  1603. foundRange = container.equal_range(55546193);
  1604. // The ConstructorCount should still be the same
  1605. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1606. EXPECT_NE(foundRange.first, foundRange.second);
  1607. // In the case when the element isn't found, no constructor shouldn't be invoked as well
  1608. foundRange = container.equal_range(0x9034);
  1609. EXPECT_EQ(1, TreeContainerTransparentTestInternal::s_allConstructorCount);
  1610. EXPECT_EQ(foundRange.first, foundRange.second);
  1611. // No assignments should have taken place from any of the container operations
  1612. EXPECT_EQ(0, TreeContainerTransparentTestInternal::s_allAssignmentCount);
  1613. }
  1614. }