From 17fcc788f201ccf7e597ae6bc11c0ba3341e2a8d Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Tue, 8 Mar 2022 07:44:04 +0000 Subject: [PATCH] arrays: add generic copy fn (#13677) --- vlib/arrays/arrays.v | 12 ++++++++++++ vlib/arrays/arrays_test.v | 17 +++++++++++++++++ vlib/builtin/array.v | 4 ++-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/vlib/arrays/arrays.v b/vlib/arrays/arrays.v index fda4c84045..cacd9906df 100644 --- a/vlib/arrays/arrays.v +++ b/vlib/arrays/arrays.v @@ -530,3 +530,15 @@ fn swap_nonoverlapping(x_ &T, y_ &T, count int) { memswap(x, y, len) } } + +// copy copies the `src` array elements to the `dst` array. +// The number of the elements copied is the minimum of the length of both arrays. +// Returns the number of elements copied. +pub fn copy(dst []T, src []T) int { + min := if dst.len < src.len { dst.len } else { src.len } + if min > 0 { + blen := min * int(sizeof(T)) + unsafe { vmemmove(&T(dst.data), src.data, blen) } + } + return min +} diff --git a/vlib/arrays/arrays_test.v b/vlib/arrays/arrays_test.v index c61d71f74f..dfb3f364ff 100644 --- a/vlib/arrays/arrays_test.v +++ b/vlib/arrays/arrays_test.v @@ -264,3 +264,20 @@ fn test_rotate_left_string() { rotate_left(mut x, 2) assert x == ['x3', 'x4', 'x5', 'x6', 'x1', 'x2'] } + +fn test_copy() { + mut a := [1, 2, 3] + mut b := [4, 5, 6] + assert copy(b, a) == 3 + assert b == [1, 2, 3] + // check independent copies + b[0] = 99 + assert a[0] == 1 + // check longer src + b << 7 + assert copy(a, b) == 3 + assert a == [99, 2, 3] + // check longer dst + assert copy(b, [8, 9]) == 2 + assert b == [8, 9, 3, 7] +} diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index 8e741567f1..50e927ead6 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -815,11 +815,11 @@ pub fn (b []byte) hex() string { // The number of the elements copied is the minimum of the length of both arrays. // Returns the number of elements copied. // NOTE: This is not an `array` method. It is a function that takes two arrays of bytes. -// TODO: implement for all types +// See also: `arrays.copy`. pub fn copy(dst []byte, src []byte) int { min := if dst.len < src.len { dst.len } else { src.len } if min > 0 { - unsafe { vmemcpy(&byte(dst.data), src.data, min) } + unsafe { vmemmove(&byte(dst.data), src.data, min) } } return min }