• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stillwater-sc / universal / 23679908589

28 Mar 2026 07:02AM UTC coverage: 84.367% (-0.04%) from 84.409%
23679908589

push

github

web-flow
fix(blockbinary): use bitwise AND instead of logical OR in any() (#646)

* fix(blockbinary): use bitwise AND instead of logical OR in any()

* test(blockbinary): add bit pattern regression tests

Add exhaustive tests for any(), none(), all(), anyAfter(), count(),
and any(msb) across multiple block types and sizes.

111 of 152 new or added lines in 2 files covered. (73.03%)

17 existing lines in 3 files now uncovered.

44561 of 52818 relevant lines covered (84.37%)

6037732.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.67
/internal/blockbinary/logic/bit_patterns.cpp
1
// bit_patterns.cpp : regression test for bit pattern queries (any, none, all, anyAfter, count)
2
//
3
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
4
// SPDX-License-Identifier: MIT
5
//
6
// This file is part of the universal numbers project, which is released under an MIT Open Source license.
7
#include <universal/utility/directives.hpp>
8
#include <universal/utility/long_double.hpp>
9
#include <iostream>
10
#include <iomanip>
11
#include <string>
12

13
#include <universal/internal/blockbinary/blockbinary.hpp>
14
#include <universal/verification/test_status.hpp>
15
#include <universal/verification/test_reporters.hpp>
16

17
// Regression testing guards: typically set by the cmake configuration, but MANUAL_TESTING is set here
18
#define MANUAL_TESTING 0
19
// REGRESSION_LEVEL controls test depth
20
#define REGRESSION_LEVEL_1 1
21
#define REGRESSION_LEVEL_2 0
22
#define REGRESSION_LEVEL_3 0
23
#define REGRESSION_LEVEL_4 0
24

25
namespace sw { namespace universal {
26

27
/// Verify any() returns false for zero and true for non-zero across all bit patterns
28
template<unsigned nbits, typename BlockType>
29
int VerifyAny(bool reportTestCases) {
7✔
30
        int nrOfFailedTests = 0;
7✔
31
        constexpr unsigned NR_VALUES = (1u << nbits);
7✔
32
        blockbinary<nbits, BlockType> a;
33
        for (unsigned i = 0; i < NR_VALUES; ++i) {
139,799✔
34
                a.setbits(i);
139,792✔
35
                bool expected = (i != 0);
139,792✔
36
                bool result = a.any();
139,792✔
37
                if (result != expected) {
139,792✔
NEW
38
                        ++nrOfFailedTests;
×
NEW
39
                        if (reportTestCases) {
×
NEW
40
                                std::cerr << "FAIL: any() for " << to_binary(a) << " = " << result
×
NEW
41
                                          << " (expected " << expected << ")\n";
×
42
                        }
43
                }
44
        }
45
        return nrOfFailedTests;
7✔
46
}
47

48
/// Verify none() returns true for zero and false for non-zero across all bit patterns
49
template<unsigned nbits, typename BlockType>
50
int VerifyNone(bool reportTestCases) {
4✔
51
        int nrOfFailedTests = 0;
4✔
52
        constexpr unsigned NR_VALUES = (1u << nbits);
4✔
53
        blockbinary<nbits, BlockType> a;
54
        for (unsigned i = 0; i < NR_VALUES; ++i) {
69,908✔
55
                a.setbits(i);
69,904✔
56
                bool expected = (i == 0);
69,904✔
57
                bool result = a.none();
69,904✔
58
                if (result != expected) {
69,904✔
NEW
59
                        ++nrOfFailedTests;
×
NEW
60
                        if (reportTestCases) {
×
NEW
61
                                std::cerr << "FAIL: none() for " << to_binary(a) << " = " << result
×
NEW
62
                                          << " (expected " << expected << ")\n";
×
63
                        }
64
                }
65
        }
66
        return nrOfFailedTests;
4✔
67
}
68

69
/// Verify all() returns true only when every bit within the nbits range is set
70
template<unsigned nbits, typename BlockType>
71
int VerifyAll(bool reportTestCases) {
4✔
72
        int nrOfFailedTests = 0;
4✔
73
        constexpr unsigned NR_VALUES = (1u << nbits);
4✔
74
        constexpr unsigned ALL_BITS_SET = NR_VALUES - 1;
4✔
75
        blockbinary<nbits, BlockType> a;
76
        for (unsigned i = 0; i < NR_VALUES; ++i) {
69,908✔
77
                a.setbits(i);
69,904✔
78
                bool expected = (i == ALL_BITS_SET);
69,904✔
79
                bool result = a.all();
69,904✔
80
                if (result != expected) {
69,904✔
NEW
81
                        ++nrOfFailedTests;
×
NEW
82
                        if (reportTestCases) {
×
NEW
83
                                std::cerr << "FAIL: all() for " << to_binary(a) << " = " << result
×
NEW
84
                                          << " (expected " << expected << ")\n";
×
85
                        }
86
                }
87
        }
88
        return nrOfFailedTests;
4✔
89
}
90

91
/// Verify any() and none() are always consistent (never both true, never both false for same value)
92
template<unsigned nbits, typename BlockType>
93
int VerifyAnyNoneConsistency(bool reportTestCases) {
3✔
94
        int nrOfFailedTests = 0;
3✔
95
        constexpr unsigned NR_VALUES = (1u << nbits);
3✔
96
        blockbinary<nbits, BlockType> a;
97
        for (unsigned i = 0; i < NR_VALUES; ++i) {
69,891✔
98
                a.setbits(i);
69,888✔
99
                bool anyResult = a.any();
69,888✔
100
                bool noneResult = a.none();
69,888✔
101
                // any() and none() must be complementary
102
                if (anyResult == noneResult) {
69,888✔
NEW
103
                        ++nrOfFailedTests;
×
NEW
104
                        if (reportTestCases) {
×
105
                                std::cerr << "FAIL: any()==none() for " << to_binary(a)
NEW
106
                                          << " any=" << anyResult << " none=" << noneResult << "\n";
×
107
                        }
108
                }
109
        }
110
        return nrOfFailedTests;
3✔
111
}
112

113
/// Verify anyAfter(bitIndex) by comparing against bit-by-bit reference
114
template<unsigned nbits, typename BlockType>
115
int VerifyAnyAfter(bool reportTestCases) {
3✔
116
        int nrOfFailedTests = 0;
3✔
117
        constexpr unsigned NR_VALUES = (1u << nbits);
3✔
118
        blockbinary<nbits, BlockType> a;
119
        for (unsigned i = 0; i < NR_VALUES; ++i) {
4,371✔
120
                a.setbits(i);
4,368✔
121
                for (unsigned bitIndex = 0; bitIndex <= nbits; ++bitIndex) {
60,000✔
122
                        // reference: check if any bit below bitIndex is set
123
                        bool expected = false;
55,632✔
124
                        unsigned limit = (bitIndex < nbits) ? bitIndex : nbits;
55,632✔
125
                        for (unsigned b = 0; b < limit; ++b) {
102,531✔
126
                                if (a.test(b)) { expected = true; break; }
93,798✔
127
                        }
128
                        bool result = a.anyAfter(bitIndex);
55,632✔
129
                        if (result != expected) {
55,632✔
NEW
130
                                ++nrOfFailedTests;
×
NEW
131
                                if (reportTestCases) {
×
NEW
132
                                        std::cerr << "FAIL: anyAfter(" << bitIndex << ") for "
×
NEW
133
                                                  << to_binary(a) << " = " << result
×
NEW
134
                                                  << " (expected " << expected << ")\n";
×
135
                                }
136
                        }
137
                }
138
        }
139
        return nrOfFailedTests;
3✔
140
}
141

142
/// Verify count() returns the correct popcount for all bit patterns
143
template<unsigned nbits, typename BlockType>
144
int VerifyCount(bool reportTestCases) {
4✔
145
        int nrOfFailedTests = 0;
4✔
146
        constexpr unsigned NR_VALUES = (1u << nbits);
4✔
147
        blockbinary<nbits, BlockType> a;
148
        for (unsigned i = 0; i < NR_VALUES; ++i) {
69,908✔
149
                a.setbits(i);
69,904✔
150
                // reference popcount
151
                unsigned expected = 0;
69,904✔
152
                for (unsigned b = 0; b < nbits; ++b) {
1,169,744✔
153
                        if (i & (1u << b)) ++expected;
1,099,840✔
154
                }
155
                unsigned result = a.count();
69,904✔
156
                if (result != expected) {
69,904✔
NEW
157
                        ++nrOfFailedTests;
×
NEW
158
                        if (reportTestCases) {
×
NEW
159
                                std::cerr << "FAIL: count() for " << to_binary(a) << " = " << result
×
NEW
160
                                          << " (expected " << expected << ")\n";
×
161
                        }
162
                }
163
        }
164
        return nrOfFailedTests;
4✔
165
}
166

167
/// Verify any(msb) - the overload that checks bits [0, msb]
168
template<unsigned nbits, typename BlockType>
169
int VerifyAnyMsb(bool reportTestCases) {
3✔
170
        int nrOfFailedTests = 0;
3✔
171
        constexpr unsigned NR_VALUES = (1u << nbits);
3✔
172
        blockbinary<nbits, BlockType> a;
173
        for (unsigned i = 0; i < NR_VALUES; ++i) {
4,371✔
174
                a.setbits(i);
4,368✔
175
                for (unsigned msb = 0; msb < nbits; ++msb) {
55,632✔
176
                        // reference: any bit set in [0..msb]?
177
                        unsigned mask = (1u << (msb + 1)) - 1;
51,264✔
178
                        bool expected = (i & mask) != 0;
51,264✔
179
                        bool result = a.any(msb);
51,264✔
180
                        if (result != expected) {
51,264✔
NEW
181
                                ++nrOfFailedTests;
×
NEW
182
                                if (reportTestCases) {
×
NEW
183
                                        std::cerr << "FAIL: any(" << msb << ") for "
×
NEW
184
                                                  << to_binary(a) << " = " << result
×
NEW
185
                                                  << " (expected " << expected << ")\n";
×
186
                                }
187
                        }
188
                }
189
        }
190
        return nrOfFailedTests;
3✔
191
}
192

193
}} // namespace sw::universal
194

195
int main()
1✔
196
try {
197
        using namespace sw::universal;
198

199
        std::string test_suite = "blockbinary bit pattern verification";
2✔
200
        std::string test_tag = "bit_patterns";
1✔
201
        bool reportTestCases = true;
1✔
202
        int nrOfFailedTestCases = 0;
1✔
203

204
        std::cout << test_suite << '\n';
1✔
205

206
#if MANUAL_TESTING
207
        // quick manual smoke test
208
        {
209
                blockbinary<8> zero;
210
                zero.clear();
211
                std::cout << "zero.any()  = " << zero.any()  << " (expected 0)\n";
212
                std::cout << "zero.none() = " << zero.none() << " (expected 1)\n";
213
                std::cout << "zero.all()  = " << zero.all()  << " (expected 0)\n";
214

215
                blockbinary<8> allones;
216
                allones.setbits(0xFF);
217
                std::cout << "all.any()   = " << allones.any()  << " (expected 1)\n";
218
                std::cout << "all.none()  = " << allones.none() << " (expected 0)\n";
219
                std::cout << "all.all()   = " << allones.all()  << " (expected 1)\n";
220
        }
221

222
#else // !MANUAL_TESTING
223

224
#if REGRESSION_LEVEL_1
225
        // any() exhaustive verification across block types
226
        nrOfFailedTestCases += ReportTestResult(VerifyAny<4, uint8_t>(reportTestCases), "blockbinary<4,uint8_t>", "any()");
4✔
227
        nrOfFailedTestCases += ReportTestResult(VerifyAny<8, uint8_t>(reportTestCases), "blockbinary<8,uint8_t>", "any()");
4✔
228
        nrOfFailedTestCases += ReportTestResult(VerifyAny<8, uint16_t>(reportTestCases), "blockbinary<8,uint16_t>", "any()");
4✔
229
        nrOfFailedTestCases += ReportTestResult(VerifyAny<12, uint8_t>(reportTestCases), "blockbinary<12,uint8_t>", "any()");
4✔
230
        nrOfFailedTestCases += ReportTestResult(VerifyAny<12, uint16_t>(reportTestCases), "blockbinary<12,uint16_t>", "any()");
4✔
231
        nrOfFailedTestCases += ReportTestResult(VerifyAny<16, uint8_t>(reportTestCases), "blockbinary<16,uint8_t>", "any()");
4✔
232
        nrOfFailedTestCases += ReportTestResult(VerifyAny<16, uint16_t>(reportTestCases), "blockbinary<16,uint16_t>", "any()");
4✔
233

234
        // none() exhaustive verification
235
        nrOfFailedTestCases += ReportTestResult(VerifyNone<4, uint8_t>(reportTestCases), "blockbinary<4,uint8_t>", "none()");
4✔
236
        nrOfFailedTestCases += ReportTestResult(VerifyNone<8, uint8_t>(reportTestCases), "blockbinary<8,uint8_t>", "none()");
4✔
237
        nrOfFailedTestCases += ReportTestResult(VerifyNone<12, uint8_t>(reportTestCases), "blockbinary<12,uint8_t>", "none()");
4✔
238
        nrOfFailedTestCases += ReportTestResult(VerifyNone<16, uint8_t>(reportTestCases), "blockbinary<16,uint8_t>", "none()");
4✔
239

240
        // all() exhaustive verification
241
        nrOfFailedTestCases += ReportTestResult(VerifyAll<4, uint8_t>(reportTestCases), "blockbinary<4,uint8_t>", "all()");
4✔
242
        nrOfFailedTestCases += ReportTestResult(VerifyAll<8, uint8_t>(reportTestCases), "blockbinary<8,uint8_t>", "all()");
4✔
243
        nrOfFailedTestCases += ReportTestResult(VerifyAll<12, uint8_t>(reportTestCases), "blockbinary<12,uint8_t>", "all()");
4✔
244
        nrOfFailedTestCases += ReportTestResult(VerifyAll<16, uint8_t>(reportTestCases), "blockbinary<16,uint8_t>", "all()");
4✔
245

246
        // any/none consistency
247
        nrOfFailedTestCases += ReportTestResult(VerifyAnyNoneConsistency<8, uint8_t>(reportTestCases), "blockbinary<8,uint8_t>", "any/none consistency");
4✔
248
        nrOfFailedTestCases += ReportTestResult(VerifyAnyNoneConsistency<12, uint8_t>(reportTestCases), "blockbinary<12,uint8_t>", "any/none consistency");
4✔
249
        nrOfFailedTestCases += ReportTestResult(VerifyAnyNoneConsistency<16, uint16_t>(reportTestCases), "blockbinary<16,uint16_t>", "any/none consistency");
4✔
250

251
        // anyAfter() exhaustive verification
252
        nrOfFailedTestCases += ReportTestResult(VerifyAnyAfter<4, uint8_t>(reportTestCases), "blockbinary<4,uint8_t>", "anyAfter()");
4✔
253
        nrOfFailedTestCases += ReportTestResult(VerifyAnyAfter<8, uint8_t>(reportTestCases), "blockbinary<8,uint8_t>", "anyAfter()");
4✔
254
        nrOfFailedTestCases += ReportTestResult(VerifyAnyAfter<12, uint8_t>(reportTestCases), "blockbinary<12,uint8_t>", "anyAfter()");
4✔
255

256
        // count() exhaustive verification
257
        nrOfFailedTestCases += ReportTestResult(VerifyCount<4, uint8_t>(reportTestCases), "blockbinary<4,uint8_t>", "count()");
4✔
258
        nrOfFailedTestCases += ReportTestResult(VerifyCount<8, uint8_t>(reportTestCases), "blockbinary<8,uint8_t>", "count()");
4✔
259
        nrOfFailedTestCases += ReportTestResult(VerifyCount<12, uint8_t>(reportTestCases), "blockbinary<12,uint8_t>", "count()");
4✔
260
        nrOfFailedTestCases += ReportTestResult(VerifyCount<16, uint8_t>(reportTestCases), "blockbinary<16,uint8_t>", "count()");
4✔
261

262
        // any(msb) overload verification
263
        nrOfFailedTestCases += ReportTestResult(VerifyAnyMsb<4, uint8_t>(reportTestCases), "blockbinary<4,uint8_t>", "any(msb)");
4✔
264
        nrOfFailedTestCases += ReportTestResult(VerifyAnyMsb<8, uint8_t>(reportTestCases), "blockbinary<8,uint8_t>", "any(msb)");
4✔
265
        nrOfFailedTestCases += ReportTestResult(VerifyAnyMsb<12, uint8_t>(reportTestCases), "blockbinary<12,uint8_t>", "any(msb)");
3✔
266
#endif
267

268
#if REGRESSION_LEVEL_2
269
        // larger sizes
270
        nrOfFailedTestCases += ReportTestResult(VerifyAny<16, uint32_t>(reportTestCases), "blockbinary<16,uint32_t>", "any()");
271
        nrOfFailedTestCases += ReportTestResult(VerifyNone<16, uint32_t>(reportTestCases), "blockbinary<16,uint32_t>", "none()");
272
        nrOfFailedTestCases += ReportTestResult(VerifyAll<16, uint32_t>(reportTestCases), "blockbinary<16,uint32_t>", "all()");
273
        nrOfFailedTestCases += ReportTestResult(VerifyAnyAfter<16, uint8_t>(reportTestCases), "blockbinary<16,uint8_t>", "anyAfter()");
274
        nrOfFailedTestCases += ReportTestResult(VerifyAnyAfter<16, uint16_t>(reportTestCases), "blockbinary<16,uint16_t>", "anyAfter()");
275
#endif
276

277
#if REGRESSION_LEVEL_3
278
#endif
279

280
#if REGRESSION_LEVEL_4
281
#endif
282

283
        ReportTestSuiteResults(test_suite, nrOfFailedTestCases);
1✔
284

285
#endif // MANUAL_TESTING
286

287
        return (nrOfFailedTestCases > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
1✔
288
}
1✔
NEW
289
catch (char const* msg) {
×
NEW
290
        std::cerr << "Caught ad-hoc exception: " << msg << std::endl;
×
NEW
291
        return EXIT_FAILURE;
×
NEW
292
}
×
NEW
293
catch (const std::runtime_error& err) {
×
NEW
294
        std::cerr << "Caught runtime exception: " << err.what() << std::endl;
×
NEW
295
        return EXIT_FAILURE;
×
NEW
296
}
×
NEW
297
catch (...) {
×
NEW
298
        std::cerr << "Caught unknown exception" << std::endl;
×
NEW
299
        return EXIT_FAILURE;
×
NEW
300
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc