@zigc/lib 0.17.0-dev.315 → 0.17.0-dev.329
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compiler/aro/aro/Preprocessor.zig +2 -2
- package/compiler/aro/backend/Ir/x86/Renderer.zig +3 -3
- package/compiler_rt/float_from_int.zig +1 -1
- package/compiler_rt/int_from_float.zig +1 -1
- package/package.json +1 -1
- package/std/Io/RwLock.zig +2 -0
- package/std/Io/Threaded.zig +1 -1
- package/std/Io/Writer.zig +51 -6
- package/std/ascii.zig +0 -9
- package/std/bit_set.zig +0 -24
- package/std/enums.zig +0 -12
- package/std/math/acos.zig +2 -0
- package/std/math/asin.zig +2 -0
- package/std/mem.zig +9 -38
- package/std/testing.zig +61 -0
|
@@ -45,11 +45,11 @@ const IfContext = struct {
|
|
|
45
45
|
level: u8,
|
|
46
46
|
|
|
47
47
|
fn get(self: *const IfContext) Nesting {
|
|
48
|
-
return @enumFromInt(std.mem.
|
|
48
|
+
return @enumFromInt(std.mem.readPackedInt(Backing, &self.kind, @as(usize, self.level) * 2, .native));
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
fn set(self: *IfContext, context: Nesting) void {
|
|
52
|
-
std.mem.
|
|
52
|
+
std.mem.writePackedInt(Backing, &self.kind, @as(usize, self.level) * 2, @intFromEnum(context), .native);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
fn increment(self: *IfContext) bool {
|
|
@@ -21,17 +21,17 @@ const RegisterManager = zig.RegisterManager(Renderer, Register, Ir.Ref, abi.allo
|
|
|
21
21
|
const RegisterBitSet = RegisterManager.RegisterBitSet;
|
|
22
22
|
const RegisterClass = struct {
|
|
23
23
|
const gp: RegisterBitSet = blk: {
|
|
24
|
-
var set =
|
|
24
|
+
var set: RegisterBitSet = .empty;
|
|
25
25
|
for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .general_purpose) set.set(index);
|
|
26
26
|
break :blk set;
|
|
27
27
|
};
|
|
28
28
|
const x87: RegisterBitSet = blk: {
|
|
29
|
-
var set =
|
|
29
|
+
var set: RegisterBitSet = .empty;
|
|
30
30
|
for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .x87) set.set(index);
|
|
31
31
|
break :blk set;
|
|
32
32
|
};
|
|
33
33
|
const sse: RegisterBitSet = blk: {
|
|
34
|
-
var set =
|
|
34
|
+
var set: RegisterBitSet = .empty;
|
|
35
35
|
for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .sse) set.set(index);
|
|
36
36
|
break :blk set;
|
|
37
37
|
};
|
|
@@ -97,7 +97,7 @@ pub inline fn floatFromBigInt(comptime T: type, comptime signedness: std.builtin
|
|
|
97
97
|
if (limb(x, limb_index) != 0) break true;
|
|
98
98
|
} else limb(x, exponent_limb) & ((@as(u32, 1) << @truncate(exponent)) - 1) != 0;
|
|
99
99
|
return math.ldexp(@as(T, @floatFromInt(
|
|
100
|
-
std.mem.
|
|
100
|
+
std.mem.readPackedInt(I, std.mem.sliceAsBytes(x), exponent, .native) | @intFromBool(sticky),
|
|
101
101
|
)), @intCast(exponent));
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -141,7 +141,7 @@ pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, resul
|
|
|
141
141
|
},
|
|
142
142
|
.unsigned => @memset(result, 0),
|
|
143
143
|
}
|
|
144
|
-
std.mem.
|
|
144
|
+
std.mem.writePackedInt(I, std.mem.sliceAsBytes(result), exponent, int, .native);
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
test {
|
package/package.json
CHANGED
package/std/Io/RwLock.zig
CHANGED
|
@@ -284,6 +284,8 @@ test "concurrent access" {
|
|
|
284
284
|
}
|
|
285
285
|
|
|
286
286
|
test "lock canceling" {
|
|
287
|
+
if (builtin.cpu.arch.isSPARC() and builtin.os.tag == .linux) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35347
|
|
288
|
+
|
|
287
289
|
const io = testing.io;
|
|
288
290
|
|
|
289
291
|
var rl: Io.RwLock = .init;
|
package/std/Io/Threaded.zig
CHANGED
|
@@ -14401,7 +14401,7 @@ pub fn setTimestampToPosix(set_ts: File.SetTimestamp) posix.timespec {
|
|
|
14401
14401
|
}
|
|
14402
14402
|
|
|
14403
14403
|
pub fn pathToPosix(file_path: []const u8, buffer: *[posix.PATH_MAX]u8) Dir.PathNameError![:0]u8 {
|
|
14404
|
-
if (std.mem.
|
|
14404
|
+
if (std.mem.containsAtLeastScalar(u8, file_path, 0, 1)) return error.BadPathName;
|
|
14405
14405
|
// >= rather than > to make room for the null byte
|
|
14406
14406
|
if (file_path.len >= buffer.len) return error.NameTooLong;
|
|
14407
14407
|
@memcpy(buffer[0..file_path.len], file_path);
|
package/std/Io/Writer.zig
CHANGED
|
@@ -802,12 +802,14 @@ pub fn splatBytePreserve(w: *Writer, preserve: usize, byte: u8, n: usize) Error!
|
|
|
802
802
|
return;
|
|
803
803
|
}
|
|
804
804
|
}
|
|
805
|
-
//
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
805
|
+
// Ensure the contract of `rebase` is upheld.
|
|
806
|
+
assert(w.end + remaining > w.buffer.len);
|
|
807
|
+
// Offset the amount preserved by the amount we have left to splat
|
|
808
|
+
// since the remaining splat is always going to be part of that
|
|
809
|
+
// preservation.
|
|
810
|
+
try w.vtable.rebase(w, preserve -| remaining, remaining);
|
|
811
|
+
@memset(w.buffer[w.end..][0..remaining], byte);
|
|
812
|
+
w.end += remaining;
|
|
811
813
|
}
|
|
812
814
|
|
|
813
815
|
/// Writes the same byte many times, allowing short writes.
|
|
@@ -2887,3 +2889,46 @@ test "writableSlice with fixed writer" {
|
|
|
2887
2889
|
try w.writeByte(1);
|
|
2888
2890
|
try std.testing.expectError(error.WriteFailed, w.writableSlice(2));
|
|
2889
2891
|
}
|
|
2892
|
+
|
|
2893
|
+
test splatBytePreserve {
|
|
2894
|
+
try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 5, .splat_len = 5 });
|
|
2895
|
+
try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 9, .preserve = 5, .splat_len = 2 });
|
|
2896
|
+
try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 5, .splat_len = 6 });
|
|
2897
|
+
try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 6, .splat_len = 6 });
|
|
2898
|
+
try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 5, .splat_len = 10 });
|
|
2899
|
+
try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 6, .splat_len = 10 });
|
|
2900
|
+
try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 6, .splat_len = 11 });
|
|
2901
|
+
try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 6, .splat_len = 80 });
|
|
2902
|
+
try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 6, .splat_len = 85 });
|
|
2903
|
+
try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 10, .splat_len = 6 });
|
|
2904
|
+
try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 10, .splat_len = 11 });
|
|
2905
|
+
try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 10, .splat_len = 80 });
|
|
2906
|
+
try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 10, .splat_len = 85 });
|
|
2907
|
+
}
|
|
2908
|
+
|
|
2909
|
+
fn testSplatBytePreserve(options: struct { buf_len: u4, fill_len: u4, preserve: u4, splat_len: u8 }) !void {
|
|
2910
|
+
assert(options.fill_len <= options.buf_len);
|
|
2911
|
+
assert(options.preserve <= options.buf_len);
|
|
2912
|
+
|
|
2913
|
+
const fill_buf = "abcdefghijklmno";
|
|
2914
|
+
const fill = fill_buf[0..options.fill_len];
|
|
2915
|
+
var expected_out_buf: [256]u8 = @splat('X');
|
|
2916
|
+
@memcpy(expected_out_buf[0..options.fill_len], fill);
|
|
2917
|
+
const expected_out = expected_out_buf[0 .. options.fill_len + options.splat_len];
|
|
2918
|
+
const expected_preserved = expected_out[expected_out.len -| options.preserve..];
|
|
2919
|
+
|
|
2920
|
+
var out_buf: [256]u8 = undefined;
|
|
2921
|
+
var fw: Writer = .fixed(&out_buf);
|
|
2922
|
+
var indirect_buffer: [16]u8 = undefined;
|
|
2923
|
+
var twi: std.testing.WriterIndirect = .init(&fw, indirect_buffer[0..options.buf_len]);
|
|
2924
|
+
const w = &twi.interface;
|
|
2925
|
+
|
|
2926
|
+
try w.writeAll(fill);
|
|
2927
|
+
try w.splatBytePreserve(options.preserve, 'X', options.splat_len);
|
|
2928
|
+
|
|
2929
|
+
try std.testing.expectEqualStrings(expected_preserved, w.buffer[w.end -| options.preserve..w.end]);
|
|
2930
|
+
|
|
2931
|
+
try w.flush();
|
|
2932
|
+
|
|
2933
|
+
try std.testing.expectEqualStrings(expected_out, fw.buffer[0..fw.end]);
|
|
2934
|
+
}
|
package/std/ascii.zig
CHANGED
|
@@ -378,17 +378,11 @@ test endsWithIgnoreCase {
|
|
|
378
378
|
try std.testing.expect(!endsWithIgnoreCase("BoB", "Bo"));
|
|
379
379
|
}
|
|
380
380
|
|
|
381
|
-
/// Deprecated in favor of `findIgnoreCase`.
|
|
382
|
-
pub const indexOfIgnoreCase = findIgnoreCase;
|
|
383
|
-
|
|
384
381
|
/// Finds `needle` in `haystack`, ignoring case, starting at index 0.
|
|
385
382
|
pub fn findIgnoreCase(haystack: []const u8, needle: []const u8) ?usize {
|
|
386
383
|
return findIgnoreCasePos(haystack, 0, needle);
|
|
387
384
|
}
|
|
388
385
|
|
|
389
|
-
/// Deprecated in favor of `findIgnoreCasePos`.
|
|
390
|
-
pub const indexOfIgnoreCasePos = findIgnoreCasePos;
|
|
391
|
-
|
|
392
386
|
/// Finds `needle` in `haystack`, ignoring case, starting at `start_index`.
|
|
393
387
|
/// Uses Boyer-Moore-Horspool algorithm on large inputs; `findIgnoreCasePosLinear` on small inputs.
|
|
394
388
|
pub fn findIgnoreCasePos(haystack: []const u8, start_index: usize, needle: []const u8) ?usize {
|
|
@@ -410,9 +404,6 @@ pub fn findIgnoreCasePos(haystack: []const u8, start_index: usize, needle: []con
|
|
|
410
404
|
return null;
|
|
411
405
|
}
|
|
412
406
|
|
|
413
|
-
/// Deprecated in favor of `findIgnoreCaseLinear`.
|
|
414
|
-
pub const indexOfIgnoreCasePosLinear = findIgnoreCasePosLinear;
|
|
415
|
-
|
|
416
407
|
/// Consider using `findIgnoreCasePos` instead of this, which will automatically use a
|
|
417
408
|
/// more sophisticated algorithm on larger inputs.
|
|
418
409
|
pub fn findIgnoreCasePosLinear(haystack: []const u8, start_index: usize, needle: []const u8) ?usize {
|
package/std/bit_set.zig
CHANGED
|
@@ -73,18 +73,6 @@ pub fn Integer(comptime size: u16) type {
|
|
|
73
73
|
/// The bit mask, as a single integer
|
|
74
74
|
mask: MaskInt,
|
|
75
75
|
|
|
76
|
-
/// Deprecated: use `.empty`.
|
|
77
|
-
/// Creates a bit set with no elements present.
|
|
78
|
-
pub fn initEmpty() Self {
|
|
79
|
-
return .{ .mask = 0 };
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/// Deprecated: use `.full`.
|
|
83
|
-
/// Creates a bit set with all elements present.
|
|
84
|
-
pub fn initFull() Self {
|
|
85
|
-
return .{ .mask = ~@as(MaskInt, 0) };
|
|
86
|
-
}
|
|
87
|
-
|
|
88
76
|
/// A bit set with no elements present.
|
|
89
77
|
pub const empty: Self = .{ .mask = 0 };
|
|
90
78
|
|
|
@@ -403,18 +391,6 @@ pub fn Array(comptime MaskIntType: type, comptime size: usize) type {
|
|
|
403
391
|
/// Padding bits at the end are undefined.
|
|
404
392
|
masks: [num_masks]MaskInt,
|
|
405
393
|
|
|
406
|
-
/// Deprecated: use `.empty`.
|
|
407
|
-
/// Creates a bit set with no elements present.
|
|
408
|
-
pub fn initEmpty() Self {
|
|
409
|
-
return .empty;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
/// Deprecated: use `.full`.
|
|
413
|
-
/// Creates a bit set with all elements present.
|
|
414
|
-
pub fn initFull() Self {
|
|
415
|
-
return .full;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
394
|
/// A bit set with no elements present.
|
|
419
395
|
pub const empty: Self = .{ .masks = @splat(0) };
|
|
420
396
|
|
package/std/enums.zig
CHANGED
|
@@ -284,18 +284,6 @@ pub fn EnumSet(comptime E: type) type {
|
|
|
284
284
|
/// A set containing all possible keys.
|
|
285
285
|
pub const full: Self = .{ .bits = .full };
|
|
286
286
|
|
|
287
|
-
/// Deprecated: use `.empty`.
|
|
288
|
-
/// Returns a set containing no keys.
|
|
289
|
-
pub fn initEmpty() Self {
|
|
290
|
-
return .empty;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/// Deprecated: use `.full`.
|
|
294
|
-
/// Returns a set containing all possible keys.
|
|
295
|
-
pub fn initFull() Self {
|
|
296
|
-
return .full;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
287
|
/// Returns a set containing multiple keys.
|
|
300
288
|
pub fn initMany(keys: []const Key) Self {
|
|
301
289
|
var set: Self = .empty;
|
package/std/math/acos.zig
CHANGED
|
@@ -448,6 +448,8 @@ test "acosBinary128.special" {
|
|
|
448
448
|
}
|
|
449
449
|
|
|
450
450
|
test "acosBinary128" {
|
|
451
|
+
if (builtin.cpu.arch.isSPARC()) return error.SkipZigTest;
|
|
452
|
+
|
|
451
453
|
try testing.expectApproxEqAbs(0x1.250e9a58f049eeafa99db4360c88p1, acosBinary128(-0x1.511bdb99a3c4373bedf834ef4f68p-1), math.floatEpsAt(f128, 0x1.250e9a58f049eeafa99db4360c88p1));
|
|
452
454
|
try testing.expectApproxEqAbs(0x1.2786664b1c676c99437b68590004p1, acosBinary128(-0x1.5879cc3ad6dfd2a52e9891c69808p-1), math.floatEpsAt(f128, 0x1.2786664b1c676c99437b68590004p1));
|
|
453
455
|
try testing.expectApproxEqAbs(0x1.cb190cd361c7c03a09c470b4caebp-1, acosBinary128(0x1.3f988ba64a7eb97a751c5f0b3077p-1), math.floatEpsAt(f128, 0x1.cb190cd361c7c03a09c470b4caebp-1));
|
package/std/math/asin.zig
CHANGED
|
@@ -442,6 +442,8 @@ test "asinBinary128.special" {
|
|
|
442
442
|
}
|
|
443
443
|
|
|
444
444
|
test "asinBinary128" {
|
|
445
|
+
if (builtin.cpu.arch.isSPARC()) return error.SkipZigTest;
|
|
446
|
+
|
|
445
447
|
try testing.expectApproxEqAbs(0x1.87e9c740d7837f8e8fa667988fbep-3, asinBinary128(0x1.85868ce287ca0196b01c25fec5ffp-3), math.floatEpsAt(f128, 0x1.87e9c740d7837f8e8fa667988fbep-3));
|
|
446
448
|
try testing.expectApproxEqAbs(0x1.bd11a474e864213b48e0f005f1f4p-1, asinBinary128(0x1.8718d6d30b4daed08d04ef59f478p-1), math.floatEpsAt(f128, 0x1.bd11a474e864213b48e0f005f1f4p-1));
|
|
447
449
|
try testing.expectApproxEqAbs(0x1.20b56f8b42649fe72d1f8d68a378p-1, asinBinary128(0x1.11a67640cd7f0ba5d5e362f3abfap-1), math.floatEpsAt(f128, 0x1.20b56f8b42649fe72d1f8d68a378p-1));
|
package/std/mem.zig
CHANGED
|
@@ -1691,7 +1691,7 @@ test countScalar {
|
|
|
1691
1691
|
//
|
|
1692
1692
|
/// See also: `containsAtLeastScalar`
|
|
1693
1693
|
pub fn containsAtLeast(comptime T: type, haystack: []const T, expected_count: usize, needle: []const T) bool {
|
|
1694
|
-
if (needle.len == 1) return containsAtLeastScalar(T, haystack,
|
|
1694
|
+
if (needle.len == 1) return containsAtLeastScalar(T, haystack, needle[0], expected_count);
|
|
1695
1695
|
assert(needle.len > 0);
|
|
1696
1696
|
if (expected_count == 0) return true;
|
|
1697
1697
|
|
|
@@ -1722,17 +1722,12 @@ test containsAtLeast {
|
|
|
1722
1722
|
try testing.expect(!containsAtLeast(u8, " radar radar ", 3, "radar"));
|
|
1723
1723
|
}
|
|
1724
1724
|
|
|
1725
|
-
/// Deprecated in favor of `containsAtLeastScalar2`.
|
|
1726
|
-
pub fn containsAtLeastScalar(comptime T: type, list: []const T, minimum: usize, element: T) bool {
|
|
1727
|
-
return containsAtLeastScalar2(T, list, element, minimum);
|
|
1728
|
-
}
|
|
1729
|
-
|
|
1730
1725
|
/// Returns true if `element` appears at least `minimum` number of times in `list`.
|
|
1731
1726
|
//
|
|
1732
1727
|
/// Related:
|
|
1733
1728
|
/// * `containsAtLeast`
|
|
1734
1729
|
/// * `countScalar`
|
|
1735
|
-
pub fn
|
|
1730
|
+
pub fn containsAtLeastScalar(comptime T: type, list: []const T, element: T, minimum: usize) bool {
|
|
1736
1731
|
const n = list.len;
|
|
1737
1732
|
var i: usize = 0;
|
|
1738
1733
|
var found: usize = 0;
|
|
@@ -1760,14 +1755,14 @@ pub fn containsAtLeastScalar2(comptime T: type, list: []const T, element: T, min
|
|
|
1760
1755
|
return false;
|
|
1761
1756
|
}
|
|
1762
1757
|
|
|
1763
|
-
test
|
|
1764
|
-
try testing.expect(
|
|
1765
|
-
try testing.expect(
|
|
1766
|
-
try testing.expect(
|
|
1767
|
-
try testing.expect(!
|
|
1758
|
+
test containsAtLeastScalar {
|
|
1759
|
+
try testing.expect(containsAtLeastScalar(u8, "aa", 'a', 0));
|
|
1760
|
+
try testing.expect(containsAtLeastScalar(u8, "aa", 'a', 1));
|
|
1761
|
+
try testing.expect(containsAtLeastScalar(u8, "aa", 'a', 2));
|
|
1762
|
+
try testing.expect(!containsAtLeastScalar(u8, "aa", 'a', 3));
|
|
1768
1763
|
|
|
1769
|
-
try testing.expect(
|
|
1770
|
-
try testing.expect(!
|
|
1764
|
+
try testing.expect(containsAtLeastScalar(u8, "adadda", 'd', 3));
|
|
1765
|
+
try testing.expect(!containsAtLeastScalar(u8, "adadda", 'd', 4));
|
|
1771
1766
|
}
|
|
1772
1767
|
|
|
1773
1768
|
/// Reads an integer from memory with size equal to bytes.len.
|
|
@@ -1973,18 +1968,6 @@ fn readPackedIntBig(comptime T: type, bytes: []const u8, bit_offset: usize) T {
|
|
|
1973
1968
|
} else return @as(T, @bitCast(val));
|
|
1974
1969
|
}
|
|
1975
1970
|
|
|
1976
|
-
/// Deprecated: use readPackedInt(T, bytes, bit_offset, value, .native)
|
|
1977
|
-
pub const readPackedIntNative = switch (native_endian) {
|
|
1978
|
-
.little => readPackedIntLittle,
|
|
1979
|
-
.big => readPackedIntBig,
|
|
1980
|
-
};
|
|
1981
|
-
|
|
1982
|
-
/// Deprecated: use readPackedInt(T, bytes, bit_offset, value, .foreign)
|
|
1983
|
-
pub const readPackedIntForeign = switch (native_endian) {
|
|
1984
|
-
.little => readPackedIntBig,
|
|
1985
|
-
.big => readPackedIntLittle,
|
|
1986
|
-
};
|
|
1987
|
-
|
|
1988
1971
|
/// Loads an integer from packed memory.
|
|
1989
1972
|
/// Asserts that buffer contains at least bit_offset + @bitSizeOf(T) bits.
|
|
1990
1973
|
pub fn readPackedInt(comptime T: type, bytes: []const u8, bit_offset: usize, endian: Endian) T {
|
|
@@ -2128,18 +2111,6 @@ fn writePackedIntBig(comptime T: type, bytes: []u8, bit_offset: usize, value: T)
|
|
|
2128
2111
|
writeInt(StoreInt, write_bytes[(byte_count - store_size)..][0..store_size], write_value, .big);
|
|
2129
2112
|
}
|
|
2130
2113
|
|
|
2131
|
-
/// Deprecated: use writePackedInt(T, bytes, bit_offset, value, .native)
|
|
2132
|
-
pub const writePackedIntNative = switch (native_endian) {
|
|
2133
|
-
.little => writePackedIntLittle,
|
|
2134
|
-
.big => writePackedIntBig,
|
|
2135
|
-
};
|
|
2136
|
-
|
|
2137
|
-
/// Deprecated: use writePackedInt(T, bytes, bit_offset, value, .foreign)
|
|
2138
|
-
pub const writePackedIntForeign = switch (native_endian) {
|
|
2139
|
-
.little => writePackedIntBig,
|
|
2140
|
-
.big => writePackedIntLittle,
|
|
2141
|
-
};
|
|
2142
|
-
|
|
2143
2114
|
/// Stores an integer to packed memory.
|
|
2144
2115
|
/// Asserts that buffer contains at least bit_offset + @bitSizeOf(T) bits.
|
|
2145
2116
|
pub fn writePackedInt(comptime T: type, bytes: []u8, bit_offset: usize, value: T, endian: Endian) void {
|
package/std/testing.zig
CHANGED
|
@@ -1334,6 +1334,67 @@ pub const ReaderIndirect = struct {
|
|
|
1334
1334
|
}
|
|
1335
1335
|
};
|
|
1336
1336
|
|
|
1337
|
+
/// A `Io.Writer` that writes its data to another `Io.Writer`, and only
|
|
1338
|
+
/// writes new data to its own buffer during `drain`.
|
|
1339
|
+
pub const WriterIndirect = struct {
|
|
1340
|
+
out: *Io.Writer,
|
|
1341
|
+
interface: Io.Writer,
|
|
1342
|
+
|
|
1343
|
+
pub fn init(out: *Io.Writer, buffer: []u8) WriterIndirect {
|
|
1344
|
+
return .{
|
|
1345
|
+
.out = out,
|
|
1346
|
+
.interface = .{
|
|
1347
|
+
.vtable = &.{
|
|
1348
|
+
.drain = drain,
|
|
1349
|
+
},
|
|
1350
|
+
.buffer = buffer,
|
|
1351
|
+
.end = 0,
|
|
1352
|
+
},
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
fn drain(w: *Io.Writer, data: []const []const u8, splat: usize) std.Io.Writer.Error!usize {
|
|
1357
|
+
const w_indirect: *WriterIndirect = @alignCast(@fieldParentPtr("interface", w));
|
|
1358
|
+
|
|
1359
|
+
// Write all data in the buffer to `out`
|
|
1360
|
+
try w_indirect.out.writeAll(w.buffer[0..w.end]);
|
|
1361
|
+
w.end = 0;
|
|
1362
|
+
|
|
1363
|
+
// Refill buffer using data
|
|
1364
|
+
{
|
|
1365
|
+
const end_before_fill = w.end;
|
|
1366
|
+
for (data[0 .. data.len - 1]) |bytes| {
|
|
1367
|
+
const dest = w.buffer[w.end..];
|
|
1368
|
+
const len = @min(bytes.len, dest.len);
|
|
1369
|
+
@memcpy(dest[0..len], bytes[0..len]);
|
|
1370
|
+
w.end += len;
|
|
1371
|
+
}
|
|
1372
|
+
const pattern = data[data.len - 1];
|
|
1373
|
+
switch (pattern.len) {
|
|
1374
|
+
0 => {},
|
|
1375
|
+
1 => {
|
|
1376
|
+
const len = @min(w.buffer[w.end..].len, splat);
|
|
1377
|
+
@memset(w.buffer[w.end..][0..len], pattern[0]);
|
|
1378
|
+
w.end += len;
|
|
1379
|
+
},
|
|
1380
|
+
else => {
|
|
1381
|
+
const dest = w.buffer[w.end..];
|
|
1382
|
+
for (0..splat) |i| {
|
|
1383
|
+
const start_i = i * pattern.len;
|
|
1384
|
+
if (start_i >= dest.len) break;
|
|
1385
|
+
const remaining = dest[start_i..];
|
|
1386
|
+
const len = @min(pattern.len, remaining.len);
|
|
1387
|
+
@memcpy(remaining[0..len], pattern[0..len]);
|
|
1388
|
+
w.end += len;
|
|
1389
|
+
}
|
|
1390
|
+
},
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
return w.end - end_before_fill;
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
};
|
|
1397
|
+
|
|
1337
1398
|
test {
|
|
1338
1399
|
_ = &Smith;
|
|
1339
1400
|
}
|