made 'make()' more versatile for arrays and slices
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 7 Apr 2022 20:32:57 +0000 (15:32 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 7 Apr 2022 20:32:57 +0000 (15:32 -0500)
core/builtin.onyx
core/container/array.onyx
core/memory.onyx

index 99dcf209e1ffbbf4d04b695c42eabab3421d770f..b48e89aaa099371a449b2b8d9dc9425b2413c74f 100644 (file)
@@ -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;
-    }
+    },
 }
 
 
index 3fca8aaadab7e6c7a1296d1aa6ec34d42686ff45..99a82ed2642a8a344a07055459b7de3220907be8 100644 (file)
@@ -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;
index de6a7c6f284d6be6ce402062abe13f61cf61d7b9..88433372ecce25712d18c0159cc36a11e11a9052 100644 (file)
@@ -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;