Repository: JuliaLang/julia
File: base/char.jl (Julia)

Code before:
"""
    ncodeunits(c::Char) -> Int

Return the number of code units required to encode a character as UTF-8.
This is the number of bytes which will be printed if the character is written
to an output stream, or `ncodeunits(string(c))` but computed efficiently.

!!! compat "Julia 1.1"
    This method requires at least Julia 1.1. In Julia 1.0 consider
    using `ncodeunits(string(c))`.
"""
function ncodeunits(c::Char)
    u = reinterpret(UInt32, c)
    # We care about how many trailing bytes are all zero
    # subtract that from the total number of bytes
    n_nonzero_bytes = sizeof(UInt32) - div(trailing_zeros(u), 0x8)
    # Take care of '\0', which has an all-zero bitpattern
    n_nonzero_bytes + iszero(u)
end

"""
    codepoint(c::AbstractChar) -> Integer

Return the Unicode codepoint (an unsigned integer) corresponding
to the character `c` (or throw an exception if `c` does not represent
a well-formed character). For `Char`, this is a `UInt32` value, but
`AbstractChar` types that represent only a subset of Unicode may
return a different-sized integer (e.g. `UInt8`).

Should succeed for any non-malformed character, i.e. when
[`Base.ismalformed(c)`](@ref) returns `false`.   This includes
invalid Unicode characters (such as unpaired surrogates)
and overlong encodings.

!!! compat "Julia 1.12"
    Prior to Julia 1.12, `codepoint(c)` fails for overlong encodings (when
    [`Base.isoverlong(c)`](@ref) is `true`), and `Base.decode_overlong(c)` was needed.
"""
function codepoint end

@constprop :aggressive codepoint(c::Char) = UInt32(c)

struct InvalidCharError{T<:AbstractChar} <: Exception
    char::T
end
struct CodePointError{T<:Integer} <: Exception
    code::T
end
@noinline throw_invalid_char(c::AbstractChar) = throw(InvalidCharError(c))
@noinline throw_code_point_err(u::Integer) = throw(CodePointError(u))


Review comment (suggestion):
Would this be equivalent?
```suggestion
to the character `c` (or throw an exception if `c` represents
a malformed character). For `Char`, this is a `UInt32` value, bu
```
If so, I think it is more clear because `malformed` more clearly refers to `ismalformed`.

Code after:
(::Type{T})(x::T) where {T<:AbstractChar} = x

"""
    ncodeunits(c::Char)::Int

Return the number of code units required to encode a character as UTF-8.
This is the number of bytes which will be printed if the character is written
to an output stream, or `ncodeunits(string(c))` but computed efficiently.

!!! compat "Julia 1.1"
    This method requires at least Julia 1.1. In Julia 1.0 consider
    using `ncodeunits(string(c))`.
"""
function ncodeunits(c::Char)
    u = reinterpret(UInt32, c)
    # We care about how many trailing bytes are all zero
    # subtract that from the total number of bytes
    n_nonzero_bytes = sizeof(UInt32) - div(trailing_zeros(u), 0x8)
    # Take care of '\0', which has an all-zero bitpattern
    n_nonzero_bytes + iszero(u)
end

"""
    codepoint(c::AbstractChar)::Integer

Return the Unicode codepoint (an unsigned integer) corresponding
to the character `c` (or throw an exception if `c` represents
a malformed character). For `Char`, this is a `UInt32` value, but
`AbstractChar` types that represent only a subset of Unicode may
return a different-sized integer (e.g. `UInt8`).

Should succeed for any non-malformed character, i.e. when
[`Base.ismalformed(c)`](@ref) returns `false`.   This includes
invalid Unicode characters (such as unpaired surrogates)
and overlong encodings.

!!! compat "Julia 1.12"
    Prior to Julia 1.12, `codepoint(c)` fails for overlong encodings (when
    [`Base.isoverlong(c)`](@ref) is `true`), and `Base.decode_overlong(c)` was needed.
"""
function codepoint end

@constprop :aggressive codepoint(c::Char) = UInt32(c)

struct InvalidCharError{T<:AbstractChar} <: Exception
    char::T
end
struct CodePointError{T<:Integer} <: Exception
    code::T
end
@noinline throw_invalid_char(c::AbstractChar) = throw(InvalidCharError(c))