# This file is part of the IntervalArithmetic.jl package; MIT licensed

__precompile__(true)

module IntervalArithmetic

import CRlibm

using FastRounding
using SetRounding

using Markdown

import Base:
    +, -, *, /, //, fma,
    <, >, ==, !=, ⊆, ^, <=,
    zero, one, eps, abs, abs2, real, min, max,
    sqrt, exp, log, sin, cos, tan, cot, inv, cbrt, csc, hypot, sec,
    exp2, exp10, expm1, log2, log10, log1p,
    asin, acos, atan, acot,
    sinh, cosh, tanh, coth, csch, sech, asinh, acosh, atanh, acoth,
    sinpi, cospi,
    in, ∈, intersect, ∩, isempty, ⊆, ⊇,
    convert, promote_rule, float, real, big,
    eps, precision, setrounding, setprecision,
    floor, ceil, trunc, sign, round, copysign,
    show, hash, valtype

import .Broadcast: broadcasted

export
    AbstractInterval, Interval, ValidInterval, EmptyInterval,
    interval, emptyinterval, ∅, nai, entireinterval, widened, hull,
    inf, sup, diam, radius, mid, mag, mig, midpoint_radius,
    isempty, isnai, isentire, isthin, isatomic, iscommon,
    isinterior, ⪽, precedes, strictprecedes, ≼, ≺, ⊂, ⊃, ⊇,
    cancelminus, cancelplus, nthroot, mul_rev_to_pair,
    RoundTiesToEven, RoundTiesToAway

# export forbidden for type piracy: ±

if VERSION >= v"1.5.0-DEV.124"
    import Base: isdisjoint
else
    export isdisjoint
end

export show

## Includes
include("intervals.jl")
include(joinpath("internals", "special.jl"))
include(joinpath("internals", "rounding_macros.jl"))
include(joinpath("internals", "rounding.jl"))
include(joinpath("internals", "conversion.jl"))
include(joinpath("operations", "boolean.jl"))
include(joinpath("operations", "numeric.jl"))
include(joinpath("operations", "set_operations.jl"))
include(joinpath("operations", "arithmetic.jl"))
include(joinpath("operations", "round.jl"))
include(joinpath("operations", "powers.jl"))
include(joinpath("operations", "exp_log.jl"))
include(joinpath("operations", "trigonometric.jl"))
include(joinpath("operations", "hyperbolic.jl"))
include(joinpath("complementary", "complementary.jl"))

# These definitions has been put there because generated functions must be
# defined after all methods they use.
@generated function interval(::Type{T}, x::I) where {T <: Real, I <: Irrational}
    res = unsafe_atomic(T, x())  # Precompute the interval
    return :(return $res)  # Set body of the function to return the precomputed result
end

end # module IntervalArithmetic
