Main.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include "Vector.h"
  2. #include <iostream>
  3. #include <memory>
  4. #include <vector>
  5. // All implementations in this class use ints insteads of size_t because size_t
  6. // is interely slow compared to ints. C++20 also adds new methods to call for
  7. // signed container sizes. Several online resources also suggest to use unsigned
  8. // types mostly for bit operations and nothing else.
  9. // This struct is used in the automated tests at the end of the file.
  10. // It counts all instances with different numbers to ensure each object is
  11. // constructed and destructed the same amount of times.
  12. // A also has a non trivial constructor to test the vector
  13. struct A {
  14. static int instances;
  15. int a;
  16. A(int a) : a(a) {
  17. // std::cout << "construct A " << a << "\n";
  18. instances += a;
  19. }
  20. A(const A& other) : a(other.a) {
  21. // std::cout << "copy construct A " << a << "\n";
  22. instances += a;
  23. }
  24. A(A&& other) : a(other.a) {
  25. // std::cout << "move construct A " << a << "\n";
  26. instances += a;
  27. }
  28. A& operator=(const A& other) {
  29. instances -= a;
  30. a = other.a;
  31. instances += a;
  32. // std::cout << "copy assignment A " << a << "\n";
  33. return *this;
  34. }
  35. A& operator=(A&& other) {
  36. instances -= a;
  37. a = other.a;
  38. instances += a;
  39. // std::cout << "move assignment A " << a << "\n";
  40. return *this;
  41. }
  42. ~A() {
  43. // std::cout << "destruct A " << a << "\n";
  44. instances -= a;
  45. }
  46. };
  47. int A::instances = 0;
  48. void printError(int number) {
  49. std::cout << "\033[0;31mError " << number << "\033[0m\n";
  50. }
  51. // V is either std::vector or Vector to test for complete same behaviour in both
  52. // implementations
  53. template<typename V>
  54. void test() {
  55. {
  56. const int elements = 2;
  57. V v;
  58. for(int i = 0; i < elements; i++) {
  59. v.push_back(A(i));
  60. }
  61. const V& cv = v;
  62. for(int i = 0; i < elements; i++) {
  63. if(v[i].a != i || cv[i].a != i || v.at(i).a != i ||
  64. cv.at(i).a != i) {
  65. printError(1);
  66. }
  67. }
  68. if(v.size() != elements) {
  69. printError(2);
  70. }
  71. }
  72. {
  73. V v1;
  74. v1.push_back(A(10));
  75. V v2 = v1;
  76. V v3;
  77. v3.push_back(A(20));
  78. v3 = v1;
  79. if(v1[0].a != 10 || v2[0].a != 10 || v3[0].a != 10) {
  80. printError(3);
  81. }
  82. V v4 = std::move(v1);
  83. V v5(std::move(v2));
  84. V v6;
  85. v6 = std::move(v3);
  86. if(v1.size() != 0 || v2.size() != 0 || v3.size() != 0 ||
  87. v4.size() != 1 || v5.size() != 1 || v6.size() != 1) {
  88. printError(4);
  89. }
  90. }
  91. {
  92. V v;
  93. v.resize(1, A(8));
  94. v.resize(3, A(9));
  95. if(v.size() != 3 || v[0].a != 8 || v[1].a != 9 || v[2].a != 9) {
  96. printError(5);
  97. }
  98. v.resize(1, A(10));
  99. if(v.size() != 1 || v[0].a != 8) {
  100. printError(6);
  101. }
  102. }
  103. {
  104. std::vector<A> v1;
  105. V v2;
  106. for(int i = 0; i < 200; i++) {
  107. v1.push_back(A(i));
  108. v2.push_back(A(i));
  109. }
  110. v1.erase(v1.begin());
  111. v1.erase(v1.begin() + 4, v1.begin() + 8);
  112. v1.erase(v1.begin() + 30, v1.begin() + 56);
  113. v2.erase(v2.begin());
  114. v2.erase(v2.begin() + 4, v2.begin() + 8);
  115. v2.erase(v2.begin() + 30, v2.begin() + 56);
  116. if(static_cast<int>(v1.size()) != static_cast<int>(v2.size())) {
  117. printError(100);
  118. } else {
  119. for(unsigned int i = 0; i < v1.size(); i++) {
  120. if(v1[i].a != v2[i].a) {
  121. printError(200);
  122. }
  123. }
  124. }
  125. }
  126. if(A::instances != 0) {
  127. std::cout << "object counter is not 0: " << A::instances << "\n";
  128. }
  129. }
  130. void test() {
  131. {
  132. Vector<A> v;
  133. v.push_back(1);
  134. v.push_back(2);
  135. v.push_back(3);
  136. v.erase_by_swap(1);
  137. if(v.size() != 2 || v[0].a != 1 || v[1].a != 3) {
  138. printError(9);
  139. }
  140. v.erase_by_swap(1);
  141. if(v.size() != 1 || v[0].a != 1) {
  142. printError(10);
  143. }
  144. v.erase_by_swap(0);
  145. if(v.size() != 0) {
  146. printError(11);
  147. }
  148. }
  149. if(A::instances != 0) {
  150. std::cout << "object counter is not 0: " << A::instances << "\n";
  151. }
  152. }
  153. int main() {
  154. test<Vector<A>>();
  155. test();
  156. std::cout << "--------------------------\n";
  157. test<std::vector<A>>();
  158. Vector<int> test(3);
  159. Vector<std::unique_ptr<A>> test2;
  160. test2.resize(5);
  161. }