Main.cpp 4.4 KB

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