builtin: unsafe vlib pointer indexing (#5836)

pull/5842/head
Nick Treleaven 2020-07-15 20:56:50 +01:00 committed by GitHub
parent cc7c8009a1
commit f5e6a83a05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 326 additions and 189 deletions

View File

@ -488,12 +488,18 @@ pub fn (b []byte) hex() string {
mut dst_i := 0
for i in b {
n0 := i >> 4
hex[dst_i++] = if n0 < 10 { n0 + `0` } else { n0 + byte(87) }
unsafe {
hex[dst_i++] = if n0 < 10 { n0 + `0` } else { n0 + byte(87) }
}
n1 := i & 0xF
hex[dst_i++] = if n1 < 10 { n1 + `0` } else { n1 + byte(87) }
unsafe {
hex[dst_i++] = if n1 < 10 { n1 + `0` } else { n1 + byte(87) }
}
}
unsafe {
hex[dst_i] = `\0`
return tos(hex,dst_i)
}
hex[dst_i] = `\0`
return tos(hex,dst_i)
}
// copy copies the `src` byte array elements to the `dst` byte array.

View File

@ -72,13 +72,17 @@ pub fn (nn int) str_l(max int) string {
}
mut index := max
buf[index--] = `\0`
unsafe {
buf[index--] = `\0`
}
for n > 0 {
n1 := n / 100
d = ((n - (n1 * 100)) << 1)
n = n1
buf[index--] = digit_pairs.str[d++]
buf[index--] = digit_pairs.str[d]
unsafe {
buf[index--] = digit_pairs.str[d++]
buf[index--] = digit_pairs.str[d]
}
}
index++
@ -90,13 +94,15 @@ pub fn (nn int) str_l(max int) string {
// Prepend - if it's negative
if is_neg {
index--
buf[index] = `-`
unsafe {
buf[index] = `-`
}
}
unsafe {
C.memmove(buf,buf+index, (max-index)+1 )
return tos(buf, (max-index))
}
return tos(buf, (max-index))
//return tos(buf + index, (max-index))
}
@ -126,13 +132,17 @@ pub fn (nn u32) str() string {
mut buf := malloc(max + 1)
mut index := max
buf[index--] = `\0`
unsafe {
buf[index--] = `\0`
}
for n > 0 {
n1 := n / u32(100)
d = ((n - (n1 * u32(100))) << u32(1))
n = n1
buf[index--] = digit_pairs[d++]
buf[index--] = digit_pairs[d]
unsafe {
buf[index--] = digit_pairs[d++]
buf[index--] = digit_pairs[d]
}
}
index++
@ -143,8 +153,8 @@ pub fn (nn u32) str() string {
unsafe {
C.memmove(buf,buf+index, (max-index)+1 )
return tos(buf, (max-index))
}
return tos(buf, (max-index))
//return tos(buf + index, (max-index))
}
@ -169,13 +179,17 @@ pub fn (nn i64) str() string {
}
mut index := max
buf[index--] = `\0`
unsafe {
buf[index--] = `\0`
}
for n > 0 {
n1 := n / i64(100)
d = ((n - (n1 * i64(100))) << i64(1))
n = n1
buf[index--] = digit_pairs[d++]
buf[index--] = digit_pairs[d]
unsafe {
buf[index--] = digit_pairs[d++]
buf[index--] = digit_pairs[d]
}
}
index++
@ -187,13 +201,15 @@ pub fn (nn i64) str() string {
// Prepend - if it's negative
if is_neg {
index--
buf[index] = `-`
unsafe {
buf[index] = `-`
}
}
unsafe {
C.memmove(buf,buf+index, (max-index)+1 )
return tos(buf, (max-index))
}
return tos(buf, (max-index))
//return tos(buf + index, (max-index))
}
@ -207,13 +223,17 @@ pub fn (nn u64) str() string {
mut buf := vcalloc(max + 1)
mut index := max
buf[index--] = `\0`
unsafe {
buf[index--] = `\0`
}
for n > 0 {
n1 := n / 100
d = ((n - (n1 * 100)) << 1)
n = n1
buf[index--] = digit_pairs[d++]
buf[index--] = digit_pairs[d]
unsafe {
buf[index--] = digit_pairs[d++]
buf[index--] = digit_pairs[d]
}
}
index++
@ -224,8 +244,8 @@ pub fn (nn u64) str() string {
unsafe {
C.memmove(buf,buf+index, (max-index)+1 )
return tos(buf, (max-index))
}
return tos(buf, (max-index))
//return tos(buf + index, (max-index))
}
@ -258,11 +278,15 @@ pub fn (nn byte) hex() string {
mut buf := malloc(max + 1)
mut index := max
buf[index--] = `\0`
unsafe {
buf[index--] = `\0`
}
for n > 0 {
d := n & 0xF
n = n >> 4
buf[index--] = if d < 10 { d + `0` } else { d + 87 }
unsafe {
buf[index--] = if d < 10 { d + `0` } else { d + 87 }
}
}
//buf[index--] = `x`
//buf[index] = `0`
@ -287,11 +311,15 @@ pub fn (nn u16) hex() string {
mut buf := malloc(max + 1)
mut index := max
buf[index--] = `\0`
unsafe {
buf[index--] = `\0`
}
for n > 0 {
d := byte(n & 0xF)
n = n >> 4
buf[index--] = if d < 10 { d + `0` } else { d + 87 }
unsafe {
buf[index--] = if d < 10 { d + `0` } else { d + 87 }
}
}
//buf[index--] = `x`
//buf[index] = `0`
@ -316,11 +344,15 @@ pub fn (nn u32) hex() string {
mut buf := malloc(max + 1)
mut index := max
buf[index--] = `\0`
unsafe {
buf[index--] = `\0`
}
for n > 0 {
d := byte(n & 0xF)
n = n >> 4
buf[index--] = if d < 10 { d + `0` } else { d + 87 }
unsafe {
buf[index--] = if d < 10 { d + `0` } else { d + 87 }
}
}
//buf[index--] = `x`
//buf[index] = `0`
@ -349,11 +381,15 @@ pub fn (nn u64) hex() string {
mut buf := malloc(max + 1)
mut index := max
buf[index--] = `\0`
unsafe {
buf[index--] = `\0`
}
for n > 0 {
d := byte(n & 0xF)
n = n >> 4
buf[index--] = if d < 10 { d + `0` } else { d + 87 }
unsafe {
buf[index--] = if d < 10 { d + `0` } else { d + 87 }
}
}
//buf[index--] = `x`
//buf[index] = `0`
@ -361,8 +397,8 @@ pub fn (nn u64) hex() string {
unsafe {
C.memmove(buf,buf+index, (max-index)+1 )
return tos(buf, (max-index))
}
return tos(buf, (max-index))
//return tos(buf + index, (max-index))
}
@ -405,8 +441,10 @@ pub fn (c byte) str() string {
str: malloc(2)
len: 1
}
str.str[0] = c
str.str[1] = `\0`
unsafe {
str.str[0] = c
str.str[1] = `\0`
}
return str
}

View File

@ -120,12 +120,14 @@ fn new_dense_array(value_bytes int) DenseArray {
fn (mut d DenseArray) push(key string, value voidptr) u32 {
if d.cap == d.len {
d.cap += d.cap >> 3
d.keys = &string(v_realloc(d.keys, sizeof(string) * d.cap))
d.values = v_realloc(d.values, u32(d.value_bytes) * d.cap)
unsafe {
d.keys = &string(v_realloc(d.keys, sizeof(string) * d.cap))
d.values = v_realloc(d.values, u32(d.value_bytes) * d.cap)
}
}
push_index := d.len
d.keys[push_index] = key
unsafe {
d.keys[push_index] = key
C.memcpy(d.values + push_index * u32(d.value_bytes), value, d.value_bytes)
}
d.len++
@ -148,11 +150,13 @@ fn (mut d DenseArray) zeros_to_end() {
mut tmp_value := malloc(d.value_bytes)
mut count := u32(0)
for i in 0 .. d.len {
if d.keys[i].str != 0 {
if unsafe {d.keys[i]}.str != 0 {
// swap keys
tmp_key := d.keys[count]
d.keys[count] = d.keys[i]
d.keys[i] = tmp_key
unsafe {
tmp_key := d.keys[count]
d.keys[count] = d.keys[i]
d.keys[i] = tmp_key
}
// swap values (TODO: optimize)
unsafe {
C.memcpy(tmp_value, d.values + count * u32(d.value_bytes), d.value_bytes)
@ -166,8 +170,10 @@ fn (mut d DenseArray) zeros_to_end() {
d.deletes = 0
d.len = count
d.cap = if count < 8 { u32(8) } else { count }
d.keys = &string(v_realloc(d.keys, sizeof(string) * d.cap))
d.values = v_realloc(d.values, u32(d.value_bytes) * d.cap)
unsafe {
d.keys = &string(v_realloc(d.keys, sizeof(string) * d.cap))
d.values = v_realloc(d.values, u32(d.value_bytes) * d.cap)
}
}
pub struct map {
@ -229,7 +235,7 @@ fn (m &map) key_to_index(key string) (u32,u32) {
fn (m &map) meta_less(_index u32, _metas u32) (u32,u32) {
mut index := _index
mut meta := _metas
for meta < m.metas[index] {
for meta < unsafe {m.metas[index]} {
index += 2
meta += probe_inc
}
@ -241,20 +247,26 @@ fn (mut m map) meta_greater(_index u32, _metas u32, kvi u32) {
mut meta := _metas
mut index := _index
mut kv_index := kvi
for m.metas[index] != 0 {
if meta > m.metas[index] {
tmp_meta := m.metas[index]
m.metas[index] = meta
meta = tmp_meta
tmp_index := m.metas[index + 1]
m.metas[index + 1] = kv_index
for unsafe {m.metas[index]} != 0 {
if meta > unsafe {m.metas[index]} {
unsafe {
tmp_meta := m.metas[index]
m.metas[index] = meta
meta = tmp_meta
}
tmp_index := unsafe {m.metas[index + 1]}
unsafe {
m.metas[index + 1] = kv_index
}
kv_index = tmp_index
}
index += 2
meta += probe_inc
}
m.metas[index] = meta
m.metas[index + 1] = kv_index
unsafe {
m.metas[index] = meta
m.metas[index + 1] = kv_index
}
probe_count := (meta >> hashbits) - 1
m.ensure_extra_metas(probe_count)
}
@ -287,9 +299,9 @@ fn (mut m map) set(k string, value voidptr) {
mut index,mut meta := m.key_to_index(key)
index,meta = m.meta_less(index, meta)
// While we might have a match
for meta == m.metas[index] {
kv_index := m.metas[index + 1]
if fast_string_eq(key, m.key_values.keys[kv_index]) {
for meta == unsafe {m.metas[index]} {
kv_index := unsafe {m.metas[index + 1]}
if fast_string_eq(key, unsafe {m.key_values.keys[kv_index]}) {
unsafe {
C.memcpy(m.key_values.values + kv_index * u32(m.value_bytes), value, m.value_bytes)
}
@ -326,13 +338,15 @@ fn (mut m map) expand() {
// the max_load_factor in an operation.
fn (mut m map) rehash() {
meta_bytes := sizeof(u32) * (m.cap + 2 + m.extra_metas)
m.metas = &u32(v_realloc(m.metas, meta_bytes))
C.memset(m.metas, 0, meta_bytes)
unsafe {
m.metas = &u32(v_realloc(m.metas, meta_bytes))
C.memset(m.metas, 0, meta_bytes)
}
for i := u32(0); i < m.key_values.len; i++ {
if m.key_values.keys[i].str == 0 {
if unsafe {m.key_values.keys[i]}.str == 0 {
continue
}
mut index,mut meta := m.key_to_index(m.key_values.keys[i])
mut index,mut meta := m.key_to_index(unsafe {m.key_values.keys[i]})
index,meta = m.meta_less(index, meta)
m.meta_greater(index, meta, i)
}
@ -345,16 +359,16 @@ fn (mut m map) cached_rehash(old_cap u32) {
m.metas = &u32(vcalloc(int(sizeof(u32) * (m.cap + 2 + m.extra_metas))))
old_extra_metas := m.extra_metas
for i := u32(0); i <= old_cap + old_extra_metas; i += 2 {
if old_metas[i] == 0 {
if unsafe {old_metas[i]} == 0 {
continue
}
old_meta := old_metas[i]
old_meta := unsafe {old_metas[i]}
old_probe_count := ((old_meta >> hashbits) - 1) << 1
old_index := (i - old_probe_count) & (m.cap >> 1)
mut index := (old_index | (old_meta << m.shift)) & m.cap
mut meta := (old_meta & hash_mask) | probe_inc
index,meta = m.meta_less(index, meta)
kv_index := old_metas[i + 1]
kv_index := unsafe {old_metas[i + 1]}
m.meta_greater(index, meta, kv_index)
}
unsafe{
@ -369,9 +383,9 @@ fn (mut m map) get_and_set(key string, zero voidptr) voidptr {
for {
mut index,mut meta := m.key_to_index(key)
for {
if meta == m.metas[index] {
kv_index := m.metas[index + 1]
if fast_string_eq(key, m.key_values.keys[kv_index]) {
if meta == unsafe {m.metas[index]} {
kv_index := unsafe {m.metas[index + 1]}
if fast_string_eq(key, unsafe {m.key_values.keys[kv_index]}) {
unsafe {
return voidptr(m.key_values.values + kv_index * u32(m.value_bytes))
}
@ -379,7 +393,7 @@ fn (mut m map) get_and_set(key string, zero voidptr) voidptr {
}
index += 2
meta += probe_inc
if meta > m.metas[index] { break }
if meta > unsafe {m.metas[index]} { break }
}
// Key not found, insert key with zero-value
m.set(key, zero)
@ -392,9 +406,9 @@ fn (mut m map) get_and_set(key string, zero voidptr) voidptr {
fn (m map) get(key string, zero voidptr) voidptr {
mut index,mut meta := m.key_to_index(key)
for {
if meta == m.metas[index] {
kv_index := m.metas[index + 1]
if fast_string_eq(key, m.key_values.keys[kv_index]) {
if meta == unsafe {m.metas[index]} {
kv_index := unsafe {m.metas[index + 1]}
if fast_string_eq(key, unsafe {m.key_values.keys[kv_index]}) {
unsafe {
return voidptr(m.key_values.values + kv_index * u32(m.value_bytes))
}
@ -402,7 +416,7 @@ fn (m map) get(key string, zero voidptr) voidptr {
}
index += 2
meta += probe_inc
if meta > m.metas[index] { break }
if meta > unsafe {m.metas[index]} { break }
}
return zero
}
@ -411,15 +425,15 @@ fn (m map) get(key string, zero voidptr) voidptr {
fn (m map) exists(key string) bool {
mut index,mut meta := m.key_to_index(key)
for {
if meta == m.metas[index] {
kv_index := m.metas[index + 1]
if fast_string_eq(key, m.key_values.keys[kv_index]) {
if meta == unsafe {m.metas[index]} {
kv_index := unsafe {m.metas[index + 1]}
if fast_string_eq(key, unsafe {m.key_values.keys[kv_index]}) {
return true
}
}
index += 2
meta += probe_inc
if meta > m.metas[index] { break }
if meta > unsafe {m.metas[index]} { break }
}
return false
}
@ -429,20 +443,26 @@ pub fn (mut m map) delete(key string) {
mut index,mut meta := m.key_to_index(key)
index,meta = m.meta_less(index, meta)
// Perform backwards shifting
for meta == m.metas[index] {
kv_index := m.metas[index + 1]
if fast_string_eq(key, m.key_values.keys[kv_index]) {
for (m.metas[index + 2] >> hashbits) > 1 {
m.metas[index] = m.metas[index + 2] - probe_inc
m.metas[index + 1] = m.metas[index + 3]
for meta == unsafe {m.metas[index]} {
kv_index := unsafe {m.metas[index + 1]}
if fast_string_eq(key, unsafe {m.key_values.keys[kv_index]}) {
for (unsafe {m.metas[index + 2]} >> hashbits) > 1 {
unsafe {
m.metas[index] = m.metas[index + 2] - probe_inc
m.metas[index + 1] = m.metas[index + 3]
}
index += 2
}
m.len--
m.metas[index] = 0
unsafe {
m.metas[index] = 0
}
m.key_values.deletes++
// Mark key as deleted
m.key_values.keys[kv_index].free()
C.memset(&m.key_values.keys[kv_index], 0, sizeof(string))
unsafe {
m.key_values.keys[kv_index].free()
C.memset(&m.key_values.keys[kv_index], 0, sizeof(string))
}
if m.key_values.len <= 32 {
return
}
@ -465,10 +485,10 @@ pub fn (m &map) keys() []string {
mut keys := []string{ len:m.len }
mut j := 0
for i := u32(0); i < m.key_values.len; i++ {
if m.key_values.keys[i].str == 0 {
if unsafe {m.key_values.keys[i]}.str == 0 {
continue
}
keys[j] = m.key_values.keys[i].clone()
keys[j] = unsafe {m.key_values.keys[i]}.clone()
j++
}
return keys
@ -502,21 +522,29 @@ pub fn (m map) clone() map {
extra_metas: m.extra_metas
len: m.len
}
C.memcpy(res.metas, m.metas, metas_size)
unsafe {
C.memcpy(res.metas, m.metas, metas_size)
}
return res
}
[unsafe_fn]
pub fn (m &map) free() {
free(m.metas)
unsafe {
free(m.metas)
}
for i := u32(0); i < m.key_values.len; i++ {
if m.key_values.keys[i].str == 0 {
if unsafe {m.key_values.keys[i]}.str == 0 {
continue
}
m.key_values.keys[i].free()
unsafe {
m.key_values.keys[i].free()
}
}
unsafe {
free(m.key_values.keys)
free(m.key_values.values)
}
free(m.key_values.keys)
free(m.key_values.values)
}
pub fn (m map_string) str() string {

View File

@ -72,6 +72,7 @@ pub fn vstrlen(s byteptr) int {
// Converts a C string to a V string.
// String data is reused, not copied.
[unsafe_fn]
pub fn tos(s byteptr, len int) string {
// This should never happen.
if s == 0 {
@ -136,7 +137,9 @@ pub fn (a string) clone() string {
for i in 0..a.len {
b.str[i] = a.str[i]
}
b.str[a.len] = `\0`
unsafe {
b.str[a.len] = `\0`
}
return b
}
@ -149,10 +152,12 @@ pub fn (s string) cstr() byteptr {
// cstring_to_vstring creates a copy of cstr and turns it into a v string
pub fn cstring_to_vstring(cstr byteptr) string {
slen := C.strlen(charptr(cstr))
mut s := byteptr(memdup(cstr, slen + 1))
s[slen] = `\0`
return tos(s, slen)
unsafe {
slen := C.strlen(charptr(cstr))
mut s := byteptr(memdup(cstr, slen + 1))
s[slen] = `\0`
return tos(s, slen)
}
}
pub fn (s string) replace_once(rep, with string) string {
@ -193,7 +198,9 @@ pub fn (s string) replace(rep, with string) string {
if i == cur_idx {
// Reached the location of rep, replace it with "with"
for j in 0..with.len {
b[b_i] = with[j]
unsafe {
b[b_i] = with[j]
}
b_i++
}
// Skip the length of rep, since we just replaced it with "with"
@ -206,12 +213,16 @@ pub fn (s string) replace(rep, with string) string {
}
else {
// Rep doesnt start here, just copy
b[b_i] = s[i]
unsafe {
b[b_i] = s[i]
}
b_i++
}
}
b[new_len] = `\0`
return tos(b, new_len)
unsafe {
b[new_len] = `\0`
return tos(b, new_len)
}
}
struct RepIndex {
@ -292,7 +303,9 @@ pub fn (s string) replace_each(vals []string) string {
rep := vals[cur_idx.val_idx]
with := vals[cur_idx.val_idx + 1]
for j in 0..with.len {
b[b_i] = with[j]
unsafe {
b[b_i] = with[j]
}
b_i++
}
// Skip the length of rep, since we just replaced it with "with"
@ -305,12 +318,16 @@ pub fn (s string) replace_each(vals []string) string {
}
else {
// Rep doesnt start here, just copy
b[b_i] = s.str[i]
unsafe {
b[b_i] = s.str[i]
}
b_i++
}
}
b[new_len] = `\0`
return tos(b, new_len)
unsafe {
b[new_len] = `\0`
return tos(b, new_len)
}
}
pub fn (s string) bool() bool {
@ -411,12 +428,18 @@ fn (s string) add(a string) string {
len: new_len
}
for j in 0..s.len {
res.str[j] = s.str[j]
unsafe {
res.str[j] = s.str[j]
}
}
for j in 0..a.len {
res.str[s.len + j] = a.str[j]
unsafe {
res.str[s.len + j] = a.str[j]
}
}
unsafe {
res.str[new_len] = `\0` // V strings are not null terminated, but just in case
}
res.str[new_len] = `\0` // V strings are not null terminated, but just in case
return res
}
@ -448,10 +471,10 @@ pub fn (s string) split_nth(delim string, nth int) []string {
mut start := 0
nth_1 := nth - 1
for i <= s.len {
mut is_delim := s.str[i] == delim.str[0]
mut is_delim := unsafe {s.str[i] == delim.str[0]}
mut j := 0
for is_delim && j < delim.len {
is_delim = is_delim && s.str[i + j] == delim.str[j]
is_delim = is_delim && unsafe {s.str[i + j] == delim.str[j]}
j++
}
last := i == s.len - 1
@ -488,8 +511,8 @@ pub fn (s string) split_into_lines() []string {
}
mut start := 0
for i := 0; i < s.len; i++ {
is_lf := s.str[i] == `\n`
is_crlf := i != s.len - 1 && s.str[i] == `\r` && s.str[i + 1] == `\n`
is_lf := unsafe {s.str[i]} == `\n`
is_crlf := i != s.len - 1 && unsafe {s.str[i] == `\r` && s.str[i + 1] == `\n`}
is_eol := is_lf || is_crlf
is_last := if is_crlf {
i == s.len - 2
@ -549,16 +572,19 @@ pub fn (s string) substr(start, end int) string {
len: len
}
for i in 0..len {
res.str[i] = s.str[start + i]
unsafe {
res.str[i] = s.str[start + i]
}
}
unsafe {
res.str[len] = `\0`
}
res.str[len] = `\0`
/*
res := string {
str: s.str + start
len: len
}
*/
return res
}
@ -569,7 +595,7 @@ pub fn (s string) index_old(p string) int {
mut i := 0
for i < s.len {
mut j := 0
for j < p.len && s.str[i + j] == p.str[j] {
for j < p.len && unsafe {s.str[i + j] == p.str[j]} {
j++
}
if j == p.len {
@ -587,7 +613,7 @@ pub fn (s string) index(p string) ?int {
mut i := 0
for i < s.len {
mut j := 0
for j < p.len && s.str[i + j] == p.str[j] {
for j < p.len && unsafe {s.str[i + j] == p.str[j]} {
j++
}
if j == p.len {
@ -606,20 +632,20 @@ fn (s string) index_kmp(p string) int {
mut prefix := []int{len:p.len}
mut j := 0
for i := 1; i < p.len; i++ {
for p.str[j] != p.str[i] && j > 0 {
for unsafe {p.str[j] != p.str[i]} && j > 0 {
j = prefix[j - 1]
}
if p.str[j] == p.str[i] {
if unsafe {p.str[j] == p.str[i]} {
j++
}
prefix[i] = j
}
j = 0
for i in 0..s.len {
for p.str[j] != s.str[i] && j > 0 {
for unsafe {p.str[j] != s.str[i]} && j > 0 {
j = prefix[j - 1]
}
if p.str[j] == s.str[i] {
if unsafe {p.str[j] == s.str[i]} {
j++
}
if j == p.len {
@ -646,7 +672,7 @@ pub fn (s string) last_index(p string) ?int {
mut i := s.len - p.len
for i >= 0 {
mut j := 0
for j < p.len && s.str[i + j] == p.str[j] {
for j < p.len && unsafe {s.str[i + j] == p.str[j]} {
j++
}
if j == p.len {
@ -672,7 +698,7 @@ pub fn (s string) index_after(p string, start int) int {
for i < s.len {
mut j := 0
mut ii := i
for j < p.len && s.str[ii] == p.str[j] {
for j < p.len && unsafe {s.str[ii] == p.str[j]} {
j++
ii++
}
@ -686,7 +712,7 @@ pub fn (s string) index_after(p string, start int) int {
pub fn (s string) index_byte(c byte) int {
for i in 0..s.len {
if s.str[i] == c {
if unsafe {s.str[i]} == c {
return i
}
}
@ -695,7 +721,7 @@ pub fn (s string) index_byte(c byte) int {
pub fn (s string) last_index_byte(c byte) int {
for i := s.len - 1; i >= 0; i-- {
if s.str[i] == c {
if unsafe {s.str[i] == c} {
return i
}
}
@ -738,7 +764,7 @@ pub fn (s string) starts_with(p string) bool {
return false
}
for i in 0..p.len {
if s.str[i] != p.str[i] {
if unsafe {s.str[i] != p.str[i]} {
return false
}
}
@ -759,11 +785,13 @@ pub fn (s string) ends_with(p string) bool {
// TODO only works with ASCII
pub fn (s string) to_lower() string {
mut b := malloc(s.len + 1)
for i in 0..s.len {
b[i] = byte(C.tolower(s.str[i]))
unsafe {
mut b := malloc(s.len + 1)
for i in 0..s.len {
b[i] = byte(C.tolower(s.str[i]))
}
return tos(b, s.len)
}
return tos(b, s.len)
}
pub fn (s string) is_lower() bool {
@ -776,11 +804,13 @@ pub fn (s string) is_lower() bool {
}
pub fn (s string) to_upper() string {
mut b := malloc(s.len + 1)
for i in 0..s.len {
b[i] = byte(C.toupper(s.str[i]))
unsafe {
mut b := malloc(s.len + 1)
for i in 0..s.len {
b[i] = byte(C.toupper(s.str[i]))
}
return tos(b, s.len)
}
return tos(b, s.len)
}
pub fn (s string) is_upper() bool {
@ -996,7 +1026,7 @@ pub fn (s string) ustring() ustring {
runes: __new_array(0, s.len, int(sizeof(int)))
}
for i := 0; i < s.len; i++ {
char_len := utf8_char_len(s.str[i])
char_len := utf8_char_len(unsafe {s.str[i]})
res.runes << i
i += char_len - 1
res.len++
@ -1020,7 +1050,7 @@ pub fn (s string) ustring_tmp() ustring {
res.runes.len = s.len
mut j := 0
for i := 0; i < s.len; i++ {
char_len := utf8_char_len(s.str[i])
char_len := utf8_char_len(unsafe {s.str[i]})
res.runes[j] = i
j++
i += char_len - 1
@ -1063,14 +1093,14 @@ pub fn (u ustring) add(a ustring) ustring {
}
mut j := 0
for i := 0; i < u.s.len; i++ {
char_len := utf8_char_len(u.s.str[i])
char_len := utf8_char_len(unsafe {u.s.str[i]})
res.runes << j
i += char_len - 1
j += char_len
res.len++
}
for i := 0; i < a.s.len; i++ {
char_len := utf8_char_len(a.s.str[i])
char_len := utf8_char_len(unsafe {a.s.str[i]})
res.runes << j
i += char_len - 1
j += char_len
@ -1157,7 +1187,9 @@ fn (s string) at(idx int) byte {
panic('string index out of range: $idx / $s.len')
}
}
return s.str[idx]
unsafe {
return s.str[idx]
}
}
pub fn (u ustring) at(idx int) string {
@ -1279,18 +1311,24 @@ pub fn (a []string) join(del string) string {
// Go thru every string and copy its every char one by one
for i, val in a {
for j in 0..val.len {
res.str[idx] = val.str[j]
unsafe {
res.str[idx] = val.str[j]
}
idx++
}
// Add del if it's not last
if i != a.len - 1 {
for k in 0..del.len {
res.str[idx] = del.str[k]
unsafe {
res.str[idx] = del.str[k]
}
idx++
}
}
}
res.str[res.len] = `\0`
unsafe {
res.str[res.len] = `\0`
}
return res
}
@ -1308,7 +1346,9 @@ pub fn (s string) reverse() string {
len: s.len
}
for i := s.len - 1; i >= 0; i-- {
res.str[s.len - i - 1] = s[i]
unsafe {
res.str[s.len - i - 1] = s[i]
}
}
return res
}
@ -1362,10 +1402,14 @@ pub fn (s string) repeat(count int) string {
mut ret := malloc(s.len * count + 1)
for i in 0 .. count {
for j in 0 .. s.len {
ret[i * s.len + j] = s[j]
unsafe {
ret[i * s.len + j] = s[j]
}
}
}
ret[s.len * count] = 0
unsafe {
ret[s.len * count] = 0
}
return string(ret)
}
@ -1375,11 +1419,13 @@ pub fn (s string) fields() []string {
}
pub fn (s string) map(func fn(byte) byte) string {
mut res := malloc(s.len + 1)
for i in 0..s.len {
res[i] = func(s[i])
unsafe {
mut res := malloc(s.len + 1)
for i in 0..s.len {
res[i] = func(s[i])
}
return tos(res, s.len)
}
return tos(res, s.len)
}
pub fn (s string) filter(func fn(b byte) bool) string {
@ -1425,11 +1471,15 @@ pub fn (s string) strip_margin_custom(del byte) string {
mut count := 0
for i := 0; i < s.len; i++ {
if s[i] in [`\n`, `\r`] {
ret[count] = s[i]
unsafe {
ret[count] = s[i]
}
count++
// CRLF
if s[i] == `\r` && i < s.len - 1 && s[i+1] == `\n` {
ret[count] = s[i+1]
unsafe {
ret[count] = s[i+1]
}
count++
i++
}
@ -1441,10 +1491,14 @@ pub fn (s string) strip_margin_custom(del byte) string {
}
}
} else {
ret[count] = s[i]
unsafe {
ret[count] = s[i]
}
count++
}
}
ret[count] = 0
unsafe {
ret[count] = 0
}
return string(ret)
}

View File

@ -48,7 +48,7 @@ fn wyhash64(key byteptr, len, seed_ u64) u64 {
if len == 0 {
return 0
}
mut p := &key[0]
mut p := key
mut seed := seed_
mut i := len & 63
unsafe {
@ -119,15 +119,21 @@ pub fn wymum(a, b u64) u64 {
[inline]
fn wyr3(p byteptr, k u64) u64 {
return (u64(p[0])<<16) | (u64(p[k>>1])<<8) | u64(p[k - 1])
unsafe {
return (u64(p[0])<<16) | (u64(p[k>>1])<<8) | u64(p[k - 1])
}
}
[inline]
fn wyr4(p byteptr) u64 {
return u32(p[0]) | (u32(p[1])<<u32(8)) | (u32(p[2])<<u32(16)) | (u32(p[3])<<u32(24))
unsafe {
return u32(p[0]) | (u32(p[1])<<u32(8)) | (u32(p[2])<<u32(16)) | (u32(p[3])<<u32(24))
}
}
[inline]
fn wyr8(p byteptr) u64 {
return u64(p[0]) | (u64(p[1])<<8) | (u64(p[2])<<16) | (u64(p[3])<<24) | (u64(p[4])<<32) | (u64(p[5])<<40) | (u64(p[6])<<48) | (u64(p[7])<<56)
unsafe {
return u64(p[0]) | (u64(p[1])<<8) | (u64(p[2])<<16) | (u64(p[3])<<24) | (u64(p[4])<<32) | (u64(p[5])<<40) | (u64(p[6])<<48) | (u64(p[7])<<56)
}
}

View File

@ -384,7 +384,7 @@ pub fn remove_tail_zeros(s string) string {
mut in_decimal := false
mut prev_ch := byte(0)
for i < s.len {
ch := s.str[i]
ch := unsafe {s.str[i]}
if ch == `.` {
in_decimal = true
dot_pos = i
@ -405,14 +405,14 @@ pub fn remove_tail_zeros(s string) string {
mut tmp := ""
if last_zero_start > 0 {
if last_zero_start == dot_pos+1 {
tmp = s[..dot_pos] + s [i..]
tmp = s[..dot_pos] + s[i..]
}else {
tmp = s[..last_zero_start] + s [i..]
tmp = s[..last_zero_start] + s[i..]
}
} else {
tmp = s
}
if tmp.str[tmp.len-1] == `.` {
if unsafe {tmp.str[tmp.len-1]} == `.` {
return tmp[..tmp.len-1]
}
return tmp
@ -474,7 +474,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
// single char, manage it here
if ch == `c` && status == .field_char {
d1 := *(&byte(pt[p_index]))
d1 := unsafe {*(&byte(pt[p_index]))}
res.write_b(d1)
status = .reset_params
p_index++
@ -484,7 +484,8 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
// pointer, manage it here
if ch == `p` && status == .field_char {
res.write("0x"+ptr_str(pt[p_index]))
res.write("0x")
res.write(ptr_str(unsafe {pt[p_index]}))
status = .reset_params
p_index++
i++
@ -525,9 +526,9 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
}
// manage "%.*s" precision field
else if ch == `.` && fc_ch1 == `*` && fc_ch2 == `s` {
len := *(&int(pt[p_index]))
len := unsafe {*(&int(pt[p_index]))}
p_index++
mut s := *(&string(pt[p_index]))
mut s := unsafe {*(&string(pt[p_index]))}
s = s[..len]
p_index++
res.write(s)
@ -629,11 +630,11 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
// hh fot 8 bit int
`h` {
if ch2 == `h` {
x := *(&i8(pt[p_index]))
x := unsafe {*(&i8(pt[p_index]))}
positive = if x >= 0 { true } else { false }
d1 = if positive { u64(x) } else { u64(-x) }
} else {
x := *(&i16(pt[p_index]))
x := unsafe {*(&i16(pt[p_index]))}
positive = if x >= 0 { true } else { false }
d1 = if positive { u64(x) } else { u64(-x) }
}
@ -653,13 +654,13 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
d1 = if positive { u64(x) } else { u64(-x) }
}
*/
x := *(&i64(pt[p_index]))
x := unsafe {*(&i64(pt[p_index]))}
positive = if x >= 0 { true } else { false }
d1 = if positive { u64(x) } else { u64(-x) }
}
// defualt int
// default int
else {
x := *(&int(pt[p_index]))
x := unsafe {*(&int(pt[p_index]))}
positive = if x >= 0 { true } else { false }
d1 = if positive { u64(x) } else { u64(-x) }
}
@ -685,9 +686,9 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
// hh fot 8 bit unsigned int
`h` {
if ch2 == `h` {
d1 = u64(*(&byte(pt[p_index])))
d1 = u64(unsafe {*(&byte(pt[p_index]))})
} else {
d1 = u64(*(&u16(pt[p_index])))
d1 = u64(unsafe {*(&u16(pt[p_index]))})
}
}
// l u64
@ -701,11 +702,11 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
d1 = u64(*(&u64(pt[p_index])))
}
*/
d1 = u64(*(&u64(pt[p_index])))
d1 = u64(unsafe {*(&u64(pt[p_index]))})
}
// defualt int
else {
d1 = u64(*(&u32(pt[p_index])))
d1 = u64(unsafe {*(&u32(pt[p_index]))})
}
}
@ -725,10 +726,10 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
// hh fot 8 bit int
`h` {
if ch2 == `h` {
x := *(&i8(pt[p_index]))
x := unsafe {*(&i8(pt[p_index]))}
s = x.hex()
} else {
x := *(&i16(pt[p_index]))
x := unsafe {*(&i16(pt[p_index]))}
s = x.hex()
}
}
@ -745,11 +746,11 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
s = x.hex()
}
*/
x := *(&i64(pt[p_index]))
x := unsafe {*(&i64(pt[p_index]))}
s = x.hex()
}
else {
x := *(&int(pt[p_index]))
x := unsafe {*(&int(pt[p_index]))}
s = x.hex()
}
}
@ -767,7 +768,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
// float and double
if ch in [`f`, `F`] {
x := *(&f64(pt[p_index]))
x := unsafe {*(&f64(pt[p_index]))}
mut positive := x >= f64(0.0)
len1 = if len1 >= 0 { len1 } else { def_len1 }
s := format_fl(f64(x), {pad_ch: pad_ch, len0: len0, len1: len1, positive: positive, sign_flag: sign, allign: allign})
@ -778,7 +779,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
continue
}
else if ch in [`e`, `E`] {
x := *(&f64(pt[p_index]))
x := unsafe {*(&f64(pt[p_index]))}
mut positive := x >= f64(0.0)
len1 = if len1 >= 0 { len1 } else { def_len1 }
s := format_es(f64(x), {pad_ch: pad_ch, len0: len0, len1: len1, positive: positive, sign_flag: sign, allign: allign})
@ -789,7 +790,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
continue
}
else if ch in [`g`, `G`] {
x := *(&f64(pt[p_index]))
x := unsafe {*(&f64(pt[p_index]))}
mut positive := x >= f64(0.0)
mut s := ""
tx := fabs(x)
@ -810,7 +811,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
// string
else if ch == `s` {
s1 := *(&string(pt[p_index]))
s1 := unsafe{*(&string(pt[p_index]))}
pad_ch = ` `
res.write(format_str(s1, {pad_ch: pad_ch, len0: len0, len1: 0, positive: true, sign_flag: false, allign: allign}))
status = .reset_params

View File

@ -5,10 +5,11 @@ pub fn repeat(c byte, n int) string {
if n <= 0 {
return ''
}
mut bytes := &byte(0)
unsafe { bytes = malloc(n + 1) }
C.memset( bytes, c, n )
bytes[n] = `0`
mut bytes := unsafe {malloc(n + 1)}
unsafe {
C.memset( bytes, c, n )
bytes[n] = `0`
}
return string( bytes, n )
}
@ -21,14 +22,17 @@ pub fn repeat_string(s string, n int) string {
}
slen := s.len
blen := slen*n
mut bytes := &byte(0)
unsafe { bytes = malloc(blen + 1) }
mut bytes := unsafe {malloc(blen + 1)}
for bi in 0..n {
bislen := bi*slen
for si in 0..slen {
bytes[bislen+si] = s[si]
unsafe {
bytes[bislen+si] = s[si]
}
}
}
bytes[blen] = `0`
unsafe {
bytes[blen] = `0`
}
return string( bytes, blen )
}