Skip to content

Commit

Permalink
strings: add Bulder.write_decimal/1 method (write a decimal number, w…
Browse files Browse the repository at this point in the history
…ithout additional allocations) (#19625)
  • Loading branch information
spytheman committed Oct 22, 2023
1 parent 39310a2 commit af7a213
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
29 changes: 28 additions & 1 deletion vlib/strings/builder.c.v
Expand Up @@ -74,7 +74,34 @@ pub fn (mut b Builder) write_byte(data byte) {
b << data
}

// write implements the Writer interface
// write_decimal appends a decimal representation of the number `n` into the builder `b`,
// without dynamic allocation. The higher order digits come first, i.e. 6123 will be written
// with the digit `6` first, then `1`, then `2` and `3` last.
[direct_array_access]
pub fn (mut b Builder) write_decimal(n i64) {
if n == 0 {
b.write_u8(0x30)
return
}
mut buf := [25]u8{}
mut x := if n < 0 { -n } else { n }
mut i := 24
for x != 0 {
nextx := x / 10
r := x % 10
buf[i] = u8(r) + 0x30
x = nextx
i--
}
if n < 0 {
buf[i] = `-`
i--
}
unsafe { b.write_ptr(&buf[i + 1], 24 - i) }
}

// write implements the io.Writer interface, that is why it
// it returns how many bytes were written to the string builder.
pub fn (mut b Builder) write(data []u8) !int {
if data.len == 0 {
return 0
Expand Down
22 changes: 22 additions & 0 deletions vlib/strings/builder_test.v
Expand Up @@ -144,3 +144,25 @@ fn test_drain_builder() {
assert target_sb.len == 3
assert target_sb.str() == 'abc'
}

[manualfree]
fn sb_i64_str(n i64) string {
mut sb := strings.new_builder(24)
defer {
unsafe { sb.free() }
}
sb.write_decimal(n)
return sb.str()
}

fn test_write_decimal() {
assert sb_i64_str(0) == '0'
assert sb_i64_str(1) == '1'
assert sb_i64_str(-1) == '-1'
assert sb_i64_str(1001) == '1001'
assert sb_i64_str(-1001) == '-1001'
assert sb_i64_str(1234567890) == '1234567890'
assert sb_i64_str(-1234567890) == '-1234567890'
assert sb_i64_str(9223372036854775807) == '9223372036854775807'
assert sb_i64_str(-9223372036854775807) == '-9223372036854775807'
}

0 comments on commit af7a213

Please sign in to comment.