Mat4 :: #type,distinct Vec(4 * 4, float); m4 :: (r0: Vec4, r1: Vec4, r2: Vec4, r3: Vec4) -> Mat4 #expand { return .{ components = .[ r0.x, r0.y, r0.z, r0.w, r1.x, r1.y, r1.z, r1.w, r2.x, r2.y, r2.z, r2.w, r3.x, r3.y, r3.z, r3.w, ], }; } m4_identity :: #bake_arguments m4d(diag = 1); m4d :: (diag: float) -> Mat4 #expand { res: Mat4; res[0][0] = diag; res[1][1] = diag; res[2][2] = diag; res[3][3] = diag; return res; } operator [] :: inline (m: Mat4, idx: int) -> Vec4 #expand { bounds_check_index(idx * 4, m.N); return (m.components[idx * 4]).(*Vec4).*; } operator *[] :: inline (m: *Mat4, $$idx: int) -> *Vec4 #no_abc { N :: Mat4.{}.N; // @note(judah): dumb workaround for not being able to access pointer type field constants bounds_check_index(idx * 4, N); return (*m.components[idx * 4]).(*Vec4); } operator []= :: inline (m: *Mat4, $$idx: int, value: Vec4) #no_abc { N :: Mat4.{}.N; bounds_check_index(idx * 4, N); ptr := (*m.components[idx * 4]).(*Vec4); ptr.*= value; }