vector_ut.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  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. UNIT_ASSERT_EXCEPTION(v.at(1) = 20, std::out_of_range);
  259. }
  260. void TestPointer() {
  261. TVector<int*> v1;
  262. TVector<int*> v2 = v1;
  263. TVector<int*> v3;
  264. v3.insert(v3.end(), v1.begin(), v1.end());
  265. }
  266. void TestAutoRef() {
  267. TVector<int> ref;
  268. for (int i = 0; i < 5; ++i) {
  269. ref.push_back(i);
  270. }
  271. TVector<TVector<int>> v_v_int(1, ref);
  272. v_v_int.push_back(v_v_int[0]);
  273. v_v_int.push_back(ref);
  274. v_v_int.push_back(v_v_int[0]);
  275. v_v_int.push_back(v_v_int[0]);
  276. v_v_int.push_back(ref);
  277. TVector<TVector<int>>::iterator vvit(v_v_int.begin()), vvitEnd(v_v_int.end());
  278. for (; vvit != vvitEnd; ++vvit) {
  279. UNIT_ASSERT(*vvit == ref);
  280. }
  281. }
  282. struct Point {
  283. int x, y;
  284. };
  285. struct PointEx: public Point {
  286. PointEx()
  287. : builtFromBase(false)
  288. {
  289. }
  290. PointEx(const Point&)
  291. : builtFromBase(true)
  292. {
  293. }
  294. bool builtFromBase;
  295. };
  296. void TestIterators() {
  297. TVector<int> vint(10, 0);
  298. TVector<int> const& crvint = vint;
  299. UNIT_ASSERT(vint.begin() == vint.begin());
  300. UNIT_ASSERT(crvint.begin() == vint.begin());
  301. UNIT_ASSERT(vint.begin() == crvint.begin());
  302. UNIT_ASSERT(crvint.begin() == crvint.begin());
  303. UNIT_ASSERT(vint.begin() != vint.end());
  304. UNIT_ASSERT(crvint.begin() != vint.end());
  305. UNIT_ASSERT(vint.begin() != crvint.end());
  306. UNIT_ASSERT(crvint.begin() != crvint.end());
  307. UNIT_ASSERT(vint.rbegin() == vint.rbegin());
  308. // Not Standard:
  309. // UNIT_ASSERT(vint.rbegin() == crvint.rbegin());
  310. // UNIT_ASSERT(crvint.rbegin() == vint.rbegin());
  311. UNIT_ASSERT(crvint.rbegin() == crvint.rbegin());
  312. UNIT_ASSERT(vint.rbegin() != vint.rend());
  313. // Not Standard:
  314. // UNIT_ASSERT(vint.rbegin() != crvint.rend());
  315. // UNIT_ASSERT(crvint.rbegin() != vint.rend());
  316. UNIT_ASSERT(crvint.rbegin() != crvint.rend());
  317. }
  318. void TestShrink() {
  319. TVector<int> v;
  320. v.resize(1000);
  321. v.resize(10);
  322. v.shrink_to_fit();
  323. UNIT_ASSERT_EQUAL(v.capacity(), 10);
  324. v.push_back(0);
  325. v.shrink_to_fit();
  326. UNIT_ASSERT_EQUAL(v.capacity(), 11);
  327. }
  328. /* This test check a potential issue with empty base class
  329. * optimization. Some compilers (VC6) do not implement it
  330. * correctly resulting ina wrong behavior. */
  331. void TestEbo() {
  332. // We use heap memory as test failure can corrupt vector internal
  333. // representation making executable crash on vector destructor invocation.
  334. // We prefer a simple memory leak, internal corruption should be reveal
  335. // by size or capacity checks.
  336. using V = TVector<int>;
  337. V* pv1 = new V(1, 1);
  338. V* pv2 = new V(10, 2);
  339. size_t v1Capacity = pv1->capacity();
  340. size_t v2Capacity = pv2->capacity();
  341. pv1->swap(*pv2);
  342. UNIT_ASSERT(pv1->size() == 10);
  343. UNIT_ASSERT(pv1->capacity() == v2Capacity);
  344. UNIT_ASSERT((*pv1)[5] == 2);
  345. UNIT_ASSERT(pv2->size() == 1);
  346. UNIT_ASSERT(pv2->capacity() == v1Capacity);
  347. UNIT_ASSERT((*pv2)[0] == 1);
  348. delete pv2;
  349. delete pv1;
  350. }
  351. void TestFillInConstructor() {
  352. for (int k = 0; k < 3; ++k) {
  353. TVector<int> v(100);
  354. UNIT_ASSERT_VALUES_EQUAL(100u, v.size());
  355. for (size_t i = 0; i < v.size(); ++i) {
  356. UNIT_ASSERT_VALUES_EQUAL(0, v[i]);
  357. }
  358. // fill with garbage for the next iteration
  359. for (size_t i = 0; i < v.size(); ++i) {
  360. v[i] = 10;
  361. }
  362. }
  363. }
  364. struct TPod {
  365. int x;
  366. operator int() {
  367. return x;
  368. }
  369. };
  370. struct TNonPod {
  371. int x;
  372. TNonPod() {
  373. x = 0;
  374. }
  375. operator int() {
  376. return x;
  377. }
  378. };
  379. template <typename T>
  380. class TDebugAlloc: public std::allocator<T> {
  381. public:
  382. using TBase = std::allocator<T>;
  383. T* allocate(typename TBase::size_type n) {
  384. auto p = TBase::allocate(n);
  385. for (size_t i = 0; i < n; ++i) {
  386. memset(p + i, 0xab, sizeof(T));
  387. }
  388. return p;
  389. }
  390. template <class TOther>
  391. struct rebind {
  392. using other = TDebugAlloc<TOther>;
  393. };
  394. };
  395. template <typename T>
  396. void TestYResize() {
  397. #ifdef _YNDX_LIBCXX_ENABLE_VECTOR_POD_RESIZE_UNINITIALIZED
  398. constexpr bool ALLOW_UNINITIALIZED = std::is_pod_v<T>;
  399. #else
  400. constexpr bool ALLOW_UNINITIALIZED = false;
  401. #endif
  402. TVector<T, TDebugAlloc<T>> v;
  403. v.reserve(5);
  404. auto firstBegin = v.begin();
  405. v.yresize(5); // No realloc, no initialization if allowed
  406. UNIT_ASSERT(firstBegin == v.begin());
  407. for (int i = 0; i < 5; ++i) {
  408. UNIT_ASSERT_VALUES_EQUAL(bool(v[i]), ALLOW_UNINITIALIZED);
  409. }
  410. v.yresize(20); // Realloc, still no initialization
  411. UNIT_ASSERT(firstBegin != v.begin());
  412. for (int i = 0; i < 20; ++i) {
  413. UNIT_ASSERT_VALUES_EQUAL(bool(v[i]), ALLOW_UNINITIALIZED);
  414. }
  415. }
  416. struct TNoDefaultConstructor {
  417. TNoDefaultConstructor() = delete;
  418. explicit TNoDefaultConstructor(int val)
  419. : Val(val)
  420. {
  421. }
  422. int Val;
  423. };
  424. void TestCrop() {
  425. TVector<TNoDefaultConstructor> vec;
  426. vec.emplace_back(42);
  427. vec.emplace_back(1337);
  428. vec.emplace_back(8888);
  429. vec.crop(1); // Should not require default constructor
  430. UNIT_ASSERT(vec.size() == 1);
  431. UNIT_ASSERT(vec[0].Val == 42);
  432. vec.crop(50); // Does nothing if new size is greater than the current size()
  433. UNIT_ASSERT(vec.size() == 1);
  434. UNIT_ASSERT(vec[0].Val == 42);
  435. }
  436. void TestYResize() {
  437. TestYResize<int>();
  438. TestYResize<TPod>();
  439. TestYResize<TNonPod>();
  440. }
  441. void CheckInitializeList(const TVector<int>& v) {
  442. for (size_t i = 0; i < v.size(); ++i) {
  443. UNIT_ASSERT_EQUAL(v[i], static_cast<int>(i));
  444. }
  445. }
  446. void TestInitializeList() {
  447. {
  448. TVector<int> v;
  449. v.assign({0, 1, 2});
  450. CheckInitializeList(v);
  451. }
  452. {
  453. TVector<int> v = {0, 1, 2};
  454. CheckInitializeList(v);
  455. }
  456. {
  457. TVector<int> v;
  458. v = {0, 1, 2};
  459. CheckInitializeList(v);
  460. }
  461. {
  462. TVector<int> v = {0, 3};
  463. v.insert(v.begin() + 1, {1, 2});
  464. CheckInitializeList(v);
  465. }
  466. }
  467. };
  468. UNIT_TEST_SUITE_REGISTRATION(TYVectorTest);