Compare commits
2 Commits
de5474b6c3
...
4ff3695895
Author | SHA1 | Date |
---|---|---|
Rekai Nyangadzayi Musuka | 4ff3695895 | |
Rekai Nyangadzayi Musuka | e0ab786ef0 |
34
src/lib.zig
34
src/lib.zig
|
@ -121,8 +121,6 @@ pub fn extract(comptime bit_string: []const u8, value: anytype) Bitfield(bit_str
|
||||||
};
|
};
|
||||||
comptime verify(ValT, bit_string);
|
comptime verify(ValT, bit_string);
|
||||||
|
|
||||||
std.debug.assert(match(bit_string, value)); // prevents branchless impl in ReleaseSafe
|
|
||||||
|
|
||||||
var ret: ReturnT = undefined;
|
var ret: ReturnT = undefined;
|
||||||
|
|
||||||
inline for (@typeInfo(ReturnT).Struct.fields) |field| {
|
inline for (@typeInfo(ReturnT).Struct.fields) |field| {
|
||||||
|
@ -148,6 +146,11 @@ pub fn extract(comptime bit_string: []const u8, value: anytype) Bitfield(bit_str
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn matchExtract(comptime bit_string: []const u8, value: anytype) ?Bitfield(bit_string) {
|
||||||
|
if (!match(bit_string, value)) return null;
|
||||||
|
return extract(bit_string, value);
|
||||||
|
}
|
||||||
|
|
||||||
test "extract" {
|
test "extract" {
|
||||||
// doc tests
|
// doc tests
|
||||||
{
|
{
|
||||||
|
@ -183,6 +186,29 @@ test "extract" {
|
||||||
try std.testing.expectEqual(@as(u4, 0b1110), ret.a);
|
try std.testing.expectEqual(@as(u4, 0b1110), ret.a);
|
||||||
try std.testing.expectEqual(@as(u4, 0b1011), ret.b);
|
try std.testing.expectEqual(@as(u4, 0b1011), ret.b);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
const ret = extract("--------ddddrrrr", @as(u16, 0b0000_0010_1011_0110));
|
||||||
|
try std.testing.expectEqual(@as(u4, 0b1011), ret.d);
|
||||||
|
try std.testing.expectEqual(@as(u4, 0b0110), ret.r);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const ret = extract("--------", @as(u8, 0b00000000));
|
||||||
|
const T = @TypeOf(ret);
|
||||||
|
|
||||||
|
try std.testing.expectEqual(@as(usize, 0), @typeInfo(T).Struct.fields.len);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const ret = extract("00000000", @as(u8, 0b00000000));
|
||||||
|
const T = @TypeOf(ret);
|
||||||
|
|
||||||
|
try std.testing.expectEqual(@as(usize, 0), @typeInfo(T).Struct.fields.len);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const ret = extract("0-0-0-0-", @as(u8, 0b01010101));
|
||||||
|
const T = @TypeOf(ret);
|
||||||
|
|
||||||
|
try std.testing.expectEqual(@as(usize, 0), @typeInfo(T).Struct.fields.len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a bit string and reifies a struct that will contain fields that correspond to the variables present in the bit string.
|
/// Parses a bit string and reifies a struct that will contain fields that correspond to the variables present in the bit string.
|
||||||
|
@ -213,13 +239,13 @@ pub fn Bitfield(comptime bit_string: []const u8) type {
|
||||||
var tmp: [field_len]StructField = undefined;
|
var tmp: [field_len]StructField = undefined;
|
||||||
|
|
||||||
const Tmp = struct { bits: u8 = 0, char: ?u8 = null };
|
const Tmp = struct { bits: u8 = 0, char: ?u8 = null };
|
||||||
var things: [field_len]Tmp = [_]Tmp{.{}} ** field_len;
|
var things: [field_len]Tmp = [_]Tmp{.{}} ** field_len; // TODO: rename this lol
|
||||||
|
|
||||||
for (bit_string) |char| {
|
for (bit_string) |char| {
|
||||||
switch (char) {
|
switch (char) {
|
||||||
'a'...'z' => |c| {
|
'a'...'z' => |c| {
|
||||||
const bit_in_set = @as(u26, 1) << @intCast(c - 'a');
|
const bit_in_set = @as(u26, 1) << @intCast(c - 'a');
|
||||||
const pos = @ctz(alphabet_set & ~(bit_in_set - 1));
|
const pos = @popCount(alphabet_set & ~(bit_in_set - 1)) - 1; // TODO: investigate this off-by-one
|
||||||
|
|
||||||
things[pos].bits += 1;
|
things[pos].bits += 1;
|
||||||
things[pos].char = c;
|
things[pos].char = c;
|
||||||
|
|
Loading…
Reference in New Issue