#Include/exclude fields of a union in comptime

1 messages · Page 1 of 1 (latest)

lilac salmon
#

Hi, I'm looking for ways to simplify this code. I believe usingnamespace cannot be used in such scenario.

pub fn MyUnion(comptime support_u16: bool) type {
    return switch (support_u16) {
        true => union {
            first: u32,
            second: [4]u8,
            third: [2]u16,
        },
        false => union {
            first: u32,
            second: [4]u8,
        },
    };
}
slate schooner
#

One way is to use @Type and construct fields programatically

#

Maybe you could do:

pub fn MyUnion2(comptime support_u16: bool) type {
    return union {
            first: u32,
            second: [4]u8,
            third: if(support_u16) [2]u16 else void,
    };
}
#

BTW, you can't use bare unions to reinterpret memory

lilac salmon
lilac salmon
slate schooner
slate schooner
lilac salmon
#

I believe switch on a tagged union can still hit void fields, I have a union that looks like this:

// values needed by operations
pub const Operation = union(OperationType) {
    // various kinds of cancel operations are supported
    // https://man7.org/linux/man-pages/man3/io_uring_prep_cancel.3.html
    pub const CancelType = enum(u1) { all_io, completion };

    pub const Cancel = union(CancelType) {
        all_io: Handle,
        completion: *Completion,
    };

    // default
    none: void,
    read: struct {
        handle: linux.fd_t,
        buffer: []u8,
        offset: u64,
    },
    write: struct {
        handle: linux.fd_t,
        buffer: []const u8,
        offset: u64,
    },
    connect: struct {
        socket: linux.fd_t,
        addr: std.net.Address,
    },
    accept: struct {
        socket: linux.fd_t,
        addr: posix.sockaddr = undefined,
        addr_size: posix.socklen_t = @sizeOf(posix.sockaddr),
    },
    cancel: Cancel,
    fds_update: struct {
        fds: []linux.fd_t,
        offset: u32,
    },
};