From 168972877e56aa4371d96771feb02be5c87bd082 Mon Sep 17 00:00:00 2001 From: Cameron Prybol Date: Fri, 24 Feb 2017 00:06:36 -0800 Subject: [PATCH 01/13] address https://github.com/JuliaStats/NullableArrays.jl/issues/167 --- src/operators.jl | 89 ++++++++++++++++++++++++++++++++++++++++++++++- test/operators.jl | 6 ++++ 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/src/operators.jl b/src/operators.jl index 72d32a7..1adb98d 100644 --- a/src/operators.jl +++ b/src/operators.jl @@ -1,7 +1,17 @@ ## Lifted operators importall Base.Operators -import Base: promote_op, abs, abs2, sqrt, cbrt, scalarmin, scalarmax, isless +import Base: abs, + abs2, + cbrt, + isless, + scalarmin, + scalarmax, + promote_op, + promote_rule, + sqrt, + typed_hcat, + typed_vcat using Compat: @compat, @functorize if isdefined(Base, :fieldname) && Base.fieldname(Nullable, 1) == :hasvalue # Julia 0.6 @@ -159,3 +169,80 @@ if !method_exists(isless, Tuple{Nullable{Int}, Nullable{Int}}) isless(x::Nullable{Union{}}, y::Nullable) = false isless(x::Nullable, y::Nullable{Union{}}) = !isnull(x) end + +function promote_rule{T1,T2}(::Type{T1}, ::Type{Nullable{T2}}) + promote_rule(Nullable{T2}, T1) +end + +function typed_hcat{T}(::Type{T}, A::AbstractVecOrMat...) + nargs = length(A) + nrows = size(A[1], 1) + ncols = 0 + dense = true + for j = 1:nargs + Aj = A[j] + if size(Aj, 1) != nrows + throw(ArgumentError("number of rows of each array must match (got $(map(x->size(x,1), A)))")) + end + dense &= isa(Aj,Array) + nd = ndims(Aj) + ncols += (nd==2 ? size(Aj,2) : 1) + end + i = findfirst(a -> isa(a, NullableArray), A) + B = similar(full(A[i == 0 ? 1 : i]), T, nrows, ncols) + pos = 1 + if dense + for k=1:nargs + Ak = A[k] + n = length(Ak) + copy!(B, pos, Ak, 1, n) + pos += n + end + else + for k=1:nargs + Ak = A[k] + p1 = pos+(isa(Ak,AbstractMatrix) ? size(Ak, 2) : 1)-1 + B[:, pos:p1] = Ak + pos = p1+1 + end + end + return B +end + +function typed_vcat{T}(::Type{T}, V::AbstractVector...) + n::Int = 0 + for Vk in V + n += length(Vk) + end + i = findfirst(v -> isa(v, NullableArray), V) + a = similar(full(V[i == 0 ? 1 : i]), T, n) + pos = 1 + for k=1:length(V) + Vk = V[k] + p1 = pos+length(Vk)-1 + a[pos:p1] = Vk + pos = p1+1 + end + a +end + +function typed_vcat{T}(::Type{T}, A::AbstractMatrix...) + nargs = length(A) + nrows = sum(a->size(a, 1), A)::Int + ncols = size(A[1], 2) + for j = 2:nargs + if size(A[j], 2) != ncols + throw(ArgumentError("number of columns of each array must match (got $(map(x->size(x,2), A)))")) + end + end + i = findfirst(a -> isa(a, NullableArray), A) + B = similar(full(A[i == 0 ? 1 : i]), T, nrows, ncols) + pos = 1 + for k=1:nargs + Ak = A[k] + p1 = pos+size(Ak,1)-1 + B[pos:p1, :] = Ak + pos = p1+1 + end + return B +end diff --git a/test/operators.jl b/test/operators.jl index d86d469..6f6eff6 100644 --- a/test/operators.jl +++ b/test/operators.jl @@ -236,4 +236,10 @@ module TestOperators @test isless(Nullable(), Nullable()) === false end end + @test promote_rule(Nullable{Int64}, Int64) == Nullable{Int64} + @test promote_rule(Int64, Nullable{Int64}) == Nullable{Int64} + @test typeof(hcat(NullableArray(1:2), 1:2)) == NullableArrays.NullableArray{Int64,2} + @test typeof(hcat(1:2, NullableArray(1:2))) == NullableArrays.NullableArray{Int64,2} + @test typeof(vcat(NullableArray(1:2), 1:2)) == NullableArrays.NullableArray{Int64,1} + @test typeof(vcat(1:2, NullableArray(1:2))) == NullableArrays.NullableArray{Int64,1} end From a36f6a457d1ad655aa05598cbda927a73c4e25a3 Mon Sep 17 00:00:00 2001 From: Cameron Prybol Date: Fri, 24 Feb 2017 00:10:02 -0800 Subject: [PATCH 02/13] reorder import statements --- src/operators.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/operators.jl b/src/operators.jl index 1adb98d..5463e37 100644 --- a/src/operators.jl +++ b/src/operators.jl @@ -5,10 +5,10 @@ import Base: abs, abs2, cbrt, isless, - scalarmin, - scalarmax, promote_op, promote_rule, + scalarmin, + scalarmax, sqrt, typed_hcat, typed_vcat From 5d9d9828f78fed5cec2c588c5c7eab184d24dd45 Mon Sep 17 00:00:00 2001 From: Cameron Prybol Date: Fri, 24 Feb 2017 00:21:28 -0800 Subject: [PATCH 03/13] move from operators files to nullablevector files --- src/nullablevector.jl | 77 +++++++++++++++++++++++++++++++++++++++ src/operators.jl | 82 +----------------------------------------- test/nullablevector.jl | 8 +++++ test/operators.jl | 6 ---- 4 files changed, 86 insertions(+), 87 deletions(-) diff --git a/src/nullablevector.jl b/src/nullablevector.jl index cd48417..78c2ba2 100644 --- a/src/nullablevector.jl +++ b/src/nullablevector.jl @@ -311,3 +311,80 @@ function Base.empty!(X::NullableVector) empty!(X.isnull) return X end + +function Base.promote_rule{T1,T2}(::Type{T1}, ::Type{Nullable{T2}}) + promote_rule(Nullable{T2}, T1) +end + +function Base.typed_hcat{T}(::Type{T}, A::AbstractVecOrMat...) + nargs = length(A) + nrows = size(A[1], 1) + ncols = 0 + dense = true + for j = 1:nargs + Aj = A[j] + if size(Aj, 1) != nrows + throw(ArgumentError("number of rows of each array must match (got $(map(x->size(x,1), A)))")) + end + dense &= isa(Aj,Array) + nd = ndims(Aj) + ncols += (nd==2 ? size(Aj,2) : 1) + end + i = findfirst(a -> isa(a, NullableArray), A) + B = similar(full(A[i == 0 ? 1 : i]), T, nrows, ncols) + pos = 1 + if dense + for k=1:nargs + Ak = A[k] + n = length(Ak) + copy!(B, pos, Ak, 1, n) + pos += n + end + else + for k=1:nargs + Ak = A[k] + p1 = pos+(isa(Ak,AbstractMatrix) ? size(Ak, 2) : 1)-1 + B[:, pos:p1] = Ak + pos = p1+1 + end + end + return B +end + +function Base.typed_vcat{T}(::Type{T}, V::AbstractVector...) + n::Int = 0 + for Vk in V + n += length(Vk) + end + i = findfirst(v -> isa(v, NullableArray), V) + a = similar(full(V[i == 0 ? 1 : i]), T, n) + pos = 1 + for k=1:length(V) + Vk = V[k] + p1 = pos+length(Vk)-1 + a[pos:p1] = Vk + pos = p1+1 + end + a +end + +function Base.typed_vcat{T}(::Type{T}, A::AbstractMatrix...) + nargs = length(A) + nrows = sum(a->size(a, 1), A)::Int + ncols = size(A[1], 2) + for j = 2:nargs + if size(A[j], 2) != ncols + throw(ArgumentError("number of columns of each array must match (got $(map(x->size(x,2), A)))")) + end + end + i = findfirst(a -> isa(a, NullableArray), A) + B = similar(full(A[i == 0 ? 1 : i]), T, nrows, ncols) + pos = 1 + for k=1:nargs + Ak = A[k] + p1 = pos+size(Ak,1)-1 + B[pos:p1, :] = Ak + pos = p1+1 + end + return B +end diff --git a/src/operators.jl b/src/operators.jl index 5463e37..6ca3e14 100644 --- a/src/operators.jl +++ b/src/operators.jl @@ -6,12 +6,9 @@ import Base: abs, cbrt, isless, promote_op, - promote_rule, scalarmin, scalarmax, - sqrt, - typed_hcat, - typed_vcat + sqrt using Compat: @compat, @functorize if isdefined(Base, :fieldname) && Base.fieldname(Nullable, 1) == :hasvalue # Julia 0.6 @@ -169,80 +166,3 @@ if !method_exists(isless, Tuple{Nullable{Int}, Nullable{Int}}) isless(x::Nullable{Union{}}, y::Nullable) = false isless(x::Nullable, y::Nullable{Union{}}) = !isnull(x) end - -function promote_rule{T1,T2}(::Type{T1}, ::Type{Nullable{T2}}) - promote_rule(Nullable{T2}, T1) -end - -function typed_hcat{T}(::Type{T}, A::AbstractVecOrMat...) - nargs = length(A) - nrows = size(A[1], 1) - ncols = 0 - dense = true - for j = 1:nargs - Aj = A[j] - if size(Aj, 1) != nrows - throw(ArgumentError("number of rows of each array must match (got $(map(x->size(x,1), A)))")) - end - dense &= isa(Aj,Array) - nd = ndims(Aj) - ncols += (nd==2 ? size(Aj,2) : 1) - end - i = findfirst(a -> isa(a, NullableArray), A) - B = similar(full(A[i == 0 ? 1 : i]), T, nrows, ncols) - pos = 1 - if dense - for k=1:nargs - Ak = A[k] - n = length(Ak) - copy!(B, pos, Ak, 1, n) - pos += n - end - else - for k=1:nargs - Ak = A[k] - p1 = pos+(isa(Ak,AbstractMatrix) ? size(Ak, 2) : 1)-1 - B[:, pos:p1] = Ak - pos = p1+1 - end - end - return B -end - -function typed_vcat{T}(::Type{T}, V::AbstractVector...) - n::Int = 0 - for Vk in V - n += length(Vk) - end - i = findfirst(v -> isa(v, NullableArray), V) - a = similar(full(V[i == 0 ? 1 : i]), T, n) - pos = 1 - for k=1:length(V) - Vk = V[k] - p1 = pos+length(Vk)-1 - a[pos:p1] = Vk - pos = p1+1 - end - a -end - -function typed_vcat{T}(::Type{T}, A::AbstractMatrix...) - nargs = length(A) - nrows = sum(a->size(a, 1), A)::Int - ncols = size(A[1], 2) - for j = 2:nargs - if size(A[j], 2) != ncols - throw(ArgumentError("number of columns of each array must match (got $(map(x->size(x,2), A)))")) - end - end - i = findfirst(a -> isa(a, NullableArray), A) - B = similar(full(A[i == 0 ? 1 : i]), T, nrows, ncols) - pos = 1 - for k=1:nargs - Ak = A[k] - p1 = pos+size(Ak,1)-1 - B[pos:p1, :] = Ak - pos = p1+1 - end - return B -end diff --git a/test/nullablevector.jl b/test/nullablevector.jl index 7bdc512..53a8d13 100644 --- a/test/nullablevector.jl +++ b/test/nullablevector.jl @@ -223,4 +223,12 @@ module TestNullableVector X = NullableArray(A, M) empty!(X) @test isempty(X) + + # tests for reciprocal behavior + @test promote_rule(Nullable{Int64}, Int64) == Nullable{Int64} + @test promote_rule(Int64, Nullable{Int64}) == Nullable{Int64} + @test typeof(hcat(NullableArray(1:2), 1:2)) == NullableArrays.NullableArray{Int64,2} + @test typeof(hcat(1:2, NullableArray(1:2))) == NullableArrays.NullableArray{Int64,2} + @test typeof(vcat(NullableArray(1:2), 1:2)) == NullableArrays.NullableArray{Int64,1} + @test typeof(vcat(1:2, NullableArray(1:2))) == NullableArrays.NullableArray{Int64,1} end diff --git a/test/operators.jl b/test/operators.jl index 6f6eff6..d86d469 100644 --- a/test/operators.jl +++ b/test/operators.jl @@ -236,10 +236,4 @@ module TestOperators @test isless(Nullable(), Nullable()) === false end end - @test promote_rule(Nullable{Int64}, Int64) == Nullable{Int64} - @test promote_rule(Int64, Nullable{Int64}) == Nullable{Int64} - @test typeof(hcat(NullableArray(1:2), 1:2)) == NullableArrays.NullableArray{Int64,2} - @test typeof(hcat(1:2, NullableArray(1:2))) == NullableArrays.NullableArray{Int64,2} - @test typeof(vcat(NullableArray(1:2), 1:2)) == NullableArrays.NullableArray{Int64,1} - @test typeof(vcat(1:2, NullableArray(1:2))) == NullableArrays.NullableArray{Int64,1} end From 4aa635c88c510e4f15e50d03431c74ffa797666b Mon Sep 17 00:00:00 2001 From: Cameron Prybol Date: Fri, 24 Feb 2017 16:02:27 -0800 Subject: [PATCH 04/13] reduce the piracy --- src/nullablevector.jl | 83 ++++++++---------------------------------- src/operators.jl | 9 +---- test/nullablevector.jl | 22 +++++++---- 3 files changed, 31 insertions(+), 83 deletions(-) diff --git a/src/nullablevector.jl b/src/nullablevector.jl index 78c2ba2..b668857 100644 --- a/src/nullablevector.jl +++ b/src/nullablevector.jl @@ -312,79 +312,26 @@ function Base.empty!(X::NullableVector) return X end -function Base.promote_rule{T1,T2}(::Type{T1}, ::Type{Nullable{T2}}) - promote_rule(Nullable{T2}, T1) -end - -function Base.typed_hcat{T}(::Type{T}, A::AbstractVecOrMat...) - nargs = length(A) - nrows = size(A[1], 1) - ncols = 0 - dense = true - for j = 1:nargs - Aj = A[j] - if size(Aj, 1) != nrows - throw(ArgumentError("number of rows of each array must match (got $(map(x->size(x,1), A)))")) - end - dense &= isa(Aj,Array) - nd = ndims(Aj) - ncols += (nd==2 ? size(Aj,2) : 1) - end - i = findfirst(a -> isa(a, NullableArray), A) - B = similar(full(A[i == 0 ? 1 : i]), T, nrows, ncols) - pos = 1 - if dense - for k=1:nargs - Ak = A[k] - n = length(Ak) - copy!(B, pos, Ak, 1, n) - pos += n - end - else - for k=1:nargs - Ak = A[k] - p1 = pos+(isa(Ak,AbstractMatrix) ? size(Ak, 2) : 1)-1 - B[:, pos:p1] = Ak - pos = p1+1 - end +function Base.hcat(A::AbstractVecOrMat...) + if any(a -> isa(a, NullableArray), A) + A = [A...] + A[1] = NullableArray(A[1]) end - return B + Base.typed_hcat(Base.promote_eltype(A...), A...) end -function Base.typed_vcat{T}(::Type{T}, V::AbstractVector...) - n::Int = 0 - for Vk in V - n += length(Vk) - end - i = findfirst(v -> isa(v, NullableArray), V) - a = similar(full(V[i == 0 ? 1 : i]), T, n) - pos = 1 - for k=1:length(V) - Vk = V[k] - p1 = pos+length(Vk)-1 - a[pos:p1] = Vk - pos = p1+1 +function Base.vcat(V::AbstractVector...) + if any(v -> isa(v, NullableArray), V) + V = [V...] + V[1] = NullableArray(V[1]) end - a + Base.typed_vcat(Base.promote_eltype(V...), V...) end -function Base.typed_vcat{T}(::Type{T}, A::AbstractMatrix...) - nargs = length(A) - nrows = sum(a->size(a, 1), A)::Int - ncols = size(A[1], 2) - for j = 2:nargs - if size(A[j], 2) != ncols - throw(ArgumentError("number of columns of each array must match (got $(map(x->size(x,2), A)))")) - end - end - i = findfirst(a -> isa(a, NullableArray), A) - B = similar(full(A[i == 0 ? 1 : i]), T, nrows, ncols) - pos = 1 - for k=1:nargs - Ak = A[k] - p1 = pos+size(Ak,1)-1 - B[pos:p1, :] = Ak - pos = p1+1 +function Base.vcat(A::AbstractMatrix...) + if any(a -> isa(a, NullableArray), A) + A = [A...] + A[1] = NullableArray(A[1]) end - return B + Base.typed_vcat(Base.promote_eltype(A...), A...) end diff --git a/src/operators.jl b/src/operators.jl index 6ca3e14..8b323dd 100644 --- a/src/operators.jl +++ b/src/operators.jl @@ -1,14 +1,7 @@ ## Lifted operators importall Base.Operators -import Base: abs, - abs2, - cbrt, - isless, - promote_op, - scalarmin, - scalarmax, - sqrt +import Base: abs, abs2, cbrt, isless, promote_op, scalarmin, scalarmax, sqrt using Compat: @compat, @functorize if isdefined(Base, :fieldname) && Base.fieldname(Nullable, 1) == :hasvalue # Julia 0.6 diff --git a/test/nullablevector.jl b/test/nullablevector.jl index 53a8d13..9c95bfe 100644 --- a/test/nullablevector.jl +++ b/test/nullablevector.jl @@ -224,11 +224,19 @@ module TestNullableVector empty!(X) @test isempty(X) - # tests for reciprocal behavior - @test promote_rule(Nullable{Int64}, Int64) == Nullable{Int64} - @test promote_rule(Int64, Nullable{Int64}) == Nullable{Int64} - @test typeof(hcat(NullableArray(1:2), 1:2)) == NullableArrays.NullableArray{Int64,2} - @test typeof(hcat(1:2, NullableArray(1:2))) == NullableArrays.NullableArray{Int64,2} - @test typeof(vcat(NullableArray(1:2), 1:2)) == NullableArrays.NullableArray{Int64,1} - @test typeof(vcat(1:2, NullableArray(1:2))) == NullableArrays.NullableArray{Int64,1} + @test typeof(hcat(NullableArray(1:2), 3:4)) == NullableArrays.NullableArray{Int64,2} + @test typeof(hcat(1:2, NullableArray(3:4))) == NullableArrays.NullableArray{Int64,2} + @test typeof(vcat(NullableArray(1:2), 3:4)) == NullableArrays.NullableArray{Int64,1} + @test typeof(vcat(1:2, NullableArray(3:4))) == NullableArrays.NullableArray{Int64,1} + @test typeof(vcat(NullableArray([1 2]), [3 4])) == NullableArrays.NullableArray{Int64,2} + @test typeof(vcat([1 2], NullableArray([3 4]))) == NullableArrays.NullableArray{Int64,2} + @test typeof(hcat(NullableArray(1:2), 3:4, 5:6)) == NullableArrays.NullableArray{Int64,2} + @test typeof(hcat(1:2, NullableArray(3:4), 5:6)) == NullableArrays.NullableArray{Int64,2} + @test typeof(hcat(1:2, 3:4, NullableArray(5:6))) == NullableArrays.NullableArray{Int64,2} + @test typeof(vcat(NullableArray(1:2), 3:4, 5:6)) == NullableArrays.NullableArray{Int64,1} + @test typeof(vcat(1:2, NullableArray(3:4), 5:6)) == NullableArrays.NullableArray{Int64,1} + @test typeof(vcat(1:2, 3:4, NullableArray(5:6))) == NullableArrays.NullableArray{Int64,1} + @test typeof(vcat(NullableArray([1 2]), [3 4], [5 6])) == NullableArrays.NullableArray{Int64,2} + @test typeof(vcat([1 2], NullableArray([3 4]), [5 6])) == NullableArrays.NullableArray{Int64,2} + @test typeof(vcat([1 2], [3 4], NullableArray([5 6]))) == NullableArrays.NullableArray{Int64,2} end From 7d948a0854157b3c55380a30337418867915bf41 Mon Sep 17 00:00:00 2001 From: Cameron Prybol Date: Fri, 24 Feb 2017 23:19:58 -0800 Subject: [PATCH 05/13] no more piracy! --- src/nullablevector.jl | 29 ++++++++--------------------- test/nullablevector.jl | 1 + 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/src/nullablevector.jl b/src/nullablevector.jl index b668857..ebddf23 100644 --- a/src/nullablevector.jl +++ b/src/nullablevector.jl @@ -312,26 +312,13 @@ function Base.empty!(X::NullableVector) return X end -function Base.hcat(A::AbstractVecOrMat...) - if any(a -> isa(a, NullableArray), A) - A = [A...] - A[1] = NullableArray(A[1]) - end - Base.typed_hcat(Base.promote_eltype(A...), A...) -end +notnullarray = Union{filter!(x -> !isa(x, Type{NullableArray}), subtypes(AbstractArray))...} +notnullmatrix = typeintersect(notnullarray, AbstractMatrix) +notnullvector = typeintersect(notnullarray, AbstractVector) -function Base.vcat(V::AbstractVector...) - if any(v -> isa(v, NullableArray), V) - V = [V...] - V[1] = NullableArray(V[1]) - end - Base.typed_vcat(Base.promote_eltype(V...), V...) -end +Base.vcat{T <: notnullarray}(A::T, B::NullableArray) = Base.vcat(NullableArray(A), B) +Base.vcat{T <: notnullmatrix}(A::T, B::NullableArray) = Base.vcat(NullableArray(A), B) +Base.vcat{T <: notnullvector}(A::T, B::NullableVector) = Base.vcat(NullableArray(A), B) -function Base.vcat(A::AbstractMatrix...) - if any(a -> isa(a, NullableArray), A) - A = [A...] - A[1] = NullableArray(A[1]) - end - Base.typed_vcat(Base.promote_eltype(A...), A...) -end +Base.hcat{T <: notnullvector}(A::T, B::NullableArray) = Base.hcat(NullableArray(A), B) +Base.hcat{T <: notnullmatrix}(A::T, B::NullableArray) = Base.hcat(NullableArray(A), B) diff --git a/test/nullablevector.jl b/test/nullablevector.jl index 9c95bfe..af4880c 100644 --- a/test/nullablevector.jl +++ b/test/nullablevector.jl @@ -228,6 +228,7 @@ module TestNullableVector @test typeof(hcat(1:2, NullableArray(3:4))) == NullableArrays.NullableArray{Int64,2} @test typeof(vcat(NullableArray(1:2), 3:4)) == NullableArrays.NullableArray{Int64,1} @test typeof(vcat(1:2, NullableArray(3:4))) == NullableArrays.NullableArray{Int64,1} + @test typeof(vcat(NullableArray([1 2]), [3 4])) == NullableArrays.NullableArray{Int64,2} @test typeof(vcat([1 2], NullableArray([3 4]))) == NullableArrays.NullableArray{Int64,2} @test typeof(hcat(NullableArray(1:2), 3:4, 5:6)) == NullableArrays.NullableArray{Int64,2} From 1b64de251f738818d82b8e9fa0ad02de4d5aa168 Mon Sep 17 00:00:00 2001 From: Cameron Prybol Date: Sat, 25 Feb 2017 10:43:08 -0800 Subject: [PATCH 06/13] passing tests --- src/nullablevector.jl | 50 +++++++++++++++++++++++++++++++++++------- src/operators.jl | 2 +- test/nullablevector.jl | 32 +++++++++++++-------------- 3 files changed, 59 insertions(+), 25 deletions(-) diff --git a/src/nullablevector.jl b/src/nullablevector.jl index ebddf23..8c755db 100644 --- a/src/nullablevector.jl +++ b/src/nullablevector.jl @@ -1,3 +1,5 @@ +import Base: hcat, vcat + """ push!{T, V}(X::NullableVector{T}, v::V) @@ -312,13 +314,45 @@ function Base.empty!(X::NullableVector) return X end -notnullarray = Union{filter!(x -> !isa(x, Type{NullableArray}), subtypes(AbstractArray))...} -notnullmatrix = typeintersect(notnullarray, AbstractMatrix) -notnullvector = typeintersect(notnullarray, AbstractVector) +# 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 -Base.vcat{T <: notnullarray}(A::T, B::NullableArray) = Base.vcat(NullableArray(A), B) -Base.vcat{T <: notnullmatrix}(A::T, B::NullableArray) = Base.vcat(NullableArray(A), B) -Base.vcat{T <: notnullvector}(A::T, B::NullableVector) = Base.vcat(NullableArray(A), B) +# 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 -Base.hcat{T <: notnullvector}(A::T, B::NullableArray) = Base.hcat(NullableArray(A), B) -Base.hcat{T <: notnullmatrix}(A::T, B::NullableArray) = Base.hcat(NullableArray(A), B) +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 diff --git a/src/operators.jl b/src/operators.jl index 8b323dd..72d32a7 100644 --- a/src/operators.jl +++ b/src/operators.jl @@ -1,7 +1,7 @@ ## Lifted operators importall Base.Operators -import Base: abs, abs2, cbrt, isless, promote_op, scalarmin, scalarmax, sqrt +import Base: promote_op, abs, abs2, sqrt, cbrt, scalarmin, scalarmax, isless using Compat: @compat, @functorize if isdefined(Base, :fieldname) && Base.fieldname(Nullable, 1) == :hasvalue # Julia 0.6 diff --git a/test/nullablevector.jl b/test/nullablevector.jl index af4880c..f8b8b39 100644 --- a/test/nullablevector.jl +++ b/test/nullablevector.jl @@ -224,20 +224,20 @@ module TestNullableVector empty!(X) @test isempty(X) - @test typeof(hcat(NullableArray(1:2), 3:4)) == NullableArrays.NullableArray{Int64,2} - @test typeof(hcat(1:2, NullableArray(3:4))) == NullableArrays.NullableArray{Int64,2} - @test typeof(vcat(NullableArray(1:2), 3:4)) == NullableArrays.NullableArray{Int64,1} - @test typeof(vcat(1:2, NullableArray(3:4))) == NullableArrays.NullableArray{Int64,1} - - @test typeof(vcat(NullableArray([1 2]), [3 4])) == NullableArrays.NullableArray{Int64,2} - @test typeof(vcat([1 2], NullableArray([3 4]))) == NullableArrays.NullableArray{Int64,2} - @test typeof(hcat(NullableArray(1:2), 3:4, 5:6)) == NullableArrays.NullableArray{Int64,2} - @test typeof(hcat(1:2, NullableArray(3:4), 5:6)) == NullableArrays.NullableArray{Int64,2} - @test typeof(hcat(1:2, 3:4, NullableArray(5:6))) == NullableArrays.NullableArray{Int64,2} - @test typeof(vcat(NullableArray(1:2), 3:4, 5:6)) == NullableArrays.NullableArray{Int64,1} - @test typeof(vcat(1:2, NullableArray(3:4), 5:6)) == NullableArrays.NullableArray{Int64,1} - @test typeof(vcat(1:2, 3:4, NullableArray(5:6))) == NullableArrays.NullableArray{Int64,1} - @test typeof(vcat(NullableArray([1 2]), [3 4], [5 6])) == NullableArrays.NullableArray{Int64,2} - @test typeof(vcat([1 2], NullableArray([3 4]), [5 6])) == NullableArrays.NullableArray{Int64,2} - @test typeof(vcat([1 2], [3 4], NullableArray([5 6]))) == NullableArrays.NullableArray{Int64,2} + @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 From 9cc8381d2e777111d1d37c33ad4eb247e664e92e Mon Sep 17 00:00:00 2001 From: Cameron Prybol Date: Sat, 25 Feb 2017 10:48:03 -0800 Subject: [PATCH 07/13] rearrange functions to cleanup comments --- src/nullablevector.jl | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/nullablevector.jl b/src/nullablevector.jl index 8c755db..eeab3ca 100644 --- a/src/nullablevector.jl +++ b/src/nullablevector.jl @@ -323,19 +323,15 @@ 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...) +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 # 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 From b8c87b54984a4c239db069fd715ffca6c9e983bd Mon Sep 17 00:00:00 2001 From: Cameron Prybol Date: Sat, 25 Feb 2017 10:57:39 -0800 Subject: [PATCH 08/13] spacing --- src/nullablevector.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/nullablevector.jl b/src/nullablevector.jl index eeab3ca..79f6cb9 100644 --- a/src/nullablevector.jl +++ b/src/nullablevector.jl @@ -335,7 +335,6 @@ vcat{T <: NotNullMatrix}(A::T, B::NullableMatrix, C::AbstractMatrix...) = vcat(N 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 @@ -344,7 +343,6 @@ 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 From bb0b1ee13ecb067515c168a534940a14f28c031e Mon Sep 17 00:00:00 2001 From: Cameron Prybol Date: Sat, 25 Feb 2017 11:02:36 -0800 Subject: [PATCH 09/13] add more tests and reorder tests to match function order --- test/nullablevector.jl | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/test/nullablevector.jl b/test/nullablevector.jl index f8b8b39..8ccf300 100644 --- a/test/nullablevector.jl +++ b/test/nullablevector.jl @@ -224,20 +224,25 @@ module TestNullableVector 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} + + @test typeof(hcat(NullableArray(1:2), 3:4)) == NullableArray{Int64,2} + @test typeof(hcat(1:2, NullableArray(3:4))) == NullableArray{Int64,2} + @test typeof(hcat(NullableArray([1 2]), [3 4])) == NullableArray{Int64,2} + @test typeof(hcat([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(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} end From b8211a973193bdf1448724b2e98d989fe8bd44bb Mon Sep 17 00:00:00 2001 From: Cameron Prybol Date: Sat, 25 Feb 2017 12:35:00 -0800 Subject: [PATCH 10/13] no more stack overflows --- src/nullablevector.jl | 47 ++++++++++++++++--------------------------- 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/src/nullablevector.jl b/src/nullablevector.jl index 79f6cb9..7cfe496 100644 --- a/src/nullablevector.jl +++ b/src/nullablevector.jl @@ -1,4 +1,4 @@ -import Base: hcat, vcat +import Base: vcat, hcat, typed_vcat, typed_hcat, promote_eltype """ push!{T, V}(X::NullableVector{T}, v::V) @@ -314,39 +314,26 @@ function Base.empty!(X::NullableVector) 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...) -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...) +function vcat(A::AbstractVector, B::AbstractVector...) + any(b -> isa(b, NullableArray), B) ? + typed_vcat(promote_eltype(A, B...), NullableArray(A), B...) : + typed_vcat(promote_eltype(A, B...), A, B...) end -# 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...) -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...) +function vcat(A::AbstractMatrix, B::AbstractMatrix...) + any(b -> isa(b, NullableArray), B) ? + typed_vcat(promote_eltype(A, B...), NullableArray(A), B...) : + typed_vcat(promote_eltype(A, B...), A, B...) 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...) +function vcat(A::AbstractArray, B::AbstractArray...) + any(b -> isa(b, NullableArray), B) ? + typed_vcat(promote_eltype(A, B...), NullableArray(A), B...) : + typed_vcat(promote_eltype(A, B...), A, B...) 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...) +function hcat(A::AbstractVecOrMat, B::AbstractVecOrMat...) + any(b -> isa(b, NullableArray), B) ? + typed_hcat(promote_eltype(A, B...), NullableArray(A), B...) : + typed_hcat(promote_eltype(A, B...), A, B...) end From d28b7b84245433ce57ec9b35195a3a2526bcef61 Mon Sep 17 00:00:00 2001 From: Cameron Prybol Date: Sat, 25 Feb 2017 13:06:38 -0800 Subject: [PATCH 11/13] Int64 -> Int --- test/nullablevector.jl | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/test/nullablevector.jl b/test/nullablevector.jl index 8ccf300..b157583 100644 --- a/test/nullablevector.jl +++ b/test/nullablevector.jl @@ -224,25 +224,25 @@ module TestNullableVector empty!(X) @test isempty(X) - @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(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} - - @test typeof(hcat(NullableArray(1:2), 3:4)) == NullableArray{Int64,2} - @test typeof(hcat(1:2, NullableArray(3:4))) == NullableArray{Int64,2} - @test typeof(hcat(NullableArray([1 2]), [3 4])) == NullableArray{Int64,2} - @test typeof(hcat([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(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)) == NullableArray{Int,1} + @test typeof(vcat(1:2, NullableArray(3:4))) == NullableArray{Int,1} + @test typeof(vcat(NullableArray([1 2]), [3 4])) == NullableArray{Int,2} + @test typeof(vcat([1 2], NullableArray([3 4]))) == NullableArray{Int,2} + @test typeof(vcat(NullableArray(1:2), 3:4, 5:6)) == NullableArray{Int,1} + @test typeof(vcat(1:2, NullableArray(3:4), 5:6)) == NullableArray{Int,1} + @test typeof(vcat(1:2, 3:4, NullableArray(5:6))) == NullableArray{Int,1} + @test typeof(vcat(NullableArray([1 2]), [3 4], [5 6])) == NullableArray{Int,2} + @test typeof(vcat([1 2], NullableArray([3 4]), [5 6])) == NullableArray{Int,2} + @test typeof(vcat([1 2], [3 4], NullableArray([5 6]))) == NullableArray{Int,2} + + @test typeof(hcat(NullableArray(1:2), 3:4)) == NullableArray{Int,2} + @test typeof(hcat(1:2, NullableArray(3:4))) == NullableArray{Int,2} + @test typeof(hcat(NullableArray([1 2]), [3 4])) == NullableArray{Int,2} + @test typeof(hcat([1 2], NullableArray([3 4]))) == NullableArray{Int,2} + @test typeof(hcat(NullableArray(1:2), 3:4, 5:6)) == NullableArray{Int,2} + @test typeof(hcat(1:2, NullableArray(3:4), 5:6)) == NullableArray{Int,2} + @test typeof(hcat(1:2, 3:4, NullableArray(5:6))) == NullableArray{Int,2} + @test typeof(hcat(NullableArray([1 2]), [3 4], [5 6])) == NullableArray{Int,2} + @test typeof(hcat([1 2], NullableArray([3 4]), [5 6])) == NullableArray{Int,2} + @test typeof(hcat([1 2], [3 4], NullableArray([5 6]))) == NullableArray{Int,2} end From 6c30d14f62ab750a9e0f65a1767a3a20e13a8702 Mon Sep 17 00:00:00 2001 From: Cameron Prybol Date: Wed, 1 Mar 2017 14:44:05 -0800 Subject: [PATCH 12/13] implement 2 argument cases and comment out 3 argument tests --- src/nullablevector.jl | 25 +++++++++---------------- test/nullablevector.jl | 28 ++++++++++++++++------------ 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/nullablevector.jl b/src/nullablevector.jl index 7cfe496..72c6a56 100644 --- a/src/nullablevector.jl +++ b/src/nullablevector.jl @@ -314,26 +314,19 @@ function Base.empty!(X::NullableVector) return X end -function vcat(A::AbstractVector, B::AbstractVector...) - any(b -> isa(b, NullableArray), B) ? - typed_vcat(promote_eltype(A, B...), NullableArray(A), B...) : - typed_vcat(promote_eltype(A, B...), A, B...) +function vcat(A::AbstractVector, B::NullableVector) + typed_vcat(promote_eltype(A, B), NullableArray(A), B) end -function vcat(A::AbstractMatrix, B::AbstractMatrix...) - any(b -> isa(b, NullableArray), B) ? - typed_vcat(promote_eltype(A, B...), NullableArray(A), B...) : - typed_vcat(promote_eltype(A, B...), A, B...) +function vcat(A::AbstractMatrix, B::NullableMatrix) + typed_vcat(promote_eltype(A, B), NullableArray(A), B) end -function vcat(A::AbstractArray, B::AbstractArray...) - any(b -> isa(b, NullableArray), B) ? - typed_vcat(promote_eltype(A, B...), NullableArray(A), B...) : - typed_vcat(promote_eltype(A, B...), A, B...) +function vcat(A::AbstractArray, B::NullableArray) + typed_vcat(promote_eltype(A, B), NullableArray(A), B) end -function hcat(A::AbstractVecOrMat, B::AbstractVecOrMat...) - any(b -> isa(b, NullableArray), B) ? - typed_hcat(promote_eltype(A, B...), NullableArray(A), B...) : - typed_hcat(promote_eltype(A, B...), A, B...) +NullableVecOrMat = Union{NullableVector, NullableMatrix} +function hcat(A::AbstractVecOrMat, B::NullableVecOrMat) + typed_hcat(promote_eltype(A, B), NullableArray(A), B) end diff --git a/test/nullablevector.jl b/test/nullablevector.jl index b157583..dd19dd2 100644 --- a/test/nullablevector.jl +++ b/test/nullablevector.jl @@ -228,21 +228,25 @@ module TestNullableVector @test typeof(vcat(1:2, NullableArray(3:4))) == NullableArray{Int,1} @test typeof(vcat(NullableArray([1 2]), [3 4])) == NullableArray{Int,2} @test typeof(vcat([1 2], NullableArray([3 4]))) == NullableArray{Int,2} - @test typeof(vcat(NullableArray(1:2), 3:4, 5:6)) == NullableArray{Int,1} - @test typeof(vcat(1:2, NullableArray(3:4), 5:6)) == NullableArray{Int,1} - @test typeof(vcat(1:2, 3:4, NullableArray(5:6))) == NullableArray{Int,1} - @test typeof(vcat(NullableArray([1 2]), [3 4], [5 6])) == NullableArray{Int,2} - @test typeof(vcat([1 2], NullableArray([3 4]), [5 6])) == NullableArray{Int,2} - @test typeof(vcat([1 2], [3 4], NullableArray([5 6]))) == NullableArray{Int,2} @test typeof(hcat(NullableArray(1:2), 3:4)) == NullableArray{Int,2} @test typeof(hcat(1:2, NullableArray(3:4))) == NullableArray{Int,2} @test typeof(hcat(NullableArray([1 2]), [3 4])) == NullableArray{Int,2} @test typeof(hcat([1 2], NullableArray([3 4]))) == NullableArray{Int,2} - @test typeof(hcat(NullableArray(1:2), 3:4, 5:6)) == NullableArray{Int,2} - @test typeof(hcat(1:2, NullableArray(3:4), 5:6)) == NullableArray{Int,2} - @test typeof(hcat(1:2, 3:4, NullableArray(5:6))) == NullableArray{Int,2} - @test typeof(hcat(NullableArray([1 2]), [3 4], [5 6])) == NullableArray{Int,2} - @test typeof(hcat([1 2], NullableArray([3 4]), [5 6])) == NullableArray{Int,2} - @test typeof(hcat([1 2], [3 4], NullableArray([5 6]))) == NullableArray{Int,2} + + # add these back if we can find a general solution to propogating array type + # see https://github.com/JuliaLang/julia/issues/2326 + # @test typeof(vcat(NullableArray(1:2), 3:4, 5:6)) == NullableArray{Int,1} + # @test typeof(vcat(1:2, NullableArray(3:4), 5:6)) == NullableArray{Int,1} + # @test typeof(vcat(1:2, 3:4, NullableArray(5:6))) == NullableArray{Int,1} + # @test typeof(vcat(NullableArray([1 2]), [3 4], [5 6])) == NullableArray{Int,2} + # @test typeof(vcat([1 2], NullableArray([3 4]), [5 6])) == NullableArray{Int,2} + # @test typeof(vcat([1 2], [3 4], NullableArray([5 6]))) == NullableArray{Int,2} + + # @test typeof(hcat(NullableArray(1:2), 3:4, 5:6)) == NullableArray{Int,2} + # @test typeof(hcat(1:2, NullableArray(3:4), 5:6)) == NullableArray{Int,2} + # @test typeof(hcat(1:2, 3:4, NullableArray(5:6))) == NullableArray{Int,2} + # @test typeof(hcat(NullableArray([1 2]), [3 4], [5 6])) == NullableArray{Int,2} + # @test typeof(hcat([1 2], NullableArray([3 4]), [5 6])) == NullableArray{Int,2} + # @test typeof(hcat([1 2], [3 4], NullableArray([5 6]))) == NullableArray{Int,2} end From 2e2b98a7b3734d1744a91fe462acd16a596b392f Mon Sep 17 00:00:00 2001 From: Cameron Prybol Date: Wed, 1 Mar 2017 16:44:24 -0800 Subject: [PATCH 13/13] correct spacing issue --- src/nullablevector.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/nullablevector.jl b/src/nullablevector.jl index 72c6a56..2eff274 100644 --- a/src/nullablevector.jl +++ b/src/nullablevector.jl @@ -315,18 +315,18 @@ function Base.empty!(X::NullableVector) end function vcat(A::AbstractVector, B::NullableVector) - typed_vcat(promote_eltype(A, B), NullableArray(A), B) + typed_vcat(promote_eltype(A, B), NullableArray(A), B) end function vcat(A::AbstractMatrix, B::NullableMatrix) - typed_vcat(promote_eltype(A, B), NullableArray(A), B) + typed_vcat(promote_eltype(A, B), NullableArray(A), B) end function vcat(A::AbstractArray, B::NullableArray) - typed_vcat(promote_eltype(A, B), NullableArray(A), B) + typed_vcat(promote_eltype(A, B), NullableArray(A), B) end NullableVecOrMat = Union{NullableVector, NullableMatrix} function hcat(A::AbstractVecOrMat, B::NullableVecOrMat) - typed_hcat(promote_eltype(A, B), NullableArray(A), B) + typed_hcat(promote_eltype(A, B), NullableArray(A), B) end