@@ -313,15 +313,17 @@ isless(a::Symbol, b::Symbol) = cmp(a, b) < 0
313313# # character index arithmetic ##
314314
315315"""
316- length(s::AbstractString, lo::Integer=1, hi::Integer=ncodeunits(s)) -> Integer
316+ length(s::AbstractString, i::Integer, j::Integer) -> Int
317+ length(s::AbstractString) -> Int
317318
318- The number of characters in string `s` from indices `lo ` through `hi `. This is
319- computed as the number of code unit indices from `lo ` to `hi ` which are valid
319+ The number of characters in string `s` from indices `i ` through `j `. This is
320+ computed as the number of code unit indices from `i ` to `j ` which are valid
320321character indices. Without only a single string argument, this computes the
321- number of characters in the entire string. With `lo` and `hi` arguments it computes
322- the number of indices between `lo` and `hi` inclusive that are valid indices in
323- the string `s`. Note that the trailing character may include code units past `hi`
324- and still be counted.
322+ number of characters in the entire string. With `i` and `j` arguments it
323+ computes the number of indices between `i` and `j` inclusive that are valid
324+ indices in the string `s`. In addition to in-bounds values, `i` may take the
325+ out-of-bounds value `ncodeunits(s) + 1` and `j` may take the out-of-bounds
326+ value `0`.
325327
326328See also: [`isvalid`](@ref), [`ncodeunits`](@ref), [`endof`](@ref),
327329[`thisind`](@ref), [`nextind`](@ref), [`prevind`](@ref)
@@ -332,18 +334,23 @@ julia> length("jμΛIα")
3323345
333335```
334336"""
335- function length (s:: AbstractString , lo:: Integer = 1 , hi:: Integer = ncodeunits (s))
336- lo ≤ hi || return 0
337- z = ncodeunits (s)
338- a = Int (max (1 , min (z, lo)))
339- b = Int (min (z, max (1 , hi)))
340- n = a - b
341- for i = a: b
342- n += isvalid (s, i)
337+ @propagate_inbounds length (s:: AbstractString , i:: Integer , j:: Integer ) =
338+ length (s, Int (i), Int (j))
339+
340+ function length (s:: AbstractString , i:: Int , j:: Int )
341+ @boundscheck begin
342+ 0 < i ≤ ncodeunits (s)+ 1 || throw (BoundsError (s, i))
343+ 0 ≤ j < ncodeunits (s)+ 1 || throw (BoundsError (s, j))
343344 end
344- return n + hi - lo
345+ n = 0
346+ for k = i: j
347+ @inbounds n += isvalid (s, k)
348+ end
349+ return n
345350end
346351
352+ length (s:: AbstractString ) = @inbounds return length (s, 1 , ncodeunits (s))
353+
347354"""
348355 thisind(s::AbstractString, i::Integer) -> Int
349356
0 commit comments