1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

builtin: add .nogrow and .nofree flags to array (#16661)

This commit is contained in:
l-m 2022-12-14 18:44:14 +11:00 committed by GitHub
parent b07e447764
commit acbd93b54c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 0 deletions

View File

@ -24,6 +24,8 @@ pub mut:
pub enum ArrayFlags {
noslices // when <<, `.noslices` will free the old data block immediately (you have to be sure, that there are *no slices* to that specific array). TODO: integrate with reference counting/compiler support for the static cases.
noshrink // when `.noslices` and `.noshrink` are *both set*, .delete(x) will NOT allocate new memory and free the old. It will just move the elements in place, and adjust .len.
nogrow // the array will never be allowed to grow past `.cap`. set `.nogrow` and `.noshrink` for a truly fixed heap array
nofree // `.data` will never be freed
}
// Internal function, used by V (`nums := []int`)
@ -133,6 +135,9 @@ fn (mut a array) ensure_cap(required int) {
if required <= a.cap {
return
}
if a.flags.has(.nogrow) {
panic('array.ensure_cap: array with the flag `.nogrow` cannot grow in size, array required new size: ${required}')
}
mut cap := if a.cap > 0 { a.cap } else { 2 }
for required > cap {
cap *= 2
@ -698,6 +703,9 @@ pub fn (a &array) free() {
// if a.is_slice {
// return
// }
if a.flags.has(.nofree) {
return
}
mblock_ptr := &u8(u64(a.data) - u64(a.offset))
unsafe { free(mblock_ptr) }
}

View File

@ -55,3 +55,40 @@ fn test_array_cap_shrinkage_after_deletion() {
assert a.len == 12
assert a.cap == 20
}
fn fixed_array_on_the_heap(len int, size int) []u8 {
data := vcalloc(size)
println(ptr_str(data))
return unsafe {
array{
element_size: 1
len: len
cap: size
data: data
flags: .noshrink | .nogrow | .nofree
}
}
}
fn test_array_fixed_growth() {
mut x := fixed_array_on_the_heap(0, 10)
println(ptr_str(x.data))
x << 5
x << 10
x << 15
x << 20
dump(x)
dump(x.flags)
assert x[2] == 15
assert x.flags == .noshrink | .nogrow | .nofree
}
fn test_array_fixed() {
mut x := fixed_array_on_the_heap(10, 10)
println(ptr_str(x.data))
x[2] = 5
dump(x)
dump(x.flags)
assert x[2] == 5
assert x.flags == .noshrink | .nogrow | .nofree
}