Remove Optional from a type

I have from Vulkan:

pub const struct_VkDescriptorSetLayout_T = opaque {};
pub const VkDescriptorSetLayout = ?*struct_VkDescriptorSetLayout_T;

Is there something I can do to VkDescriptorSetLayout to remove that optional?

I can obviously just redefine VkDescriptorSetLayout without the optional, but I would have to do that for dozens and dozens of types in Vulkan. I’m hoping there is something clever I can do.

Thanks.

I’m not sure how helpful this is, as it depends somewhat on how you’re using the types, but you can unwrap, or “de-optional”, a value by using the orelse keyword. It works similarly to the catch keyword. For example the following code:

const myVar: ?i32 = null;
const myVarUnwrapped: i32 = myVar orelse 5;

The orelse can also be substituted for a code block, the same as with catch.

There is also a shorthand for orelse unreachable which is simply .?.

If you aren’t comfortable with this stuff, I’d also recommend having a read through the links below, as they go over zig optionals in more depth.

https://ziglang.org/documentation/master/#Optionals

Generally you will only use such handles as arguments in Vulkan functions, which take an optional pointer as a parameter, so it’s not really necessary to remove the optional. If you’re worried about safety, I’m fairly confident your validation layers (if enabled) will check for null pointers anyway, so you shouldn’t need to yourself.

The issue is I’m slinging some of this stuff around in Zig arrays and tuples and having to “deoptional” everything at variable use is kind of a pest since I’ve already established that none of these things are null.

I didn’t think there was an obvious way to do this, but I thought I would ask.

comptime lets you cough up a lot of interesting manipulations on types and sometimes an action that you would think is complicated is surprisingly easy.

@cyuria This is about removing the Optional from the type, not the value.

In this case, it would be like:

const U32OptionalType = ?u32;
const U64OptionalType = ?u64;

const pp: U32OptionalType = null;  // fine
const qq: U64OptionalType = null;  // fine

const rr: @magicDeoptional(U32OptionalType) = null;  // bzzzt.  error.  It's a u32.
const ss: @magicDeoptional(U64OptionalType) = null;  // bzzzt.  error.  It's a u64.

std.meta.Child(VkDescriptorSetLayout)

2 Likes

What’s wrong with slinging them around as optional pointers? There’s no cost to doing this. I’m curious why you would ever need to unwrap them, seeing as the underlying type is opaque.

1 Like

You’ have to define your own types. You could do it manually or write a script based on the API registry, which is what vulkan-zig does.

@cztomsik That’s it! Thanks!

I would never have thought of it as “Child” a priori, but it makes sense now.