DequeAndSimilar.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  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/allocator_ref.h>
  10. #include <AzCore/std/allocator_static.h>
  11. #include <AzCore/std/containers/array.h>
  12. #include <AzCore/std/containers/deque.h>
  13. #include <AzCore/std/containers/queue.h>
  14. #include <AzCore/std/containers/ring_buffer.h>
  15. #include <AzCore/std/containers/set.h>
  16. #include <AzCore/std/containers/span.h>
  17. #include <AzCore/std/containers/stack.h>
  18. #include <AzCore/std/ranges/transform_view.h>
  19. #define AZ_TEST_VALIDATE_EMPTY_DEQUE(_Deque) \
  20. AZ_TEST_ASSERT(_Deque.validate()); \
  21. AZ_TEST_ASSERT(_Deque.size() == 0); \
  22. AZ_TEST_ASSERT(_Deque.empty()); \
  23. AZ_TEST_ASSERT(_Deque.begin() == _Deque.end());
  24. #define AZ_TEST_VALIDATE_DEQUE(_Deque, _NumElements) \
  25. AZ_TEST_ASSERT(_Deque.validate()); \
  26. AZ_TEST_ASSERT(_Deque.size() == _NumElements); \
  27. AZ_TEST_ASSERT((_NumElements > 0) ? !_Deque.empty() : _Deque.empty()); \
  28. AZ_TEST_ASSERT((_NumElements > 0) ? _Deque.begin() != _Deque.end() : _Deque.begin() == _Deque.end());
  29. namespace UnitTest
  30. {
  31. class Containers
  32. : public LeakDetectionFixture
  33. {
  34. };
  35. /**
  36. * Deque container test.
  37. */
  38. TEST_F(Containers, Deque)
  39. {
  40. // DequeContainerTest-Begin
  41. using int_deque_type = AZStd::deque<int>;
  42. int_deque_type int_deque;
  43. AZ_TEST_VALIDATE_EMPTY_DEQUE(int_deque);
  44. int_deque_type int_deque1(10);
  45. AZ_TEST_VALIDATE_DEQUE(int_deque1, 10);
  46. int_deque_type int_deque2(6, 101);
  47. AZ_TEST_VALIDATE_DEQUE(int_deque2, 6);
  48. AZ_TEST_ASSERT(int_deque2.front() == 101);
  49. AZ_TEST_ASSERT(int_deque2.back() == 101);
  50. int_deque_type int_deque3(int_deque1);
  51. AZ_TEST_VALIDATE_DEQUE(int_deque3, int_deque1.size());
  52. AZ_TEST_ASSERT(int_deque3 == int_deque1);
  53. AZ_TEST_ASSERT(int_deque3 != int_deque2);
  54. int_deque_type int_deque4(int_deque2.begin(), int_deque2.end());
  55. AZ_TEST_VALIDATE_DEQUE(int_deque4, int_deque2.size());
  56. AZ_TEST_ASSERT(int_deque4 == int_deque2);
  57. AZ_TEST_ASSERT(int_deque4 != int_deque3);
  58. // This one will force the map to grow, which is a different code path.
  59. int_deque1.insert(int_deque1.end(), 10, 99);
  60. AZ_TEST_VALIDATE_DEQUE(int_deque1, 20);
  61. AZ_TEST_ASSERT(int_deque1.back() == 99);
  62. int_deque3 = int_deque2;
  63. AZ_TEST_VALIDATE_DEQUE(int_deque3, int_deque2.size());
  64. AZ_TEST_ASSERT(int_deque3 == int_deque2);
  65. int_deque1.resize(30, 199);
  66. AZ_TEST_VALIDATE_DEQUE(int_deque1, 30);
  67. AZ_TEST_ASSERT(int_deque1.back() == 199);
  68. int_deque1.resize(40, 299);
  69. AZ_TEST_VALIDATE_DEQUE(int_deque1, 40);
  70. AZ_TEST_ASSERT(int_deque1.at(29) == 199);
  71. AZ_TEST_ASSERT(int_deque1.at(30) == 299);
  72. for (int_deque_type::size_type i = 0; i < int_deque1.size(); ++i)
  73. {
  74. AZ_TEST_ASSERT(int_deque1.at(i) == int_deque1[i]);
  75. }
  76. AZ_TEST_ASSERT(int_deque2.front() == 101);
  77. AZ_TEST_ASSERT(int_deque2.back() == 101);
  78. int_deque2.push_front(11);
  79. AZ_TEST_VALIDATE_DEQUE(int_deque2, 7);
  80. AZ_TEST_ASSERT(int_deque2.front() == 11);
  81. int_deque2.push_back(21);
  82. AZ_TEST_VALIDATE_DEQUE(int_deque2, 8);
  83. AZ_TEST_ASSERT(int_deque2.back() == 21);
  84. int_deque2.pop_front();
  85. AZ_TEST_VALIDATE_DEQUE(int_deque2, 7);
  86. AZ_TEST_ASSERT(int_deque2.front() == 101);
  87. int_deque2.pop_back();
  88. AZ_TEST_VALIDATE_DEQUE(int_deque2, 6);
  89. AZ_TEST_ASSERT(int_deque2.back() == 101);
  90. int_deque1.assign(5, 333);
  91. AZ_TEST_VALIDATE_DEQUE(int_deque1, 5);
  92. AZStd::array<int, 7> elements = {
  93. {1, 2, 3, 4, 5, 6, 7}
  94. };
  95. int_deque1.assign(elements.begin(), elements.end());
  96. AZ_TEST_VALIDATE_DEQUE(int_deque1, 7);
  97. int_deque1.insert(int_deque1.begin(), 101);
  98. AZ_TEST_VALIDATE_DEQUE(int_deque1, 8);
  99. AZ_TEST_ASSERT(int_deque1.front() == 101);
  100. int_deque1.insert(int_deque1.end(), 201);
  101. AZ_TEST_VALIDATE_DEQUE(int_deque1, 9);
  102. AZ_TEST_ASSERT(int_deque1.back() == 201);
  103. int_deque1.insert(next(int_deque1.begin(), 3), 301);
  104. AZ_TEST_VALIDATE_DEQUE(int_deque1, 10);
  105. AZ_TEST_ASSERT(int_deque1[3] == 301);
  106. int_deque1.insert(int_deque1.begin(), 2, 401);
  107. AZ_TEST_VALIDATE_DEQUE(int_deque1, 12);
  108. AZ_TEST_ASSERT(int_deque1.front() == 401);
  109. int_deque1.insert(int_deque1.end(), 3, 501);
  110. AZ_TEST_VALIDATE_DEQUE(int_deque1, 15);
  111. AZ_TEST_ASSERT(int_deque1.back() == 501);
  112. int_deque1.insert(next(int_deque1.begin(), 3), 5, 601);
  113. AZ_TEST_VALIDATE_DEQUE(int_deque1, 20);
  114. AZ_TEST_ASSERT(int_deque1[3] == 601);
  115. int_deque1.insert(int_deque1.begin(), elements.begin(), AZStd::next(elements.begin()));
  116. AZ_TEST_VALIDATE_DEQUE(int_deque1, 21);
  117. AZ_TEST_ASSERT(int_deque1.front() == 1);
  118. int_deque1.insert(int_deque1.end(), AZStd::prev(elements.end()), elements.end());
  119. AZ_TEST_VALIDATE_DEQUE(int_deque1, 22);
  120. AZ_TEST_ASSERT(int_deque1.back() == 7);
  121. int_deque1.insert(next(int_deque1.begin(), 3), elements.begin(), elements.end());
  122. AZ_TEST_VALIDATE_DEQUE(int_deque1, 29);
  123. AZ_TEST_ASSERT(int_deque1[3] == 1);
  124. int_deque1.insert(int_deque1.begin(), { 42 });
  125. AZ_TEST_VALIDATE_DEQUE(int_deque1, 30);
  126. AZ_TEST_ASSERT(int_deque1.front() == 42);
  127. int_deque1.insert(int_deque1.begin(), { 1, 1, 2, 3, 5, 8, 13 });
  128. AZ_TEST_VALIDATE_DEQUE(int_deque1, 37);
  129. AZ_TEST_ASSERT(int_deque1.front() == 1);
  130. AZ_TEST_ASSERT(int_deque1[3] == 3);
  131. AZ_TEST_VALIDATE_DEQUE(int_deque1, 37);
  132. int_deque1.erase(int_deque1.begin(), int_deque1.begin() + 8);
  133. AZ_TEST_VALIDATE_DEQUE(int_deque1, 29);
  134. int_deque1.erase(int_deque1.begin());
  135. AZ_TEST_VALIDATE_DEQUE(int_deque1, 28);
  136. AZ_TEST_ASSERT(int_deque1.front() == 401);
  137. int_deque1.erase(prev(int_deque1.end()));
  138. AZ_TEST_VALIDATE_DEQUE(int_deque1, 27);
  139. AZ_TEST_ASSERT(int_deque1.back() == 501);
  140. int_deque1.erase(next(int_deque1.begin()), int_deque1.end());
  141. AZ_TEST_VALIDATE_DEQUE(int_deque1, 1);
  142. AZ_TEST_ASSERT(int_deque1.front() == 401);
  143. int_deque1.swap(int_deque2);
  144. AZ_TEST_VALIDATE_DEQUE(int_deque1, 6);
  145. AZ_TEST_VALIDATE_DEQUE(int_deque2, 1);
  146. AZ_TEST_ASSERT(int_deque1.front() == 101);
  147. AZ_TEST_ASSERT(int_deque1.back() == 101);
  148. AZ_TEST_ASSERT(int_deque2.front() == 401);
  149. for (int_deque_type::iterator it = int_deque2.begin(); it != int_deque2.end(); ++it)
  150. {
  151. AZ_TEST_ASSERT(*it == 401);
  152. }
  153. for (int_deque_type::reverse_iterator rit = int_deque2.rbegin(); rit != int_deque2.rend(); ++rit)
  154. {
  155. AZ_TEST_ASSERT(*rit == 401);
  156. }
  157. // extensions
  158. int_deque2.emplace_back();
  159. AZ_TEST_VALIDATE_DEQUE(int_deque2, 2);
  160. AZ_TEST_ASSERT(int_deque2.front() == 401);
  161. int_deque2.emplace_front();
  162. AZ_TEST_VALIDATE_DEQUE(int_deque2, 3);
  163. AZ_TEST_ASSERT(int_deque2[1] == 401);
  164. // alignment
  165. AZStd::deque<UnitTestInternal::MyClass> aligned_deque(5, 99);
  166. for (AZStd::size_t i = 0; i < aligned_deque.size(); ++i)
  167. {
  168. AZ_TEST_ASSERT(((AZStd::size_t)&aligned_deque[i] & (AZStd::alignment_of<UnitTestInternal::MyClass>::value - 1)) == 0);
  169. }
  170. // different allocators
  171. using static_buffer_16KB_type = AZStd::static_buffer_allocator<16 * 1024, 1>;
  172. static_buffer_16KB_type myMemoryManager1;
  173. static_buffer_16KB_type myMemoryManager2;
  174. using static_allocator_ref_type = AZStd::allocator_ref<static_buffer_16KB_type>;
  175. static_allocator_ref_type allocator1(myMemoryManager1);
  176. static_allocator_ref_type allocator2(myMemoryManager2);
  177. using int_deque_myalloc_type = AZStd::deque<int, static_allocator_ref_type>;
  178. int_deque_myalloc_type int_deque10(100, 13, allocator1); /// Allocate 100 elements using memory manager 1
  179. AZ_TEST_VALIDATE_DEQUE(int_deque10, 100);
  180. AZ_TEST_ASSERT(myMemoryManager1.get_allocated_size() >= 100 * sizeof(int));
  181. // leak_and_reset
  182. int_deque10.leak_and_reset(); /// leave the allocated memory and reset the vector.
  183. AZ_TEST_VALIDATE_EMPTY_DEQUE(int_deque10);
  184. AZ_TEST_ASSERT(myMemoryManager1.get_allocated_size() >= 100 * sizeof(int));
  185. myMemoryManager1.reset(); /// discard the memory
  186. // allocate again from myMemoryManager1
  187. int_deque10.resize(100, 15);
  188. const size_t allocator1AllocatedSize = myMemoryManager1.get_allocated_size();
  189. int_deque10.set_allocator(allocator2);
  190. AZ_TEST_VALIDATE_DEQUE(int_deque10, 100);
  191. // now we move the allocated size from manager1 to manager2
  192. EXPECT_LE(myMemoryManager1.get_allocated_size(), allocator1AllocatedSize);
  193. EXPECT_GE(myMemoryManager2.get_allocated_size(), 100 * sizeof(int));
  194. myMemoryManager1.reset(); // flush manager 1 again (int_vector10 is stored in manager 2)
  195. // swap with different allocators
  196. int_deque_myalloc_type int_deque11(50, 25, allocator1); // create copy in manager1
  197. AZ_TEST_VALIDATE_DEQUE(int_deque11, 50);
  198. int_deque11.swap(int_deque10); // swap the vectors content (since the allocators are different)
  199. AZ_TEST_VALIDATE_DEQUE(int_deque10, 50);
  200. AZ_TEST_VALIDATE_DEQUE(int_deque11, 100);
  201. AZ_TEST_ASSERT(int_deque11.front() == 15);
  202. AZ_TEST_ASSERT(int_deque10.front() == 25);
  203. //////////////////////////////////////////////////////////////////////////////////////////
  204. // Test asserts (which don't cause throw exceptions)
  205. //AZ_TEST_START_TRACE_SUPPRESSION;
  206. //int_deque10.resize(1000000); // too many elements, 1 assert on too many, 1 assert on allocator returning NULL
  207. //AZ_TEST_STOP_TRACE_SUPPRESSION(2);
  208. #ifdef AZSTD_HAS_CHECKED_ITERATORS
  209. int_deque.clear();
  210. int_deque_type::iterator iter = int_deque.end();
  211. // We have exeption when we access the map.
  212. //AZ_TEST_START_TRACE_SUPPRESSION;
  213. //int b = *iter; // the end if is valid but can not dereferenced
  214. //int_deque.validate_iterator(iter);
  215. //(void)b;
  216. //AZ_TEST_STOP_TRACE_SUPPRESSION(1);
  217. int_deque.push_back(1);
  218. AZ_TEST_START_TRACE_SUPPRESSION;
  219. int_deque.validate_iterator(iter); // The push back should make the end iterator invalid.
  220. AZ_TEST_STOP_TRACE_SUPPRESSION(1);
  221. iter = int_deque.begin();
  222. int_deque.clear();
  223. AZ_TEST_START_TRACE_SUPPRESSION;
  224. int_deque.validate_iterator(iter); // The clear should invalidate all iterators
  225. AZ_TEST_STOP_TRACE_SUPPRESSION(1);
  226. #endif
  227. aligned_deque.emplace_back(10, true, 2.0f);
  228. // DequeContainerTest-End
  229. }
  230. TEST_F(Containers, Deque_DeductionGuide_Compiles)
  231. {
  232. constexpr AZStd::string_view testView;
  233. AZStd::deque testDeque(testView.begin(), testView.end());
  234. EXPECT_TRUE(testDeque.empty());
  235. }
  236. /**
  237. * Queue container test.
  238. */
  239. TEST_F(Containers, Queue)
  240. {
  241. // QueueContainerTest-Begin
  242. using int_queue_type = AZStd::queue<int>;
  243. int_queue_type int_queue;
  244. AZ_TEST_ASSERT(int_queue.empty());
  245. AZ_TEST_ASSERT(int_queue.size() == 0);
  246. // Queue uses deque as default container, so try to construct to queue from a deque.
  247. AZStd::deque<int> container(40, 10);
  248. int_queue_type int_queue2(container);
  249. AZ_TEST_ASSERT(!int_queue2.empty());
  250. AZ_TEST_ASSERT(int_queue2.size() == 40);
  251. int_queue.push(10);
  252. AZ_TEST_ASSERT(!int_queue.empty());
  253. AZ_TEST_ASSERT(int_queue.size() == 1);
  254. AZ_TEST_ASSERT(int_queue.front() == int_queue.back());
  255. AZ_TEST_ASSERT(int_queue.front() == 10);
  256. int_queue.pop();
  257. AZ_TEST_ASSERT(int_queue.empty());
  258. AZ_TEST_ASSERT(int_queue.size() == 0);
  259. int_queue2.push(20);
  260. AZ_TEST_ASSERT(!int_queue2.empty());
  261. AZ_TEST_ASSERT(int_queue2.size() == 41);
  262. AZ_TEST_ASSERT(int_queue2.back() == 20);
  263. int_queue2.pop();
  264. AZ_TEST_ASSERT(!int_queue2.empty());
  265. AZ_TEST_ASSERT(int_queue2.size() == 40);
  266. AZ_TEST_ASSERT(int_queue2.back() == 20);
  267. int_queue.emplace();
  268. AZ_TEST_ASSERT(!int_queue.empty());
  269. AZ_TEST_ASSERT(int_queue.size() == 1);
  270. // Test Swap
  271. int_queue.swap(int_queue2);
  272. AZ_TEST_ASSERT(!int_queue2.empty());
  273. AZ_TEST_ASSERT(int_queue2.size() == 1);
  274. AZ_TEST_ASSERT(!int_queue.empty());
  275. AZ_TEST_ASSERT(int_queue.size() == 40);
  276. AZ_TEST_ASSERT(int_queue.back() == 20);
  277. AZStd::queue<UnitTestInternal::MyClass> class_queue;
  278. class_queue.emplace(3, false, 1.0f);
  279. // QueueContainerTest-End
  280. }
  281. /**
  282. * Priority queue container test.
  283. */
  284. TEST_F(Containers, PriorityQueue)
  285. {
  286. // PriorityQueueContainerTest-Begin
  287. using int_priority_queue_type = AZStd::priority_queue<int>;
  288. int_priority_queue_type int_queue;
  289. AZ_TEST_ASSERT(int_queue.empty());
  290. AZ_TEST_ASSERT(int_queue.size() == 0);
  291. AZStd::array<int, 10> elements = {
  292. {10, 2, 6, 3, 5, 8, 7, 9, 1, 4}
  293. };
  294. int_priority_queue_type int_queue2(elements.begin(), elements.end());
  295. AZ_TEST_ASSERT(!int_queue2.empty());
  296. AZ_TEST_ASSERT(int_queue2.size() == 10);
  297. int lastValue = 11;
  298. while (!int_queue2.empty())
  299. {
  300. AZ_TEST_ASSERT(int_queue2.top() < lastValue);
  301. lastValue = int_queue2.top();
  302. int_queue2.pop();
  303. }
  304. AZ_TEST_ASSERT(int_queue2.size() == 0);
  305. AZStd::priority_queue<int, AZStd::vector<int>, AZStd::greater<int> > int_queue3(elements.begin(), elements.end());
  306. AZ_TEST_ASSERT(!int_queue3.empty());
  307. AZ_TEST_ASSERT(int_queue3.size() == 10);
  308. lastValue = 0;
  309. while (!int_queue3.empty())
  310. {
  311. AZ_TEST_ASSERT(int_queue3.top() > lastValue);
  312. lastValue = int_queue3.top();
  313. int_queue3.pop();
  314. }
  315. AZ_TEST_ASSERT(int_queue3.size() == 0);
  316. int_priority_queue_type int_queue4(elements.begin(), elements.end());
  317. int_queue4.push(100);
  318. AZ_TEST_ASSERT(!int_queue4.empty());
  319. AZ_TEST_ASSERT(int_queue4.size() == 11);
  320. AZ_TEST_ASSERT(int_queue4.top() == 100);
  321. // PriorityQueueContainerTest-End
  322. }
  323. /**
  324. * Stack container test.
  325. */
  326. TEST_F(Containers, Stack)
  327. {
  328. // StackContainerTest-Begin
  329. using int_stack_type = AZStd::stack<int>;
  330. int_stack_type int_stack;
  331. AZ_TEST_ASSERT(int_stack.empty());
  332. AZ_TEST_ASSERT(int_stack.size() == 0);
  333. AZStd::deque<int> container(40, 10);
  334. int_stack_type int_stack2(container);
  335. AZ_TEST_ASSERT(!int_stack2.empty());
  336. AZ_TEST_ASSERT(int_stack2.size() == 40);
  337. int_stack.push(20);
  338. AZ_TEST_ASSERT(!int_stack.empty());
  339. AZ_TEST_ASSERT(int_stack.size() == 1);
  340. AZ_TEST_ASSERT(int_stack.top() == 20);
  341. int_stack.pop();
  342. AZ_TEST_ASSERT(int_stack.empty());
  343. AZ_TEST_ASSERT(int_stack.size() == 0);
  344. int_stack2.push(20);
  345. AZ_TEST_ASSERT(!int_stack2.empty());
  346. AZ_TEST_ASSERT(int_stack2.size() == 41);
  347. AZ_TEST_ASSERT(int_stack2.top() == 20);
  348. int_stack2.pop();
  349. AZ_TEST_ASSERT(!int_stack2.empty());
  350. AZ_TEST_ASSERT(int_stack2.size() == 40);
  351. AZ_TEST_ASSERT(int_stack2.top() == 10);
  352. int_stack.emplace();
  353. AZ_TEST_ASSERT(!int_stack.empty());
  354. AZ_TEST_ASSERT(int_stack.size() == 1);
  355. // StackContainerTest-End
  356. }
  357. /**
  358. * Make sure a ring_buffer is empty, and control all functions to return the proper values.
  359. * Empty ring_buffer as all AZStd containers should not have allocated any memory. Empty and clean containers are not the same.
  360. */
  361. #define AZ_TEST_VALIDATE_EMPTY_RINGBUFFER(_RingBuffer) \
  362. AZ_TEST_ASSERT(_RingBuffer.validate()); \
  363. AZ_TEST_ASSERT(_RingBuffer.size() == 0); \
  364. AZ_TEST_ASSERT(_RingBuffer.empty()); \
  365. AZ_TEST_ASSERT(_RingBuffer.capacity() == 0); \
  366. AZ_TEST_ASSERT(_RingBuffer.begin() == _RingBuffer.end());
  367. /**
  368. * Validate a ring_buffer for certain number of elements.
  369. */
  370. #define AZ_TEST_VALIDATE_RINGBUFFER(_RingBuffer, _NumElements) \
  371. AZ_TEST_ASSERT(_RingBuffer.validate()); \
  372. AZ_TEST_ASSERT(_RingBuffer.size() == _NumElements); \
  373. AZ_TEST_ASSERT((_NumElements > 0) ? !_RingBuffer.empty() : _RingBuffer.empty()); \
  374. AZ_TEST_ASSERT((_NumElements > 0) ? _RingBuffer.capacity() >= _NumElements : true); \
  375. AZ_TEST_ASSERT((_NumElements > 0) ? _RingBuffer.begin() != _RingBuffer.end() : _RingBuffer.begin() == _RingBuffer.end());
  376. /**
  377. * ring_buffer container test.
  378. */
  379. TEST_F(Containers, RingBuffer)
  380. {
  381. using int_ringbuffer_type = AZStd::ring_buffer<int>;
  382. using class_ringbuffer_type = AZStd::ring_buffer<UnitTestInternal::MyClass>;
  383. // Test empty buffer with intergral type.
  384. int_ringbuffer_type int_buffer;
  385. AZ_TEST_VALIDATE_EMPTY_RINGBUFFER(int_buffer);
  386. // Default vector (non-integral type).
  387. class_ringbuffer_type myclass_buffer;
  388. AZ_TEST_VALIDATE_EMPTY_RINGBUFFER(myclass_buffer);
  389. // Allocate buffer with capacity of 10 elements.
  390. int_ringbuffer_type int_buffer1(10);
  391. AZ_TEST_ASSERT(int_buffer1.size() == 0);
  392. AZ_TEST_ASSERT(int_buffer1.capacity() == 10);
  393. AZ_TEST_ASSERT(int_buffer1.empty());
  394. AZ_TEST_ASSERT(int_buffer1.begin() == int_buffer1.end());
  395. // Allocate buffer with 15 elements init to 13.
  396. int_ringbuffer_type int_buffer2(15, 13);
  397. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer2, 15);
  398. for (int_ringbuffer_type::iterator iter = int_buffer2.begin(); iter != int_buffer2.end(); ++iter)
  399. {
  400. AZ_TEST_ASSERT(*iter == 13);
  401. }
  402. // Allocate buffer with 15 elements init to 13 and a capacity 31.
  403. int_ringbuffer_type int_buffer3(31, 15, 13);
  404. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer3, 15);
  405. AZ_TEST_ASSERT(int_buffer3.capacity() == 31);
  406. for (int_ringbuffer_type::iterator iter = int_buffer3.begin(); iter != int_buffer3.end(); ++iter)
  407. {
  408. AZ_TEST_ASSERT(*iter == 13);
  409. }
  410. // Copy ctor
  411. int_ringbuffer_type int_buffer4(int_buffer3);
  412. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer4, 15);
  413. AZ_TEST_ASSERT(int_buffer4.capacity() == 31);
  414. for (int_ringbuffer_type::iterator iter = int_buffer4.begin(); iter != int_buffer4.end(); ++iter)
  415. {
  416. AZ_TEST_ASSERT(*iter == 13);
  417. }
  418. // Test == and !=
  419. AZ_TEST_ASSERT(int_buffer4 == int_buffer3);
  420. AZ_TEST_ASSERT((int_buffer4 != int_buffer3) == false);
  421. AZStd::array<int, 6> myArr = {
  422. {0, 1, 2, 3, 4, 5}
  423. };
  424. int_ringbuffer_type int_buffer5(myArr.begin(), myArr.end());
  425. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer5, myArr.size());
  426. int i = 0;
  427. for (int_ringbuffer_type::iterator iter = int_buffer5.begin(); iter != int_buffer5.end(); ++iter, ++i)
  428. {
  429. AZ_TEST_ASSERT(*iter == i);
  430. }
  431. int_ringbuffer_type int_buffer6(10, myArr.begin(), myArr.end());
  432. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer6, myArr.size());
  433. AZ_TEST_ASSERT(int_buffer6.capacity() == 10);
  434. i = 0;
  435. for (int_ringbuffer_type::iterator iter = int_buffer6.begin(); iter != int_buffer6.end(); ++iter, ++i)
  436. {
  437. AZ_TEST_ASSERT(*iter == i);
  438. }
  439. // =
  440. int_buffer1 = int_buffer6;
  441. AZ_TEST_ASSERT(int_buffer1 == int_buffer6);
  442. // []
  443. AZ_TEST_ASSERT(int_buffer5[3] == 3);
  444. AZ_TEST_ASSERT(int_buffer5[4] == int_buffer5.at(4));
  445. AZ_TEST_ASSERT(int_buffer5.front() == 0);
  446. AZ_TEST_ASSERT(int_buffer5.back() == 5);
  447. // full
  448. AZ_TEST_ASSERT(int_buffer5.full() == true);
  449. AZ_TEST_ASSERT(int_buffer6.full() == false);
  450. // Circular checks
  451. AZ_TEST_ASSERT(int_buffer5.is_linearized() == true);
  452. int_ringbuffer_type::array_range arr1 = int_buffer5.array_one();
  453. int_ringbuffer_type::array_range arr2 = int_buffer5.array_two();
  454. AZ_TEST_ASSERT(arr1.second == int_buffer5.size()); // we have only 1 linear array
  455. AZ_TEST_ASSERT(arr2.second == 0);
  456. AZ_TEST_ASSERT(*arr1.first == 0); // Check that we are pointing to the first elements, which is 0.
  457. // Overwrite the first 2 elements.
  458. int_buffer5.push_back(6);
  459. int_buffer5.push_back(7);
  460. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer5, myArr.size());
  461. AZ_TEST_ASSERT(int_buffer5.front() == 2);
  462. AZ_TEST_ASSERT(int_buffer5.back() == 7);
  463. arr1 = int_buffer5.array_one();
  464. arr2 = int_buffer5.array_two();
  465. AZ_TEST_ASSERT(arr1.second == 4);
  466. AZ_TEST_ASSERT(*arr1.first == 2);
  467. AZ_TEST_ASSERT(arr2.second == 2);
  468. AZ_TEST_ASSERT(*arr2.first == 6);
  469. // rotate - full buffer
  470. int_buffer5.rotate(int_buffer5.begin() + 1); // rotate right by 1
  471. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer5, myArr.size());
  472. AZ_TEST_ASSERT(int_buffer5.front() == 3);
  473. AZ_TEST_ASSERT(int_buffer5.back() == 2);
  474. arr1 = int_buffer5.array_one();
  475. arr2 = int_buffer5.array_two();
  476. AZ_TEST_ASSERT(arr1.second == 3);
  477. AZ_TEST_ASSERT(*arr1.first == 3);
  478. AZ_TEST_ASSERT(arr2.second == 3);
  479. AZ_TEST_ASSERT(*arr2.first == 6);
  480. // rotate - !full buffer
  481. int_buffer6.rotate(int_buffer6.begin() + 5);
  482. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer6, myArr.size());
  483. AZ_TEST_ASSERT(int_buffer6.front() == 5);
  484. AZ_TEST_ASSERT(int_buffer6.back() == 4);
  485. arr1 = int_buffer6.array_one();
  486. arr2 = int_buffer6.array_two();
  487. AZ_TEST_ASSERT(arr1.second == 1);
  488. AZ_TEST_ASSERT(*arr1.first == 5);
  489. AZ_TEST_ASSERT(arr2.second == 5);
  490. AZ_TEST_ASSERT(*arr2.first == 0);
  491. // linearize
  492. int_buffer5.linearize();
  493. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer5, myArr.size());
  494. AZ_TEST_ASSERT(int_buffer5.is_linearized());
  495. AZ_TEST_ASSERT(int_buffer5.front() == 3);
  496. AZ_TEST_ASSERT(int_buffer5.back() == 2);
  497. arr1 = int_buffer5.array_one();
  498. arr2 = int_buffer5.array_two();
  499. AZ_TEST_ASSERT(arr1.second == 6);
  500. AZ_TEST_ASSERT(*arr1.first == 3);
  501. AZ_TEST_ASSERT(arr2.second == 0);
  502. // resize - grow
  503. int_buffer5.resize(100, 11);
  504. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer5, 100);
  505. AZ_TEST_ASSERT(int_buffer5.front() == 3);
  506. AZ_TEST_ASSERT(int_buffer5.back() == 11);
  507. // resize - shrink
  508. int_buffer5.resize(5);
  509. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer5, 5);
  510. AZ_TEST_ASSERT(int_buffer5.front() == 3);
  511. AZ_TEST_ASSERT(int_buffer5.back() == 7);
  512. // swap
  513. int_buffer5.swap(int_buffer6);
  514. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer6, 5);
  515. AZ_TEST_ASSERT(int_buffer6.front() == 3);
  516. AZ_TEST_ASSERT(int_buffer6.back() == 7);
  517. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer5, myArr.size());
  518. AZ_TEST_ASSERT(int_buffer5.front() == 5);
  519. AZ_TEST_ASSERT(int_buffer5.back() == 4);
  520. // push
  521. int_buffer5.push_back(101);
  522. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer5, myArr.size() + 1);
  523. AZ_TEST_ASSERT(int_buffer5.back() == 101);
  524. int_buffer5.emplace_back();
  525. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer5, myArr.size() + 2);
  526. int_buffer5.emplace_front(201);
  527. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer5, myArr.size() + 3);
  528. AZ_TEST_ASSERT(int_buffer5.front() == 201);
  529. int_buffer5.emplace_front();
  530. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer5, myArr.size() + 4);
  531. // pop
  532. int_buffer5.pop_front();
  533. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer5, myArr.size() + 3);
  534. AZ_TEST_ASSERT(int_buffer5.front() == 201);
  535. int_buffer5.pop_back();
  536. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer5, myArr.size() + 2);
  537. AZ_TEST_ASSERT(int_buffer5.back() == 101);
  538. // insert
  539. int_buffer5.insert(int_buffer5.begin() + 1, 303);
  540. AZ_TEST_VALIDATE_RINGBUFFER(int_buffer5, myArr.size() + 3);
  541. AZ_TEST_ASSERT(int_buffer5[0] == 201);
  542. AZ_TEST_ASSERT(int_buffer5[1] == 303);
  543. /* int_buffer5.insert(int_buffer5.begin(),3,404);
  544. AZ_TEST_ASSERT(int_buffer5[0]==404);
  545. AZ_TEST_ASSERT(int_buffer5[3]==201);*/
  546. // erase
  547. int_buffer5.erase(int_buffer5.begin() + 1);
  548. AZ_TEST_ASSERT(int_buffer5[0] == 201);
  549. }
  550. TEST_F(Containers, RingBufferReverseIterators)
  551. {
  552. using int_ringbuffer_type = AZStd::ring_buffer<int>;
  553. const int max = 42;
  554. int_ringbuffer_type rev_buffer(max);
  555. for (int i = 0; i < max; ++i)
  556. {
  557. rev_buffer.push_back(i);
  558. }
  559. int iteration = 0;
  560. for (int_ringbuffer_type::const_reverse_iterator rit = rev_buffer.rbegin(); rit != rev_buffer.rend(); ++rit)
  561. {
  562. EXPECT_EQ(max - iteration - 1, *rit);
  563. ++iteration;
  564. }
  565. }
  566. using StackContainerTestFixture = LeakDetectionFixture;
  567. TEST_F(StackContainerTestFixture, StackEmplaceOperator_SupportsZeroOrMoreArguments)
  568. {
  569. using TestPairType = AZStd::pair<int, int>;
  570. AZStd::stack<TestPairType> testStack;
  571. testStack.emplace();
  572. testStack.emplace(1);
  573. testStack.emplace(2, 3);
  574. using ContainerType = typename AZStd::stack<TestPairType>::container_type;
  575. AZStd::stack<TestPairType> expectedStack(ContainerType{ TestPairType{ 0, 0 }, TestPairType{ 1, 0 }, TestPairType{ 2, 3 } });
  576. EXPECT_EQ(expectedStack, testStack);
  577. }
  578. using DequeTestFixture = LeakDetectionFixture;
  579. TEST_F(DequeTestFixture, RangeConstructors_Succeeds)
  580. {
  581. constexpr AZStd::string_view testView = "abc";
  582. AZStd::deque testDeque(AZStd::from_range, testView);
  583. EXPECT_THAT(testDeque, ::testing::ElementsAre('a', 'b', 'c'));
  584. testDeque = AZStd::deque(AZStd::from_range, AZStd::vector<char>{testView.begin(), testView.end()});
  585. EXPECT_THAT(testDeque, ::testing::ElementsAre('a', 'b', 'c'));
  586. testDeque = AZStd::deque(AZStd::from_range, AZStd::list<char>{testView.begin(), testView.end()});
  587. EXPECT_THAT(testDeque, ::testing::ElementsAre('a', 'b', 'c'));
  588. testDeque = AZStd::deque(AZStd::from_range, AZStd::deque<char>{testView.begin(), testView.end()});
  589. EXPECT_THAT(testDeque, ::testing::ElementsAre('a', 'b', 'c'));
  590. testDeque = AZStd::deque(AZStd::from_range, AZStd::set<char>{testView.begin(), testView.end()});
  591. EXPECT_THAT(testDeque, ::testing::ElementsAre('a', 'b', 'c'));
  592. testDeque = AZStd::deque(AZStd::from_range, AZStd::unordered_set<char>{testView.begin(), testView.end()});
  593. EXPECT_THAT(testDeque, ::testing::ElementsAre('a', 'b', 'c'));
  594. testDeque = AZStd::deque(AZStd::from_range, AZStd::fixed_vector<char, 8>{testView.begin(), testView.end()});
  595. EXPECT_THAT(testDeque, ::testing::ElementsAre('a', 'b', 'c'));
  596. testDeque = AZStd::deque(AZStd::from_range, AZStd::array{ 'a', 'b', 'c' });
  597. EXPECT_THAT(testDeque, ::testing::ElementsAre('a', 'b', 'c'));
  598. testDeque = AZStd::deque(AZStd::from_range, AZStd::span(testView));
  599. EXPECT_THAT(testDeque, ::testing::ElementsAre('a', 'b', 'c'));
  600. AZStd::fixed_string<8> testValue(testView);
  601. testDeque = AZStd::deque(AZStd::from_range, testValue);
  602. EXPECT_THAT(testDeque, ::testing::ElementsAre('a', 'b', 'c'));
  603. testDeque = AZStd::deque(AZStd::from_range, AZStd::string(testView));
  604. EXPECT_THAT(testDeque, ::testing::ElementsAre('a', 'b', 'c'));
  605. // Test Range views
  606. testDeque = AZStd::deque(AZStd::from_range, testValue | AZStd::views::transform([](const char elem) -> char { return elem + 1; }));
  607. EXPECT_THAT(testDeque, ::testing::ElementsAre('b', 'c', 'd'));
  608. }
  609. TEST_F(DequeTestFixture, AssignRange_Succeeds)
  610. {
  611. constexpr AZStd::string_view testView = "def";
  612. AZStd::deque testDev{ 'a', 'b', 'c' };
  613. testDev.assign_range(AZStd::vector<char>{testView.begin(), testView.end()});
  614. testDev.assign_range(AZStd::vector<char>{testView.begin(), testView.end()});
  615. EXPECT_THAT(testDev, ::testing::ElementsAre('d', 'e', 'f'));
  616. }
  617. TEST_F(DequeTestFixture, InsertRange_Succeeds)
  618. {
  619. constexpr AZStd::string_view testView = "abc";
  620. AZStd::deque testDeque{ 'd', 'e', 'f' };
  621. testDeque.insert_range(testDeque.begin(), AZStd::vector<char>{testView.begin(), testView.end()});
  622. testDeque.insert_range(testDeque.end(), testView | AZStd::views::transform([](const char elem) -> char { return elem + 6; }));
  623. EXPECT_THAT(testDeque, ::testing::ElementsAre('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'));
  624. }
  625. TEST_F(DequeTestFixture, AppendRange_Succeeds)
  626. {
  627. constexpr AZStd::string_view testView = "def";
  628. AZStd::deque testDeque{ 'a', 'b', 'c' };
  629. testDeque.append_range(AZStd::vector<char>{testView.begin(), testView.end()});
  630. testDeque.append_range(testView | AZStd::views::transform([](const char elem) -> char { return elem + 3; }));
  631. EXPECT_THAT(testDeque, ::testing::ElementsAre('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'));
  632. }
  633. TEST_F(DequeTestFixture, PrependRange_Succeeds)
  634. {
  635. constexpr AZStd::string_view testView = "def";
  636. AZStd::deque testDeque{ 'g', 'h', 'i' };
  637. testDeque.prepend_range(AZStd::vector<char>{testView.begin(), testView.end()});
  638. testDeque.prepend_range(testView | AZStd::views::transform([](const char elem) -> char { return elem + -3; }));
  639. EXPECT_THAT(testDeque, ::testing::ElementsAre('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'));
  640. }
  641. }