diff --git a/base/abstractarray.jl b/base/abstractarray.jl index d40f0ae4ac140d..5700c601e1e35f 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -796,50 +796,8 @@ function hvcat(nbc::Integer, as...) hvcat(ntuple(i->nbc, nbr), as...) end -function hvcat{T}(rows::Tuple{Vararg{Int}}, as::AbstractMatrix{T}...) - nbr = length(rows) # number of block rows - - nc = 0 - for i=1:rows[1] - nc += size(as[i],2) - end - - nr = 0 - a = 1 - for i = 1:nbr - nr += size(as[a],1) - a += rows[i] - end - - out = similar(full(as[1]), T, nr, nc) - - a = 1 - r = 1 - for i = 1:nbr - c = 1 - szi = size(as[a],1) - for j = 1:rows[i] - Aj = as[a+j-1] - szj = size(Aj,2) - if size(Aj,1) != szi - throw(ArgumentError("mismatched height in block row $(i) (expected $szi, got $(size(Aj,1)))")) - end - if c-1+szj > nc - throw(ArgumentError("block row $(i) has mismatched number of columns (expected $nc, got $(c-1+szj))")) - end - out[r:r-1+szi, c:c-1+szj] = Aj - c += szj - end - if c != nc+1 - throw(ArgumentError("block row $(i) has mismatched number of columns (expected $nc, got $(c-1))")) - end - r += szi - a += rows[i] - end - out -end - hvcat(rows::Tuple{Vararg{Int}}) = [] +typed_hvcat(T::Type, rows::Tuple{Vararg{Int}}) = [] function hvcat{T<:Number}(rows::Tuple{Vararg{Int}}, xs::T...) nr = length(rows) @@ -874,6 +832,8 @@ function hvcat_fill(a::Array, xs::Tuple) a end +hvcat(rows::Tuple{Vararg{Int}}, xs::Number...) = typed_hvcat(promote_typeof(xs...), rows, xs...) + function typed_hvcat(T::Type, rows::Tuple{Vararg{Int}}, xs::Number...) nr = length(rows) nc = rows[1] @@ -889,9 +849,50 @@ function typed_hvcat(T::Type, rows::Tuple{Vararg{Int}}, xs::Number...) hvcat_fill(Array{T}(nr, nc), xs) end -function hvcat(rows::Tuple{Vararg{Int}}, xs::Number...) - T = promote_typeof(xs...) - typed_hvcat(T, rows, xs...) +hvcat(rows::Tuple{Vararg{Int}}, xs::AbstractMatrix...) = typed_hvcat(promote_eltype(xs...), rows, xs...) +hvcat{T}(rows::Tuple{Vararg{Int}}, xs::AbstractMatrix{T}...) = typed_hvcat(T, rows, xs...) + +function typed_hvcat{T}(TT::Type{T}, rows::Tuple{Vararg{Int}}, as::AbstractMatrix{T}...) + nbr = length(rows) # number of block rows + + nc = 0 + for i=1:rows[1] + nc += size(as[i],2) + end + + nr = 0 + a = 1 + for i = 1:nbr + nr += size(as[a],1) + a += rows[i] + end + + out = similar(full(as[1]), T, nr, nc) + + a = 1 + r = 1 + for i = 1:nbr + c = 1 + szi = size(as[a],1) + for j = 1:rows[i] + Aj = as[a+j-1] + szj = size(Aj,2) + if size(Aj,1) != szi + throw(ArgumentError("mismatched height in block row $(i) (expected $szi, got $(size(Aj,1)))")) + end + if c-1+szj > nc + throw(ArgumentError("block row $(i) has mismatched number of columns (expected $nc, got $(c-1+szj))")) + end + out[r:r-1+szi, c:c-1+szj] = Aj + c += szj + end + if c != nc+1 + throw(ArgumentError("block row $(i) has mismatched number of columns (expected $nc, got $(c-1))")) + end + r += szi + a += rows[i] + end + out end # fallback definition of hvcat in terms of hcat and vcat