A game about forced loneliness, made by TACStudios
1using NUnit.Framework;
2using System;
3using Unity.Burst;
4using Unity.Collections;
5using Unity.Collections.LowLevel.Unsafe;
6using Unity.Jobs;
7using Unity.Mathematics;
8using Assert = FastAssert;
9
10namespace Unity.Collections.Tests
11{
12 internal class UnsafeBitArrayTests
13 {
14 [Test]
15 public void UnsafeBitArray_Init()
16 {
17 var container = new UnsafeBitArray(0, Allocator.Persistent, NativeArrayOptions.ClearMemory);
18 Assert.True(container.IsCreated);
19 Assert.True(container.IsEmpty);
20 Assert.DoesNotThrow(() => container.Dispose());
21 }
22
23 [Test]
24 public void UnsafeBitArray_Get_Set_Long()
25 {
26 var numBits = 256;
27
28 var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
29
30 Assert.False(test.IsSet(123));
31 test.Set(123, true);
32 Assert.True(test.IsSet(123));
33
34 Assert.False(test.TestAll(0, numBits));
35 Assert.False(test.TestNone(0, numBits));
36 Assert.True(test.TestAny(0, numBits));
37 Assert.AreEqual(1, test.CountBits(0, numBits));
38
39 Assert.False(test.TestAll(0, 122));
40 Assert.True(test.TestNone(0, 122));
41 Assert.False(test.TestAny(0, 122));
42
43 test.Clear();
44 Assert.False(test.IsSet(123));
45 Assert.AreEqual(0, test.CountBits(0, numBits));
46
47 test.SetBits(40, true, 4);
48 Assert.AreEqual(4, test.CountBits(0, numBits));
49
50 test.SetBits(0, true, numBits);
51 Assert.False(test.TestNone(0, numBits));
52 Assert.True(test.TestAll(0, numBits));
53
54 test.SetBits(0, false, numBits);
55 Assert.True(test.TestNone(0, numBits));
56 Assert.False(test.TestAll(0, numBits));
57
58 test.SetBits(123, true, 7);
59 Assert.True(test.TestAll(123, 7));
60
61 test.Clear();
62 test.SetBits(64, true, 64);
63 Assert.AreEqual(false, test.IsSet(63));
64 Assert.AreEqual(true, test.TestAll(64, 64));
65 Assert.AreEqual(false, test.IsSet(128));
66 Assert.AreEqual(64, test.CountBits(64, 64));
67 Assert.AreEqual(64, test.CountBits(0, numBits));
68
69 test.Clear();
70 test.SetBits(65, true, 62);
71 Assert.AreEqual(false, test.IsSet(64));
72 Assert.AreEqual(true, test.TestAll(65, 62));
73 Assert.AreEqual(false, test.IsSet(127));
74 Assert.AreEqual(62, test.CountBits(64, 64));
75 Assert.AreEqual(62, test.CountBits(0, numBits));
76
77 test.Clear();
78 test.SetBits(66, true, 64);
79 Assert.AreEqual(false, test.IsSet(65));
80 Assert.AreEqual(true, test.TestAll(66, 64));
81 Assert.AreEqual(false, test.IsSet(130));
82 Assert.AreEqual(64, test.CountBits(66, 64));
83 Assert.AreEqual(64, test.CountBits(0, numBits));
84
85 test.Dispose();
86 }
87
88 [Test]
89 public void UnsafeBitArray_Get_Set_Short()
90 {
91 var numBits = 31;
92
93 var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
94
95 Assert.False(test.IsSet(13));
96 test.Set(13, true);
97 Assert.True(test.IsSet(13));
98
99 Assert.False(test.TestAll(0, numBits));
100 Assert.False(test.TestNone(0, numBits));
101 Assert.True(test.TestAny(0, numBits));
102 Assert.AreEqual(1, test.CountBits(0, numBits));
103
104 Assert.False(test.TestAll(0, 12));
105 Assert.True(test.TestNone(0, 12));
106 Assert.False(test.TestAny(0, 12));
107
108 test.Clear();
109 Assert.False(test.IsSet(13));
110 Assert.AreEqual(0, test.CountBits(0, numBits));
111
112 test.SetBits(4, true, 4);
113 Assert.AreEqual(4, test.CountBits(0, numBits));
114
115 test.SetBits(0, true, numBits);
116 Assert.False(test.TestNone(0, numBits));
117 Assert.True(test.TestAll(0, numBits));
118
119 test.SetBits(0, false, numBits);
120 Assert.True(test.TestNone(0, numBits));
121 Assert.False(test.TestAll(0, numBits));
122
123 test.SetBits(13, true, 7);
124 Assert.True(test.TestAll(13, 7));
125
126 test.Clear();
127 test.SetBits(4, true, 4);
128 Assert.AreEqual(false, test.IsSet(3));
129 Assert.AreEqual(true, test.TestAll(4, 4));
130 Assert.AreEqual(false, test.IsSet(18));
131 Assert.AreEqual(4, test.CountBits(4, 4));
132 Assert.AreEqual(4, test.CountBits(0, numBits));
133
134 test.Clear();
135 test.SetBits(5, true, 2);
136 Assert.AreEqual(false, test.IsSet(4));
137 Assert.AreEqual(true, test.TestAll(5, 2));
138 Assert.AreEqual(false, test.IsSet(17));
139 Assert.AreEqual(2, test.CountBits(4, 4));
140 Assert.AreEqual(2, test.CountBits(0, numBits));
141
142 test.Clear();
143 test.SetBits(6, true, 4);
144 Assert.AreEqual(false, test.IsSet(5));
145 Assert.AreEqual(true, test.TestAll(6, 4));
146 Assert.AreEqual(false, test.IsSet(10));
147 Assert.AreEqual(4, test.CountBits(6, 4));
148 Assert.AreEqual(4, test.CountBits(0, numBits));
149
150 test.Dispose();
151 }
152
153 [Test]
154 public void UnsafeBitArray_Get_Set_Tiny()
155 {
156 var numBits = 7;
157
158 var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
159
160 Assert.False(test.IsSet(3));
161 test.Set(3, true);
162 Assert.True(test.IsSet(3));
163
164 Assert.False(test.TestAll(0, numBits));
165 Assert.False(test.TestNone(0, numBits));
166 Assert.True(test.TestAny(0, numBits));
167 Assert.AreEqual(1, test.CountBits(0, numBits));
168
169 Assert.False(test.TestAll(0, 2));
170 Assert.True(test.TestNone(0, 2));
171 Assert.False(test.TestAny(0, 2));
172
173 test.Clear();
174 Assert.False(test.IsSet(3));
175 Assert.AreEqual(0, test.CountBits(0, numBits));
176
177 test.SetBits(3, true, 4);
178 Assert.AreEqual(4, test.CountBits(0, numBits));
179
180 test.SetBits(0, true, numBits);
181 Assert.False(test.TestNone(0, numBits));
182 Assert.True(test.TestAll(0, numBits));
183
184 test.SetBits(0, false, numBits);
185 Assert.True(test.TestNone(0, numBits));
186 Assert.False(test.TestAll(0, numBits));
187
188 test.Dispose();
189 }
190
191 [Test]
192 [TestRequiresDotsDebugOrCollectionChecks]
193 public unsafe void UnsafeBitArray_Throws()
194 {
195 var numBits = 256;
196
197 using (var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory))
198 {
199 Assert.DoesNotThrow(() => { test.TestAll(0, numBits); });
200 Assert.DoesNotThrow(() => { test.TestAny(numBits - 1, numBits); });
201
202 Assert.Throws<ArgumentException>(() => { test.IsSet(-1); });
203 Assert.Throws<ArgumentException>(() => { test.IsSet(numBits); });
204 Assert.Throws<ArgumentException>(() => { test.TestAny(0, 0); });
205 Assert.Throws<ArgumentException>(() => { test.TestAny(numBits, 1); });
206 Assert.Throws<ArgumentException>(() => { test.TestAny(numBits - 1, 0); });
207
208 // GetBits numBits must be 1-64.
209 Assert.Throws<ArgumentException>(() => { test.GetBits(0, 0); });
210 Assert.Throws<ArgumentException>(() => { test.GetBits(0, 65); });
211 Assert.DoesNotThrow(() => { test.GetBits(63, 2); });
212
213 Assert.Throws<ArgumentException>(() => { new UnsafeBitArray(null, 7); /* check sizeInBytes must be multiple of 8-bytes. */ });
214 }
215 }
216
217 static void GetBitsTest(ref UnsafeBitArray test, int pos, int numBits)
218 {
219 test.SetBits(pos, true, numBits);
220 Assert.AreEqual(numBits, test.CountBits(0, test.Length));
221 Assert.AreEqual(0xfffffffffffffffful >> (64 - numBits), test.GetBits(pos, numBits));
222 test.Clear();
223 }
224
225 [Test]
226 public void UnsafeBitArray_GetBits()
227 {
228 var numBits = 256;
229
230 var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
231
232 GetBitsTest(ref test, 0, 5);
233 GetBitsTest(ref test, 1, 3);
234 GetBitsTest(ref test, 0, 63);
235 GetBitsTest(ref test, 0, 64);
236 GetBitsTest(ref test, 1, 63);
237 GetBitsTest(ref test, 1, 64);
238 GetBitsTest(ref test, 62, 5);
239 GetBitsTest(ref test, 127, 3);
240 GetBitsTest(ref test, 250, 6);
241 GetBitsTest(ref test, 254, 2);
242
243 test.Dispose();
244 }
245
246 static void SetBitsTest(ref UnsafeBitArray test, int pos, ulong value, int numBits)
247 {
248 test.SetBits(pos, value, numBits);
249 Assert.AreEqual(value, test.GetBits(pos, numBits));
250 test.Clear();
251 }
252
253 [Test]
254 public void UnsafeBitArray_SetBits()
255 {
256 var numBits = 256;
257
258 var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
259
260 SetBitsTest(ref test, 0, 16, 5);
261 SetBitsTest(ref test, 1, 7, 3);
262 SetBitsTest(ref test, 1, 32, 64);
263 SetBitsTest(ref test, 62, 6, 5);
264 SetBitsTest(ref test, 127, 1, 3);
265 SetBitsTest(ref test, 60, 0xaa, 8);
266
267 test.Dispose();
268 }
269
270 static void CopyBitsTest(ref UnsafeBitArray dstBitArray, int dstPos, ref UnsafeBitArray srcBitArray, int srcPos, int numBits)
271 {
272 for (int pos = 0; pos < dstBitArray.Length; pos += 64)
273 {
274 dstBitArray.SetBits(pos, 0xaaaaaaaaaaaaaaaaul, 64);
275 }
276
277 srcBitArray.SetBits(srcPos, true, numBits);
278 dstBitArray.Copy(dstPos, ref srcBitArray, srcPos, numBits);
279 Assert.AreEqual(true, dstBitArray.TestAll(dstPos, numBits));
280
281 for (int pos = 0; pos < dstBitArray.Length; ++pos)
282 {
283 if ((pos >= dstPos && pos < dstPos + numBits) ||
284 (pos >= srcPos && pos < srcPos + numBits))
285 {
286 Assert.AreEqual(true, dstBitArray.IsSet(pos));
287 }
288 else
289 {
290 Assert.AreEqual((0 != (pos & 1)), dstBitArray.IsSet(pos));
291 }
292 }
293
294 dstBitArray.Clear();
295 }
296
297 static void CopyBitsTest(ref UnsafeBitArray test, int dstPos, int srcPos, int numBits)
298 {
299 CopyBitsTest(ref test, dstPos, ref test, srcPos, numBits);
300 }
301
302 static void CopyBitsTests(ref UnsafeBitArray test)
303 {
304 CopyBitsTest(ref test, 1, 16, 12); // short up to 64-bits copy
305 CopyBitsTest(ref test, 1, 80, 63); // short up to 64-bits copy
306 CopyBitsTest(ref test, 1, 11, 12); // short up to 64-bits copy overlapped
307 CopyBitsTest(ref test, 11, 1, 12); // short up to 64-bits copy overlapped
308
309 CopyBitsTest(ref test, 1, 16, 76); // short up to 128-bits copy
310 CopyBitsTest(ref test, 1, 80, 127); // short up to 128-bits copy
311 CopyBitsTest(ref test, 1, 11, 76); // short up to 128-bits copy overlapped
312 CopyBitsTest(ref test, 11, 1, 76); // short up to 128-bits copy overlapped
313
314 CopyBitsTest(ref test, 1, 81, 255); // long copy aligned
315 CopyBitsTest(ref test, 8, 0, 255); // long copy overlapped aligned
316 CopyBitsTest(ref test, 1, 80, 255); // long copy unaligned
317 CopyBitsTest(ref test, 80, 1, 255); // long copy overlapped unaligned
318 }
319
320 [Test]
321 public void UnsafeBitArray_Copy()
322 {
323 var numBits = 512;
324
325 var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
326 CopyBitsTests(ref test);
327
328 test.Dispose();
329 }
330
331 [Test]
332 public void UnsafeBitArray_Resize()
333 {
334 var test = new UnsafeBitArray(1, Allocator.Persistent, NativeArrayOptions.ClearMemory);
335 Assert.AreEqual(1, test.Length);
336 Assert.AreEqual(64, test.Capacity);
337
338 test.SetCapacity(200); // expand
339 Assert.AreEqual(1, test.Length);
340 Assert.AreEqual(256, test.Capacity);
341
342 test.Resize(100, NativeArrayOptions.ClearMemory);
343 Assert.True(test.TestNone(0, test.Length));
344
345 // prepare survival test
346 test.Set(0, true);
347 test.Set(99, true);
348 Assert.True(test.IsSet(0));
349 Assert.True(test.TestNone(1, 98));
350 Assert.True(test.IsSet(99));
351
352 test.SetCapacity(1000); // expand
353 Assert.AreEqual(100, test.Length);
354 Assert.AreEqual(1024, test.Capacity);
355
356 // test resize survival
357 Assert.True(test.IsSet(0));
358 Assert.True(test.TestNone(1, 98));
359 Assert.True(test.IsSet(99));
360
361 // manual clear
362 test.Resize(1);
363 test.Set(0, false);
364
365 test.SetCapacity(200); // truncate capacity
366 Assert.AreEqual(1, test.Length);
367 Assert.AreEqual(256, test.Capacity);
368
369 test.Resize(512, NativeArrayOptions.ClearMemory); // resize
370 Assert.AreEqual(512, test.Length);
371 Assert.AreEqual(512, test.Capacity);
372 Assert.True(test.TestNone(0, test.Length));
373
374 CopyBitsTests(ref test);
375
376 test.Resize(256); // truncate length
377 Assert.AreEqual(256, test.Length);
378 Assert.AreEqual(512, test.Capacity);
379
380 test.TrimExcess();
381 Assert.AreEqual(256, test.Length);
382 Assert.AreEqual(256, test.Capacity);
383
384 test.Dispose();
385 }
386
387 [Test]
388 public void UnsafeBitArray_CopyBetweenBitArrays()
389 {
390 var numBits = 512;
391
392 var test0 = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
393 var test1 = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
394 var test2 = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
395
396 for (int pos = 0; pos < test0.Length; pos += 64)
397 {
398 test0.SetBits(pos, 0xaaaaaaaaaaaaaaaaul, 64);
399 test1.SetBits(pos, 0x5555555555555555ul, 64);
400 }
401
402 var numCopyBits = 255;
403
404 test0.SetBits(13, true, numCopyBits);
405
406 test1.Copy(1, ref test0, 13, numCopyBits);
407 Assert.AreEqual(true, test1.TestAll(1, numCopyBits));
408
409 test2.Copy(43, ref test1, 1, numCopyBits);
410 Assert.AreEqual(true, test2.TestAll(43, numCopyBits));
411
412 test0.Dispose();
413 test1.Dispose();
414 test2.Dispose();
415 }
416
417 [Test]
418 [TestRequiresDotsDebugOrCollectionChecks]
419 public unsafe void UnsafeBitArray_Copy_Throws()
420 {
421 var numBits = 512;
422
423 var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory);
424
425 Assert.Throws<ArgumentException>(() => { CopyBitsTest(ref test, 0, numBits - 1, 16); }); // short up to 64-bits copy out of bounds
426 Assert.Throws<ArgumentException>(() => { CopyBitsTest(ref test, numBits - 1, 0, 16); }); // short up to 64-bits copy out of bounds
427
428 Assert.Throws<ArgumentException>(() => { CopyBitsTest(ref test, 0, numBits - 1, 80); }); // short up to 128-bits copy out of bounds
429 Assert.Throws<ArgumentException>(() => { CopyBitsTest(ref test, numBits - 1, 0, 80); }); // short up to 128-bits copy out of bounds
430
431 Assert.Throws<ArgumentException>(() => { CopyBitsTest(ref test, 1, numBits - 7, 127); }); // long copy aligned
432 Assert.Throws<ArgumentException>(() => { CopyBitsTest(ref test, numBits - 7, 1, 127); }); // long copy aligned
433
434 Assert.Throws<ArgumentException>(() => { CopyBitsTest(ref test, 2, numBits - 1, 127); }); // long copy unaligned
435 Assert.Throws<ArgumentException>(() => { CopyBitsTest(ref test, numBits - 1, 2, 127); }); // long copy unaligned
436
437 test.Dispose();
438 }
439
440 [Test]
441 public unsafe void UnsafeBitArray_Find()
442 {
443 var numBits = 512;
444
445 using (var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory))
446 {
447 test.SetBits(0, true, 11);
448
449 for (var i = 0; i < 256; ++i)
450 {
451 Assert.AreEqual(11, test.Find(0, i + 1));
452 }
453
454 for (var j = 0; j < 64; ++j)
455 {
456 for (var i = 0; i < 256; ++i)
457 {
458 var numBitsToFind = 7 + i;
459 var pos = 37 + j;
460
461 test.SetBits(0, true, test.Length);
462 test.SetBits(pos, false, numBitsToFind);
463
464 Assert.AreEqual(pos, test.Find(0, numBitsToFind), $"{j}/{i}: pos {pos}, numBitsToFind {numBitsToFind}");
465 Assert.AreEqual(pos, test.Find(pos, numBitsToFind), $"{j}/{i}:pos {pos}, numBitsToFind {numBitsToFind}");
466
467 Assert.AreEqual(pos, test.Find(0, numBitsToFind), $"{j}/{i}: pos {pos}, numBitsToFind {numBitsToFind}");
468 Assert.AreEqual(pos, test.Find(pos, numBitsToFind), $"{j}/{i}: pos {pos}, numBitsToFind {numBitsToFind}");
469
470 Assert.IsTrue(test.TestNone(test.Find(0, numBitsToFind), numBitsToFind));
471
472 Assert.AreEqual(int.MaxValue, test.Find(pos + 1, numBitsToFind), $"{j}/{i}: pos {pos}, numBitsToFind {numBitsToFind}");
473 }
474 }
475 }
476 }
477
478 [Test]
479 public unsafe void UnsafeBitArray_Find_With_Begin_End()
480 {
481 var numBits = 512;
482
483 using (var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory))
484 {
485 Assert.AreEqual(0, test.Find(0, 2, 1));
486 Assert.AreEqual(1, test.Find(1, 2, 1));
487 test.SetBits(0, true, 6);
488 Assert.AreEqual(int.MaxValue, test.Find(0, 2, 1));
489
490 for (var j = 0; j < 64; ++j)
491 {
492 for (var i = 0; i < 256; ++i)
493 {
494 var numBitsToFind = 7 + i;
495 var padding = 11;
496 var begin = 37 + j;
497 var end = begin + padding + numBitsToFind;
498 var count = end - begin;
499
500 test.Clear();
501 test.SetBits(begin, true, count);
502 test.SetBits(begin + padding + 1, false, numBitsToFind - 1);
503
504 Assert.AreEqual(begin + padding + 1, test.Find(begin, count, numBitsToFind - 1)); //, $"{j}/{i}: begin {begin}, end {end}, count {count}, numBitsToFind {numBitsToFind}");
505 Assert.AreEqual(int.MaxValue, test.Find(begin, count, numBitsToFind)); //, $"{j}/{i}: begin {begin}, end {end}, count {count}, numBitsToFind {numBitsToFind}");
506 }
507 }
508 }
509 }
510
511 [Test]
512 [TestRequiresDotsDebugOrCollectionChecks]
513 public unsafe void UnsafeBitArray_Find_Throws()
514 {
515 var numBits = 512;
516
517 using (var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory))
518 {
519 Assert.Throws<ArgumentException>(() => { test.Find(0, 0, 1); }); // empty range
520 Assert.Throws<ArgumentException>(() => { test.Find(0, 1, 0); }); // zero bits
521 Assert.Throws<ArgumentException>(() => { test.Find(0, 1, 2); }); // numBits is larger than range
522 Assert.Throws<ArgumentException>(() => { test.Find(10, 0, 0); }); // empty range, numBits is less than 1
523 Assert.Throws<ArgumentException>(() => { test.Find(1, 10, -2); }); // numBits can't be negative
524 }
525 }
526
527 void findWithPattern(ref UnsafeBitArray test, byte pattern, int numBits)
528 {
529 for (int pos = 0; pos < test.Length; pos += 8)
530 {
531 test.SetBits(pos, pattern, 8);
532 }
533
534 var bitCount = math.countbits((int)pattern);
535 var numEmptyBits = test.Length - (test.Length / 8 * bitCount);
536
537 for (int i = 0; i < numEmptyBits; i += numBits)
538 {
539 var pos = test.Find(0, numBits);
540 Assert.AreNotEqual(int.MaxValue, pos, $"{i}");
541 test.SetBits(pos, true, numBits);
542 }
543
544 Assert.True(test.TestAll(0, test.Length));
545 }
546
547 [Test]
548 public void UnsafeBitArray_FindWithPattern()
549 {
550 var test = new UnsafeBitArray(512, Allocator.Persistent, NativeArrayOptions.ClearMemory);
551
552 // Separated test for some more interesting patterns
553 findWithPattern(ref test, 0x81, 1);
554 findWithPattern(ref test, 0x81, 2);
555 findWithPattern(ref test, 0x81, 3);
556 findWithPattern(ref test, 0x81, 6);
557 findWithPattern(ref test, 0x88, 3);
558 findWithPattern(ref test, 0x99, 2);
559 findWithPattern(ref test, 0xaa, 1);
560 findWithPattern(ref test, 0xc3, 1);
561 findWithPattern(ref test, 0xc3, 2);
562 findWithPattern(ref test, 0xc3, 4);
563 findWithPattern(ref test, 0xe7, 1);
564 findWithPattern(ref test, 0xe7, 2);
565
566 // Test all patterns
567 for (int i = 0; i < 256; i++)
568 {
569 findWithPattern(ref test, (byte)i, 1);
570 }
571
572 test.Dispose();
573 }
574
575 [Test]
576 public void UnsafeBitArray_FindInTinyBitArray()
577 {
578 var test = new UnsafeBitArray(3, Allocator.Persistent, NativeArrayOptions.ClearMemory);
579 Assert.AreEqual(3, test.Length);
580
581 test.SetBits(0, 0x55, test.Length);
582
583 Assert.AreEqual(1, test.Find(0, 1));
584 Assert.AreEqual(1, test.Find(0, test.Length, 1));
585 test.SetBits(1, true, 1);
586 Assert.True(test.TestAll(0, test.Length));
587 Assert.AreEqual(int.MaxValue, test.Find(0, test.Length, 1));
588
589 test.Dispose();
590 }
591
592 [Test]
593 public void UnsafeBitArray_FindLastUnsetBit([NUnit.Framework.Range(1, 64)] int numBits)
594 {
595 using (var bits = new UnsafeBitArray(numBits, Allocator.Persistent))
596 {
597 // Set all bits to one then unset a single bit to find.
598 for (int i = 0; i < numBits; ++i)
599 {
600 bits.SetBits(0, true, numBits);
601 bits.Set(i, false);
602 Assert.AreEqual(i, bits.Find(0, 1));
603 }
604 }
605 }
606
607 [Test]
608 public void UnsafeBitArray_CustomAllocatorTest()
609 {
610 AllocatorManager.Initialize();
611 var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent);
612 ref var allocator = ref allocatorHelper.Allocator;
613 allocator.Initialize();
614
615 using (var container = new UnsafeBitArray(1, allocator.Handle))
616 {
617 }
618
619 Assert.IsTrue(allocator.WasUsed);
620 allocator.Dispose();
621 allocatorHelper.Dispose();
622 AllocatorManager.Shutdown();
623 }
624
625 [BurstCompile]
626 struct BurstedCustomAllocatorJob : IJob
627 {
628 [NativeDisableUnsafePtrRestriction]
629 public unsafe CustomAllocatorTests.CountingAllocator* Allocator;
630
631 public void Execute()
632 {
633 unsafe
634 {
635 using (var container = new UnsafeBitArray(1, Allocator->Handle))
636 {
637 }
638 }
639 }
640 }
641
642 [Test]
643 public unsafe void UnsafeBitArray_BurstedCustomAllocatorTest()
644 {
645 AllocatorManager.Initialize();
646 var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent);
647 ref var allocator = ref allocatorHelper.Allocator;
648 allocator.Initialize();
649
650 var allocatorPtr = (CustomAllocatorTests.CountingAllocator*)UnsafeUtility.AddressOf<CustomAllocatorTests.CountingAllocator>(ref allocator);
651 unsafe
652 {
653 var handle = new BurstedCustomAllocatorJob { Allocator = allocatorPtr }.Schedule();
654 handle.Complete();
655 }
656
657 Assert.IsTrue(allocator.WasUsed);
658 allocator.Dispose();
659 allocatorHelper.Dispose();
660 AllocatorManager.Shutdown();
661 }
662 }
663}