Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

Value

ubsan_rt.Value
const Value = extern struct

File

lib/ubsan_rt.zig:52

Code

const Value = extern struct {
    td: *const TypeDescriptor,
    handle: ValueHandle,

    fn getUnsignedInteger(value: Value) u128 {
        assert(!value.td.isSigned());
        const size = value.td.getIntegerSize();
        const max_inline_size = @bitSizeOf(ValueHandle);
        if (size <= max_inline_size) {
            return @intFromPtr(value.handle);
        }

        return switch (size) {
            64 => @as(*const u64, @ptrCast(@alignCast(value.handle))).*,
            128 => @as(*const u128, @ptrCast(@alignCast(value.handle))).*,
            else => @trap(),
        };
    }

    fn getSignedInteger(value: Value) i128 {
        assert(value.td.isSigned());
        const size = value.td.getIntegerSize();
        const max_inline_size = @bitSizeOf(ValueHandle);
        if (size <= max_inline_size) {
            const extra_bits: std.math.Log2Int(usize) = @intCast(max_inline_size - size);
            const handle: isize = @bitCast(@intFromPtr(value.handle));
            return (handle << extra_bits) >> extra_bits;
        }
        return switch (size) {
            64 => @as(*const i64, @ptrCast(@alignCast(value.handle))).*,
            128 => @as(*const i128, @ptrCast(@alignCast(value.handle))).*,
            else => @trap(),
        };
    }

    fn getFloat(value: Value) f128 {
        assert(value.td.kind == .float);
        const size = value.td.info.float;
        const max_inline_size = @bitSizeOf(ValueHandle);
        if (size <= max_inline_size) {
            return @as(switch (@bitSizeOf(usize)) {
                32 => f32,
                64 => f64,
                else => @compileError("unsupported target"),
            }, @bitCast(@intFromPtr(value.handle)));
        }
        return @floatCast(switch (size) {
            64 => @as(*const f64, @ptrCast(@alignCast(value.handle))).*,
            80 => @as(*const f80, @ptrCast(@alignCast(value.handle))).*,
            128 => @as(*const f128, @ptrCast(@alignCast(value.handle))).*,
            else => @trap(),
        });
    }

    fn isMinusOne(value: Value) bool {
        return value.td.isSigned() and
            value.getSignedInteger() == -1;
    }

    fn isNegative(value: Value) bool {
        return value.td.isSigned() and
            value.getSignedInteger() < 0;
    }

    fn getPositiveInteger(value: Value) u128 {
        if (value.td.isSigned()) {
            const signed = value.getSignedInteger();
            assert(signed >= 0);
            return @intCast(signed);
        } else {
            return value.getUnsignedInteger();
        }
    }

    pub fn format(value: Value, writer: *std.Io.Writer) std.Io.Writer.Error!void {
        switch (value.td.kind) {
            .integer => {
                if (value.td.isSigned()) {
                    try writer.print("{d}", .{value.getSignedInteger()});
                } else {
                    try writer.print("{d}", .{value.getUnsignedInteger()});
                }
            },
            .float => try writer.print("{d}", .{value.getFloat()}),
            .unknown => try writer.writeAll("(unknown)"),
        }
    }
}