about summary refs log tree commit diff
path: root/lang/zig/struct-packed.zig
diff options
context:
space:
mode:
Diffstat (limited to 'lang/zig/struct-packed.zig')
-rw-r--r--lang/zig/struct-packed.zig73
1 files changed, 73 insertions, 0 deletions
diff --git a/lang/zig/struct-packed.zig b/lang/zig/struct-packed.zig
new file mode 100644
index 0000000..f493661
--- /dev/null
+++ b/lang/zig/struct-packed.zig
@@ -0,0 +1,73 @@
+const std = @import("std");
+const endian = std.builtin.endian;
+const expect = std.testing.expect;
+
+const Full = packed struct {
+    number: u16,
+};
+const Divided = packed struct {
+    half1: u8,
+    quarter3: u4,
+    quarter4: u4,
+};
+
+fn doTheTest() void {
+    expect(@sizeOf(Full) == 2);
+    expect(@sizeOf(Divided) == 2);
+    var full = Full{ .number = 0x1234 };
+    var divided = @bitCast(Divided, full);
+    switch (endian) {
+        .Big => {
+            expect(divided.half1 == 0x12);
+            expect(divided.quarter3 == 0x3);
+            expect(divided.quarter4 == 0x4);
+        },
+        .Little => {
+            expect(divided.half1 == 0x34);
+            expect(divided.quarter3 == 0x2);
+            expect(divided.quarter4 == 0x1);
+        },
+    }
+}
+
+test "@bitCast between packed structs" {
+    doTheTest();
+    comptime doTheTest();
+}
+
+const BitField = packed struct {
+    a: u3,
+    b: u3,
+    c: u2,
+};
+
+var foo = BitField{
+    .a = 1,
+    .b = 2,
+    .c = 3,
+};
+
+fn bar(x: *const u3) u3 {
+    return x.*;
+}
+
+test "pointer to non-byte-aligned field" {
+    const ptr = &foo.b;
+    expect(ptr.* == 2);
+    // The pointer to a non-byte-aligned field has special properties
+    // and cannot be passed when a normal pointer is expected:
+    // expect(bar(ptr) == 2);
+    // Here's why:
+    expect(@ptrToInt(&foo.a) == @ptrToInt(&foo.b));
+    expect(@ptrToInt(&foo.a) == @ptrToInt(&foo.c));
+
+    comptime {
+        expect(@bitOffsetOf(BitField, "a") == 0);
+        expect(@bitOffsetOf(BitField, "b") == 3);
+        expect(@bitOffsetOf(BitField, "c") == 6);
+
+        expect(@byteOffsetOf(BitField, "a") == 0);
+        expect(@byteOffsetOf(BitField, "b") == 0);
+        expect(@byteOffsetOf(BitField, "c") == 0);
+    }
+}