From: Brendan Hansen Date: Thu, 7 Apr 2022 20:32:57 +0000 (-0500) Subject: made 'make()' more versatile for arrays and slices X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=66eafa3565397d2546ccb2da7ca84941c1d44823;p=onyx.git made 'make()' more versatile for arrays and slices --- diff --git a/core/builtin.onyx b/core/builtin.onyx index 99dcf209..b48e89aa 100644 --- a/core/builtin.onyx +++ b/core/builtin.onyx @@ -134,51 +134,63 @@ calloc :: (size: u32) -> rawptr do return raw_alloc(context.allocator, size); cresize :: (ptr: rawptr, size: u32) -> rawptr do return raw_resize(context.allocator, ptr, size); cfree :: (ptr: rawptr) do raw_free(context.allocator, ptr); -// CLEANUP: Does this really need to be limited to a non-custom runtime? -#if runtime.runtime != .Custom { - new :: #match { - ($T: type_expr, allocator := context.allocator) -> ^T { - use package core.intrinsics.onyx { __initialize } - memory :: package core.memory - - res := cast(^T) raw_alloc(allocator, sizeof T); - memory.set(res, 0, sizeof T); - __initialize(res); - - return res; - }, - - (T: type_expr, allocator := context.allocator) -> rawptr { - memory :: package core.memory - - info := type_info.get_type_info(T); - size := type_info.size_of(T); - if size == 0 do return null; - - res := raw_alloc(allocator, size); - memory.set(res, 0, size); - - if info.kind == .Struct { - s_info := cast(^type_info.Type_Info_Struct) info; - for s_info.members { - if it.default != null { - member_size := type_info.size_of(it.type); - memory.copy(cast(^u8) res + it.offset, it.default, member_size); - } +new :: #match { + ($T: type_expr, allocator := context.allocator) -> ^T { + use package core.intrinsics.onyx { __initialize } + memory :: package core.memory + + res := cast(^T) raw_alloc(allocator, sizeof T); + memory.set(res, 0, sizeof T); + __initialize(res); + + return res; + }, + + (T: type_expr, allocator := context.allocator) -> rawptr { + memory :: package core.memory + + info := type_info.get_type_info(T); + size := type_info.size_of(T); + if size == 0 do return null; + + res := raw_alloc(allocator, size); + memory.set(res, 0, size); + + if info.kind == .Struct { + s_info := cast(^type_info.Type_Info_Struct) info; + for s_info.members { + if it.default != null { + member_size := type_info.size_of(it.type); + memory.copy(cast(^u8) res + it.offset, it.default, member_size); } } - - return res; } + + return res; } +} + +make :: #match { + macro ($T: type_expr, allocator := context.allocator) => { + return __make_overload(cast(^T) null, allocator=allocator); + }, + + macro ($T: type_expr, n: u32, allocator := context.allocator) => { + return __make_overload(cast(^T) null, n, allocator=allocator); + }, +} - make :: ($T: type_expr, allocator := context.allocator) -> ^T { +__make_overload :: #match { + // + // This is the fallback option for make. It simply allocates a zero-intialized + // element of type T. + #precedence 1000 (_: ^$T, allocator := context.allocator) -> ^T { memory :: package core.memory res := cast(^T) raw_alloc(allocator, sizeof T); memory.set(res, 0, sizeof T); return res; - } + }, } diff --git a/core/container/array.onyx b/core/container/array.onyx index 3fca8aaa..99a82ed2 100644 --- a/core/container/array.onyx +++ b/core/container/array.onyx @@ -20,6 +20,14 @@ make :: ($T: type_expr, capacity := 4, allocator := context.allocator) -> [..] T return arr; } +#match __make_overload macro (_: ^[..] $T, allocator := context.allocator) -> [..] T { + return (package core.array).make(T, allocator=allocator); +} + +#match __make_overload macro (_: ^[..] $T, capacity: u32, allocator := context.allocator) -> [..] T { + return (package core.array).make(T, capacity, allocator); +} + init :: (arr: ^[..] $T, capacity := 4, allocator := context.allocator) { arr.count = 0; arr.capacity = capacity; diff --git a/core/memory.onyx b/core/memory.onyx index de6a7c6f..88433372 100644 --- a/core/memory.onyx +++ b/core/memory.onyx @@ -29,6 +29,10 @@ make_slice :: ($T: type_expr, count: i32, allocator := context.allocator) -> [] }; } +#match __make_overload macro (_: ^[] $T, count: u32, allocator := context.allocator) -> [] T { + return (package core.memory).make_slice(T, count, allocator); +} + free_slice :: (sl: ^[] $T, allocator := context.allocator) { if sl.data == null do return;