2 * Copyright 2017 Jacob Lifshay
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // https://github.com/programmerjake/hashlife-voxels/blob/0dd91021a5b9caeffb7849b2114dca89204876bd/util/bitset.cpp
42 #warning testing bitset
43 struct Bitset_nontemplate_base::Tester final
45 template <std::size_t Bit_count
>
46 static void check_unused_bits(const bitset
<Bit_count
> &value
)
48 constexpr Word_type unused_bits
=
49 Bit_count
% word_bit_count
? ~((1ULL << (Bit_count
% word_bit_count
)) - 1ULL) : 0;
50 assert((value
.get_word(value
.word_count
- 1) & unused_bits
) == 0);
52 static void check_unused_bits(const bitset
<0> &)
55 template <std::size_t Bit_count
>
56 static void test_default_construct()
58 bitset
<Bit_count
> value
;
59 for(std::size_t i
= 0; i
< value
.word_count
; i
++)
60 assert(value
.get_word(i
) == 0);
61 check_unused_bits(value
);
63 template <std::size_t Bit_count
>
64 static void test_construct_from_ull()
66 for(std::size_t i
= 0; i
< std::numeric_limits
<unsigned long long>::digits
; i
++)
68 bitset
<Bit_count
> value(1ULL << i
);
69 check_unused_bits(value
);
70 assert(bitset
<Bit_count
>(1ULL << i
).to_ullong() == (1ULL << i
) || i
>= Bit_count
);
73 template <std::size_t Bit_count
>
74 static void test_reference_assign()
76 std::default_random_engine re
;
77 std::uniform_int_distribution
<unsigned long long> distribution
;
78 for(std::size_t i
= 0; i
< 1000; i
++)
80 bitset
<Bit_count
> src(distribution(re
)), dest
;
81 for(std::size_t j
= 0; j
< Bit_count
; j
++)
84 check_unused_bits(src
);
85 check_unused_bits(dest
);
90 template <std::size_t Bit_count
>
91 static void test_reference_flip()
95 std::default_random_engine re
;
96 std::vector
<bool> vector
;
97 vector
.resize(Bit_count
, false);
98 bitset
<Bit_count
> value
;
99 for(std::size_t i
= 0; i
< 1000; i
++)
101 std::size_t index
= std::uniform_int_distribution
<std::size_t>(0, Bit_count
- 1)(re
);
102 vector
[index
].flip();
104 check_unused_bits(value
);
105 for(std::size_t j
= 0; j
< Bit_count
; j
++)
106 assert(value
[index
] == static_cast<bool>(vector
[index
]));
109 template <std::size_t Bit_count
>
110 static void test_test()
112 std::default_random_engine re
;
113 std::vector
<bool> vector
;
114 vector
.resize(Bit_count
, false);
115 bitset
<Bit_count
> value
;
118 for(std::size_t i
= 0; i
< 1000; i
++)
121 std::uniform_int_distribution
<std::size_t>(0, Bit_count
- 1)(re
);
122 vector
[index
].flip();
124 check_unused_bits(value
);
127 for(std::size_t i
= 0; i
< Bit_count
+ 1000; i
++)
133 result
= value
.test(i
);
135 catch(std::out_of_range
&)
146 assert(result
== vector
[i
]);
150 template <std::size_t Bit_count
>
151 static void test_all_none_any_and_count_helper(const std::vector
<bool> &vector
,
152 const bitset
<Bit_count
> &value
)
154 std::size_t set_bit_count
= 0;
155 for(std::size_t i
= 0; i
< Bit_count
; i
++)
158 assert(value
.all() == (set_bit_count
== Bit_count
));
159 assert(value
.any() == (set_bit_count
!= 0));
160 assert(value
.none() == (set_bit_count
== 0));
161 assert(value
.count() == set_bit_count
);
163 template <std::size_t Bit_count
>
164 static void test_all_none_any_and_count()
166 std::default_random_engine re
;
167 std::vector
<bool> vector
;
168 vector
.resize(Bit_count
, false);
169 bitset
<Bit_count
> value
;
170 test_all_none_any_and_count_helper(vector
, value
);
173 for(std::size_t i
= 0; i
< 1000; i
++)
176 std::uniform_int_distribution
<std::size_t>(0, Bit_count
- 1)(re
);
177 vector
[index
].flip();
179 check_unused_bits(value
);
180 test_all_none_any_and_count_helper(vector
, value
);
183 for(std::size_t i
= 0; i
< Bit_count
; i
++)
187 check_unused_bits(value
);
188 test_all_none_any_and_count_helper(vector
, value
);
191 template <std::size_t Bit_count
>
192 static void test_and_or_and_xor_helper(const std::vector
<bool> &vector1
,
193 const std::vector
<bool> &vector2
,
194 const bitset
<Bit_count
> &bitset1
,
195 const bitset
<Bit_count
> &bitset2
)
197 bitset
<Bit_count
> dest_bitset_and
= bitset1
& bitset2
;
198 bitset
<Bit_count
> dest_bitset_or
= bitset1
| bitset2
;
199 bitset
<Bit_count
> dest_bitset_xor
= bitset1
^ bitset2
;
200 check_unused_bits(dest_bitset_and
);
201 check_unused_bits(dest_bitset_or
);
202 check_unused_bits(dest_bitset_xor
);
203 for(std::size_t i
= 0; i
< Bit_count
; i
++)
205 assert(dest_bitset_and
[i
] == (vector1
[i
] && vector2
[i
]));
206 assert(dest_bitset_or
[i
] == (vector1
[i
] || vector2
[i
]));
207 assert(dest_bitset_xor
[i
] == (static_cast<bool>(vector1
[i
]) != vector2
[i
]));
210 template <std::size_t Bit_count
>
211 static void test_and_or_and_xor()
213 std::default_random_engine re
;
214 std::vector
<bool> vector1
, vector2
;
215 vector1
.resize(Bit_count
, false);
216 vector2
.resize(Bit_count
, false);
217 bitset
<Bit_count
> bitset1
, bitset2
;
218 test_and_or_and_xor_helper(vector1
, vector2
, bitset1
, bitset2
);
221 for(std::size_t i
= 0; i
< 2000; i
++)
224 std::uniform_int_distribution
<std::size_t>(0, Bit_count
* 2 - 1)(re
);
225 bool is_second_bit_set
= index
>= Bit_count
;
227 if(is_second_bit_set
)
229 vector2
[index
].flip();
230 bitset2
[index
].flip();
234 vector1
[index
].flip();
235 bitset1
[index
].flip();
237 check_unused_bits(bitset1
);
238 check_unused_bits(bitset2
);
239 test_and_or_and_xor_helper(vector1
, vector2
, bitset1
, bitset2
);
242 for(std::size_t i
= 0; i
< Bit_count
; i
++)
246 check_unused_bits(bitset1
);
247 check_unused_bits(bitset2
);
248 test_and_or_and_xor_helper(vector1
, vector2
, bitset1
, bitset2
);
250 for(std::size_t i
= 0; i
< Bit_count
; i
++)
254 check_unused_bits(bitset1
);
255 check_unused_bits(bitset2
);
256 test_and_or_and_xor_helper(vector1
, vector2
, bitset1
, bitset2
);
259 template <std::size_t Bit_count
>
260 static void test_not()
262 std::default_random_engine re
;
263 std::vector
<bool> vector
;
264 vector
.resize(Bit_count
, false);
265 bitset
<Bit_count
> value
;
268 for(std::size_t i
= 0; i
< 1000; i
++)
271 std::uniform_int_distribution
<std::size_t>(0, Bit_count
- 1)(re
);
272 vector
[index
].flip();
274 check_unused_bits(value
);
275 bitset
<Bit_count
> bitset_not
= ~value
;
276 check_unused_bits(bitset_not
);
277 for(std::size_t j
= 0; j
< Bit_count
; j
++)
278 assert(vector
[j
] == !bitset_not
[j
]);
282 template <std::size_t Bit_count
>
283 static void test_shift_helper(const std::vector
<bool> &vector
, const bitset
<Bit_count
> &value
)
285 for(std::size_t shift_count
= 0; shift_count
< Bit_count
* 2 + 1; shift_count
++)
287 bitset
<Bit_count
> bitset_shifted_left
= value
<< shift_count
;
288 bitset
<Bit_count
> bitset_shifted_right
= value
>> shift_count
;
289 check_unused_bits(bitset_shifted_left
);
290 check_unused_bits(bitset_shifted_right
);
291 for(std::size_t i
= 0; i
< Bit_count
; i
++)
293 assert(bitset_shifted_left
[i
]
294 == (i
< shift_count
? false : static_cast<bool>(vector
[i
- shift_count
])));
295 assert(bitset_shifted_right
[i
] == (shift_count
>= Bit_count
- i
?
297 static_cast<bool>(vector
[i
+ shift_count
])));
301 template <std::size_t Bit_count
>
302 static void test_shift()
304 std::default_random_engine re
;
305 std::vector
<bool> vector
;
306 vector
.resize(Bit_count
, false);
307 bitset
<Bit_count
> value
;
308 test_shift_helper(vector
, value
);
311 for(std::size_t i
= 0; i
< 1000; i
++)
314 std::uniform_int_distribution
<std::size_t>(0, Bit_count
- 1)(re
);
315 vector
[index
].flip();
317 check_unused_bits(value
);
318 test_shift_helper(vector
, value
);
321 for(std::size_t i
= 0; i
< Bit_count
; i
++)
325 check_unused_bits(value
);
326 test_shift_helper(vector
, value
);
329 template <std::size_t Bit_count
>
330 static void test_global_set_and_reset()
332 bitset
<Bit_count
> value
;
334 check_unused_bits(value
);
335 assert(value
.none());
337 check_unused_bits(value
);
340 template <std::size_t Bit_count
>
341 static void test_find_helper(const std::string
&string
, const bitset
<Bit_count
> &value
)
343 for(std::size_t i
= 0; i
< Bit_count
; i
++)
344 assert(string
[i
] == (value
[i
] ? '1' : '0'));
345 for(std::size_t start
= 0; start
<= Bit_count
; start
++)
347 assert(string
.find_first_of('1', start
) == value
.find_first(true, start
));
348 assert(string
.find_first_not_of('1', start
) == value
.find_first(false, start
));
349 assert(string
.find_last_of('1', start
) == value
.find_last(true, start
));
350 assert(string
.find_last_not_of('1', start
) == value
.find_last(false, start
));
353 template <std::size_t Bit_count
>
354 static void test_find()
356 std::default_random_engine re
;
358 string
.resize(Bit_count
, '0');
359 bitset
<Bit_count
> value
;
360 test_find_helper(string
, value
);
363 for(std::size_t i
= 0; i
< 1000; i
++)
366 std::uniform_int_distribution
<std::size_t>(0, Bit_count
- 1)(re
);
367 string
[index
] = (string
[index
] == '0' ? '1' : '0');
369 check_unused_bits(value
);
370 test_find_helper(string
, value
);
373 for(std::size_t i
= 0; i
< Bit_count
; i
++)
377 check_unused_bits(value
);
378 test_find_helper(string
, value
);
382 for(std::size_t i
= 0; i
< 1000; i
++)
385 std::uniform_int_distribution
<std::size_t>(0, Bit_count
- 1)(re
);
386 string
[index
] = (string
[index
] == '0' ? '1' : '0');
388 check_unused_bits(value
);
389 test_find_helper(string
, value
);
393 template <std::size_t Bit_count
>
396 std::cout
<< "testing bitset<" << Bit_count
<< ">" << std::endl
;
397 test_default_construct
<Bit_count
>();
398 test_construct_from_ull
<Bit_count
>();
399 test_reference_assign
<Bit_count
>();
400 test_reference_flip
<Bit_count
>();
401 test_test
<Bit_count
>();
402 test_all_none_any_and_count
<Bit_count
>();
403 test_and_or_and_xor
<Bit_count
>();
404 test_not
<Bit_count
>();
405 test_shift
<Bit_count
>();
406 test_global_set_and_reset
<Bit_count
>();
407 test_find
<Bit_count
>();
410 template <typename
... Args
>
411 static void test_helper(Args
...)
414 template <std::size_t... Bit_counts
>
415 static void test(std::index_sequence
<Bit_counts
...>)
417 test_helper(test
<Bit_counts
>()...);
419 struct Test_runner final
423 test(std::make_index_sequence
<128>());
427 static Test_runner test_runner
;
429 Bitset_nontemplate_base::Tester::Test_runner
Bitset_nontemplate_base::Tester::test_runner
;