Project
Loading...
Searching...
No Matches
testBitSet.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15#define BOOST_TEST_MODULE Test MCHRaw bitset
16#define BOOST_TEST_MAIN
17#define BOOST_TEST_DYN_LINK
18
19#include <boost/test/unit_test.hpp>
20#include <iostream>
21#include "BitSet.h"
22#include <vector>
23#include <fmt/format.h>
24#include <ctime>
25
26using namespace o2::mch::raw;
27
28uint64_t allones = 0x3FFFFFFFFFFFF;
29BOOST_AUTO_TEST_SUITE(o2_mch_raw)
30
31BOOST_AUTO_TEST_SUITE(bitset)
32
33// Most of the tests (and their names) are adapted from github.com/mrrtf/sampa/pkg/bitset/bitset_test.go
34
36{
37 BitSet bs;
38 BOOST_CHECK_NO_THROW(bs.set(1, true));
39 BOOST_CHECK_NO_THROW(bs.set(2, true));
40 BOOST_CHECK_NO_THROW(bs.set(3, false));
41 BOOST_CHECK_NO_THROW(bs.set(9, true));
42 BOOST_CHECK_EQUAL(bs.count(), 3);
43}
44
46{
47 BitSet bs;
48 bs.append(true);
49 bs.append(true);
50 bs.append(false);
51 bs.append(false);
52 bs.append(true);
53 BOOST_CHECK_EQUAL(bs.uint8(0, 5), 0x13);
54 BitSet bs2;
55 BOOST_CHECK_EQUAL(bs2.len(), 0);
56 bs2.append(static_cast<uint64_t>(0x1555540F00113), 50);
57 BOOST_CHECK_EQUAL(bs2.len(), 50);
58}
59
60BOOST_AUTO_TEST_CASE(TestPruneFirst)
61{
62 BitSet bs;
63 BOOST_CHECK_NO_THROW(bs.setRangeFromString(0, 6, "1101011"));
64 bs.pruneFirst(2);
65 BOOST_CHECK_EQUAL(bs.stringLSBLeft(), "01011");
66}
67
69{
70 BitSet bs;
71 BOOST_CHECK_EQUAL(bs.any(), false);
72 bs.set(2, true);
73 BOOST_CHECK_EQUAL(bs.any(), true);
74}
75
77{
78 BOOST_CHECK_NO_THROW(BitSet a(static_cast<uint8_t>(100)));
79}
80
82{
83 BitSet bs;
84 BOOST_CHECK_NO_THROW(bs.set(0, true));
85 BOOST_CHECK_NO_THROW(bs.set(2, true));
86 BOOST_CHECK_NO_THROW(bs.set(20, true));
87 BOOST_CHECK_EQUAL(bs.size(), 32);
88 BOOST_CHECK_EQUAL(bs.len(), 21);
89 BOOST_CHECK_THROW(bs.set(-1, true), std::invalid_argument);
90}
91
93{
94 BitSet bs;
95 BOOST_CHECK_NO_THROW(bs.set(0, true));
96 BOOST_CHECK_NO_THROW(bs.set(2, true));
97 BOOST_CHECK_EQUAL(bs.get(0), true);
98 BOOST_CHECK_EQUAL(bs.get(2), true);
99 BOOST_CHECK_EQUAL(bs.get(1), false);
100 BOOST_CHECK_THROW(bs.get(100), std::out_of_range);
101}
102
104{
105 BitSet bs;
106 bs.set(24, true);
107 BOOST_CHECK_EQUAL(bs.len(), 25);
108 bs.clear();
109 BOOST_CHECK_EQUAL(bs.len(), 0);
110}
111
113{
114 BitSet bs;
115 bs.set(1, true);
116 bs.set(3, true);
117 bs.set(5, true);
118 BOOST_CHECK_EQUAL(bs.stringLSBLeft(), "010101");
119}
120
121BOOST_AUTO_TEST_CASE(TestFromString)
122{
123 BOOST_CHECK_THROW(BitSet("00011x"), std::invalid_argument);
124 BitSet bs("01011011");
125 BOOST_CHECK_EQUAL(bs.len(), 8);
126 BOOST_CHECK_EQUAL(bs.stringLSBLeft(), "01011011");
127}
128
129BOOST_AUTO_TEST_CASE(TestRangeFromString)
130{
131 BitSet bs("110011");
133 BOOST_CHECK_EQUAL(bs.stringLSBLeft(), "111111");
134 BOOST_CHECK_THROW(bs.setRangeFromString(2, 3, "x-"), std::invalid_argument);
135 BOOST_CHECK_THROW(bs.setRangeFromString(4, 1, "101"), std::invalid_argument);
136 BOOST_CHECK_THROW(bs.setRangeFromString(32, 38, "1100"), std::invalid_argument);
137 BOOST_CHECK_NO_THROW(bs.setRangeFromString(32, 38, "1100110"));
138 BOOST_CHECK_THROW(BitSet("abcd"), std::invalid_argument);
139}
140
141BOOST_AUTO_TEST_CASE(TestFromIntegers)
142{
143 uint64_t v = 0xF0F8FCFEFF3F3F1F;
144 BitSet bs(v);
145 std::string s = "1111100011111100111111001111111101111111001111110001111100001111";
147 uint64_t x = bs.uint64(0, 63);
149
150 bs = BitSet(static_cast<uint8_t>(0x13));
151 BOOST_CHECK_EQUAL(bs.uint8(0, 7), 0x13);
152
153 bs = BitSet(static_cast<uint16_t>(0x8000));
154 BOOST_CHECK_EQUAL(bs.uint16(0, 15), 0x8000);
155
156 bs = BitSet(static_cast<uint32_t>(0xF0008000));
157 BOOST_CHECK_EQUAL(bs.uint32(0, 31), 0xF0008000);
158
159 bs = BitSet{};
160 BOOST_CHECK_THROW(bs.setRangeFromUint(0, 9, static_cast<uint8_t>(0)), std::invalid_argument);
161 BOOST_CHECK_THROW(bs.setRangeFromUint(9, 32, static_cast<uint16_t>(0)), std::invalid_argument);
162 BOOST_CHECK_THROW(bs.setRangeFromUint(24, 57, static_cast<uint32_t>(0)), std::invalid_argument);
163 BOOST_CHECK_THROW(bs.setRangeFromUint(56, 122, static_cast<uint64_t>(0)), std::invalid_argument);
164 BOOST_CHECK_NO_THROW(bs.setRangeFromUint(0, 7, static_cast<uint8_t>(0xFF)));
165 BOOST_CHECK_EQUAL(bs.len(), 8);
166}
167
168BOOST_AUTO_TEST_CASE(TestRangeFromUint16)
169{
170 uint16_t v = 0xF0F8;
171
172 auto bs = BitSet(v);
173 bs.setRangeFromUint(12, 14, static_cast<uint16_t>(0));
174 BOOST_CHECK_EQUAL(bs.uint16(0, 15), 0x80F8);
175}
176
177BOOST_AUTO_TEST_CASE(TestRangeFromUint32)
178{
179 uint32_t v = 0xF0F8FCFE;
180
181 auto bs = BitSet(v);
182 bs.setRangeFromUint(28, 30, static_cast<uint32_t>(0));
183 BOOST_CHECK_EQUAL(bs.uint32(0, 31), 0x80F8FCFE);
184}
185
186BOOST_AUTO_TEST_CASE(TestRangeFromUint64)
187{
188 uint64_t v = 0xF0F8FCFEFF3F3F1F;
189
190 auto bs = BitSet(v);
191 bs.setRangeFromUint(60, 62, static_cast<uint64_t>(0));
192 uint64_t expected = 0x80F8FCFEFF3F3F1F;
193 BOOST_CHECK_EQUAL(bs.uint64(0, 63), expected);
194}
195
196BOOST_AUTO_TEST_CASE(TestRangeFromIntegers)
197{
198 BitSet bs(static_cast<uint64_t>(0));
199 BOOST_CHECK_NO_THROW(bs.setRangeFromUint(0, 5, static_cast<uint8_t>(0x13)));
200 bs.set(8, true);
201 BOOST_CHECK_NO_THROW(bs.setRangeFromUint(20, 23, static_cast<uint8_t>(0xF)));
202 BOOST_CHECK_NO_THROW(bs.setRangeFromUint(29, 48, static_cast<uint32_t>(0xAAAAA)));
203 BOOST_CHECK_EQUAL(bs.uint64(0, 63), UINT64_C(0x1555540F00113));
204}
205
207{
208 BitSet bs;
209 std::vector<uint8_t> bytes = {0xfe, 0x5a, 0x1e, 0xda};
210 bs.setFromBytes(bytes);
211 BOOST_CHECK_EQUAL(bs.uint32(0, 31), 0XDA1E5AFE);
212 BOOST_CHECK_EQUAL(bs.size(), 32);
213 BOOST_CHECK_EQUAL(bs.len(), 32);
214}
215
217{
218 BitSet b1("110011");
219 BitSet b2("110011");
220 BOOST_CHECK(b1 == b2);
221 b2 = BitSet("1010");
222 BOOST_CHECK(b1 != b2);
223}
224
226{
227 BitSet bs("110011");
228 auto b = bs.subset(2, 4);
229 BOOST_CHECK_EQUAL(b.stringLSBLeft(), "001");
230 b.set(1, true);
231 BOOST_CHECK_EQUAL(b.stringLSBLeft(), "011");
232}
233
235{
236 BitSet bs("110011");
237 auto v2 = bs.uint64(0, 5);
239 v2 = bs.uint64(0, 1);
241
242 uint64_t v = UINT64_C(0xFFFFFFFFFFFFFFFF);
243 bs = BitSet(v);
244 BOOST_CHECK_EQUAL(bs.stringLSBLeft(), "1111111111111111111111111111111111111111111111111111111111111111");
245 auto x = bs.uint64(0, 63);
247}
248
250{
251 BitSet bs(static_cast<uint16_t>(0xFFFF));
252 BOOST_CHECK_EQUAL(bs.grow(15), false);
253 BOOST_CHECK_THROW(bs.grow((BitSet::maxSize() + 1)), std::length_error);
254 BOOST_CHECK_EQUAL(bs.grow(34), true);
255}
256
258{
259 uint16_t v = 0xFFFF;
260 BitSet bs = BitSet(v);
261 BOOST_CHECK_EQUAL(bs.stringLSBLeft(), "1111111111111111");
262 auto x = bs.uint16(0, 15);
264}
265
267{
268 uint32_t v = 0xFFFFFFFF;
269 BitSet bs = BitSet(v);
270 BOOST_CHECK_EQUAL(bs.stringLSBLeft(), "11111111111111111111111111111111");
271 auto x = bs.uint32(0, 31);
273}
274
276{
277 BitSet bs("1010110101111");
278 BOOST_CHECK(bs.last(4) == BitSet("1111"));
279 BOOST_CHECK(bs.last(6) == BitSet("101111"));
280}
281
282BOOST_AUTO_TEST_CASE(TestEmptyBitSet)
283{
284 BitSet bs;
287 BOOST_CHECK_EQUAL(bs.isEmpty(), true);
288 BOOST_CHECK_EQUAL(bs.len(), 0);
289 BOOST_CHECK(bs.size() > 0);
290}
291
292std::string bitNumberScale(int n, int nspaces, bool right2left)
293{
294 std::string line1;
295 std::string line2;
296 for (int i = 0; i < n; i++) {
297 if (i > 0 && i % 10 == 0) {
298 line1 += std::to_string(i / 10);
299 } else {
300 line1 += " ";
301 }
302 line2 += std::to_string(i % 10);
303 }
304
305 if (right2left) {
306 std::reverse(begin(line1), end(line1));
307 std::reverse(begin(line2), end(line2));
308 }
309 std::string spaces(nspaces, ' ');
310 std::string rv;
311
312 if (n > 10) {
313 rv = spaces + line1 + "\n";
314 }
315 rv += spaces + line2;
316 return rv;
317}
318
319BOOST_AUTO_TEST_CASE(TestAppendUint32)
320{
321 BitSet bs;
322 auto C = UINT32_C(0XDA1E5AFE);
323
324 bs.append(C);
325
326 BOOST_CHECK_EQUAL(bs.len(), 32);
327 BOOST_CHECK_EQUAL(bs.uint32(0, 31), C);
328
329 // std::cout << fmt::format("BS -> {0}\n", bs.stringLSBLeft());
330 // std::cout << bitNumberScale(32, 6, false) << "\n\n";
331 // std::cout << fmt::format("BS <- {0}\n", bs.stringLSBRight());
332 // std::cout << bitNumberScale(32, 6, true) << "\n\n";
333}
334
335BOOST_AUTO_TEST_CASE(TestAppendUint64)
336{
337 BitSet bs;
338
339 auto C = UINT64_C(0x1555540f00113);
340 bs.append(C, 64);
341
342 BOOST_CHECK_EQUAL(bs.len(), 64);
343 BOOST_CHECK_EQUAL(bs.uint64(0, 63), C);
344
345 // std::cout << fmt::format("BS -> {0}\n", bs.stringLSBLeft());
346 // std::cout << bitNumberScale(64, 6, false) << "\n\n";
347 // std::cout << fmt::format("BS <- {0}\n", bs.stringLSBRight());
348 // std::cout << bitNumberScale(64, 6, true) << "\n\n";
349}
350
351BOOST_AUTO_TEST_CASE(TestAppendUint64Bis)
352{
353 BitSet bs;
354
355 for (int i = 0; i < 50; i++) {
356 bs.set(i, true);
357 }
358 BOOST_CHECK_EQUAL(bs.len(), 50);
359 BOOST_CHECK_EQUAL(bs.uint64(0, 49), allones);
360}
361
362BOOST_AUTO_TEST_CASE(TestAppendUint8)
363{
364 BitSet bs;
365
366 uint8_t a(42);
367
368 BOOST_CHECK_THROW(bs.append(a, 9), std::invalid_argument);
369
370 // append bits, letting appendUint8 compute the number
371 // of actual bits to add
373
374 BOOST_CHECK_EQUAL(bs.len(), 6);
375 BOOST_CHECK_EQUAL(bs.uint8(0, 5), a);
376
377 BOOST_CHECK_EQUAL(bs.stringLSBLeft(), "010101");
378 BOOST_CHECK_EQUAL(bs.stringLSBRight(), "101010");
379
380 bs.clear();
381 // append bits, forcing 8 bits to be added
382 bs.append(a, 8);
383 BOOST_CHECK_EQUAL(bs.stringLSBLeft(), "01010100");
384 BOOST_CHECK_EQUAL(bs.uint8(0, 7), a);
385
386 bs = BitSet("111");
387 bs.append(static_cast<uint8_t>(128), 8);
388
389 BOOST_CHECK_EQUAL(bs.stringLSBLeft(), "11100000001");
390}
391
392void compare(std::string_view s1, std::string_view s2)
393{
394 if (s1.size() != s2.size()) {
395 std::cout << "sizes differ\n";
396 return;
397 }
398 std::vector<int> dif;
399
400 for (auto i = 0; i < s1.size(); i++) {
401 if (s1[i] != s2[i]) {
402 dif.push_back(i);
403 }
404 }
405 if (dif.size()) {
406 std::cout << "indices of " << dif.size() << " differences:\n";
407 for (auto d : dif) {
408 std::cout << d << " ";
409 }
410 std::cout << "\n";
411 }
412}
413
414BOOST_AUTO_TEST_CASE(TestLongAppend)
415{
416 std::string expected = "11010101010110010101011011100011000011101000010110010100101100010100001001100100110010110100000000111100110110101101101110001111010110010010000101101111101110101011011111100101101010111011011111000010011010000100111111001000011010100111101101011110110001010";
417 BitSet bs;
418
419 for (int i = 0; i < expected.size(); i++) {
420 if (expected[i] == '1') {
421 bs.append(true);
422 } else {
423 bs.append(false);
424 }
425 if (bs.stringLSBLeft() != expected.substr(0, bs.len())) {
426 std::cout << "diff\n";
427 }
428 }
430}
431
432BOOST_AUTO_TEST_CASE(TestLoopAppend)
433{
434 std::string expected;
435 BitSet bs;
436
437 std::srand(std::time(nullptr));
438 for (int i = 0; i < BitSet::maxSize(); i++) {
439 bool bit = static_cast<bool>(rand() % 2);
440 if (bit) {
441 expected += "1";
442 } else {
443 expected += "0";
444 }
445 bs.append(bit);
446 }
448}
449
450BOOST_AUTO_TEST_CASE(TestLimitedCtor)
451{
452 BOOST_CHECK_THROW(BitSet bs(static_cast<uint8_t>(123), 9), std::invalid_argument);
453 BOOST_CHECK_NO_THROW(BitSet bs(static_cast<uint8_t>(123), 4));
454 BitSet bs(static_cast<uint8_t>(123), 4);
455 BOOST_CHECK_EQUAL(bs.uint8(0, 3), 11);
456}
457
458BOOST_AUTO_TEST_CASE(TestCircularAppend)
459{
460 uint64_t syncValue = 0x1555540F00113;
461 BitSet bs;
462 BitSet sync(syncValue, 50);
463
464 int next = circularAppend(bs, sync, 0, 10);
465 BOOST_CHECK_EQUAL(bs.len(), 10);
466 BOOST_CHECK_EQUAL(bs, sync.subset(0, 9));
467 BOOST_CHECK_EQUAL(next, 10);
468
469 next = circularAppend(bs, sync, next, 40);
470 BOOST_CHECK_EQUAL(bs.len(), 50);
471 BOOST_CHECK_EQUAL(bs, sync);
472 BOOST_CHECK_EQUAL(next, 0);
473
474 next = circularAppend(bs, sync, next, 145);
475 BitSet expected("110010001000000000001111000000101010101010101010101100100010000000000011110000001010101010101010101011001000100000000000111100000010101010101010101010110010001000000000001111000000101010101010101");
476
478}
479
480BOOST_AUTO_TEST_SUITE_END()
481BOOST_AUTO_TEST_SUITE_END()
int32_t i
const GPUTPCGMMerger::trackCluster & b1
uint8_t uint8(int a, int b) const
Definition BitSet.cxx:397
uint16_t uint16(int a, int b) const
Definition BitSet.cxx:402
uint64_t uint64(int a, int b) const
Definition BitSet.cxx:412
bool grow(int n)
Definition BitSet.cxx:234
void pruneFirst(int n)
Definition BitSet.cxx:266
void setFromBytes(gsl::span< uint8_t > bytes)
Definition BitSet.cxx:307
static int maxSize()
Definition BitSet.h:100
BitSet last(int n) const
Definition BitSet.cxx:254
std::string stringLSBLeft() const
Definition BitSet.cxx:357
void setRangeFromString(int a, int b, std::string_view s)
Definition BitSet.cxx:320
void setRangeFromUint(int a, int b, uint8_t v)
Definition BitSet.cxx:337
int append(bool val)
Definition BitSet.cxx:172
bool any() const
Definition BitSet.cxx:198
int len() const
Definition BitSet.h:103
bool get(int pos) const
Definition BitSet.cxx:225
uint32_t uint32(int a, int b) const
Definition BitSet.cxx:407
BitSet subset(int a, int b) const
Definition BitSet.cxx:383
bool isEmpty() const
Definition BitSet.h:80
int count() const
Definition BitSet.cxx:214
void set(int pos, bool val)
Definition BitSet.cxx:277
int size() const
Definition BitSet.h:97
std::string stringLSBRight() const
Definition BitSet.cxx:370
GLdouble n
Definition glcorearb.h:1982
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint GLuint end
Definition glcorearb.h:469
const GLdouble * v
Definition glcorearb.h:832
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Definition glcorearb.h:5034
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLfloat GLfloat GLfloat v2
Definition glcorearb.h:813
int circularAppend(BitSet &bs, const BitSet &ringBuffer, int startBit, int n)
Definition BitSet.cxx:421
BOOST_AUTO_TEST_CASE(FlatHisto)
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
std::string bitNumberScale(int n, int nspaces, bool right2left)
uint64_t allones
void compare(std::string_view s1, std::string_view s2)
std::map< std::string, ID > expected
BOOST_CHECK_NO_THROW(algorithm::merge(target, other))
BOOST_CHECK(tree)
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())