stl_test.cc 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. #include "catch.hpp"
  2. #include "stl.hh"
  3. #include "view.hh"
  4. #include <list>
  5. struct S {
  6. S() { ++default_constructed; }
  7. S(const S&) { ++copy_constructed; }
  8. S(S&&) { ++move_constructed; }
  9. S& operator=(const S&) { ++copy_assignment; return *this; }
  10. S& operator=(S&&) { ++move_assignment; return *this; }
  11. ~S() { ++destructed; }
  12. static void reset() {
  13. default_constructed = 0;
  14. copy_constructed = 0;
  15. move_constructed = 0;
  16. copy_assignment = 0;
  17. move_assignment = 0;
  18. destructed = 0;
  19. }
  20. static inline int default_constructed = 0;
  21. static inline int copy_constructed = 0;
  22. static inline int move_constructed = 0;
  23. static inline int copy_assignment = 0;
  24. static inline int move_assignment = 0;
  25. static inline int destructed = 0;
  26. };
  27. TEST_CASE("append")
  28. {
  29. std::vector<int> v;
  30. std::vector<int> v0;
  31. std::vector<int> v123 = {1, 2, 3};
  32. std::vector<int> v45 = {4, 5};
  33. SECTION("non-empty + non-empty") {
  34. append(v123, v45);
  35. CHECK(v123 == std::vector<int>{1, 2, 3, 4, 5});
  36. }
  37. SECTION("non-empty + empty") {
  38. append(v123, v0);
  39. CHECK(v123 == std::vector<int>{1, 2, 3});
  40. }
  41. SECTION("empty + non-empty") {
  42. append(v, v45);
  43. CHECK(v == std::vector<int>{4, 5});
  44. }
  45. SECTION("empty + empty") {
  46. append(v, v0);
  47. CHECK(v == std::vector<int>{});
  48. }
  49. SECTION("non-empty + view") {
  50. append(v45, view::drop(v123, 1));
  51. CHECK(v45 == std::vector<int>{4, 5, 2, 3});
  52. }
  53. SECTION("empty + l-value") {
  54. {
  55. S::reset();
  56. std::vector<S> v1;
  57. std::vector<S> v2 = {S(), S()};
  58. CHECK(S::default_constructed == 2);
  59. CHECK(S::copy_constructed == 2);
  60. CHECK(S::move_constructed == 0);
  61. CHECK(S::copy_assignment == 0);
  62. CHECK(S::move_assignment == 0);
  63. CHECK(S::destructed == 2);
  64. S::reset();
  65. append(v1, v2);
  66. CHECK(S::default_constructed == 0);
  67. CHECK(S::copy_constructed == 2);
  68. CHECK(S::move_constructed == 0);
  69. CHECK(S::copy_assignment == 0);
  70. CHECK(S::move_assignment == 0);
  71. CHECK(S::destructed == 0);
  72. S::reset();
  73. }
  74. CHECK(S::default_constructed == 0);
  75. CHECK(S::copy_constructed == 0);
  76. CHECK(S::move_constructed == 0);
  77. CHECK(S::copy_assignment == 0);
  78. CHECK(S::move_assignment == 0);
  79. CHECK(S::destructed == 4);
  80. }
  81. SECTION("empty + r-value") {
  82. {
  83. S::reset();
  84. std::vector<S> v1;
  85. std::vector<S> v2 = {S(), S()};
  86. CHECK(S::default_constructed == 2);
  87. CHECK(S::copy_constructed == 2);
  88. CHECK(S::move_constructed == 0);
  89. CHECK(S::copy_assignment == 0);
  90. CHECK(S::move_assignment == 0);
  91. CHECK(S::destructed == 2);
  92. S::reset();
  93. append(v1, std::move(v2));
  94. CHECK(S::default_constructed == 0);
  95. CHECK(S::copy_constructed == 0);
  96. CHECK(S::move_constructed == 0);
  97. CHECK(S::copy_assignment == 0);
  98. CHECK(S::move_assignment == 0);
  99. CHECK(S::destructed == 0);
  100. S::reset();
  101. }
  102. CHECK(S::default_constructed == 0);
  103. CHECK(S::copy_constructed == 0);
  104. CHECK(S::move_constructed == 0);
  105. CHECK(S::copy_assignment == 0);
  106. CHECK(S::move_assignment == 0);
  107. CHECK(S::destructed == 2);
  108. }
  109. }
  110. TEST_CASE("to_vector: from list")
  111. {
  112. SECTION("deduce type") {
  113. std::list<int> l = {1, 2, 3};
  114. auto v = to_vector(l);
  115. CHECK(v.size() == 3);
  116. CHECK(v[0] == 1);
  117. CHECK(v[1] == 2);
  118. CHECK(v[2] == 3);
  119. CHECK(std::is_same_v<decltype(v)::value_type, int>);
  120. }
  121. SECTION("convert type") {
  122. std::list<int> l = {1, 2, 3};
  123. auto v = to_vector<char>(l);
  124. CHECK(v.size() == 3);
  125. CHECK(v[0] == 1);
  126. CHECK(v[1] == 2);
  127. CHECK(v[2] == 3);
  128. CHECK(std::is_same_v<decltype(v)::value_type, char>);
  129. }
  130. }
  131. TEST_CASE("to_vector: from view")
  132. {
  133. std::vector<int> v1 = {1, 2, 3};
  134. SECTION("deduce type") {
  135. auto v = to_vector(view::drop(v1, 2));
  136. CHECK(v.size() == 1);
  137. CHECK(v[0] == 3);
  138. CHECK(std::is_same_v<decltype(v)::value_type, int>);
  139. }
  140. SECTION("convert type") {
  141. auto v = to_vector<long long>(view::drop(v1, 1));
  142. CHECK(v.size() == 2);
  143. CHECK(v[0] == 2ll);
  144. CHECK(v[1] == 3ll);
  145. CHECK(std::is_same_v<decltype(v)::value_type, long long>);
  146. }
  147. }
  148. TEST_CASE("to_vector: optimized r-value")
  149. {
  150. SECTION("l-value") {
  151. S::reset();
  152. {
  153. std::vector<S> v1 = {S(), S(), S()};
  154. CHECK(S::default_constructed == 3);
  155. CHECK(S::copy_constructed == 3);
  156. CHECK(S::move_constructed == 0);
  157. CHECK(S::copy_assignment == 0);
  158. CHECK(S::move_assignment == 0);
  159. CHECK(S::destructed == 3);
  160. S::reset();
  161. auto v = to_vector(v1);
  162. CHECK(S::default_constructed == 0);
  163. CHECK(S::copy_constructed == 3);
  164. CHECK(S::move_constructed == 0);
  165. CHECK(S::copy_assignment == 0);
  166. CHECK(S::move_assignment == 0);
  167. CHECK(S::destructed == 0);
  168. S::reset();
  169. }
  170. CHECK(S::default_constructed == 0);
  171. CHECK(S::copy_constructed == 0);
  172. CHECK(S::move_constructed == 0);
  173. CHECK(S::copy_assignment == 0);
  174. CHECK(S::move_assignment == 0);
  175. CHECK(S::destructed == 6);
  176. }
  177. SECTION("r-value") {
  178. S::reset();
  179. {
  180. std::vector<S> v1 = {S(), S(), S()};
  181. CHECK(S::default_constructed == 3);
  182. CHECK(S::copy_constructed == 3);
  183. CHECK(S::move_constructed == 0);
  184. CHECK(S::copy_assignment == 0);
  185. CHECK(S::move_assignment == 0);
  186. CHECK(S::destructed == 3);
  187. S::reset();
  188. auto v = to_vector(std::move(v1));
  189. CHECK(S::default_constructed == 0);
  190. CHECK(S::copy_constructed == 0);
  191. CHECK(S::move_constructed == 0);
  192. CHECK(S::copy_assignment == 0);
  193. CHECK(S::move_assignment == 0);
  194. CHECK(S::destructed == 0);
  195. S::reset();
  196. }
  197. CHECK(S::default_constructed == 0);
  198. CHECK(S::copy_constructed == 0);
  199. CHECK(S::move_constructed == 0);
  200. CHECK(S::copy_assignment == 0);
  201. CHECK(S::move_assignment == 0);
  202. CHECK(S::destructed == 3);
  203. }
  204. }
  205. // check quality of generated code
  206. #if 0
  207. std::vector<int> check1(const std::vector<int>& v)
  208. {
  209. return to_vector(view::drop(v, 1));
  210. }
  211. std::vector<int> check2(const std::vector<int>& v)
  212. {
  213. return std::vector<int>(begin(v) + 1, end(v));
  214. }
  215. #endif