-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Open
Description
Proposal extracted from #19660:
Proposal
Introduce a new type opaquebits(N) that is an opaque bag of bits that has no semantics defined except for "it takes N bits of space".
This type can be used for storing fully opaque data and the only way to interpret its content is by using @bitCast from and to it.
Use Cases
Some microcontrollers enforce that you do not change the values of certain bits in registers, but also don't define these values. This means that you always have to read them, never interpret them, and if you want to change some others, write them back as is. This could be implemented as such:
const Register = bitpacked struct(u32) {
data: u8,
reserved: opaquebits(u24),
};Another use case is the safe implementation of bitpacked union(T), where some bits determine the meaning of the others:
const VideoInputDefinition = bitpacked(u8) struct
{
const Analog = bitpacked struct(u7) {
serrations: Support,
composite_sync_on_green: Support,
composite_sync_on_horiz: Support,
separate_sync: Support,
setup: enum(u1) { … },
signal_level: enum(u2) { … },
};
const Digital = bitpacked struct(u7) {
standard: enum(u4) { … },
color_depth: enum(u3) { … },
};
config: opaquebits(u7),
type: enum(u1) { analog=0, digital=1 };
fn as_analog(vdi: VideoInputDefinition) ?Analog {
return switch(vdi.type) {
.analog => @as(Analog, @bitCast(vdi.config)),
.digital => null,
};
}
fn as_digital(vdi: VideoInputDefinition) ?Digital {
return switch(vdi.type) {
.analog => @as(Digital, @bitCast(vdi.config)),
.digital => null,
};
}
};Behaviour Tests
test "opaquebits: basic operations" {
const T = opaquebits(u8);
// Same size and alignment as backing integer:
comptime assert(@sizeOf(T) == @sizeOf(u8));
comptime assert(@alignOf(T) == @alignOf(u8));
// Exactly 8 bits:
comptime assert(@bitSizeOf(T) == 8);
const input: u8 = 10;
const value: T = @bitCast(input);
const output: u8 = @bitCast(value);
try std.testing.expectEqual(input, output);
}
test "opaquebits: assign undefined" {
const T = opaquebits(u32);
const value: T = undefined; // only possible coercion
_ = value;
}
test "opaquebits: embedding into bitpacked union" {
const U = bitpacked union(u8) {
bits: opaquebits(u8),
int: u8,
};
const bundle: U = .{ .int = 0x13 };
try std.testing.expectEqual(0x13, bundle.int);
const bits: opaquebits(u8) = bundle.bits;
const int: u8 = @bitCast(bits);
try std.testing.expectEqual(0x13, int);
}theofabilous, elijahimmer and EtienneParmentierMatthiasPortzel
Metadata
Metadata
Assignees
Labels
No labels