Fix missing free on GrowableBitSet. init_new/init_temp for GrowableBitSet, LinkedList, List, HashMap, DString, ByteBuffer. Interface to_string renamed to_new_string. Change in allocator usage, malloc is now heap. Added new_array, new_zero_array, new, new_clear, clone. Concat => concat_new. string::printf => string::new_format, string::tprintf => string::tformat. "to_*" are now "to_new_*" and "to_temp_*". "from_*" is "new_from*"

This commit is contained in:
Christoffer Lerno
2023-11-06 23:20:41 +01:00
committed by Christoffer Lerno
parent 69470b8738
commit 1e38ccdd2b
77 changed files with 1049 additions and 1412 deletions

View File

@@ -31,24 +31,23 @@ fault NumberConversion
FLOAT_OUT_OF_RANGE,
}
macro String printf(String fmt, ..., Allocator* using = mem::heap())
macro String tformat(String fmt, ...)
{
@pool(using)
DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8);
str.appendf(fmt, $vasplat());
return str.str_view();
}
macro String new_format(String fmt, ..., Allocator* allocator = mem::heap())
{
@pool(allocator)
{
DString str;
str.tinit();
str.printf(fmt, $vasplat());
return str.copy_str(using);
DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8);
str.appendf(fmt, $vasplat());
return str.copy_str(allocator);
};
}
macro String tprintf(String fmt, ...)
{
DString str;
str.tinit();
str.printf(fmt, $vasplat());
return str.str_view();
}
macro bool char_in_set(char c, String set)
{
@@ -56,11 +55,11 @@ macro bool char_in_set(char c, String set)
return false;
}
fn String join(String[] s, String joiner, Allocator* using = mem::heap())
fn String join_new(String[] s, String joiner, Allocator* allocator = mem::heap())
{
if (!s)
{
return (String)(calloc(char, 2, .using = using)[:0]);
return (String)allocator.new_zero_array(char, 2)[:0];
}
usz total_size = joiner.len * s.len;
@@ -68,16 +67,16 @@ fn String join(String[] s, String joiner, Allocator* using = mem::heap())
{
total_size += str.len;
}
@pool(using)
@pool(allocator)
{
DString res = dstring::tnew_with_capacity(total_size);
DString res = dstring::temp_with_capacity(total_size);
res.append(s[0]);
foreach (String* &str : s[1..])
{
res.append(joiner);
res.append(*str);
}
return res.copy_str(using);
return res.copy_str(allocator);
};
}
@@ -149,16 +148,16 @@ fn String String.strip_end(string, String needle)
*
* @param [in] s
* @param [in] needle
* @param [&inout] using "The allocator, defaults to the heap allocator"
* @param [&inout] allocator "The allocator, defaults to the heap allocator"
* @param max "Max number of elements, 0 means no limit, defaults to 0"
* @require needle.len > 0 "The needle must be at least 1 character long"
* @ensure return.len > 0
**/
fn String[] String.split(s, String needle, usz max = 0, Allocator* using = mem::heap())
fn String[] String.split(s, String needle, usz max = 0, Allocator* allocator = mem::heap())
{
usz capacity = 16;
usz i = 0;
String* holder = malloc(String, capacity, .using = using);
String* holder = allocator.new_array(String, capacity);
bool no_more = false;
while (!no_more)
{
@@ -177,7 +176,7 @@ fn String[] String.split(s, String needle, usz max = 0, Allocator* using = mem::
if (i == capacity)
{
capacity *= 2;
holder = realloc(holder, String.sizeof * capacity, .using = using);
holder = allocator.realloc(holder, String.sizeof * capacity);
}
holder[i++] = res;
}
@@ -313,19 +312,19 @@ fn usz ZString.len(str)
}
fn ZString String.zstr_copy(s, Allocator* using = mem::heap())
fn ZString String.zstr_copy(s, Allocator* allocator = mem::heap())
{
usz len = s.len;
char* str = malloc(len + 1, .using = using);
char* str = allocator.alloc(len + 1);
mem::copy(str, s.ptr, len);
str[len] = 0;
return (ZString)str;
}
fn String String.concat(s1, String s2, Allocator* using = mem::heap())
fn String String.concat(s1, String s2, Allocator* allocator = mem::heap())
{
usz full_len = s1.len + s2.len;
char* str = malloc(full_len + 1, .using = using);
char* str = allocator.alloc(full_len + 1);
usz s1_len = s1.len;
mem::copy(str, s1.ptr, s1_len);
mem::copy(str + s1_len, s2.ptr, s2.len);
@@ -338,25 +337,33 @@ fn String String.tconcat(s1, String s2) => s1.concat(s2, mem::temp());
fn ZString String.zstr_tcopy(s) => s.zstr_copy(mem::temp()) @inline;
fn String String.copy(s, Allocator* using = mem::heap())
fn String String.copy(s, Allocator* allocator = mem::heap())
{
usz len = s.len;
char* str = malloc(len + 1, .using = using);
char* str = allocator.alloc(len + 1);
mem::copy(str, s.ptr, len);
str[len] = 0;
return (String)str[:len];
}
fn void String.free(&s, Allocator* using = mem::heap())
fn void String.free(&s, Allocator* allocator = mem::heap())
{
if (!s.len) return;
mem::free(s.ptr, .using = using);
allocator.free(s.ptr);
*s = "";
}
fn String String.tcopy(s) => s.copy(mem::temp()) @inline;
fn String ZString.copy(z, Allocator* using = mem::heap()) => z.str_view().copy(using) @inline;
fn String ZString.tcopy(z) => z.str_view().copy(mem::temp()) @inline;
fn String ZString.copy(z, Allocator* allocator = mem::temp())
{
return z.str_view().copy(allocator) @inline;
}
fn String ZString.tcopy(z)
{
return z.str_view().copy(mem::temp()) @inline;
}
/**
* Convert an UTF-8 string to UTF-16
@@ -364,80 +371,114 @@ fn String ZString.tcopy(z) => z.str_view().copy(mem::temp()) @inline;
* @return! UnicodeResult.INVALID_UTF8 "If the string contained an invalid UTF-8 sequence"
* @return! AllocationFailure "If allocation of the string fails"
**/
fn Char16[]! String.to_utf16(s, Allocator* using = mem::heap())
fn Char16[]! String.to_new_utf16(s, Allocator* allocator = mem::heap())
{
usz len16 = conv::utf16len_for_utf8(s);
Char16* data = malloc_checked(Char16, len16 + 1, .using = using)!;
Char16* data = allocator.new_array_checked(Char16, len16 + 1)!;
conv::utf8to16_unsafe(s, data)!;
data[len16] = 0;
return data[:len16];
}
fn WString! String.to_wstring(s, Allocator* using = mem::heap()) => (WString)s.to_utf16(using).ptr;
/**
* Convert an UTF-8 string to UTF-16
* @return "The UTF-16 string as a slice, allocated using the given allocator"
* @return! UnicodeResult.INVALID_UTF8 "If the string contained an invalid UTF-8 sequence"
* @return! AllocationFailure "If allocation of the string fails"
**/
fn Char16[]! String.to_temp_utf16(s)
{
return s.to_new_utf16(mem::temp());
}
fn Char32[]! String.to_utf32(s, Allocator* using = mem::heap())
fn WString! String.to_new_wstring(s, Allocator* allocator = mem::heap())
{
return (WString)s.to_new_utf16(allocator).ptr;
}
fn WString! String.to_temp_wstring(s)
{
return (WString)s.to_temp_utf16().ptr;
}
fn Char32[]! String.to_new_utf32(s, Allocator* allocator = mem::heap())
{
usz codepoints = conv::utf8_codepoints(s);
Char32* data = malloc_checked(Char32, codepoints + 1, .using = using)!;
Char32* data = allocator.new_array(Char32, codepoints + 1);
conv::utf8to32_unsafe(s, data)!;
data[codepoints] = 0;
return data[:codepoints];
}
fn Char32[]! String.to_temp_utf32(s)
{
return s.to_new_utf32(mem::temp());
}
fn void String.convert_ascii_to_lower(s)
{
foreach (&c : s) if (c.is_upper()) *c += 'a' - 'A';
}
fn String String.ascii_to_lower(s, Allocator* using = mem::heap())
fn String String.new_ascii_to_lower(s, Allocator* allocator = mem::heap())
{
String copy = s.copy(using);
String copy = s.copy(allocator);
copy.convert_ascii_to_lower();
return copy;
}
fn String String.temp_ascii_to_lower(s, Allocator* allocator = mem::heap())
{
return s.new_ascii_to_lower(mem::temp());
}
fn void String.convert_ascii_to_upper(s)
{
foreach (&c : s) if (c.is_lower()) *c -= 'a' - 'A';
}
fn String String.ascii_to_upper(s, Allocator* using = mem::heap())
fn String String.new_ascii_to_upper(s, Allocator* allocator = mem::heap())
{
String copy = s.copy(using);
String copy = s.copy(allocator);
copy.convert_ascii_to_upper();
return copy;
}
fn String! from_utf32(Char32[] utf32, Allocator* using = mem::heap())
fn String String.temp_ascii_to_upper(s)
{
return s.new_ascii_to_upper(mem::temp());
}
fn String! new_from_utf32(Char32[] utf32, Allocator* allocator = mem::heap())
{
usz len = conv::utf8len_for_utf32(utf32);
char* data = malloc_checked(len + 1, .using = using)!;
defer catch free(data, .using = using);
char* data = allocator.alloc_checked(len + 1)!;
defer catch allocator.free(data);
conv::utf32to8_unsafe(utf32, data);
data[len] = 0;
return (String)data[:len];
}
fn String! from_utf16(Char16[] utf16, Allocator* using = mem::heap())
fn String! new_from_utf16(Char16[] utf16, Allocator* allocator = mem::heap())
{
usz len = conv::utf8len_for_utf16(utf16);
char* data = malloc_checked(len + 1, .using = using)!;
defer catch free(data, .using = using);
char* data = allocator.alloc_checked(len + 1)!;
defer catch allocator.free(data);
conv::utf16to8_unsafe(utf16, data)!;
data[len] = 0;
return (String)data[:len];
}
fn String! from_wstring(WString wstring, Allocator* using = mem::heap())
fn String! new_from_wstring(WString wstring, Allocator* allocator = mem::heap())
{
usz utf16_len;
while (wstring[utf16_len] != 0) utf16_len++;
Char16[] utf16 = wstring[:utf16_len];
return from_utf16(utf16, using);
return new_from_utf16(utf16, allocator);
}
fn String! temp_from_wstring(WString wstring) => from_wstring(wstring) @inline;
fn String! temp_from_utf16(Char16[] utf16) => temp_from_utf16(utf16) @inline;
fn String! temp_from_wstring(WString wstring) => new_from_wstring(wstring, mem::temp()) @inline;
fn String! temp_from_utf16(Char16[] utf16) => new_from_utf16(utf16, mem::temp()) @inline;
fn usz String.utf8_codepoints(s)
{
@@ -449,7 +490,6 @@ fn usz String.utf8_codepoints(s)
return len;
}
macro String.to_integer(string, $Type)
{
usz len = string.len;
@@ -521,10 +561,6 @@ macro String.to_integer(string, $Type)
return value;
}
fn Char16[]! String.to_temp_utf16(s) => s.to_utf16(mem::temp());
fn WString! String.to_temp_wstring(s) => s.to_wstring(mem::temp());
fn int128! String.to_int128(s) => s.to_integer(int128);
fn long! String.to_long(s) => s.to_integer(long);
fn int! String.to_int(s) => s.to_integer(int);