Skip to content

Commit 3556d31

Browse files
jishnubaviatesk
authored andcommitted
Assume :foldable in isuppercase/islowercase for Char (JuliaLang#54346)
With this, `isuppercase`/`islowercase` are evaluated at compile-time for `Char` arguments: ```julia julia> @code_typed (() -> isuppercase('A'))() CodeInfo( 1 ─ return true ) => Bool julia> @code_typed (() -> islowercase('A'))() CodeInfo( 1 ─ return false ) => Bool ``` This would be useful in JuliaLang#54303, where the case of the character indicates which triangular half of a matrix is filled, and may be constant-propagated downstream. --------- Co-authored-by: Shuhei Kadowaki <[email protected]>
1 parent b5f6b2b commit 3556d31

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

base/strings/unicode.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ module Unicode
55

66
import Base: show, ==, hash, string, Symbol, isless, length, eltype,
77
convert, isvalid, ismalformed, isoverlong, iterate,
8-
AnnotatedString, AnnotatedChar, annotated_chartransform
8+
AnnotatedString, AnnotatedChar, annotated_chartransform,
9+
@assume_effects
910

1011
# whether codepoints are valid Unicode scalar values, i.e. 0-0xd7ff, 0xe000-0x10ffff
1112

@@ -385,7 +386,8 @@ julia> islowercase('❤')
385386
false
386387
```
387388
"""
388-
islowercase(c::AbstractChar) = ismalformed(c) ? false : Bool(ccall(:utf8proc_islower, Cint, (UInt32,), UInt32(c)))
389+
islowercase(c::AbstractChar) = ismalformed(c) ? false :
390+
Bool(@assume_effects :foldable @ccall utf8proc_islower(UInt32(c)::UInt32)::Cint)
389391

390392
# true for Unicode upper and mixed case
391393

@@ -409,7 +411,8 @@ julia> isuppercase('❤')
409411
false
410412
```
411413
"""
412-
isuppercase(c::AbstractChar) = ismalformed(c) ? false : Bool(ccall(:utf8proc_isupper, Cint, (UInt32,), UInt32(c)))
414+
isuppercase(c::AbstractChar) = ismalformed(c) ? false :
415+
Bool(@assume_effects :foldable @ccall utf8proc_isupper(UInt32(c)::UInt32)::Cint)
413416

414417
"""
415418
iscased(c::AbstractChar) -> Bool

test/char.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,3 +360,21 @@ end
360360
@test Base.IteratorSize(Char) == Base.HasShape{0}()
361361
@test convert(ASCIIChar, 1) == Char(1)
362362
end
363+
364+
@testset "foldable isuppercase/islowercase" begin
365+
v = @inferred (() -> Val(isuppercase('C')))()
366+
@test v isa Val{true}
367+
v = @inferred (() -> Val(islowercase('C')))()
368+
@test v isa Val{false}
369+
370+
struct MyChar <: AbstractChar
371+
x :: Char
372+
end
373+
Base.codepoint(m::MyChar) = codepoint(m.x)
374+
MyChar(x::UInt32) = MyChar(Char(x))
375+
376+
v = @inferred (() -> Val(isuppercase(MyChar('C'))))()
377+
@test v isa Val{true}
378+
v = @inferred (() -> Val(islowercase(MyChar('C'))))()
379+
@test v isa Val{false}
380+
end

0 commit comments

Comments
 (0)