@@ -879,13 +879,12 @@ See also [`copyto!`](@ref).
879879 is available from the `Future` standard library as `Future.copy!`.
880880"""
881881function copy! (dst:: AbstractVector , src:: AbstractVector )
882+ firstindex (dst) == firstindex (src) || throw (ArgumentError (
883+ " vectors must have the same offset for copy! (consider using `copyto!`)" ))
882884 if length (dst) != length (src)
883885 resize! (dst, length (src))
884886 end
885- for i in eachindex (dst, src)
886- @inbounds dst[i] = src[i]
887- end
888- dst
887+ copyto! (dst, src)
889888end
890889
891890function copy! (dst:: AbstractArray , src:: AbstractArray )
@@ -1011,6 +1010,10 @@ julia> y
10111010"""
10121011function copyto! (dest:: AbstractArray , src:: AbstractArray )
10131012 isempty (src) && return dest
1013+ if dest isa BitArray
1014+ # avoid ambiguities with other copyto!(::AbstractArray, ::SourceArray) methods
1015+ return _copyto_bitarray! (dest, src)
1016+ end
10141017 src′ = unalias (dest, src)
10151018 copyto_unaliased! (IndexStyle (dest), dest, IndexStyle (src′), src′)
10161019end
@@ -1080,8 +1083,9 @@ function copyto!(dest::AbstractArray, dstart::Integer,
10801083 destinds, srcinds = LinearIndices (dest), LinearIndices (src)
10811084 (checkbounds (Bool, destinds, dstart) && checkbounds (Bool, destinds, dstart+ n- 1 )) || throw (BoundsError (dest, dstart: dstart+ n- 1 ))
10821085 (checkbounds (Bool, srcinds, sstart) && checkbounds (Bool, srcinds, sstart+ n- 1 )) || throw (BoundsError (src, sstart: sstart+ n- 1 ))
1083- @inbounds for i = 0 : (n- 1 )
1084- dest[dstart+ i] = src[sstart+ i]
1086+ src′ = unalias (dest, src)
1087+ @inbounds for i = 0 : n- 1
1088+ dest[dstart+ i] = src′[sstart+ i]
10851089 end
10861090 return dest
10871091end
@@ -1103,22 +1107,23 @@ function copyto!(B::AbstractVecOrMat{R}, ir_dest::AbstractRange{Int}, jr_dest::A
11031107 end
11041108 @boundscheck checkbounds (B, ir_dest, jr_dest)
11051109 @boundscheck checkbounds (A, ir_src, jr_src)
1110+ A′ = unalias (B, A)
11061111 jdest = first (jr_dest)
11071112 for jsrc in jr_src
11081113 idest = first (ir_dest)
11091114 for isrc in ir_src
1110- @inbounds B[idest,jdest] = A[isrc,jsrc]
1115+ @inbounds B[idest,jdest] = A′ [isrc,jsrc]
11111116 idest += step (ir_dest)
11121117 end
11131118 jdest += step (jr_dest)
11141119 end
11151120 return B
11161121end
11171122
1118- function copyto_axcheck! (dest, src)
1119- @noinline checkaxs (axd, axs) = axd == axs || throw (DimensionMismatch (" axes must agree, got $axd and $axs " ))
1123+ @noinline _checkaxs (axd, axs) = axd == axs || throw (DimensionMismatch (" axes must agree, got $axd and $axs " ))
11201124
1121- checkaxs (axes (dest), axes (src))
1125+ function copyto_axcheck! (dest, src)
1126+ _checkaxs (axes (dest), axes (src))
11221127 copyto! (dest, src)
11231128end
11241129
@@ -1712,23 +1717,16 @@ end
17121717_cs (d, a, b) = (a == b ? a : throw (DimensionMismatch (
17131718 " mismatch in dimension $d (expected $a got $b )" )))
17141719
1715- function dims2cat (:: Val{dims} ) where dims
1716- if any (≤ (0 ), dims)
1717- throw (ArgumentError (" All cat dimensions must be positive integers, but got $dims " ))
1718- end
1719- ntuple (in (dims), maximum (dims))
1720- end
1721-
1720+ dims2cat (:: Val{dims} ) where dims = dims2cat (dims)
17221721function dims2cat (dims)
17231722 if any (≤ (0 ), dims)
17241723 throw (ArgumentError (" All cat dimensions must be positive integers, but got $dims " ))
17251724 end
17261725 ntuple (in (dims), maximum (dims))
17271726end
17281727
1729- _cat (dims, X... ) = cat_t ( promote_eltypeof (X... ), X... ; dims = dims )
1728+ _cat (dims, X... ) = _cat_t (dims, promote_eltypeof (X... ), X... )
17301729
1731- @inline cat_t (:: Type{T} , X... ; dims) where {T} = _cat_t (dims, T, X... )
17321730@inline function _cat_t (dims, :: Type{T} , X... ) where {T}
17331731 catdims = dims2cat (dims)
17341732 shape = cat_size_shape (catdims, X... )
@@ -1738,6 +1736,9 @@ _cat(dims, X...) = cat_t(promote_eltypeof(X...), X...; dims=dims)
17381736 end
17391737 return __cat (A, shape, catdims, X... )
17401738end
1739+ # this version of `cat_t` is not very kind for inference and so its usage should be avoided,
1740+ # nevertheless it is here just for compat after https://github.com/JuliaLang/julia/pull/45028
1741+ @inline cat_t (:: Type{T} , X... ; dims) where {T} = _cat_t (dims, T, X... )
17411742
17421743# Why isn't this called `__cat!`?
17431744__cat (A, shape, catdims, X... ) = __cat_offset! (A, shape, catdims, ntuple (zero, length (shape)), X... )
@@ -1876,8 +1877,8 @@ julia> reduce(hcat, vs)
18761877"""
18771878hcat (X... ) = cat (X... ; dims= Val (2 ))
18781879
1879- typed_vcat (:: Type{T} , X... ) where T = cat_t ( T, X... ; dims = Val ( 1 ) )
1880- typed_hcat (:: Type{T} , X... ) where T = cat_t ( T, X... ; dims = Val ( 2 ) )
1880+ typed_vcat (:: Type{T} , X... ) where T = _cat_t ( Val ( 1 ), T, X... )
1881+ typed_hcat (:: Type{T} , X... ) where T = _cat_t ( Val ( 2 ), T, X... )
18811882
18821883"""
18831884 cat(A...; dims)
@@ -1913,7 +1914,8 @@ julia> cat(true, trues(2,2), trues(4)', dims=(1,2))
19131914```
19141915"""
19151916@inline cat (A... ; dims) = _cat (dims, A... )
1916- _cat (catdims, A:: AbstractArray{T} ...) where {T} = cat_t (T, A... ; dims= catdims)
1917+ # `@constprop :aggressive` allows `catdims` to be propagated as constant improving return type inference
1918+ @constprop :aggressive _cat (catdims, A:: AbstractArray{T} ...) where {T} = _cat_t (catdims, T, A... )
19171919
19181920# The specializations for 1 and 2 inputs are important
19191921# especially when running with --inline=no, see #11158
@@ -1924,12 +1926,12 @@ hcat(A::AbstractArray) = cat(A; dims=Val(2))
19241926hcat (A:: AbstractArray , B:: AbstractArray ) = cat (A, B; dims= Val (2 ))
19251927hcat (A:: AbstractArray... ) = cat (A... ; dims= Val (2 ))
19261928
1927- typed_vcat (T:: Type , A:: AbstractArray ) = cat_t (T, A; dims = Val (1 ))
1928- typed_vcat (T:: Type , A:: AbstractArray , B:: AbstractArray ) = cat_t ( T, A, B; dims = Val ( 1 ) )
1929- typed_vcat (T:: Type , A:: AbstractArray... ) = cat_t ( T, A... ; dims = Val ( 1 ) )
1930- typed_hcat (T:: Type , A:: AbstractArray ) = cat_t (T, A; dims = Val (2 ))
1931- typed_hcat (T:: Type , A:: AbstractArray , B:: AbstractArray ) = cat_t ( T, A, B; dims = Val ( 2 ) )
1932- typed_hcat (T:: Type , A:: AbstractArray... ) = cat_t ( T, A... ; dims = Val ( 2 ) )
1929+ typed_vcat (T:: Type , A:: AbstractArray ) = _cat_t ( Val (1 ), T, A )
1930+ typed_vcat (T:: Type , A:: AbstractArray , B:: AbstractArray ) = _cat_t ( Val ( 1 ), T, A, B)
1931+ typed_vcat (T:: Type , A:: AbstractArray... ) = _cat_t ( Val ( 1 ), T, A... )
1932+ typed_hcat (T:: Type , A:: AbstractArray ) = _cat_t ( Val (2 ), T, A )
1933+ typed_hcat (T:: Type , A:: AbstractArray , B:: AbstractArray ) = _cat_t ( Val ( 2 ), T, A, B)
1934+ typed_hcat (T:: Type , A:: AbstractArray... ) = _cat_t ( Val ( 2 ), T, A... )
19331935
19341936# 2d horizontal and vertical concatenation
19351937
0 commit comments