Skip to content

Commit 94b2b20

Browse files
committed
fix #13254, make several forms of hcat and vcat more compiler-friendly
1 parent 5c82c3e commit 94b2b20

File tree

2 files changed

+74
-16
lines changed

2 files changed

+74
-16
lines changed

base/abstractarray.jl

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -712,29 +712,29 @@ cat(catdim::Integer) = Array(Any, 0)
712712

713713
vcat() = Array(Any, 0)
714714
hcat() = Array(Any, 0)
715+
typed_vcat(T::Type) = Array(T, 0)
716+
typed_hcat(T::Type) = Array(T, 0)
715717

716718
## cat: special cases
717-
hcat{T}(X::T...) = T[ X[j] for i=1, j=1:length(X) ]
718-
hcat{T<:Number}(X::T...) = T[ X[j] for i=1, j=1:length(X) ]
719719
vcat{T}(X::T...) = T[ X[i] for i=1:length(X) ]
720720
vcat{T<:Number}(X::T...) = T[ X[i] for i=1:length(X) ]
721+
hcat{T}(X::T...) = T[ X[j] for i=1, j=1:length(X) ]
722+
hcat{T<:Number}(X::T...) = T[ X[j] for i=1, j=1:length(X) ]
721723

722-
function vcat(X::Number...)
723-
T = promote_typeof(X...)
724-
hvcat_fill(Array(T,length(X)), X)
725-
end
724+
vcat(X::Number...) = hvcat_fill(Array(promote_typeof(X...),length(X)), X)
725+
hcat(X::Number...) = hvcat_fill(Array(promote_typeof(X...),1,length(X)), X)
726+
typed_vcat(T::Type, X::Number...) = hvcat_fill(Array(T,length(X)), X)
727+
typed_hcat(T::Type, X::Number...) = hvcat_fill(Array(T,1,length(X)), X)
726728

727-
function hcat(X::Number...)
728-
T = promote_typeof(X...)
729-
hvcat_fill(Array(T,1,length(X)), X)
730-
end
729+
vcat(V::AbstractVector...) = typed_vcat(promote_eltype(V...), V...)
730+
vcat{T}(V::AbstractVector{T}...) = typed_vcat(T, V...)
731731

732-
function vcat{T}(V::AbstractVector{T}...)
732+
function typed_vcat(T::Type, V::AbstractVector...)
733733
n::Int = 0
734734
for Vk in V
735735
n += length(Vk)
736736
end
737-
a = similar(full(V[1]), n)
737+
a = similar(full(V[1]), T, n)
738738
pos = 1
739739
for k=1:length(V)
740740
Vk = V[k]
@@ -745,7 +745,10 @@ function vcat{T}(V::AbstractVector{T}...)
745745
a
746746
end
747747

748-
function hcat{T}(A::AbstractVecOrMat{T}...)
748+
hcat(A::AbstractVecOrMat...) = typed_hcat(promote_eltype(A...), A...)
749+
hcat{T}(A::AbstractVecOrMat{T}...) = typed_hcat(T, A...)
750+
751+
function typed_hcat(T::Type, A::AbstractVecOrMat...)
749752
nargs = length(A)
750753
nrows = size(A[1], 1)
751754
ncols = 0
@@ -759,7 +762,7 @@ function hcat{T}(A::AbstractVecOrMat{T}...)
759762
nd = ndims(Aj)
760763
ncols += (nd==2 ? size(Aj,2) : 1)
761764
end
762-
B = similar(full(A[1]), nrows, ncols)
765+
B = similar(full(A[1]), T, nrows, ncols)
763766
pos = 1
764767
if dense
765768
for k=1:nargs
@@ -779,7 +782,10 @@ function hcat{T}(A::AbstractVecOrMat{T}...)
779782
return B
780783
end
781784

782-
function vcat{T}(A::AbstractMatrix{T}...)
785+
vcat(A::AbstractMatrix...) = typed_vcat(promote_eltype(A...), A...)
786+
vcat{T}(A::AbstractMatrix{T}...) = typed_vcat(T, A...)
787+
788+
function typed_vcat(T::Type, A::AbstractMatrix...)
783789
nargs = length(A)
784790
nrows = sum(a->size(a, 1), A)::Int
785791
ncols = size(A[1], 2)
@@ -788,7 +794,7 @@ function vcat{T}(A::AbstractMatrix{T}...)
788794
throw(ArgumentError("number of columns of each array must match (got $(map(x->size(x,2), A)))"))
789795
end
790796
end
791-
B = similar(full(A[1]), nrows, ncols)
797+
B = similar(full(A[1]), T, nrows, ncols)
792798
pos = 1
793799
for k=1:nargs
794800
Ak = A[k]

test/arrayops.jl

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,3 +1357,55 @@ Base.getindex(S::SquaresVector, i::Int) = i*i
13571357
foo_squares = SquaresVector(5)
13581358
@test convert(Array{Int}, foo_squares) == [1,4,9,16,25]
13591359
@test convert(Array{Int, 1}, foo_squares) == [1,4,9,16,25]
1360+
1361+
# issue #13254
1362+
let A = zeros(Int, 2, 2), B = zeros(Float64, 2, 2)
1363+
f1() = [1]
1364+
f2() = [1;]
1365+
f3() = [1;2]
1366+
f4() = [1;2.0]
1367+
f5() = [1 2]
1368+
f6() = [1 2.0]
1369+
f7() = Int[1]
1370+
f8() = Float64[1]
1371+
f9() = Int[1;]
1372+
f10() = Float64[1;]
1373+
f11() = Int[1;2]
1374+
f12() = Float64[1;2]
1375+
f13() = Int[1;2.0]
1376+
f14() = Int[1 2]
1377+
f15() = Float64[1 2]
1378+
f16() = Int[1 2.0]
1379+
f17() = [1:2;]
1380+
f18() = Int[1:2;]
1381+
f19() = Float64[1:2;]
1382+
f20() = [1:2;1:2]
1383+
f21() = Int[1:2;1:2]
1384+
f22() = Float64[1:2;1:2]
1385+
f23() = [1:2;1.0:2.0]
1386+
f24() = Int[1:2;1.0:2.0]
1387+
f25() = [1:2 1:2]
1388+
f26() = Int[1:2 1:2]
1389+
f27() = Float64[1:2 1:2]
1390+
f28() = [1:2 1.0:2.0]
1391+
f29() = Int[1:2 1.0:2.0]
1392+
f30() = [A;]
1393+
f31() = Int[A;]
1394+
f32() = Float64[A;]
1395+
f33() = [A;A]
1396+
f34() = Int[A;A]
1397+
f35() = Float64[A;A]
1398+
f36() = [A;B]
1399+
f37() = Int[A;B]
1400+
f38() = [A A]
1401+
f39() = Int[A A]
1402+
f40() = Float64[A A]
1403+
f41() = [A B]
1404+
f42() = Int[A B]
1405+
1406+
for f in [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16,
1407+
f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30,
1408+
f31, f32, f33, f34, f35, f36, f37, f38, f39, f40, f41, f42]
1409+
@test isleaftype(Base.return_types(f, ())[1])
1410+
end
1411+
end

0 commit comments

Comments
 (0)