Use a branchless check for unicode range

This commit is contained in:
Kovid Goyal
2025-04-01 12:32:17 +05:30
parent 6ecd78d9db
commit d4d2ae969e
4 changed files with 35 additions and 13 deletions

View File

@@ -2,6 +2,9 @@ package wcswidth
import "unsafe"
const MAX_UNICODE = 1114111
const UNICODE_LIMIT = 1114112
type GraphemeBreakProperty uint8
const (
@@ -387,8 +390,7 @@ var charprops_t3 = [109]CharProps{
}
// Array accessor function that avoids bounds checking
func CharPropsFor(x rune) CharProps {
x = max(0, min(x, 1114111))
func charprops_for(x uint32) CharProps {
t1 := uintptr(*(*uint8)(unsafe.Pointer(uintptr(unsafe.Pointer(&charprops_t1[0])) + uintptr(x>>charprops_shift)*1)))
t1_shifted := (t1 << charprops_shift) + (uintptr(x) & charprops_mask)
t2 := uintptr(*(*uint8)(unsafe.Pointer(uintptr(unsafe.Pointer(&charprops_t2[0])) + t1_shifted*1)))
@@ -1038,8 +1040,7 @@ var graphemesegmentationresult_t3 = [630]GraphemeSegmentationResult{
}
// Array accessor function that avoids bounds checking
func GraphemeSegmentationResultFor(x uint16) GraphemeSegmentationResult {
func graphemesegmentationresult_for(x uint16) GraphemeSegmentationResult {
t1 := uintptr(*(*uint8)(unsafe.Pointer(uintptr(unsafe.Pointer(&graphemesegmentationresult_t1[0])) + uintptr(x>>graphemesegmentationresult_shift)*1)))
t1_shifted := (t1 << graphemesegmentationresult_shift) + (uintptr(x) & graphemesegmentationresult_mask)
t2 := uintptr(*(*uint16)(unsafe.Pointer(uintptr(unsafe.Pointer(&graphemesegmentationresult_t2[0])) + t1_shifted*2)))

View File

@@ -7,6 +7,19 @@ import (
var _ = fmt.Print
func ensure_char_in_range(value uint32) uint32 {
// Branchless: if (value > MAX_UNICODE) value = 0
diff := int64(value) - UNICODE_LIMIT
// The right shift gives all ones for negative diff and all zeros for positive diff
mask := uint32(diff >> 63)
return value & mask
}
func CharPropsFor(ch rune) CharProps {
q := ensure_char_in_range(uint32(ch))
return charprops_for(q)
}
func IteratorOverGraphemes(text string) iter.Seq[string] {
var s GraphemeSegmentationResult
start_pos := 0
@@ -39,7 +52,7 @@ func (s *GraphemeSegmentationResult) Reset() {
func (s GraphemeSegmentationResult) Step(ch CharProps) GraphemeSegmentationResult {
key := grapheme_segmentation_key(s, ch)
return GraphemeSegmentationResultFor(key)
return graphemesegmentationresult_for(key)
}
func Runewidth(code rune) int {