14#include "codegen_harness/types.h"
31using namespace esi_system;
40std::array<uint8_t,
sizeof(T)> wireBytes(
const T &value) {
41 std::array<uint8_t,
sizeof(T)> out{};
42 const auto *src =
reinterpret_cast<const uint8_t *
>(&value);
43 for (std::size_t i = 0; i <
sizeof(T); ++i)
48template <
typename T, std::
size_t N>
49void expectBytes(
const T &value,
const std::array<uint8_t, N> &expected,
51 static_assert(
sizeof(T) == N,
"wire-byte assertion size mismatch");
52 auto got = wireBytes(value);
53 for (std::size_t i = 0; i < N; ++i) {
54 if (got[i] != expected[i]) {
56 "%s: byte %zu mismatch: got 0x%02x expected 0x%02x\n", label,
57 i, got[i], expected[i]);
58 std::fprintf(stderr,
" got :");
60 std::fprintf(stderr,
" %02x", b);
61 std::fprintf(stderr,
"\n expected:");
62 for (
auto b : expected)
63 std::fprintf(stderr,
" %02x", b);
64 std::fprintf(stderr,
"\n");
74void testStandardWidthUnsigned() {
76 s.u8(0xAB).u16(0xCAFE).u32(0xDEADBEEFu).u64(0x0123456789ABCDEFull);
80 assert(
s.u64() == 0x0123456789ABCDEFull);
86 std::array<uint8_t, 15>{
113 std::array<uint8_t, 15>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
117 StdU cons(0xAB, 0xCAFE, 0xDEADBEEFu, 0x0123456789ABCDEFull);
118 assert(wireBytes(cons) == wireBytes(s));
121void testStandardWidthSigned() {
123 s.s8(-7).s16(-1000).s32(-1234567).s64(INT64_MIN);
132 StdS pos(127, 32767, 2147483647, INT64_MAX);
134 assert(pos.s64() == INT64_MAX);
141void testByteAlignedOddWidthUnsigned() {
146 expectBytes(s, std::array<uint8_t, 3>{0xEF, 0xCD, 0xAB},
"OddU");
149void testByteAlignedOddWidthSigned() {
153 expectBytes(s, std::array<uint8_t, 3>{0xFF, 0xFF, 0xFF},
"OddS -1");
157 expectBytes(s, std::array<uint8_t, 3>{0x00, 0x00, 0x80},
"OddS min");
161 expectBytes(s, std::array<uint8_t, 3>{0xFF, 0xFF, 0x7F},
"OddS max");
172void testSubByteUnsigned() {
174 s.u3(0b101).u12(0xABC);
183 expectBytes(s, std::array<uint8_t, 2>{0xBC, 0x5A},
"SubU");
186void testSubByteSigned() {
200 expectBytes(s, std::array<uint8_t, 2>{0xCE, 0x0E},
"SubS");
203void testBoolField() {
205 f.flag(
true).pad(0x5A);
210 expectBytes(f, std::array<uint8_t, 1>{0xDA},
"BoolField true");
213 expectBytes(f, std::array<uint8_t, 1>{0x5A},
"BoolField false");
220void testNestedStruct() {
225 o.label(0xAB).inner(in);
226 assert(o.label() == 0xAB);
227 assert(o.inner().x() == 0x12);
228 assert(o.inner().y() == 0x34);
232 expectBytes(o, std::array<uint8_t, 3>{0x34, 0x12, 0xAB},
"Outer");
239 auto copy = o2.inner();
241 assert(o2.inner().x() == 0x12);
243 assert(o2.inner().x() == 0xFF);
246void testNestedStructMisaligned() {
260 m.tag(0b101).inner(mi);
262 assert(m.inner().x() == 0x12);
263 assert(m.inner().y() == 0x34);
266 expectBytes(m, std::array<uint8_t, 3>{0xA5, 0x91, 0x00},
267 "Misaligned all-set");
272 assert(m.inner().x() == 0x12);
273 assert(m.inner().y() == 0x34);
274 expectBytes(m, std::array<uint8_t, 3>{0xA0, 0x91, 0x00},
275 "Misaligned tag cleared");
283 assert(m.inner().x() == 0xFF);
284 assert(m.inner().y() == 0x00);
292 expectBytes(m, std::array<uint8_t, 3>{0x05, 0xF8, 0x07},
293 "Misaligned inner all-ones");
300void testArrayOfIntegers() {
302 a.r({0x10, 0x20, 0x30, 0x40});
304 assert(r[0] == 0x10 && r[1] == 0x20 && r[2] == 0x30 && r[3] == 0x40);
312 expectBytes(a, std::array<uint8_t, 4>{0x10, 0x20, 0x99, 0x40},
"Arr4");
324void testSubByteUnsignedArray() {
328 a.vals({1, 2, 3, 4, 5, 6, 7, 0});
329 const std::array<uint8_t, 8> expected = {1, 2, 3, 4, 5, 6, 7, 0};
330 auto whole = a.vals();
331 for (std::size_t i = 0; i < 8; ++i) {
332 assert(whole[i] == expected[i]);
333 assert(a.vals(i) == expected[i]);
336 expectBytes(a, std::array<uint8_t, 3>{0xD1, 0x58, 0x1F},
"U3Arr packed");
342 for (std::size_t i = 0; i < 8; ++i)
345 expectBytes(b, std::array<uint8_t, 3>{0xC0, 0x01, 0x00},
"U3Arr cross-byte");
348void testSubByteBoolArray() {
353 const std::array<bool, 8> flags = {
true,
true,
false,
false,
354 true,
false,
true,
true};
356 auto whole = a.flags();
357 for (std::size_t i = 0; i < 8; ++i) {
358 assert(whole[i] == flags[i]);
359 assert(a.flags(i) == flags[i]);
361 expectBytes(a, std::array<uint8_t, 1>{0xD3},
"Bits1Arr");
364void testSubByteSignedArray() {
368 const std::array<int8_t, 4> vals = {-1, -16, 15, 0};
370 auto whole = a.vals();
371 for (std::size_t i = 0; i < 4; ++i) {
372 assert(whole[i] == vals[i]);
373 assert(a.vals(i) == vals[i]);
375 expectBytes(a, std::array<uint8_t, 3>{0x1F, 0x3E, 0x00},
"S5Arr");
378void testOddWidthArray() {
383 const std::array<uint32_t, 2> vals = {0xABCDEFu, 0x123456u};
385 auto whole = a.vals();
386 for (std::size_t i = 0; i < 2; ++i) {
387 assert(whole[i] == vals[i]);
388 assert(a.vals(i) == vals[i]);
390 expectBytes(a, std::array<uint8_t, 6>{0xEF, 0xCD, 0xAB, 0x56, 0x34, 0x12},
394void testSubByteStructArray() {
401 std::array<SbCell, 4> cells;
402 cells[0] = SbCell(1, 0);
403 cells[1] = SbCell(2, 1);
404 cells[2] = SbCell(3, 2);
405 cells[3] = SbCell(7, 3);
408 auto whole = a.cells();
409 for (std::size_t i = 0; i < 4; ++i) {
410 assert(whole[i].hi() == cells[i].hi());
411 assert(whole[i].lo() == cells[i].lo());
412 assert(a.cells(i).hi() == cells[i].hi());
413 assert(a.cells(i).lo() == cells[i].lo());
416 expectBytes(a, std::array<uint8_t, 3>{0x24, 0xB9, 0x0F},
"SbCellArr");
421 b.cells(1, SbCell(7, 3));
422 assert(b.cells(1).hi() == 7);
423 assert(b.cells(1).lo() == 3);
424 for (std::size_t i = 0; i < 4; ++i)
426 assert(b.cells(i).hi() == 0);
427 assert(b.cells(i).lo() == 0);
429 expectBytes(b, std::array<uint8_t, 3>{0xE0, 0x03, 0x00},
430 "SbCellArr cross-byte");
440 assert(u.big() == 0xCAFE);
443 assert(u.small() == 0xCA);
444 expectBytes(u, std::array<uint8_t, 2>{0xFE, 0xCA},
"Union big");
447 assert(u.small() == 0xA5);
450 expectBytes(u, std::array<uint8_t, 2>{0xFE, 0xA5},
"Union small");
457void testWindowList() {
458 std::vector<uint32_t> elements = {0xAAAA0001u, 0xBBBB0002u, 0xCCCC0003u};
459 ListWindow win(0xDEAD, elements);
463 assert(win.tag() == 0xDEAD);
464 assert(win.items_count() == elements.size());
467 auto got = win.items_vector();
468 assert(got.size() == elements.size());
469 for (std::size_t i = 0; i < elements.size(); ++i)
470 assert(got[i] == elements[i]);
474 for (uint32_t v : win.items())
475 assert(v == elements[i++]);
478 assert(win.numSegments() == 3);
479 auto header_seg = win.segment(0);
480 auto data_seg = win.segment(1);
481 auto footer_seg = win.segment(2);
482 assert(data_seg.size == elements.size() *
sizeof(uint32_t));
486 assert(header_seg.size == 4);
487 assert(header_seg.data[0] == (
static_cast<uint8_t
>(elements.size()) & 0xFF));
488 assert(header_seg.data[1] == 0);
489 assert(header_seg.data[2] == 0xAD);
490 assert(header_seg.data[3] == 0xDE);
492 assert(footer_seg.size == 4);
493 assert(footer_seg.data[0] == 0);
494 assert(footer_seg.data[1] == 0);
506 std::vector<uint8_t> storage(bytes.begin(), bytes.end());
510 std::size_t need = (width + 7) / 8;
511 if (storage.size() < need)
512 storage.resize(need, 0);
516void testWideUnsigned() {
522 auto u96 = bvFromBytes(
524 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01,
525 0xBE, 0xBA, 0xFE, 0xCA,
528 auto u128 = bvFromBytes(
530 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
531 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
535 s.u96(u96).u128(u128);
538 auto got96 =
s.u96();
539 assert(got96.width() == 96);
540 for (std::size_t i = 0; i < 96; ++i)
541 assert(got96.getBit(i) == u96.getBit(i));
542 auto got128 =
s.u128();
543 assert(got128.width() == 128);
544 for (std::size_t i = 0; i < 128; ++i)
545 assert(got128.getBit(i) == u128.getBit(i));
548 std::array<uint8_t, 28> expected{
550 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
551 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
553 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01,
554 0xBE, 0xBA, 0xFE, 0xCA,
556 expectBytes(s, expected,
"WideU");
559 WideU cons(u96, u128);
560 assert(wireBytes(cons) == wireBytes(s));
563void testWideSigned() {
567 auto s96_zero = bvFromBytes({}, 96);
568 auto s128_neg_one = bvFromBytes(
570 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
571 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
574 s.s96(s96_zero).s128(s128_neg_one);
577 for (std::size_t i = 0; i < 128; ++i)
579 auto got96 =
s.s96();
580 for (std::size_t i = 0; i < 96; ++i)
584 std::array<uint8_t, 28> expected{};
585 for (std::size_t i = 0; i < 16; ++i)
587 expectBytes(s, expected,
"WideS s128=-1, s96=0");
590void testBitsField() {
595 auto wide = bvFromBytes(
597 0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBA, 0xBE,
598 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
603 auto got_wide = f.wide();
604 assert(got_wide.width() == 128);
605 for (std::size_t i = 0; i < 128; ++i)
606 assert(got_wide.getBit(i) == wide.getBit(i));
609void testWideMisaligned() {
614 auto payload = bvFromBytes(
616 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
617 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00,
620 m.tag(0b101).payload(payload);
623 auto got = m.payload();
624 assert(got.width() == 128);
625 for (std::size_t i = 0; i < 128; ++i)
626 assert(got.getBit(i) == payload.getBit(i));
630 auto got2 = m.payload();
631 for (std::size_t i = 0; i < 128; ++i)
632 assert(got2.getBit(i) == payload.getBit(i));
638 auto narrow = bvFromBytes({0xAA}, 8);
640 auto got3 = m.payload();
642 for (std::size_t i = 0; i < 8; ++i)
643 assert(got3.getBit(i) == ((0xAA >> i) & 1));
644 for (std::size_t i = 8; i < 128; ++i)
661void testArrayOfViewsAligned() {
663 std::array<esi::MutableBitVector, 3> source;
664 for (std::size_t i = 0; i < 3; ++i) {
665 source[i] = bvFromBytes(
667 static_cast<uint8_t
>(0x10 + i),
668 static_cast<uint8_t
>(0x20 + i),
669 static_cast<uint8_t
>(0x30 + i),
670 static_cast<uint8_t
>(0x40 + i),
671 static_cast<uint8_t
>(0x50 + i),
672 static_cast<uint8_t
>(0x60 + i),
673 static_cast<uint8_t
>(0x70 + i),
674 static_cast<uint8_t
>(0x80 + i),
675 static_cast<uint8_t
>(0x91 + i),
676 static_cast<uint8_t
>(0xA2 + i),
677 static_cast<uint8_t
>(0xB3 + i),
678 static_cast<uint8_t
>(0xC4 + i),
679 static_cast<uint8_t
>(0xD5 + i),
680 static_cast<uint8_t
>(0xE6 + i),
681 static_cast<uint8_t
>(0xF7 + i),
682 static_cast<uint8_t
>(0x08 + i),
685 a.items(i, source[i]);
687 for (std::size_t i = 0; i < 3; ++i) {
688 auto got = a.items(i);
689 assert(got.width() == 128);
690 for (std::size_t b = 0; b < 128; ++b)
691 assert(got.getBit(b) == source[i].getBit(b));
695 auto fresh = bvFromBytes({0xAA}, 128);
697 for (std::size_t b = 0; b < 128; ++b) {
698 assert(a.items(0).getBit(b) == source[0].getBit(b));
699 assert(a.items(2).getBit(b) == source[2].getBit(b));
705 auto range = a.items();
706 assert(std::ranges::size(range) == 3);
708 for (
auto view : range) {
709 assert(view.width() == 128);
710 for (std::size_t b = 0; b < 128; ++b)
711 assert(view.getBit(b) == a.items(i).getBit(b));
719 std::array<esi::UIntView, 3> bulk = {
724 ArrViews ctor_built(bulk);
725 for (std::size_t k = 0; k < 3; ++k) {
726 auto got = ctor_built.items(k);
727 for (std::size_t b = 0; b < 128; ++b)
728 assert(got.getBit(b) == source[k].getBit(b));
732 bulk_set.items(bulk);
733 for (std::size_t k = 0; k < 3; ++k) {
734 auto got = bulk_set.items(k);
735 for (std::size_t b = 0; b < 128; ++b)
736 assert(got.getBit(b) == source[k].getBit(b));
740void testArrayOfViewsMisaligned() {
748 std::array<esi::MutableBitVector, 3> source;
749 for (std::size_t i = 0; i < 3; ++i) {
750 source[i] = bvFromBytes(
752 static_cast<uint8_t
>(0xC0 + i),
753 static_cast<uint8_t
>(0xC1 + i),
754 static_cast<uint8_t
>(0xC2 + i),
755 static_cast<uint8_t
>(0xC3 + i),
756 static_cast<uint8_t
>(0xC4 + i),
757 static_cast<uint8_t
>(0xC5 + i),
758 static_cast<uint8_t
>(0xC6 + i),
759 static_cast<uint8_t
>(0xC7 + i),
760 static_cast<uint8_t
>(0xC8 + i),
761 static_cast<uint8_t
>(0xC9 + i),
762 static_cast<uint8_t
>(0xCA + i),
763 static_cast<uint8_t
>(0xCB + i),
764 static_cast<uint8_t
>(0xCC + i),
765 static_cast<uint8_t
>(0xCD + i),
766 static_cast<uint8_t
>(0xCE + i),
767 static_cast<uint8_t
>(0xCF + i),
770 m.items(i, source[i]);
773 for (std::size_t i = 0; i < 3; ++i) {
774 auto got = m.items(i);
775 assert(got.width() == 128);
776 for (std::size_t b = 0; b < 128; ++b)
777 assert(got.getBit(b) == source[i].getBit(b));
784#if defined(_MSC_VER) && defined(_DEBUG)
785 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
786 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
787 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
788 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
789 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
790 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
791 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
794 testStandardWidthUnsigned();
795 testStandardWidthSigned();
796 testByteAlignedOddWidthUnsigned();
797 testByteAlignedOddWidthSigned();
798 testSubByteUnsigned();
802 testNestedStructMisaligned();
803 testArrayOfIntegers();
804 testSubByteUnsignedArray();
805 testSubByteBoolArray();
806 testSubByteSignedArray();
808 testSubByteStructArray();
814 testWideMisaligned();
815 testArrayOfViewsAligned();
816 testArrayOfViewsMisaligned();
assert(baseType &&"element must be base type")
static InstancePath empty
A mutable bit vector that owns its underlying storage.
Non-owning view of an unsigned bit vector with toUI64() and implicit conversions to unsigned scalar t...