diff --git a/base/number.jl b/base/number.jl index 852c8b715af1d..1f3d14fc1c86b 100644 --- a/base/number.jl +++ b/base/number.jl @@ -376,3 +376,32 @@ Complex{BigInt} ``` """ big(::Type{T}) where {T<:Number} = typeof(big(zero(T))) + +# Range construction with colon, one, and zero + +# start isa typeof(zero) +(:)(::typeof(zero), stop::T) where {T<:Real} = zero(stop):stop +(:)(::typeof(zero), step, stop::T) where {T<:Real} = zero(stop):step:stop +(:)(::typeof(zero), ::typeof(one), stop::T) where {T<:Real} = zero(stop):stop + +# start isa typeof(one) +(:)(::typeof(one), stop::T) where {T<:Integer} = Base.OneTo(stop) +(:)(::typeof(one), stop::T) where {T<:Real} = one(stop):stop +(:)(::typeof(one), step, stop::T) where {T<:Real} = one(stop):step:stop +(:)(::typeof(one), ::typeof(one), stop::T) where {T<:Real} = one(stop):stop + +# step isa typeof(one), also see above +(:)(start::A, ::typeof(one), stop::C) where {A<:Real,C<:Real} = start:stop +(:)(a::T, b::typeof(one), c::T) where {T<:Real} = a:c +(:)(a::T, b::typeof(one), c::T) where {T<:AbstractFloat} = a:c +(:)(a::T, b::typeof(one), c::T) where {T<:AbstractFloat} = a:c + +# stop isa typeof(zero) +(:)(start::T, ::typeof(zero)) where {T<:Real} = start:zero(start) +(:)(start::T, step, ::typeof(zero)) where {T<:Real} = start:step:zero(start) +(:)(start::T, ::typeof(one), ::typeof(zero)) where {T<:Real} = start:zero(start) + +# stop isa typeof(one) +(:)(start::T, ::typeof(one)) where {T<:Real} = start:one(start) +(:)(start::T, step, ::typeof(one)) where {T<:Real} = start:step:one(start) +(:)(start::T, ::typeof(one), ::typeof(one)) where {T<:Real} = start:one(start) diff --git a/base/range.jl b/base/range.jl index 4ddecd7bdd91c..bb8beeeec7f10 100644 --- a/base/range.jl +++ b/base/range.jl @@ -31,7 +31,7 @@ _colon(::Any, ::Any, start::T, step, stop::T) where {T} = """ (:)(start, [step], stop) -Range operator. `a:b` constructs a range from `a` to `b` with a step size of 1 (a [`UnitRange`](@ref)) +Range operator. `a:b` constructs a range from `a` to `b` with a step size of 1 (a [`AbstractUnitRange`](@ref)) , and `a:s:b` is similar but uses a step size of `s` (a [`StepRange`](@ref)). `:` is also used in indexing to select whole dimensions diff --git a/test/ranges.jl b/test/ranges.jl index 1c31585ece45e..1b56a03eebb4b 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -232,6 +232,73 @@ end @inferred((:)(0.0, -0.5)) end + @testset "one:?step:stop" begin + @inferred((:)(one, 1, 0)) + @inferred((:)(one, .2, 2)) + @inferred((:)(one, .2, 2.)) + @inferred((:)(one, -.2, 1)) + @inferred((:)(one, 0)) + @inferred((:)(one, -0.5)) + end + + @testset "zero:?step:stop" begin + @inferred((:)(zero, 1, 0)) + @inferred((:)(zero, .2, 2)) + @inferred((:)(zero, .2, 2.)) + @inferred((:)(zero, -.2, 1)) + @inferred((:)(zero, 0)) + @inferred((:)(zero, -0.5)) + end + + @testset "start:one:stop" begin + @inferred((:)(10, one, 0)) + @inferred((:)(1, one, 2)) + @inferred((:)(1., one, 2.)) + @inferred((:)(2, one, 1)) + @inferred((:)(1, one, 0)) + @inferred((:)(0.0, one, -0.5)) + end + + @testset "one:one:stop" begin + @inferred((:)(one, one, 0)) + @inferred((:)(one, one, 2)) + @inferred((:)(one, one, 2.)) + @inferred((:)(one, one, 1)) + @inferred((:)(one, one, 0)) + @inferred((:)(one, one, -0.5)) + end + + @testset "zero:one:stop" begin + @inferred((:)(zero, one, 0)) + @inferred((:)(zero, one, 2)) + @inferred((:)(zero, one, 2.)) + @inferred((:)(zero, one, 1)) + @inferred((:)(zero, one, 0)) + @inferred((:)(zero, one, -0.5)) + end + + @testset "start:?step:one" begin + @inferred((:)(-5, 1, one)) + @inferred((:)(-3.2, .2, one)) + @inferred((:)(0., .2, one)) + @inferred((:)(-3, -.2, one)) + @inferred((:)(1, one)) + @inferred((:)(0.0, one)) + @inferred((:)(0, one, one)) + @inferred((:)(-3., one, one)) + end + + @testset "start:?step:zero" begin + @inferred((:)(-5, 1, zero)) + @inferred((:)(-3.2, .2, zero)) + @inferred((:)(0., .2, zero)) + @inferred((:)(-3, -.2, zero)) + @inferred((:)(1, zero)) + @inferred((:)(0.0, zero)) + @inferred((:)(-3, one, zero)) + @inferred((:)(-3.2, one, zero)) + end + @testset "indexing" begin L32 = @inferred(range(Int32(1), stop=Int32(4), length=4)) L64 = @inferred(range(Int64(1), stop=Int64(4), length=4))