openMSX
view_test.cc
Go to the documentation of this file.
1 #include "catch.hpp"
2 #include "view.hh"
3 
4 #include "hash_map.hh"
5 #include "ranges.hh"
6 #include "stl.hh"
7 #include "xrange.hh"
8 #include <algorithm>
9 #include <list>
10 #include <map>
11 #include <string>
12 #include <tuple>
13 #include <vector>
14 
15 using namespace std;
16 using namespace view;
17 
18 static vector<int> getVector(int n)
19 {
20  return to_vector(xrange(n));
21 }
22 
23 TEST_CASE("view::drop random-access-range")
24 {
25  SECTION("empty") {
26  vector<int> v;
27  CHECK(to_vector(drop(v, 0)) == vector<int>{});
28  CHECK(to_vector(drop(v, 3)) == vector<int>{});
29  }
30  SECTION("non-empty") {
31  vector<int> v = {1, 2, 3, 4, 5};
32  CHECK(to_vector(drop(v, 0)) == vector<int>{1, 2, 3, 4, 5});
33  CHECK(to_vector(drop(v, 1)) == vector<int>{2, 3, 4, 5});
34  CHECK(to_vector(drop(v, 2)) == vector<int>{3, 4, 5});
35  CHECK(to_vector(drop(v, 3)) == vector<int>{4, 5});
36  CHECK(to_vector(drop(v, 4)) == vector<int>{5});
37  CHECK(to_vector(drop(v, 5)) == vector<int>{});
38  CHECK(to_vector(drop(v, 6)) == vector<int>{});
39  CHECK(to_vector(drop(v, 7)) == vector<int>{});
40  }
41  SECTION("r-value") {
42  CHECK(to_vector(drop(getVector(6), 3)) == vector<int>{3, 4, 5});
43  }
44 }
45 
46 TEST_CASE("view::drop non-random-access-range")
47 {
48  SECTION("empty") {
49  list<int> l;
50  CHECK(to_vector(drop(l, 0)) == vector<int>{});
51  CHECK(to_vector(drop(l, 3)) == vector<int>{});
52  }
53  SECTION("non-empty") {
54  list<int> l = {1, 2, 3, 4, 5};
55  CHECK(to_vector(drop(l, 0)) == vector<int>{1, 2, 3, 4, 5});
56  CHECK(to_vector(drop(l, 1)) == vector<int>{2, 3, 4, 5});
57  CHECK(to_vector(drop(l, 2)) == vector<int>{3, 4, 5});
58  CHECK(to_vector(drop(l, 3)) == vector<int>{4, 5});
59  CHECK(to_vector(drop(l, 4)) == vector<int>{5});
60  CHECK(to_vector(drop(l, 5)) == vector<int>{});
61  CHECK(to_vector(drop(l, 6)) == vector<int>{});
62  CHECK(to_vector(drop(l, 7)) == vector<int>{});
63  }
64 }
65 
66 TEST_CASE("view::drop capture")
67 {
68  REQUIRE(sizeof(vector<int>*) != sizeof(vector<int>));
69  SECTION("l-value") {
70  vector<int> v = {0, 1, 2, 3};
71  auto d = drop(v, 1);
72  // 'd' stores a reference to 'v'
73  CHECK(sizeof(d) == (sizeof(vector<int>*) + sizeof(size_t)));
74  }
75  SECTION("r-value") {
76  auto d = drop(getVector(4), 1);
77  // 'd' stores a vector by value
78  CHECK(sizeof(d) == (sizeof(vector<int>) + sizeof(size_t)));
79  }
80 }
81 
82 
83 TEST_CASE("view::drop_back random-access-range")
84 {
85  SECTION("empty") {
86  vector<int> v;
87  CHECK(to_vector(drop_back(v, 0)) == vector<int>{});
88  CHECK(to_vector(drop_back(v, 3)) == vector<int>{});
89  }
90  SECTION("non-empty") {
91  vector<int> v = {1, 2, 3, 4, 5};
92  CHECK(to_vector(drop_back(v, 0)) == vector<int>{1, 2, 3, 4, 5});
93  CHECK(to_vector(drop_back(v, 1)) == vector<int>{1, 2, 3, 4});
94  CHECK(to_vector(drop_back(v, 2)) == vector<int>{1, 2, 3});
95  CHECK(to_vector(drop_back(v, 3)) == vector<int>{1, 2});
96  CHECK(to_vector(drop_back(v, 4)) == vector<int>{1});
97  CHECK(to_vector(drop_back(v, 5)) == vector<int>{});
98  CHECK(to_vector(drop_back(v, 6)) == vector<int>{});
99  CHECK(to_vector(drop_back(v, 7)) == vector<int>{});
100  }
101  SECTION("r-value") {
102  CHECK(to_vector(drop_back(getVector(6), 3)) == vector<int>{0, 1, 2});
103  }
104 }
105 
106 TEST_CASE("view::drop_back non-random-access-range")
107 {
108  SECTION("empty") {
109  list<int> l;
110  CHECK(to_vector(drop_back(l, 0)) == vector<int>{});
111  CHECK(to_vector(drop_back(l, 3)) == vector<int>{});
112  }
113  SECTION("non-empty") {
114  list<int> l = {1, 2, 3, 4, 5};
115  CHECK(to_vector(drop_back(l, 0)) == vector<int>{1, 2, 3, 4, 5});
116  CHECK(to_vector(drop_back(l, 1)) == vector<int>{1, 2, 3, 4});
117  CHECK(to_vector(drop_back(l, 2)) == vector<int>{1, 2, 3});
118  CHECK(to_vector(drop_back(l, 3)) == vector<int>{1, 2});
119  CHECK(to_vector(drop_back(l, 4)) == vector<int>{1});
120  CHECK(to_vector(drop_back(l, 5)) == vector<int>{});
121  CHECK(to_vector(drop_back(l, 6)) == vector<int>{});
122  CHECK(to_vector(drop_back(l, 7)) == vector<int>{});
123  }
124 }
125 
126 
127 TEST_CASE("view::reverse")
128 {
129  vector<int> out;
130  SECTION("l-value") {
131  vector<int> in = {1, 2, 3, 4};
132  for (auto& e : reverse(in)) out.push_back(e);
133  CHECK(out == vector<int>{4, 3, 2, 1});
134  }
135  SECTION("r-value") {
136  for (auto& e : reverse(getVector(3))) out.push_back(e);
137  CHECK(out == vector<int>{2, 1, 0});
138  }
139  SECTION("2 x reverse") {
140  for (auto& e : reverse(reverse(getVector(4)))) out.push_back(e);
141  CHECK(out == vector<int>{0, 1, 2, 3});
142  }
143 }
144 
145 TEST_CASE("view::transform")
146 {
147  auto square = [](auto& x) { return x * x; };
148  size_t i = 1;
149  auto plus_i = [&](auto& x) { return int(x + i); };
150 
151  SECTION("l-value") {
152  vector<int> v = {1, 2, 3, 4};
153  CHECK(to_vector(transform(v, square)) == vector<int>{1, 4, 9, 16});
154  }
155  SECTION("r-value") {
156  i = 10;
157  CHECK(to_vector(transform(getVector(4), plus_i)) == vector<int>{10, 11, 12, 13});
158  }
159 }
160 
161 /*
162 No longer true since we use semiregular_t<> in TransformIterator
163 TEST_CASE("view::transform sizes")
164 {
165  auto square = [](auto& x) { return x * x; };
166  size_t i = 1;
167  auto plus_i = [&](auto& x) { return int(x + i); };
168 
169  vector<int> v = {1, 2, 3, 4};
170 
171  SECTION("l-value, stateless") {
172  auto vw = transform(v, square);
173  CHECK(sizeof(vw) == sizeof(std::vector<int>*));
174  CHECK(sizeof(vw.begin()) == sizeof(std::vector<int>::iterator));
175  }
176  SECTION("l-value, state") {
177  auto vw = transform(v, plus_i);
178  CHECK(sizeof(vw) == (sizeof(size_t&) + sizeof(std::vector<int>*)));
179  CHECK(sizeof(vw.begin()) == (sizeof(size_t&) + sizeof(std::vector<int>::iterator)));
180  }
181  SECTION("r-value, stateless") {
182  auto vw = transform(getVector(3), square);
183  CHECK(sizeof(vw) == sizeof(std::vector<int>));
184  CHECK(sizeof(vw.begin()) == sizeof(std::vector<int>::iterator));
185  }
186  SECTION("r-value, state") {
187  auto vw = transform(getVector(3), plus_i);
188  CHECK(sizeof(vw) == (sizeof(size_t&) + sizeof(std::vector<int>)));
189  CHECK(sizeof(vw.begin()) == (sizeof(size_t&) + sizeof(std::vector<int>::iterator)));
190  }
191 }*/
192 
193 
194 template<typename RANGE, typename T>
195 static void check(const RANGE& range, const vector<T>& expected)
196 {
197  CHECK(equal(range.begin(), range.end(), expected.begin(), expected.end()));
198 }
199 
200 template<typename RANGE, typename T>
201 static void check_unordered(const RANGE& range, const vector<T>& expected_)
202 {
203  auto result = to_vector<T>(range);
204  auto expected = expected_;
205  ranges::sort(result);
206  ranges::sort(expected);
207  CHECK(result == expected);
208 }
209 
210 TEST_CASE("view::keys, view::values") {
211  SECTION("std::map") {
212  map<int, int> m = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
213  check(keys (m), vector<int>{1, 3, 5, 7});
214  check(values(m), vector<int>{2, 4, 6, 8});
215  }
216  SECTION("std::vector<pair>") {
217  vector<pair<int, int>> v = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
218  check(keys (v), vector<int>{1, 3, 5, 7});
219  check(values(v), vector<int>{2, 4, 6, 8});
220  }
221  SECTION("hash_map") {
223  {{"foo", 1}, {"bar", 2}, {"qux", 3},
224  {"baz", 4}, {"a", 5}, {"z", 6}};
225  check_unordered(keys(m), vector<string>{
226  "foo", "bar", "qux", "baz", "a", "z"});
227  check_unordered(values(m), vector<int>{1, 2, 3, 4, 5, 6});
228  }
229  SECTION("std::vector<tuple>") {
230  vector<tuple<int, char, double, string>> v = {
231  tuple(1, 2, 1.2, "foo"),
232  tuple(3, 4, 3.4, "bar"),
233  tuple(5, 6, 5.6, "qux")
234  };
235  check(keys (v), vector<int>{1, 3, 5});
236  check(values(v), vector<char>{2, 4, 6});
237  }
238 }
CHECK(m3==m3)
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:124
auto transform(InputRange &&range, OutputIter out, UnaryOperation op)
Definition: ranges.hh:161
void sort(RandomAccessRange &&range)
Definition: ranges.hh:35
Definition: view.hh:10
constexpr auto reverse(Range &&range)
Definition: view.hh:300
constexpr auto drop(Range &&range, size_t n)
Definition: view.hh:288
constexpr auto drop_back(Range &&range, size_t n)
Definition: view.hh:294
constexpr auto keys(Map &&map)
Definition: view.hh:311
constexpr auto values(Map &&map)
Definition: view.hh:317
auto to_vector(Range &&range) -> std::vector< detail::ToVectorType< T, decltype(std::begin(range))>>
Definition: stl.hh:316
TEST_CASE("view::drop random-access-range")
Definition: view_test.cc:23
constexpr auto xrange(T e)
Definition: xrange.hh:155