Skip to content

Commit df86ae9

Browse files
alystnalimilan
authored andcommitted
Adhere to Base.copy!(x, i, y, j, n) behaviour for n <= 0 (JuliaData#111)
Skip index checks if length is 0. This is consistent with Array copy!(). Move n < 0 check before bounds checks because n<0 is likely to trigger BoundsError, but the message would be confusing (attempt to access n-element Array at index [m:m-1]). Use Base's copy!(x, i, y, j) for the default n by removing default value.
1 parent f2164f8 commit df86ae9

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

src/array.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -395,12 +395,12 @@ CatArrOrSub{T, N} = Union{CategoricalArray{T, N},
395395

396396
function copy!(dest::CatArrOrSub{T, N}, dstart::Integer,
397397
src::CatArrOrSub{<:Any, N}, sstart::Integer,
398-
n::Integer=length(src)-sstart+1) where {T, N}
398+
n::Integer) where {T, N}
399+
n == 0 && return dest
400+
n < 0 && throw(ArgumentError(string("tried to copy n=", n, " elements, but n should be nonnegative")))
399401
destinds, srcinds = linearindices(dest), linearindices(src)
400402
(dstart destinds && dstart+n-1 destinds) || throw(BoundsError(dest, dstart:dstart+n-1))
401403
(sstart srcinds && sstart+n-1 srcinds) || throw(BoundsError(src, sstart:sstart+n-1))
402-
n == 0 && return dest
403-
n < 0 && throw(ArgumentError(string("tried to copy n=", n, " elements, but n should be nonnegative")))
404404

405405
drefs = refs(dest)
406406
srefs = refs(src)

test/13_arraycommon.jl

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,37 @@ end
168168
@test levels(x) == ["Young", "Middle", "Old", "X", "Y", "Z"]
169169
@test !isordered(x)
170170

171+
@testset "0-length copy! does nothing (including bounds checks)" begin
172+
u = x[1:0]
173+
v = y[1:0]
174+
175+
@test copy!(x, 1, y, 3, 0) === x
176+
@test x a
177+
@test copy!(x, 1, y, 5, 0) === x
178+
@test x a
179+
180+
@test copy!(u, -5, v, 2, 0) === u
181+
@test u v
182+
@test copy!(x, -5, v, 2, 0) === x
183+
@test x a
184+
@test copy!(u, v) === u
185+
@test u v
186+
@test copy!(x, v) === x
187+
@test x a
188+
end
189+
190+
@testset "nonzero-length copy! into/from empty array throws bounds error" begin
191+
u = x[1:0]
192+
v = y[1:0]
193+
194+
@test_throws BoundsError copy!(u, x)
195+
@test u v
196+
@test_throws BoundsError copy!(u, 1, v, 1, 1)
197+
@test u v
198+
@test_throws BoundsError copy!(x, 1, v, 1, 1)
199+
@test x a
200+
end
201+
171202
@testset "no corruption happens in case of bounds error" begin
172203
@test_throws BoundsError copy!(x, 10, y, 2)
173204
@test x a

0 commit comments

Comments
 (0)