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:
@ -24,6 +24,8 @@ pub mut:
|
|||||||
pub enum ArrayFlags {
|
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.
|
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.
|
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`)
|
// Internal function, used by V (`nums := []int`)
|
||||||
@ -133,6 +135,9 @@ fn (mut a array) ensure_cap(required int) {
|
|||||||
if required <= a.cap {
|
if required <= a.cap {
|
||||||
return
|
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 }
|
mut cap := if a.cap > 0 { a.cap } else { 2 }
|
||||||
for required > cap {
|
for required > cap {
|
||||||
cap *= 2
|
cap *= 2
|
||||||
@ -698,6 +703,9 @@ pub fn (a &array) free() {
|
|||||||
// if a.is_slice {
|
// if a.is_slice {
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
|
if a.flags.has(.nofree) {
|
||||||
|
return
|
||||||
|
}
|
||||||
mblock_ptr := &u8(u64(a.data) - u64(a.offset))
|
mblock_ptr := &u8(u64(a.data) - u64(a.offset))
|
||||||
unsafe { free(mblock_ptr) }
|
unsafe { free(mblock_ptr) }
|
||||||
}
|
}
|
||||||
|
@ -55,3 +55,40 @@ fn test_array_cap_shrinkage_after_deletion() {
|
|||||||
assert a.len == 12
|
assert a.len == 12
|
||||||
assert a.cap == 20
|
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
|
||||||
|
}
|
Reference in New Issue
Block a user