-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
de: Add support for std.IntegerBitSet
- Loading branch information
Jason Phan
committed
Feb 4, 2023
1 parent
5d5ba25
commit 8ac2162
Showing
4 changed files
with
191 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
const std = @import("std"); | ||
|
||
const IntegerBitSetVisitor = @import("../impls/visitor/integer_bit_set.zig").Visitor; | ||
const testing = @import("../testing.zig"); | ||
|
||
const Self = @This(); | ||
|
||
/// Specifies all types that can be deserialized by this block. | ||
pub fn is( | ||
/// The type being deserialized into. | ||
comptime T: type, | ||
) bool { | ||
return comptime std.mem.startsWith(u8, @typeName(T), "bit_set.IntegerBitSet"); | ||
} | ||
|
||
/// Specifies the deserialization process for types relevant to this block. | ||
pub fn deserialize( | ||
/// An optional memory allocator. | ||
allocator: ?std.mem.Allocator, | ||
/// The type being deserialized into. | ||
comptime T: type, | ||
/// A `getty.Deserializer` interface value. | ||
deserializer: anytype, | ||
/// A `getty.de.Visitor` interface value. | ||
visitor: anytype, | ||
) !@TypeOf(visitor).Value { | ||
_ = T; | ||
|
||
return try deserializer.deserializeSeq(allocator, visitor); | ||
} | ||
|
||
/// Returns a type that implements `getty.de.Visitor`. | ||
pub fn Visitor( | ||
/// The type being deserialized into. | ||
comptime T: type, | ||
) type { | ||
return IntegerBitSetVisitor(T); | ||
} | ||
|
||
test "deserialize - std.IntegerBitSet" { | ||
const tests = .{ | ||
.{ | ||
.name = "zero-sized", | ||
.tokens = &.{ | ||
.{ .Seq = .{ .len = 0 } }, | ||
.{ .SeqEnd = {} }, | ||
}, | ||
.want = std.StaticBitSet(0).initEmpty(), | ||
}, | ||
.{ | ||
.name = "empty", | ||
.tokens = &.{ | ||
.{ .Seq = .{ .len = 3 } }, | ||
.{ .I32 = 0 }, | ||
.{ .I32 = 0 }, | ||
.{ .I32 = 0 }, | ||
.{ .SeqEnd = {} }, | ||
}, | ||
.want = std.StaticBitSet(3).initEmpty(), | ||
}, | ||
.{ | ||
.name = "full", | ||
.tokens = &.{ | ||
.{ .Seq = .{ .len = 3 } }, | ||
.{ .I32 = 1 }, | ||
.{ .I32 = 1 }, | ||
.{ .I32 = 1 }, | ||
.{ .SeqEnd = {} }, | ||
}, | ||
.want = std.StaticBitSet(3).initFull(), | ||
}, | ||
.{ | ||
.name = "mixed (I)", | ||
.tokens = &.{ | ||
.{ .Seq = .{ .len = 5 } }, | ||
.{ .I32 = 1 }, | ||
.{ .I32 = 1 }, | ||
.{ .I32 = 0 }, | ||
.{ .I32 = 1 }, | ||
.{ .I32 = 0 }, | ||
.{ .SeqEnd = {} }, | ||
}, | ||
.want = blk: { | ||
var want = std.StaticBitSet(5).initEmpty(); | ||
want.set(1); | ||
want.set(3); | ||
want.set(4); | ||
break :blk want; | ||
}, | ||
}, | ||
.{ | ||
.name = "mixed (I*)", | ||
.tokens = &.{ | ||
.{ .Seq = .{ .len = 5 } }, | ||
.{ .I32 = 1 }, | ||
.{ .I32 = 0 }, | ||
.{ .I32 = 0 }, | ||
.{ .I32 = 1 }, | ||
.{ .I32 = 1 }, | ||
.{ .SeqEnd = {} }, | ||
}, | ||
.want = blk: { | ||
var want = std.StaticBitSet(5).initEmpty(); | ||
want.set(0); | ||
want.set(1); | ||
want.set(4); | ||
break :blk want; | ||
}, | ||
}, | ||
}; | ||
|
||
inline for (tests) |t| { | ||
const Want = @TypeOf(t.want); | ||
const got = try testing.deserialize(null, t.name, Self, Want, t.tokens); | ||
try testing.expectEqual(t.name, t.want, got); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
const std = @import("std"); | ||
|
||
const free = @import("../../free.zig").free; | ||
const Ignored = @import("../../impls/seed/ignored.zig").Ignored; | ||
const VisitorInterface = @import("../../interfaces/visitor.zig").Visitor; | ||
|
||
pub fn Visitor(comptime IntegerBitSet: type) type { | ||
return struct { | ||
const Self = @This(); | ||
|
||
pub usingnamespace VisitorInterface( | ||
Self, | ||
Value, | ||
.{ | ||
.visitSeq = visitSeq, | ||
}, | ||
); | ||
|
||
const Value = IntegerBitSet; | ||
|
||
fn visitSeq(_: Self, allocator: ?std.mem.Allocator, comptime Deserializer: type, seq: anytype) Deserializer.Error!Value { | ||
var bitset = Value.initEmpty(); | ||
|
||
if (Value.bit_length == 0) { | ||
if (try seq.nextElement(allocator, Value.MaskInt) != null) { | ||
return error.InvalidLength; | ||
} | ||
|
||
return bitset; | ||
} | ||
|
||
// Deserialize bits from N to 1, where N is the bitset's bit | ||
// length. | ||
// | ||
// NOTE: The 0th bit needs to be deserialized separately due to | ||
// compile errors related to the shift bit being too large or | ||
// something. | ||
comptime var i: usize = Value.bit_length - 1; | ||
inline while (i > 0) : (i -= 1) { | ||
if (try seq.nextElement(allocator, Value.MaskInt)) |bit| { | ||
switch (bit) { | ||
0 => {}, | ||
1 => bitset.set(i), | ||
else => return error.InvalidValue, | ||
} | ||
} else { | ||
return error.InvalidValue; | ||
} | ||
} | ||
|
||
// Deserialize 0th bit. | ||
if (try seq.nextElement(allocator, Value.MaskInt)) |bit| { | ||
switch (bit) { | ||
0 => {}, | ||
1 => bitset.set(0), | ||
else => return error.InvalidValue, | ||
} | ||
} else { | ||
return error.InvalidValue; | ||
} | ||
|
||
// Check for end of sequence. | ||
if (try seq.nextElement(allocator, Value.MaskInt) != null) { | ||
return error.InvalidLength; | ||
} | ||
|
||
return bitset; | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters