ArrayTest.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2024 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include "UnitTestFramework.h"
  5. TEST_SUITE("ArrayTest")
  6. {
  7. // A test class that is non-trivially copyable to test if the Array class correctly constructs/destructs/copies and moves elements.
  8. class NonTriv
  9. {
  10. public:
  11. NonTriv() : mValue(0) { ++sNumConstructors; }
  12. explicit NonTriv(int inValue) : mValue(inValue) { ++sNumConstructors; }
  13. NonTriv(const NonTriv &inValue) : mValue(inValue.mValue) { ++sNumCopyConstructors; }
  14. NonTriv(NonTriv &&inValue) : mValue(inValue.mValue) { inValue.mValue = 0; ++sNumMoveConstructors; }
  15. ~NonTriv() { ++sNumDestructors; }
  16. NonTriv & operator = (const NonTriv &inRHS) { mValue = inRHS.mValue; return *this; }
  17. bool operator == (const NonTriv &inRHS) const { return mValue == inRHS.mValue; }
  18. bool operator != (const NonTriv &inRHS) const { return mValue != inRHS.mValue; }
  19. int Value() const { return mValue; }
  20. static void sReset() { sNumConstructors = 0; sNumCopyConstructors = 0; sNumMoveConstructors = 0; sNumDestructors = 0; }
  21. static inline int sNumConstructors = 0;
  22. static inline int sNumCopyConstructors = 0;
  23. static inline int sNumMoveConstructors = 0;
  24. static inline int sNumDestructors = 0;
  25. int mValue;
  26. };
  27. TEST_CASE("TestConstructLength")
  28. {
  29. Array<int> arr(55);
  30. CHECK(arr.size() == 55);
  31. }
  32. TEST_CASE("TestConstructLengthNonTriv")
  33. {
  34. NonTriv::sReset();
  35. Array<NonTriv> arr(55);
  36. CHECK(arr.size() == 55);
  37. CHECK(NonTriv::sNumConstructors == 55);
  38. CHECK(NonTriv::sNumCopyConstructors == 0);
  39. CHECK(NonTriv::sNumMoveConstructors == 0);
  40. CHECK(NonTriv::sNumDestructors == 0);
  41. }
  42. TEST_CASE("TestConstructValue")
  43. {
  44. Array<int> arr(5, 55);
  45. CHECK(arr.size() == 5);
  46. for (int i = 0; i < 5; ++i)
  47. CHECK(arr[i] == 55);
  48. }
  49. TEST_CASE("TestConstructValueNonTriv")
  50. {
  51. NonTriv v(55);
  52. NonTriv::sReset();
  53. Array<NonTriv> arr(5, v);
  54. CHECK(arr.size() == 5);
  55. for (int i = 0; i < 5; ++i)
  56. CHECK(arr[i].Value() == 55);
  57. CHECK(NonTriv::sNumConstructors == 0);
  58. CHECK(NonTriv::sNumCopyConstructors == 5);
  59. CHECK(NonTriv::sNumMoveConstructors == 0);
  60. CHECK(NonTriv::sNumDestructors == 0);
  61. }
  62. TEST_CASE("TestConstructIterator")
  63. {
  64. int values[] = { 1, 2, 3 };
  65. Array<int> arr(values, values + 3);
  66. CHECK(arr.size() == 3);
  67. CHECK(arr[0] == 1);
  68. CHECK(arr[1] == 2);
  69. CHECK(arr[2] == 3);
  70. }
  71. TEST_CASE("TestConstructIteratorNonTriv")
  72. {
  73. NonTriv values[] = { NonTriv(1), NonTriv(2), NonTriv(3) };
  74. NonTriv::sReset();
  75. Array<NonTriv> arr(values, values + 3);
  76. CHECK(arr.size() == 3);
  77. CHECK(arr[0].Value() == 1);
  78. CHECK(arr[1].Value() == 2);
  79. CHECK(arr[2].Value() == 3);
  80. CHECK(NonTriv::sNumConstructors == 0);
  81. CHECK(NonTriv::sNumCopyConstructors == 3);
  82. CHECK(NonTriv::sNumMoveConstructors == 0);
  83. CHECK(NonTriv::sNumDestructors == 0);
  84. }
  85. TEST_CASE("TestConstructInitializerList")
  86. {
  87. Array<int> arr({ 1, 2, 3 });
  88. CHECK(arr.size() == 3);
  89. CHECK(arr[0] == 1);
  90. CHECK(arr[1] == 2);
  91. CHECK(arr[2] == 3);
  92. }
  93. TEST_CASE("TestConstructInitializerListNonTriv")
  94. {
  95. NonTriv::sReset();
  96. Array<NonTriv> arr({ NonTriv(1), NonTriv(2), NonTriv(3) });
  97. CHECK(arr.size() == 3);
  98. CHECK(arr[0].Value() == 1);
  99. CHECK(arr[1].Value() == 2);
  100. CHECK(arr[2].Value() == 3);
  101. CHECK(NonTriv::sNumConstructors == 3); // For the initializer list
  102. CHECK(NonTriv::sNumCopyConstructors == 3); // Initializing the array
  103. CHECK(NonTriv::sNumMoveConstructors == 0);
  104. CHECK(NonTriv::sNumDestructors == 3); // For the initializer list
  105. }
  106. TEST_CASE("TestConstructFromArray")
  107. {
  108. Array<int> arr = { 1, 2, 3 };
  109. Array<int> arr2(arr);
  110. CHECK(arr2.size() == 3);
  111. CHECK(arr2[0] == 1);
  112. CHECK(arr2[1] == 2);
  113. CHECK(arr2[2] == 3);
  114. }
  115. TEST_CASE("TestConstructFromArrayNonTriv")
  116. {
  117. Array<NonTriv> arr = { NonTriv(1), NonTriv(2), NonTriv(3) };
  118. NonTriv::sReset();
  119. Array<NonTriv> arr2(arr);
  120. CHECK(arr2.size() == 3);
  121. CHECK(arr2[0].Value() == 1);
  122. CHECK(arr2[1].Value() == 2);
  123. CHECK(arr2[2].Value() == 3);
  124. CHECK(NonTriv::sNumConstructors == 0);
  125. CHECK(NonTriv::sNumCopyConstructors == 3);
  126. CHECK(NonTriv::sNumMoveConstructors == 0);
  127. CHECK(NonTriv::sNumDestructors == 0);
  128. }
  129. TEST_CASE("TestMoveFromArray")
  130. {
  131. Array<int> arr = { 1, 2, 3 };
  132. Array<int> arr2(std::move(arr));
  133. CHECK(arr2.size() == 3);
  134. CHECK(arr2[0] == 1);
  135. CHECK(arr2[1] == 2);
  136. CHECK(arr2[2] == 3);
  137. CHECK(arr.size() == 0);
  138. CHECK(arr.capacity() == 0);
  139. }
  140. TEST_CASE("TestMoveFromArrayNonTriv")
  141. {
  142. Array<NonTriv> arr = { NonTriv(1), NonTriv(2), NonTriv(3) };
  143. NonTriv::sReset();
  144. Array<NonTriv> arr2(std::move(arr)); // This just updates the mElements pointer so should not call any constructors/destructors etc.
  145. CHECK(arr2.size() == 3);
  146. CHECK(arr2[0].Value() == 1);
  147. CHECK(arr2[1].Value() == 2);
  148. CHECK(arr2[2].Value() == 3);
  149. CHECK(arr.size() == 0);
  150. CHECK(arr.capacity() == 0);
  151. CHECK(NonTriv::sNumConstructors == 0);
  152. CHECK(NonTriv::sNumCopyConstructors == 0);
  153. CHECK(NonTriv::sNumMoveConstructors == 0);
  154. CHECK(NonTriv::sNumDestructors == 0);
  155. }
  156. TEST_CASE("TestClear")
  157. {
  158. Array<int> arr({ 1, 2, 3 });
  159. CHECK(arr.size() == 3);
  160. arr.clear();
  161. CHECK(arr.size() == 0);
  162. }
  163. TEST_CASE("TestClearNonTriv")
  164. {
  165. NonTriv::sReset();
  166. Array<NonTriv> arr({ NonTriv(1), NonTriv(2), NonTriv(3) });
  167. CHECK(arr.size() == 3);
  168. CHECK(NonTriv::sNumConstructors == 3); // For initializer list
  169. CHECK(NonTriv::sNumCopyConstructors == 3); // To move into array
  170. CHECK(NonTriv::sNumMoveConstructors == 0);
  171. CHECK(NonTriv::sNumDestructors == 3); // For initializer list
  172. NonTriv::sReset();
  173. arr.clear();
  174. CHECK(arr.size() == 0);
  175. CHECK(NonTriv::sNumConstructors == 0);
  176. CHECK(NonTriv::sNumCopyConstructors == 0);
  177. CHECK(NonTriv::sNumMoveConstructors == 0);
  178. CHECK(NonTriv::sNumDestructors == 3);
  179. }
  180. TEST_CASE("TestPushBack")
  181. {
  182. Array<int> arr;
  183. CHECK(arr.size() == 0);
  184. CHECK(arr.capacity() == 0);
  185. arr.push_back(1);
  186. CHECK(arr.size() == 1);
  187. CHECK(arr[0] == 1);
  188. arr.push_back(2);
  189. CHECK(arr.size() == 2);
  190. CHECK(arr[0] == 1);
  191. CHECK(arr[1] == 2);
  192. arr.pop_back();
  193. CHECK(arr.size() == 1);
  194. arr.pop_back();
  195. CHECK(arr.size() == 0);
  196. CHECK(arr.empty());
  197. }
  198. TEST_CASE("TestPushBackNonTriv")
  199. {
  200. NonTriv v1(1);
  201. NonTriv v2(2);
  202. NonTriv::sReset();
  203. Array<NonTriv> arr;
  204. CHECK(arr.size() == 0);
  205. CHECK(arr.capacity() == 0);
  206. CHECK(NonTriv::sNumConstructors == 0);
  207. CHECK(NonTriv::sNumCopyConstructors == 0);
  208. CHECK(NonTriv::sNumMoveConstructors == 0);
  209. CHECK(NonTriv::sNumDestructors == 0);
  210. NonTriv::sReset();
  211. arr.push_back(v1);
  212. CHECK(arr.size() == 1);
  213. CHECK(arr[0].Value() == 1);
  214. CHECK(NonTriv::sNumConstructors == 0);
  215. CHECK(NonTriv::sNumCopyConstructors == 1);
  216. CHECK(NonTriv::sNumMoveConstructors == 0);
  217. CHECK(NonTriv::sNumDestructors == 0);
  218. NonTriv::sReset();
  219. arr.push_back(v2);
  220. CHECK(arr.size() == 2);
  221. CHECK(arr[0].Value() == 1);
  222. CHECK(arr[1].Value() == 2);
  223. #ifndef JPH_USE_STD_VECTOR
  224. CHECK(NonTriv::sNumConstructors == 0);
  225. CHECK(NonTriv::sNumCopyConstructors == 1);
  226. CHECK(NonTriv::sNumMoveConstructors == 1); // Array resizes from 1 to 2
  227. CHECK(NonTriv::sNumDestructors == 1); // Array resizes from 1 to 2
  228. #endif // JPH_USE_STD_VECTOR
  229. NonTriv::sReset();
  230. arr.pop_back();
  231. CHECK(arr.size() == 1);
  232. CHECK(NonTriv::sNumConstructors == 0);
  233. CHECK(NonTriv::sNumCopyConstructors == 0);
  234. CHECK(NonTriv::sNumMoveConstructors == 0);
  235. CHECK(NonTriv::sNumDestructors == 1);
  236. NonTriv::sReset();
  237. arr.pop_back();
  238. CHECK(arr.size() == 0);
  239. CHECK(arr.empty());
  240. CHECK(NonTriv::sNumConstructors == 0);
  241. CHECK(NonTriv::sNumCopyConstructors == 0);
  242. CHECK(NonTriv::sNumMoveConstructors == 0);
  243. CHECK(NonTriv::sNumDestructors == 1);
  244. }
  245. TEST_CASE("TestPushBackMove")
  246. {
  247. Array<Array<int>> arr;
  248. Array<int> arr2 = { 1, 2, 3 };
  249. arr.push_back(std::move(arr2));
  250. CHECK(arr2.size() == 0);
  251. CHECK(arr[0] == Array<int>({ 1, 2, 3 }));
  252. }
  253. TEST_CASE("TestEmplaceBack")
  254. {
  255. struct Test
  256. {
  257. Test(int inA, int inB) : mA(inA), mB(inB) { }
  258. int mA;
  259. int mB;
  260. };
  261. Array<Test> arr;
  262. arr.emplace_back(1, 2);
  263. CHECK(arr.size() == 1);
  264. CHECK(arr[0].mA == 1);
  265. CHECK(arr[0].mB == 2);
  266. }
  267. TEST_CASE("TestReserve")
  268. {
  269. Array<int> arr;
  270. CHECK(arr.capacity() == 0);
  271. arr.reserve(123);
  272. CHECK(arr.size() == 0);
  273. CHECK(arr.capacity() == 123);
  274. arr.reserve(456);
  275. CHECK(arr.size() == 0);
  276. CHECK(arr.capacity() == 456);
  277. }
  278. TEST_CASE("TestReserveNonTriv")
  279. {
  280. NonTriv::sReset();
  281. Array<NonTriv> arr;
  282. CHECK(arr.capacity() == 0);
  283. arr.reserve(123);
  284. CHECK(arr.size() == 0);
  285. CHECK(arr.capacity() == 123);
  286. arr.reserve(456);
  287. CHECK(arr.size() == 0);
  288. CHECK(arr.capacity() == 456);
  289. CHECK(NonTriv::sNumConstructors == 0);
  290. CHECK(NonTriv::sNumCopyConstructors == 0);
  291. CHECK(NonTriv::sNumMoveConstructors == 0);
  292. CHECK(NonTriv::sNumDestructors == 0);
  293. }
  294. TEST_CASE("TestResize")
  295. {
  296. Array<int> arr;
  297. CHECK(arr.size() == 0);
  298. CHECK(arr.capacity() == 0);
  299. CHECK(arr.data() == nullptr);
  300. arr.resize(0);
  301. CHECK(arr.size() == 0);
  302. CHECK(arr.capacity() == 0);
  303. CHECK(arr.data() == nullptr);
  304. arr.resize(123);
  305. CHECK(arr.size() == 123);
  306. CHECK(arr.capacity() == 123);
  307. for (int i = 0; i < 123; ++i)
  308. arr[i] = i;
  309. arr.resize(456);
  310. CHECK(arr.size() == 456);
  311. CHECK(arr.capacity() == 456);
  312. for (int i = 0; i < 123; ++i)
  313. CHECK(arr[i] == i);
  314. arr.resize(10);
  315. CHECK(arr.size() == 10);
  316. CHECK(arr.capacity() >= 10);
  317. }
  318. TEST_CASE("TestResizeNonTriv")
  319. {
  320. NonTriv::sReset();
  321. Array<NonTriv> arr;
  322. CHECK(arr.size() == 0);
  323. CHECK(arr.capacity() == 0);
  324. CHECK(NonTriv::sNumConstructors == 0);
  325. CHECK(NonTriv::sNumCopyConstructors == 0);
  326. CHECK(NonTriv::sNumMoveConstructors == 0);
  327. CHECK(NonTriv::sNumDestructors == 0);
  328. NonTriv::sReset();
  329. arr.resize(123);
  330. CHECK(arr.size() == 123);
  331. CHECK(arr.capacity() == 123);
  332. CHECK(NonTriv::sNumConstructors == 123);
  333. CHECK(NonTriv::sNumCopyConstructors == 0);
  334. CHECK(NonTriv::sNumMoveConstructors == 0);
  335. CHECK(NonTriv::sNumDestructors == 0);
  336. for (int i = 0; i < 123; ++i)
  337. arr[i] = NonTriv(i);
  338. NonTriv::sReset();
  339. arr.resize(456);
  340. CHECK(arr.size() == 456);
  341. CHECK(arr.capacity() == 456);
  342. for (int i = 0; i < 123; ++i)
  343. CHECK(arr[i].Value() == i);
  344. #ifndef JPH_USE_STD_VECTOR
  345. CHECK(NonTriv::sNumConstructors == 456 - 123);
  346. CHECK(NonTriv::sNumCopyConstructors == 0);
  347. CHECK(NonTriv::sNumMoveConstructors == 123);
  348. CHECK(NonTriv::sNumDestructors == 123); // Switched to a new block, all old elements are destroyed after being moved
  349. #endif // JPH_USE_STD_VECTOR
  350. NonTriv::sReset();
  351. arr.resize(10);
  352. CHECK(arr.size() == 10);
  353. CHECK(arr.capacity() >= 10);
  354. CHECK(NonTriv::sNumConstructors == 0);
  355. CHECK(NonTriv::sNumCopyConstructors == 0);
  356. CHECK(NonTriv::sNumMoveConstructors == 0);
  357. CHECK(NonTriv::sNumDestructors == 456 - 10);
  358. }
  359. TEST_CASE("TestResizeWithValue")
  360. {
  361. Array<int> arr;
  362. arr.resize(10, 55);
  363. CHECK(arr.size() == 10);
  364. CHECK(arr.capacity() == 10);
  365. for (int i = 0; i < 10; ++i)
  366. CHECK(arr[i] == 55);
  367. }
  368. TEST_CASE("TestResizeWithValueNonTriv")
  369. {
  370. NonTriv v(55);
  371. Array<NonTriv> arr;
  372. NonTriv::sReset();
  373. arr.resize(10, v);
  374. CHECK(arr.size() == 10);
  375. CHECK(arr.capacity() == 10);
  376. for (int i = 0; i < 10; ++i)
  377. CHECK(arr[i].Value() == 55);
  378. CHECK(NonTriv::sNumConstructors == 0);
  379. CHECK(NonTriv::sNumCopyConstructors == 10);
  380. CHECK(NonTriv::sNumMoveConstructors == 0);
  381. CHECK(NonTriv::sNumDestructors == 0);
  382. }
  383. #ifndef JPH_USE_STD_VECTOR // std::vector can choose to not shrink the array when calling shrink_to_fit so we can't test this
  384. TEST_CASE("TestShrinkToFit")
  385. {
  386. Array<int> arr;
  387. for (int i = 0; i < 5; ++i)
  388. arr.push_back(i);
  389. CHECK(arr.capacity() > 5);
  390. CHECK(arr.size() == 5);
  391. arr.shrink_to_fit();
  392. CHECK(arr.capacity() == 5);
  393. CHECK(arr.size() == 5);
  394. for (int i = 0; i < 5; ++i)
  395. CHECK(arr[i] == i);
  396. arr.clear();
  397. CHECK(arr.capacity() == 5);
  398. CHECK(arr.size() == 0);
  399. arr.shrink_to_fit();
  400. CHECK(arr.capacity() == 0);
  401. CHECK(arr.data() == nullptr);
  402. }
  403. TEST_CASE("TestShrinkToFitNonTriv")
  404. {
  405. Array<NonTriv> arr;
  406. for (int i = 0; i < 5; ++i)
  407. arr.push_back(NonTriv(i));
  408. CHECK(arr.capacity() > 5);
  409. CHECK(arr.size() == 5);
  410. NonTriv::sReset();
  411. arr.shrink_to_fit();
  412. CHECK(arr.capacity() == 5);
  413. CHECK(arr.size() == 5);
  414. for (int i = 0; i < 5; ++i)
  415. CHECK(arr[i].Value() == i);
  416. CHECK(NonTriv::sNumConstructors == 0);
  417. CHECK(NonTriv::sNumCopyConstructors == 0);
  418. CHECK(NonTriv::sNumMoveConstructors == 5);
  419. CHECK(NonTriv::sNumDestructors == 5); // Switched to a new block, all old elements are destroyed after being moved
  420. }
  421. #endif // JPH_USE_STD_VECTOR
  422. TEST_CASE("TestAssignIterator")
  423. {
  424. int values[] = { 1, 2, 3 };
  425. Array<int> arr({ 4, 5, 6 });
  426. arr.assign(values, values + 3);
  427. CHECK(arr.size() == 3);
  428. CHECK(arr[0] == 1);
  429. CHECK(arr[1] == 2);
  430. CHECK(arr[2] == 3);
  431. }
  432. TEST_CASE("TestAssignInitializerList")
  433. {
  434. Array<int> arr({ 4, 5, 6 });
  435. arr.assign({ 1, 2, 3 });
  436. CHECK(arr.size() == 3);
  437. CHECK(arr[0] == 1);
  438. CHECK(arr[1] == 2);
  439. CHECK(arr[2] == 3);
  440. }
  441. TEST_CASE("TestSwap")
  442. {
  443. Array<int> arr({ 1, 2, 3 });
  444. Array<int> arr2({ 4, 5, 6 });
  445. arr.swap(arr2);
  446. CHECK(arr == Array<int>({ 4, 5, 6 }));
  447. CHECK(arr2 == Array<int>({ 1, 2, 3 }));
  448. }
  449. TEST_CASE("TestInsertBegin")
  450. {
  451. Array<int> arr = { 1, 2, 3 };
  452. arr.insert(arr.begin(), 4);
  453. CHECK(arr == Array<int>({ 4, 1, 2, 3 }));
  454. }
  455. TEST_CASE("TestInsertMid")
  456. {
  457. Array<int> arr = { 1, 2, 3 };
  458. arr.insert(arr.begin() + 1, 4);
  459. CHECK(arr == Array<int>({ 1, 4, 2, 3 }));
  460. }
  461. TEST_CASE("TestInsertEnd")
  462. {
  463. Array<int> arr = { 1, 2, 3 };
  464. arr.insert(arr.begin() + 3, 4);
  465. CHECK(arr == Array<int>({ 1, 2, 3, 4 }));
  466. }
  467. TEST_CASE("TestInsertMultipleBegin")
  468. {
  469. Array<int> values_to_insert = { 4, 5, 6, 7 };
  470. Array<int> arr = { 1, 2, 3 };
  471. arr.insert(arr.begin(), values_to_insert.begin(), values_to_insert.end());
  472. CHECK(arr == Array<int>({ 4, 5, 6, 7, 1, 2, 3 }));
  473. }
  474. TEST_CASE("TestInsertMultipleMid")
  475. {
  476. Array<int> values_to_insert = { 4, 5, 6, 7 };
  477. Array<int> arr = { 1, 2, 3 };
  478. arr.insert(arr.begin() + 1, values_to_insert.begin(), values_to_insert.end());
  479. CHECK(arr == Array<int>({ 1, 4, 5, 6, 7, 2, 3 }));
  480. }
  481. TEST_CASE("TestInsertMultipleEnd")
  482. {
  483. Array<int> values_to_insert = { 4, 5, 6, 7 };
  484. Array<int> arr = { 1, 2, 3 };
  485. arr.insert(arr.begin() + 3, values_to_insert.begin(), values_to_insert.end());
  486. CHECK(arr == Array<int>({ 1, 2, 3, 4, 5, 6, 7 }));
  487. }
  488. TEST_CASE("TestFrontBack")
  489. {
  490. Array<int> arr({ 1, 2, 3 });
  491. CHECK(arr.front() == 1);
  492. CHECK(arr.back() == 3);
  493. }
  494. TEST_CASE("TestAssign")
  495. {
  496. Array<int> arr({ 1, 2, 3 });
  497. Array<int> arr2({ 4, 5, 6 });
  498. arr = arr2;
  499. CHECK(arr == Array<int>({ 4, 5, 6 }));
  500. Array<int> &arr3 = arr; // Avoid compiler warning
  501. arr = arr3;
  502. CHECK(arr == Array<int>({ 4, 5, 6 }));
  503. arr = { 7, 8, 9 };
  504. CHECK(arr == Array<int>({ 7, 8, 9 }));
  505. }
  506. TEST_CASE("TestAssignMove")
  507. {
  508. Array<int> arr({ 1, 2, 3 });
  509. Array<int> arr2({ 4, 5, 6 });
  510. arr = std::move(arr2);
  511. CHECK(arr == Array<int>({ 4, 5, 6 }));
  512. CHECK(arr2.empty());
  513. }
  514. TEST_CASE("TestEraseBegin")
  515. {
  516. Array<int> arr({ 1, 2, 3 });
  517. arr.erase(arr.begin());
  518. CHECK(arr == Array<int>({ 2, 3 }));
  519. }
  520. TEST_CASE("TestEraseMid")
  521. {
  522. Array<int> arr({ 1, 2, 3 });
  523. arr.erase(arr.begin() + 1);
  524. CHECK(arr == Array<int>({ 1, 3 }));
  525. }
  526. TEST_CASE("TestEraseEnd")
  527. {
  528. Array<int> arr({ 1, 2, 3 });
  529. arr.erase(arr.begin() + 2);
  530. CHECK(arr == Array<int>({ 1, 2 }));
  531. }
  532. TEST_CASE("TestEraseMultipleBegin")
  533. {
  534. Array<int> arr({ 1, 2, 3, 4, 5 });
  535. arr.erase(arr.begin(), arr.begin() + 2);
  536. CHECK(arr == Array<int>({ 3, 4, 5 }));
  537. }
  538. TEST_CASE("TestEraseMultipleMid")
  539. {
  540. Array<int> arr({ 1, 2, 3, 4, 5 });
  541. arr.erase(arr.begin() + 2, arr.begin() + 4);
  542. CHECK(arr == Array<int>({ 1, 2, 5 }));
  543. }
  544. TEST_CASE("TestEraseMultipleEnd")
  545. {
  546. Array<int> arr({ 1, 2, 3, 4, 5 });
  547. arr.erase(arr.begin() + 3, arr.begin() + 5);
  548. CHECK(arr == Array<int>({ 1, 2, 3 }));
  549. }
  550. TEST_CASE("TestEquals")
  551. {
  552. Array<int> arr({ 1, 2, 3 });
  553. Array<int> arr2({ 4, 5, 6 });
  554. CHECK(arr == arr);
  555. CHECK(!(arr == arr2));
  556. CHECK(!(arr != arr));
  557. CHECK(arr != arr2);
  558. }
  559. }