diff --git a/NEWS.md b/NEWS.md index 61f3eb4fb8867..271766bc50931 100644 --- a/NEWS.md +++ b/NEWS.md @@ -41,6 +41,7 @@ Standard library changes * `count` and `findall` now accept an `AbstractChar` argument to search for a character in a string ([#38675]). * `range` now supports `start` as an optional keyword argument ([#38041]). +* `oneto` is exported and returns the equivalen to `1:n` where `n` is an `Integer` ([#39242]). * `islowercase` and `isuppercase` are now compliant with the Unicode lower/uppercase categories ([#38574]). * `iseven` and `isodd` functions now support non-`Integer` numeric types ([#38976]). * `escape_string` can now receive a collection of characters in the keyword diff --git a/base/exports.jl b/base/exports.jl index 440b28fb155b2..3ee12d1cb4232 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -405,6 +405,7 @@ export minmax, ndims, ones, + oneto, parent, parentindices, partialsort, diff --git a/base/range.jl b/base/range.jl index 6e5a86f9c863f..5d95728a68177 100644 --- a/base/range.jl +++ b/base/range.jl @@ -415,6 +415,36 @@ struct OneTo{T<:Integer} <: AbstractUnitRange{T} end OneTo(stop::T) where {T<:Integer} = OneTo{T}(stop) OneTo(r::AbstractRange{T}) where {T<:Integer} = OneTo{T}(r) + +""" + oneto(n::Integer) + +Create an [`AbstractRange`](@ref) that behaves like to `1:n` +where `n` must be an Integer. The returned `AbstractRange` +may be more efficient than `1:n`. See also [`:`](@ref) and +[`range`](@ref). + +# Examples +```jldoctest +julia> oneto(5) +Base.OneTo(5) + +julia> collect( oneto(6) ) +6-element Vector{Int64}: + 1 + 2 + 3 + 4 + 5 + 6 + +julia> oneto(3) == range(1; stop = 3) +true + +julia> oneto(5.5) +ERROR: MethodError: no method matching Base.OneTo(::Float64) +``` +""" oneto(r) = OneTo(r) ## Step ranges parameterized by length diff --git a/test/ranges.jl b/test/ranges.jl index b9f77f211193d..17589c591519c 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -863,6 +863,7 @@ end @test 1:10 != 2:10 != 2:11 != Base.OneTo(11) @test Base.OneTo(10) != Base.OneTo(11) != 1:10 @test Base.OneTo(0) == 5:4 + @test oneto(5) == 1:5 end # issue #2959 @test 1.0:1.5 == 1.0:1.0:1.5 == 1.0:1.0 @@ -1271,6 +1272,7 @@ end @test isempty(r) @test length(r) == 0 @test size(r) == (0,) + @test r === oneto(-5) end let r = Base.OneTo(3) @test !isempty(r) @@ -1290,6 +1292,7 @@ end @test broadcast(+, r, 1) === 2:4 @test 2*r === 2:2:6 @test r + r === 2:2:6 + @test r === oneto(3) k = 0 for i in r @test i == (k += 1) @@ -1317,6 +1320,7 @@ end @test Base.OneTo{Int32}(1:2) === Base.OneTo{Int32}(2) @test Base.OneTo(Int32(1):Int32(2)) === Base.OneTo{Int32}(2) @test Base.OneTo{Int16}(3.0) === Base.OneTo{Int16}(3) + @test oneto(9) === Base.OneTo{Int}(9) @test_throws InexactError(:Int16, Int16, 3.2) Base.OneTo{Int16}(3.2) end