Skip to content

Instantly share code, notes, and snippets.

@rezich
Created January 26, 2026 22:08
Show Gist options
  • Select an option

  • Save rezich/5e4f46b0698746723de6f2ef1ba571c3 to your computer and use it in GitHub Desktop.

Select an option

Save rezich/5e4f46b0698746723de6f2ef1ba571c3 to your computer and use it in GitHub Desktop.
Tagged enum set macro (Jai beta 0.2.025)
My_Enum :: enum {
ALPHA;
BRAVO;
CHARLIE;
}
My_Tagged_Union :: union tag: My_Enum {
.ALPHA ,, alpha: int;
.BRAVO ,, bravo: float;
.CHARLIE ,, charlie: string;
}
My_Untagged_Union :: union { a: int; b: float; }
Tagged_Union_Without_Bindings :: union tag: enum { X; Y; Z; } {
x: int;
y: float;
z: string;
}
main :: () {
u: My_Tagged_Union;
set(*u, 3.14);
assert(u.tag == .BRAVO && u.bravo == 3.14);
set(*u, "Hello, sailor!");
assert(u.tag == .CHARLIE && u.charlie == "Hello, sailor!");
c: u8;
//set(*u, c); // Assertion failed: My_Tagged_Union does not have a binding for a member of type u8
uu: My_Untagged_Union;
//set(*uu, 3.14); // Assertion failed: My_Untagged_Union is not a tagged union.
u2: Tagged_Union_Without_Bindings;
//set(*u2, 108); // Assertion failed: Tagged_Union_Without_Bindings doesn't have any bindings.
}
#load "Tagged_Union_Support.jai";
#import "Basic";
set :: (u: *$U, value: $T) {
TAG_CONSTANT_VALUE, TAG_MEMBER_OFFSET :: #run -> u64, s64 {
U_info, T_info := U.(*Type_Info_Struct), T.(*Type_Info);
TAGGED_UNION_FLAGS : Struct_Textual_Flags : .UNION | .UNION_IS_TAGGED;
assert(U_info.type == .STRUCT && U_info.textual_flags & TAGGED_UNION_FLAGS == TAGGED_UNION_FLAGS,
"% is not a tagged union.", U
);
assert(U_info.tagged_union_bindings.count > 0,
"% doesn't have any bindings.", U
);
for member, member_index: U_info.members if member.type == T_info then
for binding: U_info.tagged_union_bindings if binding.member_index == member_index then
return binding.constant_value, member.offset_in_bytes;
assert(false,
"% does not have a binding for a member of type %.", U, T
);
return 0, 0;
};
u.(*u64).* = TAG_CONSTANT_VALUE; // set the tag
(u.(*void)+TAG_MEMBER_OFFSET).(*T).* = value; // set the value
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment