From 782d5374c95a1557aaa69529c86f0c1634b1f002 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Sun, 3 Apr 2022 15:05:50 +0100 Subject: [PATCH] builtin: add an `array.drop(n)` method (#13907) --- vlib/builtin/array.v | 22 ++++++++++++++++++++++ vlib/builtin/array_test.v | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index 32cf21e7a7..6d7404816a 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -328,6 +328,28 @@ pub fn (mut a array) trim(index int) { } } +// drop advances the array past the first `num` elements whilst preserving spare capacity. +// If `num` is greater than `len` the array will be emptied. +// Example: +// ```v +// mut a := [1,2] +// a << 3 +// a.drop(2) +// assert a == [3] +// assert a.cap > a.len +// ``` +pub fn (mut a array) drop(num int) { + if num <= 0 { + return + } + n := if num <= a.len { num } else { a.len } + blen := n * a.element_size + a.data = unsafe { &byte(a.data) + blen } + a.offset += blen + a.len -= n + a.cap -= n +} + // we manually inline this for single operations for performance without -prod [inline; unsafe] fn (a array) get_unsafe(i int) voidptr { diff --git a/vlib/builtin/array_test.v b/vlib/builtin/array_test.v index c2a5eac9d6..e81e1fe0aa 100644 --- a/vlib/builtin/array_test.v +++ b/vlib/builtin/array_test.v @@ -1046,6 +1046,40 @@ fn test_trim() { assert arr.last() == 2 } +[manualfree] +fn test_drop() { + mut a := [1, 2] + a << 3 // pushing assures reallocation; a.cap now should be bigger: + assert a.cap > 3 + // eprintln('>>> a.cap: $a.cap | a.len: $a.len') + + a.drop(-1000) + assert a == [1, 2, 3] // a.drop( negative ) should NOT modify the array + // eprintln('>>> a.cap: $a.cap | a.len: $a.len') + + a.drop(2) + assert a == [3] + assert a.cap > a.len + // eprintln('>>> a.cap: $a.cap | a.len: $a.len') + + a.drop(10) + assert a == [] + assert a.cap > a.len + // eprintln('>>> a.cap: $a.cap | a.len: $a.len') + + a << 123 + a << 456 + a << 789 + // eprintln('>>> a.cap: $a.cap | a.len: $a.len') + assert a == [123, 456, 789] + + a.drop(10) + assert a == [] + // eprintln('>>> a.cap: $a.cap | a.len: $a.len') + + unsafe { a.free() } // test offset OK +} + fn test_hex() { // array hex st := [byte(`V`), `L`, `A`, `N`, `G`]