aboutsummaryrefslogtreecommitdiff
path: root/core/reflect/reflect.odin
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-09-30 12:04:27 +0100
committergingerBill <bill@gingerbill.org>2021-09-30 12:04:27 +0100
commitd32d1b7e079351b52c9f66f5ac0a885b9f046b0d (patch)
tree31f912a9240f64b75a4d28c58c01888196e607a5 /core/reflect/reflect.odin
parentcf94fd7b824685949a01fda71b733dcc2abc1f80 (diff)
Add `reflect.set_union_value`dev-2021-10
Diffstat (limited to 'core/reflect/reflect.odin')
-rw-r--r--core/reflect/reflect.odin39
1 files changed, 39 insertions, 0 deletions
diff --git a/core/reflect/reflect.odin b/core/reflect/reflect.odin
index 6316115ec..f509ffe1b 100644
--- a/core/reflect/reflect.odin
+++ b/core/reflect/reflect.odin
@@ -801,6 +801,45 @@ set_union_variant_type_info :: proc(a: any, tag_ti: ^Type_Info) {
panic("expected a union to reflect.set_union_variant_type_info")
}
+set_union_value :: proc(dst: any, value: any) -> bool {
+ if dst == nil { return false }
+
+ ti := runtime.type_info_base(type_info_of(dst.id))
+ if info, ok := ti.variant.(runtime.Type_Info_Union); ok {
+ if value.id == nil {
+ mem.zero(dst.data, ti.size)
+ return true
+ }
+ if ti.id == runtime.typeid_base(value.id) {
+ mem.copy(dst.data, value.data, ti.size)
+ return true
+ }
+
+ if type_info_union_is_pure_maybe(info) {
+ if variant := info.variants[0]; variant.id == value.id {
+ mem.copy(dst.data, value.data, variant.size)
+ return true
+ }
+ return false
+ }
+
+ for variant, i in info.variants {
+ if variant.id == value.id {
+ tag := i64(i)
+ if !info.no_nil {
+ tag += 1
+ }
+ mem.copy(dst.data, value.data, variant.size)
+ set_union_variant_raw_tag(dst, tag)
+ return true
+ }
+ }
+ return false
+ }
+ panic("expected a union to reflect.set_union_variant_typeid")
+}
+
+
as_bool :: proc(a: any) -> (value: bool, valid: bool) {
if a == nil { return }