Main.cpp 5.1 KB

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