From edcefaac12c2ca9e3b3483fb793fa6920b90cebc Mon Sep 17 00:00:00 2001 From: Shane Shrybman Date: Wed, 11 Feb 2026 13:45:10 -0500 Subject: [PATCH 1/8] Remove core:mem dependency from core:strings --- core/strings/strings.odin | 75 +++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/core/strings/strings.odin b/core/strings/strings.odin index cda12f9dc..75c7154af 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -5,7 +5,6 @@ import "base:intrinsics" import "base:runtime" import "core:bytes" import "core:io" -import "core:mem" import "core:unicode" import "core:unicode/utf8" @@ -23,7 +22,7 @@ Returns: - res: The cloned string - err: An optional allocator error if one occured, `nil` otherwise */ -clone :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +clone :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { c := make([]byte, len(s), allocator, loc) or_return copy(c, s) return string(c), nil @@ -43,7 +42,7 @@ Returns: - res: A cloned cstring with an appended null-byte - err: An optional allocator error if one occured, `nil` otherwise */ -clone_to_cstring :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (res: cstring, err: mem.Allocator_Error) #optional_allocator_error { +clone_to_cstring :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (res: cstring, err: runtime.Allocator_Error) #optional_allocator_error { c := make([]byte, len(s)+1, allocator, loc) or_return copy(c, s) c[len(s)] = 0 @@ -63,7 +62,7 @@ Returns: - res: A string created from the byte pointer and length */ string_from_ptr :: proc(ptr: ^byte, len: int) -> (res: string) { - return transmute(string)mem.Raw_String{ptr, len} + return transmute(string)runtime.Raw_String{ptr, len} } /* @@ -97,7 +96,7 @@ Returns: - res: The converted cstring */ unsafe_string_to_cstring :: proc(str: string) -> (res: cstring) { - d := transmute(mem.Raw_String)str + d := transmute(runtime.Raw_String)str return cstring(d.data) } @@ -153,7 +152,7 @@ Returns: - res: The cloned string from the byte array with a null-byte - err: An optional allocator error if one occured, `nil` otherwise */ -clone_from_bytes :: proc(s: []byte, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +clone_from_bytes :: proc(s: []byte, allocator := context.allocator, loc := #caller_location) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { c := make([]byte, len(s)+1, allocator, loc) or_return copy(c, s) c[len(s)] = 0 @@ -174,7 +173,7 @@ Returns: - res: The cloned string from the cstring - err: An optional allocator error if one occured, `nil` otherwise */ -clone_from_cstring :: proc(s: cstring, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +clone_from_cstring :: proc(s: cstring, allocator := context.allocator, loc := #caller_location) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { return clone(string(s), allocator, loc) } @@ -195,7 +194,7 @@ Returns: - res: The cloned string from the byte pointer and length - err: An optional allocator error if one occured, `nil` otherwise */ -clone_from_ptr :: proc(ptr: ^byte, len: int, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +clone_from_ptr :: proc(ptr: ^byte, len: int, allocator := context.allocator, loc := #caller_location) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { s := string_from_ptr(ptr, len) return clone(s, allocator, loc) } @@ -225,7 +224,7 @@ Returns: - res: The cloned string from the null-terminated cstring and byte length - err: An optional allocator error if one occured, `nil` otherwise */ -clone_from_cstring_bounded :: proc(ptr: cstring, len: int, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +clone_from_cstring_bounded :: proc(ptr: cstring, len: int, allocator := context.allocator, loc := #caller_location) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { s := string_from_ptr((^u8)(ptr), len) s = truncate_to_byte(s, 0) return clone(s, allocator, loc) @@ -242,8 +241,16 @@ Inputs: Returns: - result: `-1` if `lhs` comes first, `1` if `rhs` comes first, or `0` if they are equal */ -compare :: proc "contextless" (lhs, rhs: string) -> (result: int) { - return mem.compare(transmute([]byte)lhs, transmute([]byte)rhs) +compare :: proc "contextless" (lhs, rhs: string) -> (res: int) { + a := transmute([]byte)lhs + b := transmute([]byte)rhs + res = runtime.memory_compare(raw_data(a), raw_data(b), min(len(a), len(b))) + if res == 0 && len(a) != len(b) { + return len(a) <= len(b) ? -1 : +1 + } else if len(a) == 0 && len(b) == 0 { + return 0 + } + return res } /* @@ -634,7 +641,7 @@ Output: a...b...c */ -join :: proc(a: []string, sep: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +join :: proc(a: []string, sep: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { if len(a) == 0 { return "", nil } @@ -681,7 +688,7 @@ Output: abc */ -concatenate :: proc(a: []string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +concatenate :: proc(a: []string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { if len(a) == 0 { return "", nil } @@ -788,7 +795,7 @@ Output: example */ -cut_clone :: proc(s: string, rune_offset := int(0), rune_length := int(0), allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +cut_clone :: proc(s: string, rune_offset := int(0), rune_length := int(0), allocator := context.allocator, loc := #caller_location) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { res = cut(s, rune_offset, rune_length) return clone(res, allocator, loc) } @@ -815,7 +822,7 @@ Returns: - err: An optional allocator error if one occured, `nil` otherwise */ @private -_split :: proc(s_, sep: string, sep_save, n_: int, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) { +_split :: proc(s_, sep: string, sep_save, n_: int, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: runtime.Allocator_Error) { s, n := s_, n_ if n == 0 { @@ -895,7 +902,7 @@ Output: ["aaa", "bbb", "ccc", "ddd", "eee"] */ -split :: proc(s, sep: string, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error { +split :: proc(s, sep: string, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: runtime.Allocator_Error) #optional_allocator_error { return _split(s, sep, 0, -1, allocator, loc) } @@ -933,7 +940,7 @@ Output: ["aaa", "bbb", "ccc.ddd.eee"] */ -split_n :: proc(s, sep: string, n: int, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error { +split_n :: proc(s, sep: string, n: int, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: runtime.Allocator_Error) #optional_allocator_error { return _split(s, sep, 0, n, allocator, loc) } @@ -970,7 +977,7 @@ Output: ["aaa.", "bbb.", "ccc.", "ddd.", "eee"] */ -split_after :: proc(s, sep: string, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error { +split_after :: proc(s, sep: string, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: runtime.Allocator_Error) #optional_allocator_error { return _split(s, sep, len(sep), -1, allocator, loc) } @@ -1008,7 +1015,7 @@ Output: ["aaa.", "bbb.", "ccc.ddd.eee"] */ -split_after_n :: proc(s, sep: string, n: int, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error { +split_after_n :: proc(s, sep: string, n: int, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: runtime.Allocator_Error) #optional_allocator_error { return _split(s, sep, len(sep), n, allocator, loc) } @@ -1224,7 +1231,7 @@ Output: ["a", "b", "c", "d", "e"] */ -split_lines :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error { +split_lines :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: runtime.Allocator_Error) #optional_allocator_error { sep :: "\n" lines := _split(s, sep, 0, -1, allocator, loc) or_return for &line in lines { @@ -1266,7 +1273,7 @@ Output: ["a", "b", "c\nd\ne"] */ -split_lines_n :: proc(s: string, n: int, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error { +split_lines_n :: proc(s: string, n: int, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: runtime.Allocator_Error) #optional_allocator_error { sep :: "\n" lines := _split(s, sep, 0, n, allocator, loc) or_return for &line in lines { @@ -1307,7 +1314,7 @@ Output: ["a\n", "b\n", "c\n", "d\n", "e"] */ -split_lines_after :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error { +split_lines_after :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: runtime.Allocator_Error) #optional_allocator_error { sep :: "\n" lines := _split(s, sep, len(sep), -1, allocator, loc) or_return for &line in lines { @@ -1350,7 +1357,7 @@ Output: ["a\n", "b\n", "c\nd\ne"] */ -split_lines_after_n :: proc(s: string, n: int, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error { +split_lines_after_n :: proc(s: string, n: int, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: runtime.Allocator_Error) #optional_allocator_error { sep :: "\n" lines := _split(s, sep, len(sep), n, allocator, loc) or_return for &line in lines { @@ -2008,7 +2015,7 @@ Output: abcabc */ -repeat :: proc(s: string, count: int, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +repeat :: proc(s: string, count: int, allocator := context.allocator, loc := #caller_location) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { if count < 0 { panic("strings: negative repeat count") } else if count > 0 && (len(s)*count)/count != len(s) { @@ -2711,7 +2718,7 @@ Output: ["testing", "this", "out", "nice", "done", "last"] */ -split_multi :: proc(s: string, substrs: []string, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error #no_bounds_check { +split_multi :: proc(s: string, substrs: []string, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: runtime.Allocator_Error) #optional_allocator_error #no_bounds_check { if s == "" || len(substrs) <= 0 { return nil, nil } @@ -2842,7 +2849,7 @@ Output: Hello? */ -scrub :: proc(s: string, replacement: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +scrub :: proc(s: string, replacement: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { str := s b: Builder builder_init(&b, 0, len(s), allocator, loc) or_return @@ -2904,7 +2911,7 @@ Output: abcxyz zyxcba */ -reverse :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +reverse :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { str := s n := len(str) buf := make([]byte, n, allocator, loc) or_return @@ -2951,7 +2958,7 @@ Output: abc1 abc2 abc3 */ -expand_tabs :: proc(s: string, tab_size: int, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +expand_tabs :: proc(s: string, tab_size: int, allocator := context.allocator, loc := #caller_location) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { if tab_size <= 0 { panic("tab size must be positive") } @@ -3063,7 +3070,7 @@ Returns: - res: A new string centered within a field of the specified length - err: An optional allocator error if one occured, `nil` otherwise */ -centre_justify :: proc(str: string, length: int, pad: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +centre_justify :: proc(str: string, length: int, pad: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { n := rune_count(str) if n >= length || pad == "" { return clone(str, allocator, loc) @@ -3100,7 +3107,7 @@ Returns: - res: A new string left-justified within a field of the specified length - err: An optional allocator error if one occured, `nil` otherwise */ -left_justify :: proc(str: string, length: int, pad: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +left_justify :: proc(str: string, length: int, pad: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { n := rune_count(str) if n >= length || pad == "" { return clone(str, allocator, loc) @@ -3136,7 +3143,7 @@ Returns: - res: A new string right-justified within a field of the specified length - err: An optional allocator error if one occured, `nil` otherwise */ -right_justify :: proc(str: string, length: int, pad: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +right_justify :: proc(str: string, length: int, pad: string, allocator := context.allocator, loc := #caller_location) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { n := rune_count(str) if n >= length || pad == "" { return clone(str, allocator, loc) @@ -3197,7 +3204,7 @@ Returns: - res: A slice of substrings of the input string, or an empty slice if the input string only contains white space - err: An optional allocator error if one occured, `nil` otherwise */ -fields :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error #no_bounds_check { +fields :: proc(s: string, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: runtime.Allocator_Error) #optional_allocator_error #no_bounds_check { n := 0 was_space := 1 set_bits := u8(0) @@ -3263,7 +3270,7 @@ Returns: - res: A slice of substrings of the input string, or an empty slice if all code points in the input string satisfy the predicate or if the input string is empty - err: An optional allocator error if one occured, `nil` otherwise */ -fields_proc :: proc(s: string, f: proc(rune) -> bool, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: mem.Allocator_Error) #optional_allocator_error #no_bounds_check { +fields_proc :: proc(s: string, f: proc(rune) -> bool, allocator := context.allocator, loc := #caller_location) -> (res: []string, err: runtime.Allocator_Error) #optional_allocator_error #no_bounds_check { substrings := make([dynamic]string, 0, 32, allocator, loc) or_return start, end := -1, -1 @@ -3347,7 +3354,7 @@ Returns: NOTE: This implementation is a single-row-version of the Wagner–Fischer algorithm, based on C code by Martin Ettl. */ -levenshtein_distance :: proc(a, b: string, allocator := context.allocator, loc := #caller_location) -> (res: int, err: mem.Allocator_Error) #optional_allocator_error { +levenshtein_distance :: proc(a, b: string, allocator := context.allocator, loc := #caller_location) -> (res: int, err: runtime.Allocator_Error) #optional_allocator_error { LEVENSHTEIN_DEFAULT_COSTS: []int : { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, From a484937fb7b29a9ef7b5087cf11f5104a1825dfc Mon Sep 17 00:00:00 2001 From: Shane Shrybman Date: Thu, 12 Feb 2026 10:43:27 -0500 Subject: [PATCH 2/8] strings.compare() can wrap runtime.string_cmp() --- core/strings/strings.odin | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/core/strings/strings.odin b/core/strings/strings.odin index 75c7154af..9b75c558b 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -242,15 +242,7 @@ Returns: - result: `-1` if `lhs` comes first, `1` if `rhs` comes first, or `0` if they are equal */ compare :: proc "contextless" (lhs, rhs: string) -> (res: int) { - a := transmute([]byte)lhs - b := transmute([]byte)rhs - res = runtime.memory_compare(raw_data(a), raw_data(b), min(len(a), len(b))) - if res == 0 && len(a) != len(b) { - return len(a) <= len(b) ? -1 : +1 - } else if len(a) == 0 && len(b) == 0 { - return 0 - } - return res + return runtime.string_cmp(lhs, rhs) } /* From 871ad165015f61f2225eb5f58db135984f65fade Mon Sep 17 00:00:00 2001 From: Shane Shrybman Date: Thu, 12 Feb 2026 10:54:59 -0500 Subject: [PATCH 3/8] Add the length checks back to string.compare() --- core/strings/strings.odin | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/strings/strings.odin b/core/strings/strings.odin index 9b75c558b..c19bf8c37 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -242,7 +242,13 @@ Returns: - result: `-1` if `lhs` comes first, `1` if `rhs` comes first, or `0` if they are equal */ compare :: proc "contextless" (lhs, rhs: string) -> (res: int) { - return runtime.string_cmp(lhs, rhs) + res = runtime.string_cmp(lhs, rhs) + if res == 0 && len(lhs) != len(rhs) { + return len(lhs) <= len(rhs) ? -1 : +1 + } else if len(lhs) == 0 && len(rhs) == 0 { + return 0 + } + return res } /* From 8a2a0c5a93c73310ec6d41cb38ca524d37fc07e7 Mon Sep 17 00:00:00 2001 From: Shane Shrybman Date: Thu, 12 Feb 2026 11:05:23 -0500 Subject: [PATCH 4/8] Remove core:mem dependency from strings intern.odin --- core/strings/intern.odin | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/strings/intern.odin b/core/strings/intern.odin index 909510c7c..9b816ff8d 100644 --- a/core/strings/intern.odin +++ b/core/strings/intern.odin @@ -1,7 +1,6 @@ package strings import "base:runtime" -import "core:mem" // Custom string entry struct Intern_Entry :: struct { @@ -35,7 +34,7 @@ Inputs: Returns: - err: An allocator error if one occured, `nil` otherwise */ -intern_init :: proc(m: ^Intern, allocator := context.allocator, map_allocator := context.allocator, loc := #caller_location) -> (err: mem.Allocator_Error) { +intern_init :: proc(m: ^Intern, allocator := context.allocator, map_allocator := context.allocator, loc := #caller_location) -> (err: runtime.Allocator_Error) { m.allocator = allocator m.entries = make(map[string]^Intern_Entry, 16, map_allocator, loc) or_return return nil From d1927e4eba67b309696899536de6279894fbcad6 Mon Sep 17 00:00:00 2001 From: Shane Shrybman Date: Thu, 12 Feb 2026 11:52:55 -0500 Subject: [PATCH 5/8] strings.compare() can be an alias of runtime.string_cmp() --- core/strings/strings.odin | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/core/strings/strings.odin b/core/strings/strings.odin index c19bf8c37..d40b81b3d 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -241,15 +241,7 @@ Inputs: Returns: - result: `-1` if `lhs` comes first, `1` if `rhs` comes first, or `0` if they are equal */ -compare :: proc "contextless" (lhs, rhs: string) -> (res: int) { - res = runtime.string_cmp(lhs, rhs) - if res == 0 && len(lhs) != len(rhs) { - return len(lhs) <= len(rhs) ? -1 : +1 - } else if len(lhs) == 0 && len(rhs) == 0 { - return 0 - } - return res -} +compare :: runtime.string_cmp /* Checks if rune `r` in the string `s` From 671c46235aa776296e5114acc07ffe34e5c53190 Mon Sep 17 00:00:00 2001 From: Shane Shrybman Date: Thu, 12 Feb 2026 13:21:19 -0500 Subject: [PATCH 6/8] Remove core:mem dependency from strings builder --- core/strings/builder.odin | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/core/strings/builder.odin b/core/strings/builder.odin index ce636a2a1..5adced779 100644 --- a/core/strings/builder.odin +++ b/core/strings/builder.odin @@ -3,7 +3,6 @@ package strings import "base:runtime" import "core:unicode/utf8" import "core:strconv" -import "core:mem" import "core:io" /* Type definition for a procedure that flushes a Builder @@ -35,7 +34,7 @@ Returns: - res: The new Builder - err: An optional allocator error if one occured, `nil` otherwise */ -builder_make_none :: proc(allocator := context.allocator, loc := #caller_location) -> (res: Builder, err: mem.Allocator_Error) #optional_allocator_error { +builder_make_none :: proc(allocator := context.allocator, loc := #caller_location) -> (res: Builder, err: runtime.Allocator_Error) #optional_allocator_error { return Builder{buf=make([dynamic]byte, allocator, loc) or_return }, nil } /* @@ -51,7 +50,7 @@ Returns: - res: The new Builder - err: An optional allocator error if one occured, `nil` otherwise */ -builder_make_len :: proc(len: int, allocator := context.allocator, loc := #caller_location) -> (res: Builder, err: mem.Allocator_Error) #optional_allocator_error { +builder_make_len :: proc(len: int, allocator := context.allocator, loc := #caller_location) -> (res: Builder, err: runtime.Allocator_Error) #optional_allocator_error { return Builder{buf=make([dynamic]byte, len, allocator, loc) or_return }, nil } /* @@ -68,7 +67,7 @@ Returns: - res: The new Builder - err: An optional allocator error if one occured, `nil` otherwise */ -builder_make_len_cap :: proc(len, cap: int, allocator := context.allocator, loc := #caller_location) -> (res: Builder, err: mem.Allocator_Error) #optional_allocator_error { +builder_make_len_cap :: proc(len, cap: int, allocator := context.allocator, loc := #caller_location) -> (res: Builder, err: runtime.Allocator_Error) #optional_allocator_error { return Builder{buf=make([dynamic]byte, len, cap, allocator, loc) or_return }, nil } /* @@ -116,7 +115,7 @@ Returns: - res: A pointer to the initialized Builder - err: An optional allocator error if one occured, `nil` otherwise */ -builder_init_none :: proc(b: ^Builder, allocator := context.allocator, loc := #caller_location) -> (res: ^Builder, err: mem.Allocator_Error) #optional_allocator_error { +builder_init_none :: proc(b: ^Builder, allocator := context.allocator, loc := #caller_location) -> (res: ^Builder, err: runtime.Allocator_Error) #optional_allocator_error { b.buf = make([dynamic]byte, allocator, loc) or_return return b, nil } @@ -135,7 +134,7 @@ Returns: - res: A pointer to the initialized Builder - err: An optional allocator error if one occured, `nil` otherwise */ -builder_init_len :: proc(b: ^Builder, len: int, allocator := context.allocator, loc := #caller_location) -> (res: ^Builder, err: mem.Allocator_Error) #optional_allocator_error { +builder_init_len :: proc(b: ^Builder, len: int, allocator := context.allocator, loc := #caller_location) -> (res: ^Builder, err: runtime.Allocator_Error) #optional_allocator_error { b.buf = make([dynamic]byte, len, allocator, loc) or_return return b, nil } @@ -153,7 +152,7 @@ Returns: - res: A pointer to the initialized Builder - err: An optional allocator error if one occured, `nil` otherwise */ -builder_init_len_cap :: proc(b: ^Builder, len, cap: int, allocator := context.allocator, loc := #caller_location) -> (res: ^Builder, err: mem.Allocator_Error) #optional_allocator_error { +builder_init_len_cap :: proc(b: ^Builder, len, cap: int, allocator := context.allocator, loc := #caller_location) -> (res: ^Builder, err: runtime.Allocator_Error) #optional_allocator_error { b.buf = make([dynamic]byte, len, cap, allocator, loc) or_return return b, nil } @@ -269,8 +268,22 @@ Output: */ builder_from_bytes :: proc(backing: []byte) -> (res: Builder) { - return Builder{ buf = mem.buffer_from_slice(backing) } + return Builder{ buf = buffer_from_slice(backing) } } + +@(private) +buffer_from_slice :: proc "contextless" (backing: $T/[]$E) -> [dynamic]E { + return transmute([dynamic]E)runtime.Raw_Dynamic_Array{ + data = raw_data(backing), + len = 0, + cap = len(backing), + allocator = runtime.Allocator{ + procedure = runtime.nil_allocator_proc, + data = nil, + }, + } +} + // Alias to `builder_from_bytes` builder_from_slice :: builder_from_bytes /* @@ -311,7 +324,7 @@ Returns: - res: A cstring of the Builder's buffer upon success - err: An optional allocator error if one occured, `nil` otherwise */ -to_cstring :: proc(b: ^Builder, loc := #caller_location) -> (res: cstring, err: mem.Allocator_Error) #optional_allocator_error { +to_cstring :: proc(b: ^Builder, loc := #caller_location) -> (res: cstring, err: runtime.Allocator_Error) #optional_allocator_error { n := append(&b.buf, 0, loc) or_return if n != 1 { return nil, .Out_Of_Memory @@ -851,7 +864,7 @@ Returns: - replaced: The number of replacements - err: if any allocation errors occurred */ -builder_replace_all :: proc(b: ^Builder, old, new: string) -> (replaced: int, err: mem.Allocator_Error) { +builder_replace_all :: proc(b: ^Builder, old, new: string) -> (replaced: int, err: runtime.Allocator_Error) { return builder_replace(b, old, new, -1) } @@ -870,7 +883,7 @@ Returns: - replaced: The number of replacements - err: if any allocation errors occurred */ -builder_replace :: proc(b: ^Builder, old, new: string, n: int, loc := #caller_location) -> (replaced: int, err: mem.Allocator_Error) { +builder_replace :: proc(b: ^Builder, old, new: string, n: int, loc := #caller_location) -> (replaced: int, err: runtime.Allocator_Error) { if old == new || n == 0 { return } From bb9d45867f5c6d0b3801caf3e865aa857db4926e Mon Sep 17 00:00:00 2001 From: Shane Shrybman Date: Thu, 12 Feb 2026 13:35:34 -0500 Subject: [PATCH 7/8] Remove core:mem dependency from strings conversion.odin --- core/strings/conversion.odin | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/core/strings/conversion.odin b/core/strings/conversion.odin index 2e82fff58..2e6bee573 100644 --- a/core/strings/conversion.odin +++ b/core/strings/conversion.odin @@ -1,7 +1,7 @@ package strings +import "base:runtime" import "core:io" -import "core:mem" import "core:unicode" import "core:unicode/utf8" @@ -21,7 +21,7 @@ Returns: - res: A valid UTF-8 string with invalid sequences replaced by `replacement`. - err: An optional allocator error if one occured, `nil` otherwise */ -to_valid_utf8 :: proc(s, replacement: string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +to_valid_utf8 :: proc(s, replacement: string, allocator := context.allocator) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { if len(s) == 0 { return "", nil } @@ -101,7 +101,7 @@ Output: test */ -to_lower :: proc(s: string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +to_lower :: proc(s: string, allocator := context.allocator) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { b: Builder builder_init(&b, 0, len(s), allocator) or_return for r in s { @@ -136,7 +136,7 @@ Output: TEST */ -to_upper :: proc(s: string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +to_upper :: proc(s: string, allocator := context.allocator) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { b: Builder builder_init(&b, 0, len(s), allocator) or_return for r in s { @@ -260,7 +260,7 @@ Returns: - res: The converted string - err: An optional allocator error if one occured, `nil` otherwise */ -to_camel_case :: proc(s: string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +to_camel_case :: proc(s: string, allocator := context.allocator) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { s := s s = trim_space(s) b: Builder @@ -296,7 +296,7 @@ Returns: - res: The converted string - err: An optional allocator error if one occured, `nil` otherwise */ -to_pascal_case :: proc(s: string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +to_pascal_case :: proc(s: string, allocator := context.allocator) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { s := s s = trim_space(s) b: Builder @@ -355,7 +355,7 @@ to_delimiter_case :: proc( delimiter: rune, all_upper_case: bool, allocator := context.allocator, -) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { s := s s = trim_space(s) b: Builder @@ -422,7 +422,7 @@ Output: hello_world */ -to_snake_case :: proc(s: string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +to_snake_case :: proc(s: string, allocator := context.allocator) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { return to_delimiter_case(s, '_', false, allocator) } // Alias for `to_upper_snake_case` @@ -454,7 +454,7 @@ Output: HELLO_WORLD */ -to_upper_snake_case :: proc(s: string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +to_upper_snake_case :: proc(s: string, allocator := context.allocator) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { return to_delimiter_case(s, '_', true, allocator) } /* @@ -484,7 +484,7 @@ Output: hello-world */ -to_kebab_case :: proc(s: string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +to_kebab_case :: proc(s: string, allocator := context.allocator) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { return to_delimiter_case(s, '-', false, allocator) } /* @@ -514,7 +514,7 @@ Output: HELLO-WORLD */ -to_upper_kebab_case :: proc(s: string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +to_upper_kebab_case :: proc(s: string, allocator := context.allocator) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { return to_delimiter_case(s, '-', true, allocator) } /* @@ -544,7 +544,7 @@ Output: Hello_World */ -to_ada_case :: proc(s: string, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { +to_ada_case :: proc(s: string, allocator := context.allocator) -> (res: string, err: runtime.Allocator_Error) #optional_allocator_error { s := s s = trim_space(s) b: Builder From ce2a1f5d022f04932f9b3093807881d1668d148c Mon Sep 17 00:00:00 2001 From: Shane Shrybman Date: Thu, 12 Feb 2026 14:04:38 -0500 Subject: [PATCH 8/8] Remove core:mem dependency from strings builder --- core/strings/builder.odin | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/core/strings/builder.odin b/core/strings/builder.odin index 5adced779..79ba6108f 100644 --- a/core/strings/builder.odin +++ b/core/strings/builder.odin @@ -268,20 +268,17 @@ Output: */ builder_from_bytes :: proc(backing: []byte) -> (res: Builder) { - return Builder{ buf = buffer_from_slice(backing) } -} - -@(private) -buffer_from_slice :: proc "contextless" (backing: $T/[]$E) -> [dynamic]E { - return transmute([dynamic]E)runtime.Raw_Dynamic_Array{ - data = raw_data(backing), - len = 0, - cap = len(backing), - allocator = runtime.Allocator{ - procedure = runtime.nil_allocator_proc, - data = nil, - }, - } + return Builder{ + buf = transmute([dynamic]byte)runtime.Raw_Dynamic_Array{ + data = raw_data(backing), + len = 0, + cap = len(backing), + allocator = runtime.Allocator{ + procedure = runtime.nil_allocator_proc, + data = nil, + }, + }, + } } // Alias to `builder_from_bytes`