| 
 | 1 | +# This file is a part of Julia. License is MIT: https://julialang.org/license  | 
 | 2 | + | 
 | 3 | +# Missing, missing and ismissing are defined in essentials.jl  | 
 | 4 | + | 
 | 5 | +show(io::IO, x::Missing) = print(io, "missing")  | 
 | 6 | + | 
 | 7 | +"""  | 
 | 8 | +    MissingException(msg)  | 
 | 9 | +
  | 
 | 10 | +Exception thrown when a [`missing`](@ref) value is encountered in a situation  | 
 | 11 | +where it is not supported. The error message, in the `msg` field  | 
 | 12 | +may provide more specific details.  | 
 | 13 | +"""  | 
 | 14 | +struct MissingException <: Exception  | 
 | 15 | +    msg::AbstractString  | 
 | 16 | +end  | 
 | 17 | + | 
 | 18 | +showerror(io::IO, ex::MissingException) =  | 
 | 19 | +    print(io, "MissingException: ", ex.msg)  | 
 | 20 | + | 
 | 21 | +promote_rule(::Type{Missing}, ::Type{T}) where {T} = Union{T, Missing}  | 
 | 22 | +promote_rule(::Type{Union{S,Missing}}, ::Type{T}) where {T,S} = Union{promote_type(T, S), Missing}  | 
 | 23 | +promote_rule(::Type{Any}, ::Type{T}) where {T} = Any  | 
 | 24 | +promote_rule(::Type{Any}, ::Type{Missing}) = Any  | 
 | 25 | +promote_rule(::Type{Missing}, ::Type{Any}) = Any  | 
 | 26 | +promote_rule(::Type{Missing}, ::Type{Missing}) = Missing  | 
 | 27 | + | 
 | 28 | +convert(::Type{Union{T, Missing}}, x) where {T} = convert(T, x)  | 
 | 29 | +# To print more appropriate message than "T not defined"  | 
 | 30 | +convert(::Type{Missing}, x) = throw(MethodError(convert, (Missing, x)))  | 
 | 31 | +convert(::Type{Missing}, ::Missing) = missing  | 
 | 32 | + | 
 | 33 | +# Comparison operators  | 
 | 34 | +==(::Missing, ::Missing) = missing  | 
 | 35 | +==(::Missing, ::Any) = missing  | 
 | 36 | +==(::Any, ::Missing) = missing  | 
 | 37 | +# To fix ambiguity  | 
 | 38 | +==(::Missing, ::WeakRef) = missing  | 
 | 39 | +==(::WeakRef, ::Missing) = missing  | 
 | 40 | +isequal(::Missing, ::Missing) = true  | 
 | 41 | +isequal(::Missing, ::Any) = false  | 
 | 42 | +isequal(::Any, ::Missing) = false  | 
 | 43 | +<(::Missing, ::Missing) = missing  | 
 | 44 | +<(::Missing, ::Any) = missing  | 
 | 45 | +<(::Any, ::Missing) = missing  | 
 | 46 | +isless(::Missing, ::Missing) = false  | 
 | 47 | +isless(::Missing, ::Any) = false  | 
 | 48 | +isless(::Any, ::Missing) = true  | 
 | 49 | + | 
 | 50 | +# Unary operators/functions  | 
 | 51 | +for f in (:(!), :(+), :(-), :(identity), :(zero), :(one), :(oneunit),  | 
 | 52 | +          :(abs), :(abs2), :(sign),  | 
 | 53 | +          :(acos), :(acosh), :(asin), :(asinh), :(atan), :(atanh),  | 
 | 54 | +          :(sin), :(sinh), :(cos), :(cosh), :(tan), :(tanh),  | 
 | 55 | +          :(exp), :(exp2), :(expm1), :(log), :(log10), :(log1p),  | 
 | 56 | +          :(log2), :(exponent), :(sqrt), :(gamma), :(lgamma),  | 
 | 57 | +          :(iseven), :(ispow2), :(isfinite), :(isinf), :(isodd),  | 
 | 58 | +          :(isinteger), :(isreal), :(isnan), :(isempty),  | 
 | 59 | +          :(iszero), :(transpose), :(float))  | 
 | 60 | +    @eval Math.$(f)(::Missing) = missing  | 
 | 61 | +end  | 
 | 62 | + | 
 | 63 | +for f in (:(Base.zero), :(Base.one), :(Base.oneunit))  | 
 | 64 | +    @eval function $(f)(::Type{Union{T, Missing}}) where T  | 
 | 65 | +        T === Any && throw(MethodError($f, (Any,)))  # To prevent StackOverflowError  | 
 | 66 | +        $f(T)  | 
 | 67 | +    end  | 
 | 68 | +end  | 
 | 69 | + | 
 | 70 | +# Binary operators/functions  | 
 | 71 | +for f in (:(+), :(-), :(*), :(/), :(^),  | 
 | 72 | +          :(div), :(mod), :(fld), :(rem), :(min), :(max))  | 
 | 73 | +    @eval begin  | 
 | 74 | +        # Scalar with missing  | 
 | 75 | +        ($f)(::Missing, ::Missing) = missing  | 
 | 76 | +        ($f)(d::Missing, x::Number) = missing  | 
 | 77 | +        ($f)(d::Number, x::Missing) = missing  | 
 | 78 | +    end  | 
 | 79 | +end  | 
 | 80 | + | 
 | 81 | +# Rounding and related functions  | 
 | 82 | +for f in (:(ceil), :(floor), :(round), :(trunc))  | 
 | 83 | +    @eval begin  | 
 | 84 | +        ($f)(::Missing, digits::Integer=0, base::Integer=0) = missing  | 
 | 85 | +        ($f)(::Type{>:Missing}, ::Missing) = missing  | 
 | 86 | +        ($f)(::Type{T}, ::Missing) where {T} =  | 
 | 87 | +            throw(MissingException("cannot convert a missing value to type $T"))  | 
 | 88 | +    end  | 
 | 89 | +end  | 
 | 90 | + | 
 | 91 | +# to avoid ambiguity warnings  | 
 | 92 | +(^)(::Missing, ::Integer) = missing  | 
 | 93 | + | 
 | 94 | +# Bit operators  | 
 | 95 | +(&)(::Missing, ::Missing) = missing  | 
 | 96 | +(&)(a::Missing, b::Bool) = ifelse(b, missing, false)  | 
 | 97 | +(&)(b::Bool, a::Missing) = ifelse(b, missing, false)  | 
 | 98 | +(&)(::Missing, ::Integer) = missing  | 
 | 99 | +(&)(::Integer, ::Missing) = missing  | 
 | 100 | +(|)(::Missing, ::Missing) = missing  | 
 | 101 | +(|)(a::Missing, b::Bool) = ifelse(b, true, missing)  | 
 | 102 | +(|)(b::Bool, a::Missing) = ifelse(b, true, missing)  | 
 | 103 | +(|)(::Missing, ::Integer) = missing  | 
 | 104 | +(|)(::Integer, ::Missing) = missing  | 
 | 105 | +xor(::Missing, ::Missing) = missing  | 
 | 106 | +xor(a::Missing, b::Bool) = missing  | 
 | 107 | +xor(b::Bool, a::Missing) = missing  | 
 | 108 | +xor(::Missing, ::Integer) = missing  | 
 | 109 | +xor(::Integer, ::Missing) = missing  | 
 | 110 | + | 
 | 111 | +*(d::Missing, x::AbstractString) = missing  | 
 | 112 | +*(d::AbstractString, x::Missing) = missing  | 
 | 113 | + | 
 | 114 | +function float(A::AbstractArray{Union{T, Missing}}) where {T}  | 
 | 115 | +    U = typeof(float(zero(T)))  | 
 | 116 | +    convert(AbstractArray{Union{U, Missing}}, A)  | 
 | 117 | +end  | 
 | 118 | +float(A::AbstractArray{Missing}) = A  | 
0 commit comments