Skip to content

Commit 2a06376

Browse files
authored
Preserve type in first for OneTo (#56263)
With this PR, ```julia julia> first(Base.OneTo(10), 4) Base.OneTo(4) ``` Previously, this would have used indexing to return a `UnitRange`. This is probably the only way to slice a `Base.OneTo` and obtain a `Base.OneTo` back.
1 parent 53ffe56 commit 2a06376

File tree

2 files changed

+11
-0
lines changed

2 files changed

+11
-0
lines changed

base/range.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,11 @@ first(r::OneTo{T}) where {T} = oneunit(T)
850850
first(r::StepRangeLen) = unsafe_getindex(r, 1)
851851
first(r::LinRange) = r.start
852852

853+
function first(r::OneTo, n::Integer)
854+
n < 0 && throw(ArgumentError("Number of elements must be non-negative"))
855+
OneTo(oftype(r.stop, min(r.stop, n)))
856+
end
857+
853858
last(r::OrdinalRange{T}) where {T} = convert(T, r.stop) # via steprange_last
854859
last(r::StepRangeLen) = unsafe_getindex(r, length(r))
855860
last(r::LinRange) = r.stop

test/ranges.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,6 +1539,9 @@ end
15391539
@test size(r) == (3,)
15401540
@test step(r) == 1
15411541
@test first(r) == 1
1542+
@test first(r,2) === Base.OneTo(2)
1543+
@test first(r,20) === r
1544+
@test_throws ArgumentError first(r,-20)
15421545
@test last(r) == 3
15431546
@test minimum(r) == 1
15441547
@test maximum(r) == 3
@@ -1570,6 +1573,9 @@ end
15701573
@test findall(in(2:(length(r) - 1)), r) === 2:(length(r) - 1)
15711574
@test findall(in(r), 2:(length(r) - 1)) === 1:(length(r) - 2)
15721575
end
1576+
let r = Base.OneTo(Int8(4))
1577+
@test first(r,4) === r
1578+
end
15731579
@test convert(Base.OneTo, 1:2) === Base.OneTo{Int}(2)
15741580
@test_throws ArgumentError("first element must be 1, got 2") convert(Base.OneTo, 2:3)
15751581
@test_throws ArgumentError("step must be 1, got 2") convert(Base.OneTo, 1:2:5)

0 commit comments

Comments
 (0)