openMSX
stl_test.cc
Go to the documentation of this file.
1 #include "catch.hpp"
2 #include "stl.hh"
3 
4 #include "view.hh"
5 #include <list>
6 
7 struct S {
9  S(const S&) { ++copy_constructed; }
10  S(S&&) { ++move_constructed; }
11  S& operator=(const S&) { ++copy_assignment; return *this; }
12  S& operator=(S&&) { ++move_assignment; return *this; }
13  ~S() { ++destructed; }
14 
15  static void reset() {
17  copy_constructed = 0;
18  move_constructed = 0;
19  copy_assignment = 0;
20  move_assignment = 0;
21  destructed = 0;
22  }
23 
24  static inline int default_constructed = 0;
25  static inline int copy_constructed = 0;
26  static inline int move_constructed = 0;
27  static inline int copy_assignment = 0;
28  static inline int move_assignment = 0;
29  static inline int destructed = 0;
30 };
31 
32 
33 TEST_CASE("append")
34 {
35  std::vector<int> v;
36  std::vector<int> v0;
37  std::vector<int> v123 = {1, 2, 3};
38  std::vector<int> v45 = {4, 5};
39 
40  SECTION("non-empty + non-empty") {
41  append(v123, v45);
42  CHECK(v123 == std::vector<int>{1, 2, 3, 4, 5});
43  }
44  SECTION("non-empty + empty") {
45  append(v123, v0);
46  CHECK(v123 == std::vector<int>{1, 2, 3});
47  }
48  SECTION("empty + non-empty") {
49  append(v, v45);
50  CHECK(v == std::vector<int>{4, 5});
51  }
52  SECTION("empty + empty") {
53  append(v, v0);
54  CHECK(v == std::vector<int>{});
55  }
56  SECTION("non-empty + view") {
57  append(v45, view::drop(v123, 1));
58  CHECK(v45 == std::vector<int>{4, 5, 2, 3});
59  }
60  SECTION("empty + l-value") {
61  {
62  S::reset();
63  std::vector<S> v1;
64  std::vector<S> v2 = {S(), S()};
70  CHECK(S::destructed == 2);
71  S::reset();
72 
73  append(v1, v2);
79  CHECK(S::destructed == 0);
80  S::reset();
81  }
87  CHECK(S::destructed == 4);
88  }
89  SECTION("empty + r-value") {
90  {
91  S::reset();
92  std::vector<S> v1;
93  std::vector<S> v2 = {S(), S()};
99  CHECK(S::destructed == 2);
100  S::reset();
101 
102  append(v1, std::move(v2));
108  CHECK(S::destructed == 0);
109  S::reset();
110  }
116  CHECK(S::destructed == 2);
117  }
118 }
119 
120 
121 TEST_CASE("to_vector: from list")
122 {
123  SECTION("deduce type") {
124  std::list<int> l = {1, 2, 3};
125  auto v = to_vector(l);
126  CHECK(v.size() == 3);
127  CHECK(v[0] == 1);
128  CHECK(v[1] == 2);
129  CHECK(v[2] == 3);
130  CHECK(std::is_same_v<decltype(v)::value_type, int>);
131  }
132  SECTION("convert type") {
133  std::list<int> l = {1, 2, 3};
134  auto v = to_vector<char>(l);
135  CHECK(v.size() == 3);
136  CHECK(v[0] == 1);
137  CHECK(v[1] == 2);
138  CHECK(v[2] == 3);
139  CHECK(std::is_same_v<decltype(v)::value_type, char>);
140  }
141 }
142 
143 TEST_CASE("to_vector: from view")
144 {
145  std::vector<int> v1 = {1, 2, 3};
146  SECTION("deduce type") {
147  auto v = to_vector(view::drop(v1, 2));
148  CHECK(v.size() == 1);
149  CHECK(v[0] == 3);
150  CHECK(std::is_same_v<decltype(v)::value_type, int>);
151  }
152  SECTION("convert type") {
153  auto v = to_vector<long long>(view::drop(v1, 1));
154  CHECK(v.size() == 2);
155  CHECK(v[0] == 2ll);
156  CHECK(v[1] == 3ll);
157  CHECK(std::is_same_v<decltype(v)::value_type, long long>);
158  }
159 }
160 
161 
162 TEST_CASE("to_vector: optimized r-value")
163 {
164  SECTION("l-value") {
165  S::reset();
166  {
167  std::vector<S> v1 = {S(), S(), S()};
173  CHECK(S::destructed == 3);
174  S::reset();
175 
176  auto v = to_vector(v1);
182  CHECK(S::destructed == 0);
183  S::reset();
184  }
190  CHECK(S::destructed == 6);
191  }
192  SECTION("r-value") {
193  S::reset();
194  {
195  std::vector<S> v1 = {S(), S(), S()};
201  CHECK(S::destructed == 3);
202  S::reset();
203 
204  auto v = to_vector(std::move(v1));
210  CHECK(S::destructed == 0);
211  S::reset();
212  }
218  CHECK(S::destructed == 3);
219  }
220 }
221 
222 
223 // check quality of generated code
224 #if 0
225 std::vector<int> check1(const std::vector<int>& v)
226 {
227  return to_vector(view::drop(v, 1));
228 }
229 std::vector<int> check2(const std::vector<int>& v)
230 {
231  return std::vector<int>(begin(v) + 1, end(v));
232 }
233 #endif
S::copy_assignment
static int copy_assignment
Definition: stl_test.cc:27
S
Definition: stl_test.cc:7
S::destructed
static int destructed
Definition: stl_test.cc:29
TEST_CASE
TEST_CASE("append")
Definition: stl_test.cc:33
CHECK
CHECK(m3==m3)
S::S
S()
Definition: stl_test.cc:8
view::drop
auto drop(Range &&range, size_t n)
Definition: view.hh:288
S::move_constructed
static int move_constructed
Definition: stl_test.cc:26
S::reset
static void reset()
Definition: stl_test.cc:15
view.hh
S::~S
~S()
Definition: stl_test.cc:13
S::S
S(const S &)
Definition: stl_test.cc:9
S::S
S(S &&)
Definition: stl_test.cc:10
S::move_assignment
static int move_assignment
Definition: stl_test.cc:28
detail::append
void append(Result &)
Definition: stl.hh:340
stl.hh
S::operator=
S & operator=(S &&)
Definition: stl_test.cc:12
S::copy_constructed
static int copy_constructed
Definition: stl_test.cc:25
to_vector
auto to_vector(Range &&range) -> std::vector< detail::ToVectorType< T, decltype(std::begin(range))>>
Definition: stl.hh:316
S::operator=
S & operator=(const S &)
Definition: stl_test.cc:11
S::default_constructed
static int default_constructed
Definition: stl_test.cc:24