vector_ut.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. #include "vector.h"
  2. #include <library/cpp/testing/unittest/registar.h>
  3. #include <utility>
  4. #include "yexception.h"
  5. #include <stdexcept>
  6. class TYVectorTest: public TTestBase {
  7. UNIT_TEST_SUITE(TYVectorTest);
  8. UNIT_TEST(TestConstructorsAndAssignments)
  9. UNIT_TEST(TestTildeEmptyToNull)
  10. UNIT_TEST(TestTilde)
  11. UNIT_TEST(Test1)
  12. UNIT_TEST(Test2)
  13. UNIT_TEST(Test3)
  14. UNIT_TEST(Test4)
  15. UNIT_TEST(Test5)
  16. UNIT_TEST(Test6)
  17. UNIT_TEST(Test7)
  18. UNIT_TEST(TestCapacity)
  19. UNIT_TEST(TestAt)
  20. UNIT_TEST(TestPointer)
  21. UNIT_TEST(TestAutoRef)
  22. UNIT_TEST(TestIterators)
  23. UNIT_TEST(TestShrink)
  24. //UNIT_TEST(TestEbo)
  25. UNIT_TEST(TestFillInConstructor)
  26. UNIT_TEST(TestYResize)
  27. UNIT_TEST(TestCrop)
  28. UNIT_TEST(TestInitializeList)
  29. UNIT_TEST_SUITE_END();
  30. private:
  31. void TestConstructorsAndAssignments() {
  32. using container = TVector<int>;
  33. container c1;
  34. c1.push_back(100);
  35. c1.push_back(200);
  36. container c2(c1);
  37. UNIT_ASSERT_VALUES_EQUAL(2, c1.size());
  38. UNIT_ASSERT_VALUES_EQUAL(2, c2.size());
  39. UNIT_ASSERT_VALUES_EQUAL(100, c1.at(0));
  40. UNIT_ASSERT_VALUES_EQUAL(200, c2.at(1));
  41. container c3(std::move(c1));
  42. UNIT_ASSERT_VALUES_EQUAL(0, c1.size());
  43. UNIT_ASSERT_VALUES_EQUAL(2, c3.size());
  44. UNIT_ASSERT_VALUES_EQUAL(100, c3.at(0));
  45. c2.push_back(300);
  46. c3 = c2;
  47. UNIT_ASSERT_VALUES_EQUAL(3, c2.size());
  48. UNIT_ASSERT_VALUES_EQUAL(3, c3.size());
  49. UNIT_ASSERT_VALUES_EQUAL(300, c3.at(2));
  50. c2.push_back(400);
  51. c3 = std::move(c2);
  52. UNIT_ASSERT_VALUES_EQUAL(0, c2.size());
  53. UNIT_ASSERT_VALUES_EQUAL(4, c3.size());
  54. UNIT_ASSERT_VALUES_EQUAL(400, c3.at(3));
  55. }
  56. inline void TestTildeEmptyToNull() {
  57. TVector<int> v;
  58. UNIT_ASSERT_EQUAL(nullptr, v.data());
  59. }
  60. inline void TestTilde() {
  61. TVector<int> v;
  62. v.push_back(10);
  63. v.push_back(20);
  64. UNIT_ASSERT_EQUAL(10, (v.data())[0]);
  65. UNIT_ASSERT_EQUAL(20, (v.data())[1]);
  66. for (int i = 0; i < 10000; ++i) {
  67. v.push_back(99);
  68. }
  69. UNIT_ASSERT_EQUAL(10, (v.data())[0]);
  70. UNIT_ASSERT_EQUAL(20, (v.data())[1]);
  71. UNIT_ASSERT_EQUAL(99, (v.data())[3]);
  72. UNIT_ASSERT_EQUAL(99, (v.data())[4]);
  73. }
  74. // Copy-paste of STLPort tests
  75. void Test1() {
  76. TVector<int> v1; // Empty vector of integers.
  77. UNIT_ASSERT(v1.empty() == true);
  78. UNIT_ASSERT(v1.size() == 0);
  79. UNIT_ASSERT(!v1);
  80. // UNIT_ASSERT(v1.max_size() == INT_MAX / sizeof(int));
  81. // cout << "max_size = " << v1.max_size() << endl;
  82. v1.push_back(42); // Add an integer to the vector.
  83. UNIT_ASSERT(v1.size() == 1);
  84. UNIT_ASSERT(v1);
  85. UNIT_ASSERT(v1[0] == 42);
  86. {
  87. TVector<TVector<int>> vect(10);
  88. TVector<TVector<int>>::iterator it(vect.begin()), end(vect.end());
  89. for (; it != end; ++it) {
  90. UNIT_ASSERT((*it).empty());
  91. UNIT_ASSERT((*it).size() == 0);
  92. UNIT_ASSERT((*it).capacity() == 0);
  93. UNIT_ASSERT((*it).begin() == (*it).end());
  94. }
  95. }
  96. }
  97. void Test2() {
  98. TVector<double> v1; // Empty vector of doubles.
  99. v1.push_back(32.1);
  100. v1.push_back(40.5);
  101. TVector<double> v2; // Another empty vector of doubles.
  102. v2.push_back(3.56);
  103. UNIT_ASSERT(v1.size() == 2);
  104. UNIT_ASSERT(v1[0] == 32.1);
  105. UNIT_ASSERT(v1[1] == 40.5);
  106. UNIT_ASSERT(v2.size() == 1);
  107. UNIT_ASSERT(v2[0] == 3.56);
  108. v1.swap(v2); // Swap the vector's contents.
  109. UNIT_ASSERT(v1.size() == 1);
  110. UNIT_ASSERT(v1[0] == 3.56);
  111. UNIT_ASSERT(v2.size() == 2);
  112. UNIT_ASSERT(v2[0] == 32.1);
  113. UNIT_ASSERT(v2[1] == 40.5);
  114. v2 = v1; // Assign one vector to another.
  115. UNIT_ASSERT(v2.size() == 1);
  116. UNIT_ASSERT(v2[0] == 3.56);
  117. }
  118. void Test3() {
  119. using vec_type = TVector<char>;
  120. vec_type v1; // Empty vector of characters.
  121. v1.push_back('h');
  122. v1.push_back('i');
  123. UNIT_ASSERT(v1.size() == 2);
  124. UNIT_ASSERT(v1[0] == 'h');
  125. UNIT_ASSERT(v1[1] == 'i');
  126. vec_type v2(v1.begin(), v1.end());
  127. v2[1] = 'o'; // Replace second character.
  128. UNIT_ASSERT(v2.size() == 2);
  129. UNIT_ASSERT(v2[0] == 'h');
  130. UNIT_ASSERT(v2[1] == 'o');
  131. UNIT_ASSERT((v1 == v2) == false);
  132. UNIT_ASSERT((v1 < v2) == true);
  133. }
  134. void Test4() {
  135. TVector<int> v(4);
  136. v[0] = 1;
  137. v[1] = 4;
  138. v[2] = 9;
  139. v[3] = 16;
  140. UNIT_ASSERT(v.front() == 1);
  141. UNIT_ASSERT(v.back() == 16);
  142. v.push_back(25);
  143. UNIT_ASSERT(v.back() == 25);
  144. UNIT_ASSERT(v.size() == 5);
  145. v.pop_back();
  146. UNIT_ASSERT(v.back() == 16);
  147. UNIT_ASSERT(v.size() == 4);
  148. }
  149. void Test5() {
  150. int array[] = {1, 4, 9, 16};
  151. TVector<int> v(array, array + 4);
  152. UNIT_ASSERT(v.size() == 4);
  153. UNIT_ASSERT(v[0] == 1);
  154. UNIT_ASSERT(v[1] == 4);
  155. UNIT_ASSERT(v[2] == 9);
  156. UNIT_ASSERT(v[3] == 16);
  157. }
  158. void Test6() {
  159. int array[] = {1, 4, 9, 16, 25, 36};
  160. TVector<int> v(array, array + 6);
  161. TVector<int>::iterator vit;
  162. UNIT_ASSERT(v.size() == 6);
  163. UNIT_ASSERT(v[0] == 1);
  164. UNIT_ASSERT(v[1] == 4);
  165. UNIT_ASSERT(v[2] == 9);
  166. UNIT_ASSERT(v[3] == 16);
  167. UNIT_ASSERT(v[4] == 25);
  168. UNIT_ASSERT(v[5] == 36);
  169. vit = v.erase(v.begin()); // Erase first element.
  170. UNIT_ASSERT(*vit == 4);
  171. UNIT_ASSERT(v.size() == 5);
  172. UNIT_ASSERT(v[0] == 4);
  173. UNIT_ASSERT(v[1] == 9);
  174. UNIT_ASSERT(v[2] == 16);
  175. UNIT_ASSERT(v[3] == 25);
  176. UNIT_ASSERT(v[4] == 36);
  177. vit = v.erase(v.end() - 1); // Erase last element.
  178. UNIT_ASSERT(vit == v.end());
  179. UNIT_ASSERT(v.size() == 4);
  180. UNIT_ASSERT(v[0] == 4);
  181. UNIT_ASSERT(v[1] == 9);
  182. UNIT_ASSERT(v[2] == 16);
  183. UNIT_ASSERT(v[3] == 25);
  184. v.erase(v.begin() + 1, v.end() - 1); // Erase all but first and last.
  185. UNIT_ASSERT(v.size() == 2);
  186. UNIT_ASSERT(v[0] == 4);
  187. UNIT_ASSERT(v[1] == 25);
  188. }
  189. void Test7() {
  190. int array1[] = {1, 4, 25};
  191. int array2[] = {9, 16};
  192. TVector<int> v(array1, array1 + 3);
  193. TVector<int>::iterator vit;
  194. vit = v.insert(v.begin(), 0); // Insert before first element.
  195. UNIT_ASSERT(*vit == 0);
  196. vit = v.insert(v.end(), 36); // Insert after last element.
  197. UNIT_ASSERT(*vit == 36);
  198. UNIT_ASSERT(v.size() == 5);
  199. UNIT_ASSERT(v[0] == 0);
  200. UNIT_ASSERT(v[1] == 1);
  201. UNIT_ASSERT(v[2] == 4);
  202. UNIT_ASSERT(v[3] == 25);
  203. UNIT_ASSERT(v[4] == 36);
  204. // Insert contents of array2 before fourth element.
  205. v.insert(v.begin() + 3, array2, array2 + 2);
  206. UNIT_ASSERT(v.size() == 7);
  207. UNIT_ASSERT(v[0] == 0);
  208. UNIT_ASSERT(v[1] == 1);
  209. UNIT_ASSERT(v[2] == 4);
  210. UNIT_ASSERT(v[3] == 9);
  211. UNIT_ASSERT(v[4] == 16);
  212. UNIT_ASSERT(v[5] == 25);
  213. UNIT_ASSERT(v[6] == 36);
  214. size_t curCapacity = v.capacity();
  215. v.clear();
  216. UNIT_ASSERT(v.empty());
  217. //check that clear save reserved data
  218. UNIT_ASSERT_EQUAL(curCapacity, v.capacity());
  219. v.insert(v.begin(), 5, 10);
  220. UNIT_ASSERT(v.size() == 5);
  221. UNIT_ASSERT(v[0] == 10);
  222. UNIT_ASSERT(v[1] == 10);
  223. UNIT_ASSERT(v[2] == 10);
  224. UNIT_ASSERT(v[3] == 10);
  225. UNIT_ASSERT(v[4] == 10);
  226. }
  227. struct TestStruct {
  228. unsigned int a[3];
  229. };
  230. void TestCapacity() {
  231. {
  232. TVector<int> v;
  233. UNIT_ASSERT(v.capacity() == 0);
  234. v.push_back(42);
  235. UNIT_ASSERT(v.capacity() >= 1);
  236. v.reserve(5000);
  237. UNIT_ASSERT(v.capacity() >= 5000);
  238. }
  239. {
  240. TVector<int> v(Reserve(100));
  241. UNIT_ASSERT(v.capacity() >= 100);
  242. UNIT_ASSERT(v.size() == 0);
  243. }
  244. {
  245. //Test that used to generate an assertion when using __debug_alloc.
  246. TVector<TestStruct> va;
  247. va.reserve(1);
  248. va.reserve(2);
  249. }
  250. }
  251. void TestAt() {
  252. TVector<int> v;
  253. TVector<int> const& cv = v;
  254. v.push_back(10);
  255. UNIT_ASSERT(v.at(0) == 10);
  256. v.at(0) = 20;
  257. UNIT_ASSERT(cv.at(0) == 20);
  258. for (;;) {
  259. try {
  260. v.at(1) = 20;
  261. UNIT_ASSERT(false);
  262. } catch (std::out_of_range const&) {
  263. return;
  264. } catch (...) {
  265. UNIT_ASSERT(false);
  266. }
  267. }
  268. }
  269. void TestPointer() {
  270. TVector<int*> v1;
  271. TVector<int*> v2 = v1;
  272. TVector<int*> v3;
  273. v3.insert(v3.end(), v1.begin(), v1.end());
  274. }
  275. void TestAutoRef() {
  276. TVector<int> ref;
  277. for (int i = 0; i < 5; ++i) {
  278. ref.push_back(i);
  279. }
  280. TVector<TVector<int>> v_v_int(1, ref);
  281. v_v_int.push_back(v_v_int[0]);
  282. v_v_int.push_back(ref);
  283. v_v_int.push_back(v_v_int[0]);
  284. v_v_int.push_back(v_v_int[0]);
  285. v_v_int.push_back(ref);
  286. TVector<TVector<int>>::iterator vvit(v_v_int.begin()), vvitEnd(v_v_int.end());
  287. for (; vvit != vvitEnd; ++vvit) {
  288. UNIT_ASSERT(*vvit == ref);
  289. }
  290. }
  291. struct Point {
  292. int x, y;
  293. };
  294. struct PointEx: public Point {
  295. PointEx()
  296. : builtFromBase(false)
  297. {
  298. }
  299. PointEx(const Point&)
  300. : builtFromBase(true)
  301. {
  302. }
  303. bool builtFromBase;
  304. };
  305. void TestIterators() {
  306. TVector<int> vint(10, 0);
  307. TVector<int> const& crvint = vint;
  308. UNIT_ASSERT(vint.begin() == vint.begin());
  309. UNIT_ASSERT(crvint.begin() == vint.begin());
  310. UNIT_ASSERT(vint.begin() == crvint.begin());
  311. UNIT_ASSERT(crvint.begin() == crvint.begin());
  312. UNIT_ASSERT(vint.begin() != vint.end());
  313. UNIT_ASSERT(crvint.begin() != vint.end());
  314. UNIT_ASSERT(vint.begin() != crvint.end());
  315. UNIT_ASSERT(crvint.begin() != crvint.end());
  316. UNIT_ASSERT(vint.rbegin() == vint.rbegin());
  317. // Not Standard:
  318. //UNIT_ASSERT(vint.rbegin() == crvint.rbegin());
  319. //UNIT_ASSERT(crvint.rbegin() == vint.rbegin());
  320. UNIT_ASSERT(crvint.rbegin() == crvint.rbegin());
  321. UNIT_ASSERT(vint.rbegin() != vint.rend());
  322. // Not Standard:
  323. //UNIT_ASSERT(vint.rbegin() != crvint.rend());
  324. //UNIT_ASSERT(crvint.rbegin() != vint.rend());
  325. UNIT_ASSERT(crvint.rbegin() != crvint.rend());
  326. }
  327. void TestShrink() {
  328. TVector<int> v;
  329. v.resize(1000);
  330. v.resize(10);
  331. v.shrink_to_fit();
  332. UNIT_ASSERT_EQUAL(v.capacity(), 10);
  333. v.push_back(0);
  334. v.shrink_to_fit();
  335. UNIT_ASSERT_EQUAL(v.capacity(), 11);
  336. }
  337. /* This test check a potential issue with empty base class
  338. * optimization. Some compilers (VC6) do not implement it
  339. * correctly resulting ina wrong behavior. */
  340. void TestEbo() {
  341. // We use heap memory as test failure can corrupt vector internal
  342. // representation making executable crash on vector destructor invocation.
  343. // We prefer a simple memory leak, internal corruption should be reveal
  344. // by size or capacity checks.
  345. using V = TVector<int>;
  346. V* pv1 = new V(1, 1);
  347. V* pv2 = new V(10, 2);
  348. size_t v1Capacity = pv1->capacity();
  349. size_t v2Capacity = pv2->capacity();
  350. pv1->swap(*pv2);
  351. UNIT_ASSERT(pv1->size() == 10);
  352. UNIT_ASSERT(pv1->capacity() == v2Capacity);
  353. UNIT_ASSERT((*pv1)[5] == 2);
  354. UNIT_ASSERT(pv2->size() == 1);
  355. UNIT_ASSERT(pv2->capacity() == v1Capacity);
  356. UNIT_ASSERT((*pv2)[0] == 1);
  357. delete pv2;
  358. delete pv1;
  359. }
  360. void TestFillInConstructor() {
  361. for (int k = 0; k < 3; ++k) {
  362. TVector<int> v(100);
  363. UNIT_ASSERT_VALUES_EQUAL(100u, v.size());
  364. for (size_t i = 0; i < v.size(); ++i) {
  365. UNIT_ASSERT_VALUES_EQUAL(0, v[i]);
  366. }
  367. // fill with garbage for the next iteration
  368. for (size_t i = 0; i < v.size(); ++i) {
  369. v[i] = 10;
  370. }
  371. }
  372. }
  373. struct TPod {
  374. int x;
  375. operator int() {
  376. return x;
  377. }
  378. };
  379. struct TNonPod {
  380. int x;
  381. TNonPod() {
  382. x = 0;
  383. }
  384. operator int() {
  385. return x;
  386. }
  387. };
  388. template <typename T>
  389. class TDebugAlloc: public std::allocator<T> {
  390. public:
  391. using TBase = std::allocator<T>;
  392. T* allocate(typename TBase::size_type n) {
  393. auto p = TBase::allocate(n);
  394. for (size_t i = 0; i < n; ++i) {
  395. memset(p + i, 0xab, sizeof(T));
  396. }
  397. return p;
  398. }
  399. template <class TOther>
  400. struct rebind {
  401. using other = TDebugAlloc<TOther>;
  402. };
  403. };
  404. template <typename T>
  405. void TestYResize() {
  406. #ifdef _YNDX_LIBCXX_ENABLE_VECTOR_POD_RESIZE_UNINITIALIZED
  407. constexpr bool ALLOW_UNINITIALIZED = std::is_pod_v<T>;
  408. #else
  409. constexpr bool ALLOW_UNINITIALIZED = false;
  410. #endif
  411. TVector<T, TDebugAlloc<T>> v;
  412. v.reserve(5);
  413. auto firstBegin = v.begin();
  414. v.yresize(5); // No realloc, no initialization if allowed
  415. UNIT_ASSERT(firstBegin == v.begin());
  416. for (int i = 0; i < 5; ++i) {
  417. UNIT_ASSERT_VALUES_EQUAL(bool(v[i]), ALLOW_UNINITIALIZED);
  418. }
  419. v.yresize(20); // Realloc, still no initialization
  420. UNIT_ASSERT(firstBegin != v.begin());
  421. for (int i = 0; i < 20; ++i) {
  422. UNIT_ASSERT_VALUES_EQUAL(bool(v[i]), ALLOW_UNINITIALIZED);
  423. }
  424. }
  425. struct TNoDefaultConstructor {
  426. TNoDefaultConstructor() = delete;
  427. explicit TNoDefaultConstructor(int val)
  428. : Val(val)
  429. {
  430. }
  431. int Val;
  432. };
  433. void TestCrop() {
  434. TVector<TNoDefaultConstructor> vec;
  435. vec.emplace_back(42);
  436. vec.emplace_back(1337);
  437. vec.emplace_back(8888);
  438. vec.crop(1); // Should not require default constructor
  439. UNIT_ASSERT(vec.size() == 1);
  440. UNIT_ASSERT(vec[0].Val == 42);
  441. vec.crop(50); // Does nothing if new size is greater than the current size()
  442. UNIT_ASSERT(vec.size() == 1);
  443. UNIT_ASSERT(vec[0].Val == 42);
  444. }
  445. void TestYResize() {
  446. TestYResize<int>();
  447. TestYResize<TPod>();
  448. TestYResize<TNonPod>();
  449. }
  450. void CheckInitializeList(const TVector<int>& v) {
  451. for (size_t i = 0; i < v.size(); ++i) {
  452. UNIT_ASSERT_EQUAL(v[i], static_cast<int>(i));
  453. }
  454. }
  455. void TestInitializeList() {
  456. {
  457. TVector<int> v;
  458. v.assign({0, 1, 2});
  459. CheckInitializeList(v);
  460. }
  461. {
  462. TVector<int> v = {0, 1, 2};
  463. CheckInitializeList(v);
  464. }
  465. {
  466. TVector<int> v;
  467. v = {0, 1, 2};
  468. CheckInitializeList(v);
  469. }
  470. {
  471. TVector<int> v = {0, 3};
  472. v.insert(v.begin() + 1, {1, 2});
  473. CheckInitializeList(v);
  474. }
  475. }
  476. };
  477. UNIT_TEST_SUITE_REGISTRATION(TYVectorTest);