Blender V4.3
BLI_bit_span_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include <array>
6
7#include "BLI_bit_span.hh"
8#include "BLI_bit_span_ops.hh"
10#include "BLI_bit_vector.hh"
11#include "BLI_timeit.hh"
12#include "BLI_vector.hh"
13
14#include "testing/testing.h"
15
16namespace blender::bits::tests {
17
18TEST(bit_span, DefaultConstructor)
19{
20 {
21 char buffer[sizeof(BitSpan)];
22 memset(buffer, 0xff, sizeof(BitSpan));
23 BitSpan &span = *new (buffer) BitSpan();
24 EXPECT_TRUE(span.is_empty());
25 EXPECT_EQ(span.size(), 0);
26 }
27 {
28 char buffer[sizeof(MutableBitSpan)];
29 memset(buffer, 0xff, sizeof(MutableBitSpan));
30 MutableBitSpan &span = *new (buffer) MutableBitSpan();
31 EXPECT_TRUE(span.is_empty());
32 EXPECT_EQ(span.size(), 0);
33 }
34}
35
36TEST(bit_span, Iteration)
37{
38 uint64_t data = (1 << 2) | (1 << 3);
39 const BitSpan span(&data, 30);
40 EXPECT_EQ(span.size(), 30);
41 int index = 0;
42 for (const BitRef bit : span) {
43 EXPECT_EQ(bit.test(), ELEM(index, 2, 3));
44 index++;
45 }
46}
47
48TEST(bit_span, MutableIteration)
49{
50 uint64_t data = 0;
51 MutableBitSpan span(&data, 40);
52 EXPECT_EQ(span.size(), 40);
53 int index = 0;
54 for (MutableBitRef bit : span) {
55 bit.set(index % 4 == 0);
56 index++;
57 }
58 EXPECT_EQ(data,
59 0b0000'0000'0000'0000'0000'0000'0001'0001'0001'0001'0001'0001'0001'0001'0001'0001);
60}
61
62TEST(bit_span, SubscriptOperator)
63{
64 uint64_t data[2] = {0, 0};
65 MutableBitSpan mutable_span(data, 128);
66 BitSpan span = mutable_span;
67
68 EXPECT_EQ(mutable_span.data(), data);
69 EXPECT_EQ(mutable_span.bit_range(), IndexRange(128));
70 EXPECT_EQ(span.data(), data);
71 EXPECT_EQ(span.bit_range(), IndexRange(128));
72
73 EXPECT_FALSE(mutable_span[5].test());
74 EXPECT_FALSE(span[5].test());
75 mutable_span[5].set(true);
76 EXPECT_TRUE(mutable_span[5].test());
77 EXPECT_TRUE(span[5].test());
78
79 EXPECT_FALSE(mutable_span[120].test());
80 EXPECT_FALSE(span[120].test());
81 mutable_span[120].set(true);
82 EXPECT_TRUE(mutable_span[120].test());
83 EXPECT_TRUE(span[120].test());
84
85 EXPECT_EQ(data[0],
86 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0010'0000);
87 EXPECT_EQ(data[1],
88 0b0000'0001'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000);
89}
90
91TEST(bit_span, RangeConstructor)
92{
93 uint64_t data = 0;
94 MutableBitSpan mutable_span(&data, IndexRange(4, 3));
95 BitSpan span = mutable_span;
96
97 EXPECT_FALSE(mutable_span[1].test());
98 EXPECT_FALSE(span[1].test());
99 mutable_span[0].set(true);
100 mutable_span[1].set(true);
101 mutable_span[2].set(true);
102 mutable_span[0].set(false);
103 mutable_span[2].set(false);
104 EXPECT_TRUE(mutable_span[1].test());
105 EXPECT_TRUE(span[1].test());
106
107 EXPECT_EQ(data,
108 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0010'0000);
109}
110
111TEST(bit_span, Set)
112{
113 uint64_t data = 0;
114 MutableBitSpan(&data, 64).set_all(true);
115 EXPECT_EQ(data, uint64_t(-1));
116 MutableBitSpan(&data, 64).set_all(false);
117 EXPECT_EQ(data, uint64_t(0));
118
119 MutableBitSpan(&data, IndexRange(4, 8)).set_all(true);
120 EXPECT_EQ(data,
121 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'1111'1111'0000);
122 MutableBitSpan(&data, IndexRange(8, 30)).set_all(false);
123
124 EXPECT_EQ(data,
125 0b0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'0000'1111'0000);
126}
127
128TEST(bit_span, SetEmpty)
129{
130 MutableBitSpan().set_all(true);
131 MutableBitSpan().set_all(false);
132}
133
134TEST(bit_span, SetSliced)
135{
136 std::array<uint64_t, 10> data;
137 memset(data.data(), 0, sizeof(data));
138 MutableBitSpan span{data.data(), 640};
139 span.slice(IndexRange(5, 500)).set_all(true);
140
141 for (const int64_t i : IndexRange(640)) {
142 EXPECT_EQ(span[i], i >= 5 && i < 505);
143 }
144
145 span.slice(IndexRange(10, 190)).set_all(false);
146
147 for (const int64_t i : IndexRange(640)) {
148 EXPECT_EQ(span[i], (i >= 5 && i < 10) || (i >= 200 && i < 505));
149 }
150}
151
152TEST(bit_span, IsBounded)
153{
154 std::array<uint64_t, 10> data;
155
156 EXPECT_TRUE(is_bounded_span(BitSpan(data.data(), 0)));
157 EXPECT_TRUE(is_bounded_span(BitSpan(data.data(), 1)));
158 EXPECT_TRUE(is_bounded_span(BitSpan(data.data(), 50)));
159 EXPECT_TRUE(is_bounded_span(BitSpan(data.data(), 63)));
160 EXPECT_TRUE(is_bounded_span(BitSpan(data.data(), 64)));
161 EXPECT_TRUE(is_bounded_span(BitSpan(data.data(), 65)));
162 EXPECT_TRUE(is_bounded_span(BitSpan(data.data(), 100)));
163 EXPECT_TRUE(is_bounded_span(BitSpan(data.data(), 400)));
164
165 EXPECT_TRUE(is_bounded_span(BitSpan(data.data(), IndexRange(0, 3))));
166 EXPECT_TRUE(is_bounded_span(BitSpan(data.data(), IndexRange(1, 3))));
167 EXPECT_TRUE(is_bounded_span(BitSpan(data.data(), IndexRange(10, 20))));
168 EXPECT_TRUE(is_bounded_span(BitSpan(data.data(), IndexRange(63, 1))));
169 EXPECT_TRUE(is_bounded_span(BitSpan(data.data(), IndexRange(10, 54))));
170
171 EXPECT_FALSE(is_bounded_span(BitSpan(data.data(), IndexRange(1, 64))));
172 EXPECT_FALSE(is_bounded_span(BitSpan(data.data(), IndexRange(10, 64))));
173 EXPECT_FALSE(is_bounded_span(BitSpan(data.data(), IndexRange(10, 200))));
174 EXPECT_FALSE(is_bounded_span(BitSpan(data.data(), IndexRange(60, 5))));
175 EXPECT_FALSE(is_bounded_span(BitSpan(data.data(), IndexRange(64, 0))));
176 EXPECT_FALSE(is_bounded_span(BitSpan(data.data(), IndexRange(70, 5))));
177}
178
179TEST(bit_span, CopyFrom)
180{
181 std::array<uint64_t, 30> src_data;
182 uint64_t i = 0;
183 for (uint64_t &value : src_data) {
184 value = i;
185 i += 234589766883;
186 }
187 const BitSpan src(src_data.data(), src_data.size() * BitsPerInt);
188
189 std::array<uint64_t, 4> dst_data;
190 dst_data.fill(-1);
191 MutableBitSpan dst(dst_data.data(), 100);
192 dst.copy_from(src.slice({401, 100}));
193
194 for (const int i : dst.index_range()) {
195 EXPECT_TRUE(dst[i].test() == src[401 + i].test());
196 }
197}
198
199TEST(bit_span, InPlaceOr)
200{
201 std::array<uint64_t, 100> data_1;
202 MutableBitSpan span_1(data_1.data(), data_1.size() * BitsPerInt);
203 for (const int i : span_1.index_range()) {
204 span_1[i].set(i % 2 == 0);
205 }
206
207 std::array<uint64_t, 100> data_2;
208 MutableBitSpan span_2(data_2.data(), data_2.size() * BitsPerInt);
209 for (const int i : span_2.index_range()) {
210 span_2[i].set(i % 2 != 0);
211 }
212
213 span_1 |= span_2;
214 for (const int i : span_1.index_range()) {
215 EXPECT_TRUE(span_1[i].test());
216 }
217}
218
219TEST(bit_span, InPlaceAnd)
220{
221 std::array<uint64_t, 100> data_1{};
222 MutableBitSpan span_1(data_1.data(), data_1.size() * BitsPerInt);
223 for (const int i : span_1.index_range()) {
224 span_1[i].set(i % 2 == 0);
225 }
226
227 std::array<uint64_t, 100> data_2{};
228 MutableBitSpan span_2(data_2.data(), data_2.size() * BitsPerInt);
229 for (const int i : span_2.index_range()) {
230 span_2[i].set(i % 2 != 0);
231 }
232
233 span_1 &= span_2;
234 for (const int i : span_1.index_range()) {
235 EXPECT_FALSE(span_1[i].test());
236 }
237}
238
239TEST(bit_span, ForEach1)
240{
241 std::array<uint64_t, 2> data{};
242 MutableBitSpan span(data.data(), data.size() * BitsPerInt);
243 for (const int i : {1, 28, 37, 86}) {
244 span[i].set();
245 }
246
247 Vector<int> indices_test;
248 foreach_1_index(span.slice({4, span.size() - 4}), [&](const int i) { indices_test.append(i); });
249
250 EXPECT_EQ(indices_test.as_span(), Span({24, 33, 82}));
251}
252
254{
255 {
256 Vector<bool> bools(5, false);
257 bools[2] = true;
258 BitVector<> bits(bools.size());
259 bits[0].set();
260 bits::or_bools_into_bits(bools, bits);
261 EXPECT_TRUE(bits[0]);
262 EXPECT_FALSE(bits[1]);
263 EXPECT_TRUE(bits[2]);
264 EXPECT_FALSE(bits[3]);
265 EXPECT_FALSE(bits[4]);
266 }
267 {
268 Vector<bool> bools(100, true);
269 BitVector<> bits(1000, false);
271 MutableBitSpan(bits).slice(IndexRange::from_begin_size(100, 500)));
272 EXPECT_FALSE(bits[99]);
273 EXPECT_TRUE(bits[100]);
274 EXPECT_TRUE(bits[101]);
275 EXPECT_TRUE(bits[199]);
276 EXPECT_FALSE(bits[200]);
277 }
278}
279
280TEST(bit_span, to_index_ranges_small)
281{
282 BitVector<> bits(10, false);
283 bits[2].set();
284 bits[3].set();
285 bits[4].set();
286 bits[6].set();
287 bits[7].set();
288
290 IndexRangesBuilder<int> builder(builder_buffer);
291 bits_to_index_ranges(bits, builder);
292
293 EXPECT_EQ(builder.size(), 2);
296}
297
298TEST(bit_span, to_index_ranges_all_ones)
299{
300 BitVector<> bits(10000, true);
301
303 IndexRangesBuilder<int> builder(builder_buffer);
304 bits_to_index_ranges(BitSpan(bits).take_back(8765), builder);
305
306 EXPECT_EQ(builder.size(), 1);
307 EXPECT_EQ(builder[0], IndexRange(8765));
308}
309
310} // namespace blender::bits::tests
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
#define ELEM(...)
static constexpr IndexRange from_begin_size(const int64_t begin, const int64_t size)
static constexpr IndexRange from_begin_end_inclusive(const int64_t begin, const int64_t last)
int64_t size() const
Span< T > as_span() const
const BitInt * data() const
int64_t size() const
BitSpan slice(const IndexRange range) const
const IndexRange & bit_range() const
MutableBitSpan slice(const IndexRange range) const
const IndexRange & bit_range() const
IndexRange index_range() const
void copy_from(const BitSpan other)
Definition bit_span.cc:62
TEST(bit_group_vector, DefaultConstruct)
bool or_bools_into_bits(Span< bool > bools, MutableBitSpan r_bits, int64_t allowed_overshoot=0)
static constexpr int64_t BitsPerInt
void bits_to_index_ranges(const BitSpan bits, IndexRangesBuilder< IntT > &builder)
bool is_bounded_span(const BitSpan span)
void foreach_1_index(const BitSpanT &data, Fn &&fn)
__int64 int64_t
Definition stdint.h:89
unsigned __int64 uint64_t
Definition stdint.h:90