Main.cpp 5.2 KB

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