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 int default_constructed;
25  static int copy_constructed;
26  static int move_constructed;
27  static int copy_assignment;
28  static int move_assignment;
29  static int destructed;
30 };
32 int S::copy_constructed = 0;
33 int S::move_constructed = 0;
34 int S::copy_assignment = 0;
35 int S::move_assignment = 0;
36 int S::destructed = 0;
37 
38 
39 TEST_CASE("append")
40 {
41  std::vector<int> v;
42  std::vector<int> v0;
43  std::vector<int> v123 = {1, 2, 3};
44  std::vector<int> v45 = {4, 5};
45 
46  SECTION("non-empty + non-empty") {
47  append(v123, v45);
48  CHECK(v123 == std::vector<int>{1, 2, 3, 4, 5});
49  }
50  SECTION("non-empty + empty") {
51  append(v123, v0);
52  CHECK(v123 == std::vector<int>{1, 2, 3});
53  }
54  SECTION("empty + non-empty") {
55  append(v, v45);
56  CHECK(v == std::vector<int>{4, 5});
57  }
58  SECTION("empty + empty") {
59  append(v, v0);
60  CHECK(v == std::vector<int>{});
61  }
62  SECTION("non-empty + view") {
63  append(v45, view::drop(v123, 1));
64  CHECK(v45 == std::vector<int>{4, 5, 2, 3});
65  }
66  SECTION("empty + l-value") {
67  {
68  S::reset();
69  std::vector<S> v1;
70  std::vector<S> v2 = {S(), S()};
76  CHECK(S::destructed == 2);
77  S::reset();
78 
79  append(v1, v2);
85  CHECK(S::destructed == 0);
86  S::reset();
87  }
93  CHECK(S::destructed == 4);
94  }
95  SECTION("empty + r-value") {
96  {
97  S::reset();
98  std::vector<S> v1;
99  std::vector<S> v2 = {S(), S()};
105  CHECK(S::destructed == 2);
106  S::reset();
107 
108  append(v1, std::move(v2));
114  CHECK(S::destructed == 0);
115  S::reset();
116  }
122  CHECK(S::destructed == 2);
123  }
124 }
125 
126 
127 TEST_CASE("to_vector: from list")
128 {
129  SECTION("deduce type") {
130  std::list<int> l = {1, 2, 3};
131  auto v = to_vector(l);
132  CHECK(v.size() == 3);
133  CHECK(v[0] == 1);
134  CHECK(v[1] == 2);
135  CHECK(v[2] == 3);
136  CHECK(std::is_same<decltype(v)::value_type, int>::value);
137  }
138  SECTION("convert type") {
139  std::list<int> l = {1, 2, 3};
140  auto v = to_vector<char>(l);
141  CHECK(v.size() == 3);
142  CHECK(v[0] == 1);
143  CHECK(v[1] == 2);
144  CHECK(v[2] == 3);
145  CHECK(std::is_same<decltype(v)::value_type, char>::value);
146  }
147 }
148 
149 TEST_CASE("to_vector: from view")
150 {
151  std::vector<int> v1 = {1, 2, 3};
152  SECTION("deduce type") {
153  auto v = to_vector(view::drop(v1, 2));
154  CHECK(v.size() == 1);
155  CHECK(v[0] == 3);
156  CHECK(std::is_same<decltype(v)::value_type, int>::value);
157  }
158  SECTION("convert type") {
159  auto v = to_vector<long long>(view::drop(v1, 1));
160  CHECK(v.size() == 2);
161  CHECK(v[0] == 2ll);
162  CHECK(v[1] == 3ll);
163  CHECK(std::is_same<decltype(v)::value_type, long long>::value);
164  }
165 }
166 
167 
168 TEST_CASE("to_vector: optimized r-value")
169 {
170  SECTION("l-value") {
171  S::reset();
172  {
173  std::vector<S> v1 = {S(), S(), S()};
179  CHECK(S::destructed == 3);
180  S::reset();
181 
182  auto v = to_vector(v1);
188  CHECK(S::destructed == 0);
189  S::reset();
190  }
196  CHECK(S::destructed == 6);
197  }
198  SECTION("r-value") {
199  S::reset();
200  {
201  std::vector<S> v1 = {S(), S(), S()};
207  CHECK(S::destructed == 3);
208  S::reset();
209 
210  auto v = to_vector(std::move(v1));
216  CHECK(S::destructed == 0);
217  S::reset();
218  }
224  CHECK(S::destructed == 3);
225  }
226 }
227 
228 
229 // check quality of generated code
230 #if 0
231 std::vector<int> check1(const std::vector<int>& v)
232 {
233  return to_vector(view::drop(v, 1));
234 }
235 std::vector<int> check2(const std::vector<int>& v)
236 {
237  return std::vector<int>(begin(v) + 1, end(v));
238 }
239 #endif
S(const S &)
Definition: stl_test.cc:9
static int destructed
Definition: stl_test.cc:29
Definition: stl_test.cc:7
static int copy_constructed
Definition: stl_test.cc:25
S(S &&)
Definition: stl_test.cc:10
TEST_CASE("append")
Definition: stl_test.cc:39
S()
Definition: stl_test.cc:8
auto begin(const string_view &x)
Definition: string_view.hh:151
void append(Result &)
Definition: stl.hh:354
CHECK(m3==m3)
S & operator=(S &&)
Definition: stl_test.cc:12
static int default_constructed
Definition: stl_test.cc:24
static int move_constructed
Definition: stl_test.cc:26
static int move_assignment
Definition: stl_test.cc:28
~S()
Definition: stl_test.cc:13
static void reset()
Definition: stl_test.cc:15
auto drop(Range &&range, size_t n)
Definition: view.hh:294
static int copy_assignment
Definition: stl_test.cc:27
auto to_vector(Range &&range) -> std::vector< detail::ToVectorType< T, decltype(std::begin(range))>>
Definition: stl.hh:325
auto end(const string_view &x)
Definition: string_view.hh:152
S & operator=(const S &)
Definition: stl_test.cc:11