authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2024-03-28 14:03:45+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2024-03-28 15:24:01+02:00
log0588595128c4534e3a6bc207d446b66032d5720c
tree52319167c55c4de7e86e281ed02673744ba30ac6
parent2cdc48a6326f61c17947867ed9bf61cba606ce97

std.PackedInt: remove workaround for stage1 bug

Closes #7635

1 files changed, 53 insertions(+), 43 deletions(-)

lib/std/packed_int_array.zig+53-43
...@@ -66,32 +66,31 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: Endian) type {...@@ -66,32 +66,31 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: Endian) type {
6666
67 fn getBits(bytes: []const u8, comptime Container: type, bit_index: usize) Int {67 fn getBits(bytes: []const u8, comptime Container: type, bit_index: usize) Int {
68 const container_bits = @bitSizeOf(Container);68 const container_bits = @bitSizeOf(Container);
69 const Shift = std.math.Log2Int(Container);
7069
71 const start_byte = bit_index / 8;70 const start_byte = bit_index / 8;
72 const head_keep_bits = bit_index - (start_byte * 8);71 const head_keep_bits = bit_index - (start_byte * 8);
73 const tail_keep_bits = container_bits - (int_bits + head_keep_bits);72 const tail_keep_bits = container_bits - (int_bits + head_keep_bits);
7473
75 //read bytes as container74 //read bytes as container
76 const value_ptr = @as(*align(1) const Container, @ptrCast(&bytes[start_byte]));75 const value_ptr: *align(1) const Container = @ptrCast(&bytes[start_byte]);
77 var value = value_ptr.*;76 var value = value_ptr.*;
7877
79 if (endian != native_endian) value = @byteSwap(value);78 if (endian != native_endian) value = @byteSwap(value);
8079
81 switch (endian) {80 switch (endian) {
82 .big => {81 .big => {
83 value <<= @as(Shift, @intCast(head_keep_bits));82 value <<= @intCast(head_keep_bits);
84 value >>= @as(Shift, @intCast(head_keep_bits));83 value >>= @intCast(head_keep_bits);
85 value >>= @as(Shift, @intCast(tail_keep_bits));84 value >>= @intCast(tail_keep_bits);
86 },85 },
87 .little => {86 .little => {
88 value <<= @as(Shift, @intCast(tail_keep_bits));87 value <<= @intCast(tail_keep_bits);
89 value >>= @as(Shift, @intCast(tail_keep_bits));88 value >>= @intCast(tail_keep_bits);
90 value >>= @as(Shift, @intCast(head_keep_bits));89 value >>= @intCast(head_keep_bits);
91 },90 },
92 }91 }
9392
94 return @as(Int, @bitCast(@as(UnInt, @truncate(value))));93 return @bitCast(@as(UnInt, @truncate(value)));
95 }94 }
9695
97 /// Sets the integer at `index` to `val` within the packed data beginning96 /// Sets the integer at `index` to `val` within the packed data beginning
...@@ -114,16 +113,16 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: Endian) type {...@@ -114,16 +113,16 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: Endian) type {
114 const start_byte = bit_index / 8;113 const start_byte = bit_index / 8;
115 const head_keep_bits = bit_index - (start_byte * 8);114 const head_keep_bits = bit_index - (start_byte * 8);
116 const tail_keep_bits = container_bits - (int_bits + head_keep_bits);115 const tail_keep_bits = container_bits - (int_bits + head_keep_bits);
117 const keep_shift = switch (endian) {116 const keep_shift: Shift = switch (endian) {
118 .big => @as(Shift, @intCast(tail_keep_bits)),117 .big => @intCast(tail_keep_bits),
119 .little => @as(Shift, @intCast(head_keep_bits)),118 .little => @intCast(head_keep_bits),
120 };119 };
121120
122 //position the bits where they need to be in the container121 //position the bits where they need to be in the container
123 const value = @as(Container, @intCast(@as(UnInt, @bitCast(int)))) << keep_shift;122 const value = @as(Container, @intCast(@as(UnInt, @bitCast(int)))) << keep_shift;
124123
125 //read existing bytes124 //read existing bytes
126 const target_ptr = @as(*align(1) Container, @ptrCast(&bytes[start_byte]));125 const target_ptr: *align(1) Container = @ptrCast(&bytes[start_byte]);
127 var target = target_ptr.*;126 var target = target_ptr.*;
128127
129 if (endian != native_endian) target = @byteSwap(target);128 if (endian != native_endian) target = @byteSwap(target);
...@@ -156,7 +155,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: Endian) type {...@@ -156,7 +155,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: Endian) type {
156 if (length == 0) return PackedIntSliceEndian(Int, endian).init(new_bytes[0..0], 0);155 if (length == 0) return PackedIntSliceEndian(Int, endian).init(new_bytes[0..0], 0);
157156
158 var new_slice = PackedIntSliceEndian(Int, endian).init(new_bytes, length);157 var new_slice = PackedIntSliceEndian(Int, endian).init(new_bytes, length);
159 new_slice.bit_offset = @as(u3, @intCast((bit_index - (start_byte * 8))));158 new_slice.bit_offset = @intCast((bit_index - (start_byte * 8)));
160 return new_slice;159 return new_slice;
161 }160 }
162161
...@@ -214,15 +213,14 @@ pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: Endian, comptim...@@ -214,15 +213,14 @@ pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: Endian, comptim
214 /// Initialize a packed array using an unpacked array213 /// Initialize a packed array using an unpacked array
215 /// or, more likely, an array literal.214 /// or, more likely, an array literal.
216 pub fn init(ints: [int_count]Int) Self {215 pub fn init(ints: [int_count]Int) Self {
217 var self = @as(Self, undefined);216 var self: Self = undefined;
218 for (ints, 0..) |int, i| self.set(i, int);217 for (ints, 0..) |int, i| self.set(i, int);
219 return self;218 return self;
220 }219 }
221220
222 /// Initialize all entries of a packed array to the same value.221 /// Initialize all entries of a packed array to the same value.
223 pub fn initAllTo(int: Int) Self {222 pub fn initAllTo(int: Int) Self {
224 // TODO: use `var self = @as(Self, undefined);` https://github.com/ziglang/zig/issues/7635223 var self: Self = undefined;
225 var self = Self{ .bytes = [_]u8{0} ** total_bytes, .len = int_count };
226 self.setAll(int);224 self.setAll(int);
227 return self;225 return self;
228 }226 }
...@@ -365,11 +363,11 @@ test "PackedIntArray" {...@@ -365,11 +363,11 @@ test "PackedIntArray" {
365 const expected_bytes = ((bits * int_count) + 7) / 8;363 const expected_bytes = ((bits * int_count) + 7) / 8;
366 try testing.expect(@sizeOf(PackedArray) == expected_bytes);364 try testing.expect(@sizeOf(PackedArray) == expected_bytes);
367365
368 var data = @as(PackedArray, undefined);366 var data: PackedArray = undefined;
369367
370 //write values, counting up368 //write values, counting up
371 var i = @as(usize, 0);369 var i: usize = 0;
372 var count = @as(I, 0);370 var count: I = 0;
373 while (i < data.len) : (i += 1) {371 while (i < data.len) : (i += 1) {
374 data.set(i, count);372 data.set(i, count);
375 if (bits > 0) count +%= 1;373 if (bits > 0) count +%= 1;
...@@ -395,17 +393,29 @@ test "PackedIntIo" {...@@ -395,17 +393,29 @@ test "PackedIntIo" {
395}393}
396394
397test "PackedIntArray init" {395test "PackedIntArray init" {
398 const PackedArray = PackedIntArray(u3, 8);396 const S = struct {
399 var packed_array = PackedArray.init([_]u3{ 0, 1, 2, 3, 4, 5, 6, 7 });397 fn doTheTest() !void {
400 var i = @as(usize, 0);398 const PackedArray = PackedIntArray(u3, 8);
401 while (i < packed_array.len) : (i += 1) try testing.expectEqual(@as(u3, @intCast(i)), packed_array.get(i));399 var packed_array = PackedArray.init([_]u3{ 0, 1, 2, 3, 4, 5, 6, 7 });
400 var i: usize = 0;
401 while (i < packed_array.len) : (i += 1) try testing.expectEqual(@as(u3, @intCast(i)), packed_array.get(i));
402 }
403 };
404 try S.doTheTest();
405 try comptime S.doTheTest();
402}406}
403407
404test "PackedIntArray initAllTo" {408test "PackedIntArray initAllTo" {
405 const PackedArray = PackedIntArray(u3, 8);409 const S = struct {
406 var packed_array = PackedArray.initAllTo(5);410 fn doTheTest() !void {
407 var i = @as(usize, 0);411 const PackedArray = PackedIntArray(u3, 8);
408 while (i < packed_array.len) : (i += 1) try testing.expectEqual(@as(u3, 5), packed_array.get(i));412 var packed_array = PackedArray.initAllTo(5);
413 var i: usize = 0;
414 while (i < packed_array.len) : (i += 1) try testing.expectEqual(@as(u3, 5), packed_array.get(i));
415 }
416 };
417 try S.doTheTest();
418 try comptime S.doTheTest();
409}419}
410420
411test "PackedIntSlice" {421test "PackedIntSlice" {
...@@ -433,8 +443,8 @@ test "PackedIntSlice" {...@@ -433,8 +443,8 @@ test "PackedIntSlice" {
433 var data = P.init(&buffer, int_count);443 var data = P.init(&buffer, int_count);
434444
435 //write values, counting up445 //write values, counting up
436 var i = @as(usize, 0);446 var i: usize = 0;
437 var count = @as(I, 0);447 var count: I = 0;
438 while (i < data.len) : (i += 1) {448 while (i < data.len) : (i += 1) {
439 data.set(i, count);449 data.set(i, count);
440 if (bits > 0) count +%= 1;450 if (bits > 0) count +%= 1;
...@@ -463,13 +473,13 @@ test "PackedIntSlice of PackedInt(Array/Slice)" {...@@ -463,13 +473,13 @@ test "PackedIntSlice of PackedInt(Array/Slice)" {
463 const Int = std.meta.Int(.unsigned, bits);473 const Int = std.meta.Int(.unsigned, bits);
464474
465 const PackedArray = PackedIntArray(Int, int_count);475 const PackedArray = PackedIntArray(Int, int_count);
466 var packed_array = @as(PackedArray, undefined);476 var packed_array: PackedArray = undefined;
467477
468 const limit = (1 << bits);478 const limit = (1 << bits);
469479
470 var i = @as(usize, 0);480 var i: usize = 0;
471 while (i < packed_array.len) : (i += 1) {481 while (i < packed_array.len) : (i += 1) {
472 packed_array.set(i, @as(Int, @intCast(i % limit)));482 packed_array.set(i, @intCast(i % limit));
473 }483 }
474484
475 //slice of array485 //slice of array
...@@ -524,20 +534,20 @@ test "PackedIntSlice accumulating bit offsets" {...@@ -524,20 +534,20 @@ test "PackedIntSlice accumulating bit offsets" {
524 // anything534 // anything
525 {535 {
526 const PackedArray = PackedIntArray(u3, 16);536 const PackedArray = PackedIntArray(u3, 16);
527 var packed_array = @as(PackedArray, undefined);537 var packed_array: PackedArray = undefined;
528538
529 var packed_slice = packed_array.slice(0, packed_array.len);539 var packed_slice = packed_array.slice(0, packed_array.len);
530 var i = @as(usize, 0);540 var i: usize = 0;
531 while (i < packed_array.len - 1) : (i += 1) {541 while (i < packed_array.len - 1) : (i += 1) {
532 packed_slice = packed_slice.slice(1, packed_slice.len);542 packed_slice = packed_slice.slice(1, packed_slice.len);
533 }543 }
534 }544 }
535 {545 {
536 const PackedArray = PackedIntArray(u11, 88);546 const PackedArray = PackedIntArray(u11, 88);
537 var packed_array = @as(PackedArray, undefined);547 var packed_array: PackedArray = undefined;
538548
539 var packed_slice = packed_array.slice(0, packed_array.len);549 var packed_slice = packed_array.slice(0, packed_array.len);
540 var i = @as(usize, 0);550 var i: usize = 0;
541 while (i < packed_array.len - 1) : (i += 1) {551 while (i < packed_array.len - 1) : (i += 1) {
542 packed_slice = packed_slice.slice(1, packed_slice.len);552 packed_slice = packed_slice.slice(1, packed_slice.len);
543 }553 }
...@@ -552,7 +562,7 @@ test "PackedInt(Array/Slice) sliceCast" {...@@ -552,7 +562,7 @@ test "PackedInt(Array/Slice) sliceCast" {
552 var packed_slice_cast_9 = packed_array.slice(0, (packed_array.len / 9) * 9).sliceCast(u9);562 var packed_slice_cast_9 = packed_array.slice(0, (packed_array.len / 9) * 9).sliceCast(u9);
553 const packed_slice_cast_3 = packed_slice_cast_9.sliceCast(u3);563 const packed_slice_cast_3 = packed_slice_cast_9.sliceCast(u3);
554564
555 var i = @as(usize, 0);565 var i: usize = 0;
556 while (i < packed_slice_cast_2.len) : (i += 1) {566 while (i < packed_slice_cast_2.len) : (i += 1) {
557 const val = switch (native_endian) {567 const val = switch (native_endian) {
558 .big => 0b01,568 .big => 0b01,
...@@ -576,9 +586,9 @@ test "PackedInt(Array/Slice) sliceCast" {...@@ -576,9 +586,9 @@ test "PackedInt(Array/Slice) sliceCast" {
576 }586 }
577 i = 0;587 i = 0;
578 while (i < packed_slice_cast_3.len) : (i += 1) {588 while (i < packed_slice_cast_3.len) : (i += 1) {
579 const val = switch (native_endian) {589 const val: u3 = switch (native_endian) {
580 .big => if (i % 2 == 0) @as(u3, 0b111) else @as(u3, 0b000),590 .big => if (i % 2 == 0) 0b111 else 0b000,
581 .little => if (i % 2 == 0) @as(u3, 0b111) else @as(u3, 0b000),591 .little => if (i % 2 == 0) 0b111 else 0b000,
582 };592 };
583 try testing.expect(packed_slice_cast_3.get(i) == val);593 try testing.expect(packed_slice_cast_3.get(i) == val);
584 }594 }
...@@ -591,7 +601,7 @@ test "PackedInt(Array/Slice)Endian" {...@@ -591,7 +601,7 @@ test "PackedInt(Array/Slice)Endian" {
591 try testing.expect(packed_array_be.bytes[0] == 0b00000001);601 try testing.expect(packed_array_be.bytes[0] == 0b00000001);
592 try testing.expect(packed_array_be.bytes[1] == 0b00100011);602 try testing.expect(packed_array_be.bytes[1] == 0b00100011);
593603
594 var i = @as(usize, 0);604 var i: usize = 0;
595 while (i < packed_array_be.len) : (i += 1) {605 while (i < packed_array_be.len) : (i += 1) {
596 try testing.expect(packed_array_be.get(i) == i);606 try testing.expect(packed_array_be.get(i) == i);
597 }607 }
...@@ -620,7 +630,7 @@ test "PackedInt(Array/Slice)Endian" {...@@ -620,7 +630,7 @@ test "PackedInt(Array/Slice)Endian" {
620 try testing.expect(packed_array_be.bytes[3] == 0b00000001);630 try testing.expect(packed_array_be.bytes[3] == 0b00000001);
621 try testing.expect(packed_array_be.bytes[4] == 0b00000000);631 try testing.expect(packed_array_be.bytes[4] == 0b00000000);
622632
623 var i = @as(usize, 0);633 var i: usize = 0;
624 while (i < packed_array_be.len) : (i += 1) {634 while (i < packed_array_be.len) : (i += 1) {
625 try testing.expect(packed_array_be.get(i) == i);635 try testing.expect(packed_array_be.get(i) == i);
626 }636 }