Skip to content
This repository has been archived by the owner on May 4, 2019. It is now read-only.

address vcat return inconsistency #187

Closed
wants to merge 13 commits into from
45 changes: 45 additions & 0 deletions src/nullablevector.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Base: hcat, vcat
Copy link
Contributor Author

@cjprybol cjprybol Feb 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file uses Base. to prefix the function extensions. Should I add all of the functions to this import call? It's an unrelated change but importing these two and leaving everything else to be Base. is inconsistent

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, better not import anything and use the Base. prefix when overloading methods.


"""
push!{T, V}(X::NullableVector{T}, v::V)

Expand Down Expand Up @@ -311,3 +313,46 @@ function Base.empty!(X::NullableVector)
empty!(X.isnull)
return X
end

# need to specify to avoid StackOverflow where vcat/hcat just keeps calling itself
NotNullArray = Union{filter!(x -> !isa(x, Type{NullableArray}), subtypes(AbstractArray))...}
NotNullMatrix = typeintersect(NotNullArray, AbstractMatrix)
NotNullVector = typeintersect(NotNullArray, AbstractVector)
NullVecOrMat = Union{NullableVector, NullableMatrix}

# create an empty vector to avoid copy and secure promotion to NullableArray
vcat{T <: NotNullVector}(A::T, B::NullableVector) = vcat(NullableVector{eltype(A)}(), A, B)
vcat{T <: NotNullVector}(A::T, B::NullableVector, C::AbstractVector...) = vcat(NullableVector{eltype(A)}(), A, B, C...)

# needs to convert A directly to avoid dimension mismatch error
vcat{T <: NotNullArray}(A::T, B::NullableArray) = vcat(NullableArray(A), B)
vcat{T <: NotNullMatrix}(A::T, B::NullableMatrix) = vcat(NullableArray(A), B)
vcat{T <: NotNullArray}(A::T, B::NullableArray, C::AbstractArray...) = vcat(NullableArray(A), B, C...)
vcat{T <: NotNullMatrix}(A::T, B::NullableMatrix, C::AbstractMatrix...) = vcat(NullableArray(A), B, C...)

# create an empty vector to avoid copy and secure promotion to NullableArray
function vcat{T <: NotNullVector}(A::T, B::AbstractVector, C::AbstractVector...)
any(c -> isa(c, NullableArray), C) ? vcat(NullableVector{eltype(A)}(), A, B, C...) : vcat(A, B, C...)
end

# create an empty vector to avoid copy and secure promotion to NullableArray
function vcat{T <: NotNullArray}(A::T, B::AbstractArray, C::AbstractArray...)
any(c -> isa(c, NullableArray), C) ? vcat(NullableArray(A), B, C...) : vcat(A, B, C...)
end

function vcat{T <: NotNullMatrix}(A::T, B::AbstractMatrix, C::AbstractMatrix...)
any(c -> isa(c, NullableArray), C) ? vcat(NullableArray(A), B, C...) : vcat(A, B, C...)
end

hcat{T <: NotNullMatrix}(A::T, B::NullVecOrMat) = hcat(NullableArray(A), B)
hcat{T <: NotNullVector}(A::T, B::NullVecOrMat) = hcat(NullableArray(A), B)
hcat{T <: NotNullMatrix}(A::T, B::NullVecOrMat, C::AbstractVecOrMat...) = hcat(NullableArray(A), B, C...)
hcat{T <: NotNullVector}(A::T, B::NullVecOrMat, C::AbstractVecOrMat...) = hcat(NullableArray(A), B, C...)

function hcat{T <: NotNullMatrix}(A::T, B::AbstractVecOrMat, C::AbstractVecOrMat...)
any(c -> isa(c, NullableArray), C) ? hcat(NullableArray(A), B, C...) : hcat(A, B, C...)
end

function hcat{T <: NotNullVector}(A::T, B::AbstractVecOrMat, C::AbstractVecOrMat...)
any(c -> isa(c, NullableArray), C) ? hcat(NullableArray(A), B, C...) : hcat(A, B, C...)
end
17 changes: 17 additions & 0 deletions test/nullablevector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,21 @@ module TestNullableVector
X = NullableArray(A, M)
empty!(X)
@test isempty(X)

@test typeof(hcat(NullableArray(1:2), 3:4)) == NullableArray{Int64,2}
@test typeof(hcat(1:2, NullableArray(3:4))) == NullableArray{Int64,2}
@test typeof(vcat(NullableArray(1:2), 3:4)) == NullableArray{Int64,1}
@test typeof(vcat(1:2, NullableArray(3:4))) == NullableArray{Int64,1}

@test typeof(vcat(NullableArray([1 2]), [3 4])) == NullableArray{Int64,2}
@test typeof(vcat([1 2], NullableArray([3 4]))) == NullableArray{Int64,2}
@test typeof(hcat(NullableArray(1:2), 3:4, 5:6)) == NullableArray{Int64,2}
@test typeof(hcat(1:2, NullableArray(3:4), 5:6)) == NullableArray{Int64,2}
@test typeof(hcat(1:2, 3:4, NullableArray(5:6))) == NullableArray{Int64,2}
@test typeof(vcat(NullableArray(1:2), 3:4, 5:6)) == NullableArray{Int64,1}
@test typeof(vcat(1:2, NullableArray(3:4), 5:6)) == NullableArray{Int64,1}
@test typeof(vcat(1:2, 3:4, NullableArray(5:6))) == NullableArray{Int64,1}
@test typeof(vcat(NullableArray([1 2]), [3 4], [5 6])) == NullableArray{Int64,2}
@test typeof(vcat([1 2], NullableArray([3 4]), [5 6])) == NullableArray{Int64,2}
@test typeof(vcat([1 2], [3 4], NullableArray([5 6]))) == NullableArray{Int64,2}
end