diff --git a/core/reflect/iterator.odin b/core/reflect/iterator.odin index e96019f68..d283f190f 100644 --- a/core/reflect/iterator.odin +++ b/core/reflect/iterator.odin @@ -44,6 +44,15 @@ iterate_array :: proc(val: any, it: ^int) -> (elem: any, index: int, ok: bool) { index = it^ it^ += 1 } + case Type_Info_Fixed_Capacity_Dynamic_Array: + count := (^int)(uintptr(val.data) + info.len_offset)^ + if it^ < count { + elem.data = rawptr(uintptr(val.data) + uintptr(it^ * info.elem_size)) + elem.id = info.elem.id + ok = true + index = it^ + it^ += 1 + } } return diff --git a/core/reflect/reflect.odin b/core/reflect/reflect.odin index 924120464..a0cc468f2 100644 --- a/core/reflect/reflect.odin +++ b/core/reflect/reflect.odin @@ -218,6 +218,7 @@ typeid_elem :: proc(id: typeid) -> typeid { case Type_Info_Slice: return v.elem.id case Type_Info_Dynamic_Array: return v.elem.id case Type_Info_Simd_Vector: return v.elem.id + case Type_Info_Fixed_Capacity_Dynamic_Array: return v.elem.id } return id } @@ -308,6 +309,9 @@ length :: proc(val: any) -> int { case Type_Info_Dynamic_Array: return (^runtime.Raw_Dynamic_Array)(val.data).len + case Type_Info_Fixed_Capacity_Dynamic_Array: + return (^int)(uintptr(val.data) + a.len_offset)^ + case Type_Info_Map: return runtime.map_len((^runtime.Raw_Map)(val.data)^) @@ -360,6 +364,9 @@ capacity :: proc(val: any) -> int { case Type_Info_Dynamic_Array: return (^runtime.Raw_Dynamic_Array)(val.data).cap + case Type_Info_Fixed_Capacity_Dynamic_Array: + return a.capacity + case Type_Info_Map: return runtime.map_cap((^runtime.Raw_Map)(val.data)^) @@ -420,6 +427,13 @@ index :: proc(val: any, i: int, loc := #caller_location) -> any { data := rawptr(uintptr(raw.data) + offset) return any{data, a.elem.id} + case Type_Info_Fixed_Capacity_Dynamic_Array: + count := (^int)(uintptr(val.data) + a.len_offset)^ + runtime.bounds_check_error_loc(loc, i, count) + offset := uintptr(a.elem.size * i) + data := rawptr(uintptr(val.data) + offset) + return any{data, a.elem.id} + case Type_Info_String: if a.is_cstring { return nil } @@ -1776,6 +1790,10 @@ as_raw_data :: proc(a: any) -> (value: rawptr, valid: bool) { valid = true value = (^runtime.Raw_Slice)(a.data).data + case Type_Info_Fixed_Capacity_Dynamic_Array: + valid = true + value = a.data + case Type_Info_Dynamic_Array: valid = true value = (^runtime.Raw_Dynamic_Array)(a.data).data diff --git a/core/reflect/types.odin b/core/reflect/types.odin index ff78708e3..079a4a172 100644 --- a/core/reflect/types.odin +++ b/core/reflect/types.odin @@ -433,6 +433,13 @@ is_simd_vector :: proc(info: ^Type_Info) -> bool { _, ok := type_info_base(info).variant.(Type_Info_Simd_Vector) return ok } +// Returns true when the type is a dynamic-array type ([dynamic]T), false otherwise. +@(require_results) +is_fixed_capacity_dynamic_array :: proc(info: ^Type_Info) -> bool { + if info == nil { return false } + _, ok := type_info_base(info).variant.(Type_Info_Fixed_Capacity_Dynamic_Array) + return ok +} // Returns true when the core-type is represented with a platform-native endian type, and returns false otherwise. @@ -840,6 +847,8 @@ has_no_indirections :: proc(ti: ^Type_Info) -> bool { return has_no_indirections(info.elem) case Type_Info_Enumerated_Array: return has_no_indirections(info.elem) + case Type_Info_Fixed_Capacity_Dynamic_Array: + return has_no_indirections(info.elem) case Type_Info_Simd_Vector: return true