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.

UnwrappedSwitchBlock

Trailing (starting at end):

  1. case_bodies: { // for each case in Case.Iterator.next() prong_body: { body_inst: Inst.Index, // for every case.prong_info.body_len, } item_body: { // for each body_len in case.item_infos body_inst: Inst.Index, // for every body_len } range_bodies: { // for each .{first_info, last_info} in case.range_infos first_body_inst: Inst.Index, // for every first_info.body_len last_body_inst: Inst.Index, // for every last_info.body_len } }
Zir.UnwrappedSwitchBlock
pub const UnwrappedSwitchBlock = struct

File

lib/std/zig/Zir.zig:5086

Code

pub const UnwrappedSwitchBlock = struct {
    /// Either `catch`/`if` or `switch` operand.
    main_operand: Inst.Ref,
    switch_src_node_offset: Ast.Node.Offset,
    catch_or_if_src_node_offset: Ast.Node.OptionalOffset,
    payload_capture_placeholder: Inst.OptionalIndex,
    tag_capture_placeholder: Inst.OptionalIndex,
    has_continue: bool,
    any_maybe_runtime_capture: bool,
    non_err_case: ?Case.NonErr,
    else_case: ?Case.Else,
    has_under: bool,
    // Refer to doc comment and `iterateCases` to access everything below correctly.
    prong_infos: []const Inst.SwitchBlock.ProngInfo,
    multi_case_items_lens: []const u32,
    multi_case_ranges_lens: ?[]const u32,
    item_infos: []const Inst.SwitchBlock.ItemInfo,
    end: usize,

    pub fn anyRanges(unwrapped: *const UnwrappedSwitchBlock) bool {
        return unwrapped.multi_case_ranges_lens != null;
    }

    pub fn scalarCasesLen(unwrapped: *const UnwrappedSwitchBlock) u32 {
        return @intCast(unwrapped.prong_infos.len - unwrapped.multi_case_items_lens.len);
    }

    pub fn multiCasesLen(unwrapped: *const UnwrappedSwitchBlock) u32 {
        return @intCast(unwrapped.multi_case_items_lens.len);
    }

    pub fn totalItemsLen(unwrapped: *const UnwrappedSwitchBlock) u32 {
        var total_items_len: u32 = @intCast(unwrapped.item_infos.len);
        if (unwrapped.multi_case_ranges_lens) |ranges_lens| {
            for (ranges_lens) |len| total_items_len -= len;
        }
        return total_items_len;
    }

    pub const Case = struct {
        index: Case.Index,
        prong_info: Inst.SwitchBlock.ProngInfo,
        item_infos: []const Inst.SwitchBlock.ItemInfo,
        range_infos: []const [2]Inst.SwitchBlock.ItemInfo,

        pub const Index = packed struct(u32) {
            kind: enum(u1) { scalar, multi },
            value: u31,

            pub const @"else": Case.Index = .{
                .kind = .scalar,
                .value = std.math.maxInt(u31),
            };
        };

        pub const NonErr = struct {
            body: []const Inst.Index,
            capture: Inst.SwitchBlock.ProngInfo.Capture,
            operand_is_ref: bool,
        };

        pub const Else = struct {
            index: Case.Index,
            body: []const Inst.Index,
            capture: Inst.SwitchBlock.ProngInfo.Capture,
            is_inline: bool,
            has_tag_capture: bool,
            is_simple_noreturn: bool,
        };

        pub const Iterator = struct {
            next_idx: u32,
            prong_infos: []const Inst.SwitchBlock.ProngInfo,
            multi_case_items_lens: []const u32,
            multi_case_ranges_lens: ?[]const u32,
            item_infos: []const Inst.SwitchBlock.ItemInfo,

            pub fn next(it: *Iterator) ?Case {
                const idx = it.next_idx;
                if (idx == it.prong_infos.len) return null;
                it.next_idx += 1;
                const scalar_cases_len = it.prong_infos.len - it.multi_case_items_lens.len;
                return if (idx < scalar_cases_len) .{
                    .index = .{
                        .kind = .scalar,
                        .value = @intCast(idx),
                    },
                    .prong_info = it.prong_infos[idx],
                    .item_infos = it.itemInfos(1),
                    .range_infos = &.{},
                } else .{
                    .index = .{
                        .kind = .multi,
                        .value = @intCast(idx - scalar_cases_len),
                    },
                    .prong_info = it.prong_infos[idx],
                    .item_infos = it.itemInfos(it.multi_case_items_lens[idx - scalar_cases_len]),
                    .range_infos = if (it.multi_case_ranges_lens) |ranges_lens| b: {
                        break :b @ptrCast(it.itemInfos(2 * ranges_lens[idx - scalar_cases_len]));
                    } else &.{},
                };
            }
            fn itemInfos(it: *Iterator, count: u32) []const Inst.SwitchBlock.ItemInfo {
                const lens = it.item_infos[0..count];
                it.item_infos = it.item_infos[count..];
                return lens;
            }
        };
    };

    pub fn iterateCases(unwrapped: UnwrappedSwitchBlock) Case.Iterator {
        return .{
            .next_idx = 0,
            .prong_infos = unwrapped.prong_infos,
            .multi_case_items_lens = unwrapped.multi_case_items_lens,
            .multi_case_ranges_lens = unwrapped.multi_case_ranges_lens,
            .item_infos = unwrapped.item_infos,
        };
    }
}