11# https://github.com/mkitti/StaticStrings.jl
22# https://github.com/JuliaPy/PythonCall.jl/blob/main/src/Utils/Utils.jl
3+ using Base: between
34
45struct StaticString{N, T} <: AbstractString
56 codeunits:: NTuple{N, T}
@@ -60,10 +61,33 @@ function Base.String(x::StaticString{N, T}) where {N, T}
6061 return String(b .= x. codeunits)
6162end
6263
63- @inline Base. ncodeunits(:: StaticString{N} ) where N = N
64+ @inline Base. ncodeunits(:: StaticString{N} ) where {N} = N
65+ Base. codeunit(:: StaticString{N, T} ) where {N, T} = T
66+ Base. @propagate_inbounds Base. codeunit(s:: StaticString , i:: Int ) = s. codeunits[i]
6467
65- function StaticString(cu:: Base.CodeUnits{T} ) where T
68+ function StaticString(cu:: Base.CodeUnits{T} ) where {T}
6669 N = length(cu)
6770 return StaticString{N, T}(NTuple{N, T}(cu))
6871end
69- StaticString(s:: AbstractString ) = StaticString(codeunits(s))
72+ StaticString(s:: AbstractString ) = StaticString(codeunits(s))
73+
74+ Base. isvalid(s:: StaticString , i:: Int ) = checkbounds(Bool, s, i) && thisind(s, i) == i
75+ Base. thisind(s:: StaticString , i:: Int ) = _thisind_str(s, i)
76+
77+ @inline function _thisind_str(s, i:: Int )
78+ i == 0 && return 0
79+ n = ncodeunits(s)
80+ i == n + 1 && return i
81+ @boundscheck between(i, 1 , n) || throw(BoundsError(s, i))
82+ @inbounds b = codeunit(s, i)
83+ (b & 0xc0 == 0x80 ) & (i - 1 > 0 ) || return i
84+ @inbounds b = codeunit(s, i - 1 )
85+ between(b, 0b11000000 , 0b11110111 ) && return i - 1
86+ (b & 0xc0 == 0x80 ) & (i - 2 > 0 ) || return i
87+ @inbounds b = codeunit(s, i - 2 )
88+ between(b, 0b11100000 , 0b11110111 ) && return i - 2
89+ (b & 0xc0 == 0x80 ) & (i - 3 > 0 ) || return i
90+ @inbounds b = codeunit(s, i - 3 )
91+ between(b, 0b11110000 , 0b11110111 ) && return i - 3
92+ return i
93+ end
0 commit comments