source: mainline/uspace/lib/cpp/src/__bits/test/algorithm.cpp@ d9a9e7b

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since d9a9e7b was d9a9e7b, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: added tests for mutating algorithms and fixed bugs found by them

  • Property mode set to 100644
File size: 8.9 KB
Line 
1/*
2 * Copyright (c) 2018 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <__bits/test/tests.hpp>
30#include <algorithm>
31#include <array>
32#include <string>
33#include <utility>
34
35namespace std::test
36{
37 bool algorithm_test::run(bool report)
38 {
39 report_ = report;
40 start();
41
42 test_non_modifying();
43 test_mutating();
44
45 return end();
46 }
47
48 const char* algorithm_test::name()
49 {
50 return "algorithm";
51 }
52
53 void algorithm_test::test_non_modifying()
54 {
55 auto data1 = {1, 2, 3, 4, 5};
56 auto res1 = std::all_of(
57 data1.begin(), data1.end(),
58 [](auto x){ return x > 0; }
59 );
60 auto res2 = std::all_of(
61 data1.begin(), data1.end(),
62 [](auto x){ return x < 4; }
63 );
64
65 test("all_of pt1", res1);
66 test("all_of pt2", !res2);
67
68 auto res3 = std::any_of(
69 data1.begin(), data1.end(),
70 [](auto x){ return x > 4; }
71 );
72 auto res4 = std::any_of(
73 data1.begin(), data1.end(),
74 [](auto x){ return x == 10; }
75 );
76
77 test("any_of pt1", res3);
78 test("any_of pt2", !res4);
79
80 auto res5 = std::none_of(
81 data1.begin(), data1.end(),
82 [](auto x){ return x < 0; }
83 );
84 auto res6 = std::none_of(
85 data1.begin(), data1.end(),
86 [](auto x){ return x == 4; }
87 );
88
89 test("none_of pt1", res5);
90 test("none_of pt2", !res6);
91
92 std::array<int, 5> data2{1, 2, 3, 4, 5};
93 auto check1 = {1, 20, 3, 40, 5};
94 std::for_each(
95 data2.begin(), data2.end(),
96 [](auto& x){
97 if (x % 2 == 0)
98 x *= 10;
99 }
100 );
101
102 test_eq(
103 "for_each", check1.begin(), check1.end(),
104 data2.begin(), data2.end()
105 );
106
107 auto res7 = std::find(data2.begin(), data2.end(), 40);
108 test_eq("find", res7, &data2[3]);
109
110 auto res8 = std::find_if(
111 data2.begin(), data2.end(),
112 [](auto x){ return x > 30; }
113 );
114 test_eq("find_if", res8, &data2[3]);
115
116 auto res9 = std::find_if_not(
117 data2.begin(), data2.end(),
118 [](auto x){ return x < 30; }
119 );
120 test_eq("find_if_not", res9, &data2[3]);
121
122 // TODO: find_end, find_first_of
123
124 std::array<int, 7> data3{1, 2, 3, 3, 4, 6, 5};
125 auto res10 = std::adjacent_find(data3.begin(), data3.end());
126 test_eq("adjacent_find pt1", res10, &data3[2]);
127
128 auto res11 = std::adjacent_find(
129 data3.begin(), data3.end(),
130 [](auto lhs, auto rhs){
131 return rhs < lhs;
132 }
133 );
134 test_eq("adjacent_find pt2", res11, &data3[5]);
135
136 auto res12 = std::count(data3.begin(), data3.end(), 3);
137 test_eq("count", res12, 2);
138
139 auto res13 = std::count_if(
140 data3.begin(), data3.end(),
141 [](auto x){
142 return x % 2 == 1;
143 }
144 );
145 test_eq("count_if", res13, 4);
146
147 std::array<int, 6> data4{1, 2, 3, 4, 5, 6};
148 std::array<int, 6> data5{1, 2, 3, 4, 6, 5};
149 auto res14 = std::mismatch(
150 data4.begin(), data4.end(),
151 data5.begin(), data5.end()
152 );
153
154 test_eq("mismatch pt1", res14.first, &data4[4]);
155 test_eq("mismatch pt2", res14.second, &data5[4]);
156
157 auto res15 = std::equal(
158 data4.begin(), data4.end(),
159 data4.begin(), data4.end()
160 );
161 test("equal pt1", res15);
162
163 auto res16 = std::equal(
164 data4.begin(), data4.end(),
165 data5.begin(), data5.end()
166 );
167 test("equal pt2", !res16);
168
169 auto res17 = std::equal(
170 data4.begin(), data4.end(),
171 data4.begin(), data4.end(),
172 [](auto lhs, auto rhs){
173 return lhs == rhs;
174 }
175 );
176 test("equal pt3", res17);
177
178 auto res18 = std::equal(
179 data4.begin(), data4.end(),
180 data5.begin(), data5.end(),
181 [](auto lhs, auto rhs){
182 return lhs == rhs;
183 }
184 );
185 test("equal pt4", !res18);
186
187 // TODO: is_permutation, search
188 }
189
190 void algorithm_test::test_mutating()
191 {
192 auto check1 = {1, 2, 3, 10, 20, 30, 40};
193 std::array<int, 4> data1{10, 20, 30, 40};
194 std::array<int, 7> data2{1, 2, 3, 4, 5, 6, 7};
195
196 auto res1 = std::copy(
197 data1.begin(), data1.end(), data2.begin() + 3
198 );
199
200 test_eq(
201 "copy pt1", check1.begin(), check1.end(),
202 data2.begin(), data2.end()
203 );
204 test_eq("copy pt2", res1, data2.end());
205
206 auto check2 = {1, 2, 3, 10, 20, 30, 7, 8};
207 std::array<int, 8> data3{1, 2, 3, 4, 5, 6, 7, 8};
208
209 auto res2 = std::copy_n(
210 data1.begin(), 3, data3.begin() + 3
211 );
212 test_eq(
213 "copy_n pt1", check2.begin(), check2.end(),
214 data3.begin(), data3.end()
215 );
216 test_eq("copy_n pt2", res2, &data3[6]);
217
218 auto check3 = {2, 4, 6, 8};
219 std::array<int, 4> data4{0, 0, 0, 0};
220 std::array<int, 9> data5{1, 2, 3, 4, 5, 6, 7, 8, 9};
221
222 auto res3 = std::copy_if(
223 data5.begin(), data5.end(), data4.begin(),
224 [](auto x){ return x % 2 == 0; }
225 );
226
227 test_eq(
228 "copy_if pt1", check3.begin(), check3.end(),
229 data4.begin(), data4.end()
230 );
231 test_eq("copy_if pt2", res3, data4.end());
232
233 /**
234 * Note: Not testing copy_backwards as it isn't
235 * really easy to test, but since it is
236 * widely used in the rest of the library
237 * (mainly right shifting in sequence
238 * containers) it's tested by other tests.
239 */
240
241 auto check4 = {std::string{"A"}, std::string{"B"}, std::string{"C"}};
242 std::array<std::string, 3> data6{"A", "B", "C"};
243 std::array<std::string, 3> data7{"", "", ""};
244
245 auto res4 = std::move(
246 data6.begin(), data6.end(), data7.begin()
247 );
248 test_eq(
249 "move pt1", check4.begin(), check4.end(),
250 data7.begin(), data7.end()
251 );
252 test(
253 "move pt2", (data6[0].empty() && data6[1].empty(),
254 data6[2].empty())
255 );
256 test_eq("move pt3", res4, data7.end());
257
258 auto check5 = {1, 2, 3, 4};
259 auto check6 = {10, 20, 30, 40};
260 std::array<int, 4> data8{1, 2, 3, 4};
261 std::array<int, 4> data9{10, 20, 30, 40};
262
263 auto res5 = std::swap_ranges(
264 data8.begin(), data8.end(),
265 data9.begin()
266 );
267
268 test_eq(
269 "swap_ranges pt1", check6.begin(), check6.end(),
270 data8.begin(), data8.end()
271 );
272 test_eq(
273 "swap_ranges pt2", check5.begin(), check5.end(),
274 data9.begin(), data9.end()
275 );
276 test_eq("swap_ranges pt3", res5, data9.end());
277
278 std::iter_swap(data8.begin(), data9.begin());
279 test_eq("swap_iter pt1", data8[0], 1);
280 test_eq("swap_iter pt2", data9[0], 10);
281
282 auto check7 = {2, 3, 4, 5};
283 std::array<int, 4> data10{1, 2, 3, 4};
284
285 auto res6 = std::transform(
286 data10.begin(), data10.end(), data10.begin(),
287 [](auto x) { return x + 1; }
288 );
289 test_eq(
290 "transform pt1",
291 check7.begin(), check7.end(),
292 data10.begin(), data10.end()
293 );
294 test_eq("transform pt2", res6, data10.end());
295 }
296}
Note: See TracBrowser for help on using the repository browser.