@@ -197,19 +197,71 @@ module Utils
197197
198198 Base. codeunit (x:: StaticString{T} ) where {T} = T
199199
200- function Base. iterate (x:: StaticString , st:: Union{Nothing,Tuple} = nothing )
201- if st === nothing
202- s = String (x)
203- z = iterate (s)
200+ function Base. isvalid (x:: StaticString{UInt8,N} , i:: Int ) where {N}
201+ if i < 1 || i > N
202+ return false
203+ end
204+ cs = x. codeunits
205+ c = @inbounds cs[i]
206+ if all (iszero, (cs[j] for j in i: N))
207+ return false
208+ elseif (c & 0x80 ) == 0x00
209+ return true
210+ elseif (c & 0x40 ) == 0x00
211+ return false
212+ elseif (c & 0x20 ) == 0x00
213+ return @inbounds (i ≤ N- 1 ) && ((cs[i+ 1 ] & 0xC0 ) == 0x80 )
214+ elseif (c & 0x10 ) == 0x00
215+ return @inbounds (i ≤ N- 2 ) && ((cs[i+ 1 ] & 0xC0 ) == 0x80 ) && ((cs[i+ 2 ] & 0xC0 ) == 0x80 )
216+ elseif (c & 0x08 ) == 0x00
217+ return @inbounds (i ≤ N- 3 ) && ((cs[i+ 1 ] & 0xC0 ) == 0x80 ) && ((cs[i+ 2 ] & 0xC0 ) == 0x80 ) && ((cs[i+ 3 ] & 0xC0 ) == 0x80 )
204218 else
205- s, st0 = st
206- z = iterate (s, st0)
219+ return false
207220 end
208- if z === nothing
221+ return false
222+ end
223+
224+ function Base. iterate (x:: StaticString{UInt8,N} , i:: Int = 1 ) where {N}
225+ i > N && return
226+ cs = x. codeunits
227+ c = @inbounds cs[i]
228+ if all (iszero, (cs[j] for j in i: N))
229+ return
230+ elseif (c & 0x80 ) == 0x00
231+ return (reinterpret (Char, UInt32 (c) << 24 ), i+ 1 )
232+ elseif (c & 0x40 ) == 0x00
209233 nothing
234+ elseif (c & 0x20 ) == 0x00
235+ if @inbounds (i ≤ N- 1 ) && ((cs[i+ 1 ] & 0xC0 ) == 0x80 )
236+ return (reinterpret (Char, (UInt32 (cs[i]) << 24 ) | (UInt32 (cs[i+ 1 ]) << 16 )), i+ 2 )
237+ end
238+ elseif (c & 0x10 ) == 0x00
239+ if @inbounds (i ≤ N- 2 ) && ((cs[i+ 1 ] & 0xC0 ) == 0x80 ) && ((cs[i+ 2 ] & 0xC0 ) == 0x80 )
240+ return (reinterpret (Char, (UInt32 (cs[i]) << 24 ) | (UInt32 (cs[i+ 1 ]) << 16 ) | (UInt32 (cs[i+ 2 ]) << 8 )), i+ 3 )
241+ end
242+ elseif (c & 0x08 ) == 0x00
243+ if @inbounds (i ≤ N- 3 ) && ((cs[i+ 1 ] & 0xC0 ) == 0x80 ) && ((cs[i+ 2 ] & 0xC0 ) == 0x80 ) && ((cs[i+ 3 ] & 0xC0 ) == 0x80 )
244+ return (reinterpret (Char, (UInt32 (cs[i]) << 24 ) | (UInt32 (cs[i+ 1 ]) << 16 ) | (UInt32 (cs[i+ 2 ]) << 8 ) | UInt32 (cs[i+ 3 ])), i+ 4 )
245+ end
246+ end
247+ throw (StringIndexError (x, i))
248+ end
249+
250+ function Base. isvalid (x:: StaticString{UInt32,N} , i:: Int ) where {N}
251+ i < 1 && return false
252+ cs = x. codeunits
253+ return ! all (iszero, (cs[j] for j in i: N))
254+ end
255+
256+ function Base. iterate (x:: StaticString{UInt32,N} , i:: Int = 1 ) where {N}
257+ i > N && return
258+ cs = x. codeunits
259+ c = @inbounds cs[i]
260+ if all (iszero, (cs[j] for j in i: N))
261+ return
210262 else
211- c, newst0 = z
212- (c, (s, newst0))
263+ return (Char (c), i+ 1 )
213264 end
214265 end
266+
215267end
0 commit comments