From e3d379a1ebf63a48f57a58d4f25fb85f83d57fed Mon Sep 17 00:00:00 2001 From: Wertzui123 <46199283+Wertzui123@users.noreply.github.com> Date: Thu, 30 Sep 2021 08:32:20 +0200 Subject: [PATCH] builtin: add byte.repeat() and rune.repeat() (#12007) --- vlib/builtin/int.v | 22 ++++++++++++++++++++++ vlib/builtin/int_test.v | 7 +++++++ vlib/builtin/rune.v | 14 ++++++++++++++ vlib/builtin/rune_test.v | 13 +++++++++++++ 4 files changed, 56 insertions(+) create mode 100644 vlib/builtin/rune_test.v diff --git a/vlib/builtin/int.v b/vlib/builtin/int.v index 87594e90e429ed..00a44820a28cfb 100644 --- a/vlib/builtin/int.v +++ b/vlib/builtin/int.v @@ -507,3 +507,25 @@ pub fn (b []byte) bytestr() string { return tos(buf, b.len) } } + +// repeat returns a new string with `count` number of copies of the byte it was called on. +pub fn (b byte) repeat(count int) string { + if count < 0 { + panic('byte.repeat: count is negative: $count') + } else if count == 0 { + return '' + } else if count == 1 { + return b.ascii_str() + } + mut ret := unsafe { malloc_noscan(count + 1) } + for i in 0 .. count { + unsafe { + ret[i] = b + } + } + new_len := count + unsafe { + ret[new_len] = 0 + } + return unsafe { ret.vstring_with_len(new_len) } +} diff --git a/vlib/builtin/int_test.v b/vlib/builtin/int_test.v index 3f233f1ebb74d7..17976685a12aaf 100644 --- a/vlib/builtin/int_test.v +++ b/vlib/builtin/int_test.v @@ -239,3 +239,10 @@ fn test_int_to_hex() { assert i64(-1).hex() == 'ffffffffffffffff' assert u64(18446744073709551615).hex() == 'ffffffffffffffff' } + +fn test_repeat() { + b := byte(`V`) + assert b.repeat(5) == 'VVVVV' + assert b.repeat(1) == b.ascii_str() + assert b.repeat(0) == '' +} diff --git a/vlib/builtin/rune.v b/vlib/builtin/rune.v index 806010c3019b7c..d08f1f6f3015b0 100644 --- a/vlib/builtin/rune.v +++ b/vlib/builtin/rune.v @@ -39,3 +39,17 @@ pub fn (ra []rune) string() string { unsafe { sb.free() } return res } + +// repeat returns a new string with `count` number of copies of the rune it was called on. +pub fn (c rune) repeat(count int) string { + if count < 0 { + panic('rune.repeat: count is negative: $count') + } else if count == 0 { + return '' + } else if count == 1 { + return c.str() + } + mut buffer := [5]byte{} + res := unsafe { utf32_to_str_no_malloc(u32(c), &buffer[0]) } + return res.repeat(count) +} diff --git a/vlib/builtin/rune_test.v b/vlib/builtin/rune_test.v new file mode 100644 index 00000000000000..6b7e98786fbfb1 --- /dev/null +++ b/vlib/builtin/rune_test.v @@ -0,0 +1,13 @@ +fn test_repeat() { + r1 := `V` + r2 := `👋` + + assert r1.repeat(5) == 'VVVVV' + assert r2.repeat(5) == '👋👋👋👋👋' + + assert r1.repeat(1) == r1.str() + assert r2.repeat(1) == r2.str() + + assert r1.repeat(0) == '' + assert r2.repeat(0) == '' +}