Skip to content

Commit d8ec6ae

Browse files
committed
Refactor similar methods
1 parent 977c0f6 commit d8ec6ae

File tree

2 files changed

+30
-13
lines changed

2 files changed

+30
-13
lines changed

src/arrays.jl

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ and so can be used in most places where a normal array would be used.
1515
# Constructors
1616
1717
- `QuantityArray(value::AbstractArray, dimensions::AbstractDimensions)`: Create a `QuantityArray` with value `value` and dimensions `dimensions`.
18-
- `QuantityArray(value::AbstractArray, quantity::Quantity)`: Create a `QuantityArray` with value `value` and dimensions inferred
18+
- `QuantityArray(value::AbstractArray, quantity::Quantity)`: Create a `QuantityArray` with value `value` and dimensions inferred
1919
with `dimension(quantity)`. This is so that you can easily create an array with the units module, like so:
2020
```julia
2121
julia> A = QuantityArray(randn(32), 1u"m")
@@ -121,22 +121,19 @@ unsafe_setindex!(A, v, i...) = setindex!(ustrip(A), ustrip(v), i...)
121121

122122
Base.IndexStyle(::Type{Q}) where {Q<:QuantityArray} = IndexStyle(array_type(Q))
123123

124-
const IntOrOneTo = Union{Integer, Base.OneTo}
125124

126-
# Unfortunately this mess of `similar` is required to avoid ambiguous methods.
127-
# c.f. base/abstractarray.jl
128125
Base.similar(A::QuantityArray) = QuantityArray(similar(ustrip(A)), dimension(A), quantity_type(A))
129126
Base.similar(A::QuantityArray, ::Type{S}) where {S} = QuantityArray(similar(ustrip(A), S), dimension(A), quantity_type(A))
130-
Base.similar(A::QuantityArray, dims::Dims{N}) where {N} = QuantityArray(similar(ustrip(A), dims), dimension(A), quantity_type(A))
131-
Base.similar(A::QuantityArray, dims::Tuple{IntOrOneTo, Vararg{IntOrOneTo}}) = QuantityArray(similar(ustrip(A), dims), dimension(A), quantity_type(A))
132-
Base.similar(A::QuantityArray, dims::Tuple{Integer, Vararg{Integer}}) = QuantityArray(similar(ustrip(A), dims), dimension(A), quantity_type(A))
133-
Base.similar(A::QuantityArray, ::Type{S}, dims::Dims{N}) where {S,N} = QuantityArray(similar(ustrip(A), S, dims), dimension(A), quantity_type(A))
134-
Base.similar(A::QuantityArray, ::Type{S}, dims::Tuple{IntOrOneTo, Vararg{IntOrOneTo}}) where {S} = QuantityArray(similar(ustrip(A), S, dims), dimension(A), quantity_type(A))
135-
Base.similar(A::QuantityArray, ::Type{S}, dims::Tuple{Integer, Vararg{Integer}}) where {S} = QuantityArray(similar(ustrip(A), S, dims), dimension(A), quantity_type(A))
136-
137-
function Base.BroadcastStyle(::Type{QA}) where {QA<:QuantityArray}
138-
return Broadcast.ArrayStyle{QA}()
127+
128+
# Unfortunately this mess of `similar` is required to avoid ambiguous methods.
129+
# c.f. base/abstractarray.jl
130+
for dim_type in (:(Dims), :(Tuple{Union{Integer,Base.OneTo},Vararg{Union{Integer,Base.OneTo}}}), :(Tuple{Integer, Vararg{Integer}}))
131+
@eval Base.similar(A::QuantityArray, dims::$dim_type) = QuantityArray(similar(ustrip(A), dims), dimension(A), quantity_type(A))
132+
@eval Base.similar(A::QuantityArray, ::Type{S}, dims::$dim_type) where {S} = QuantityArray(similar(ustrip(A), S, dims), dimension(A), quantity_type(A))
139133
end
134+
135+
Base.BroadcastStyle(::Type{QA}) where {QA<:QuantityArray} = Broadcast.ArrayStyle{QA}()
136+
140137
function Base.similar(bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{QA}}, ::Type{ElType}) where {QA<:QuantityArray,ElType<:AbstractQuantity}
141138
T = value_type(ElType)
142139
output_array = similar(bc, T)

test/unittests.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,14 @@ end
742742
a = [randn() * u"km/s" for i=1:32]
743743
@test typeof(y .* a) <: QuantityArray
744744
@test typeof(a .* y) <: QuantityArray
745+
746+
b = Quantity(randn(Float32, 32)) * u"km/s"
747+
@test typeof(b) <: Quantity
748+
@test typeof(b .* b) <: Vector{<:Quantity}
749+
@test typeof(a .* b) <: Vector{<:Quantity}
750+
@test typeof(b .* a) <: Vector{<:Quantity}
751+
@test typeof(y .* b) <: QuantityArray{Float64}
752+
@test typeof(b .* y) <: QuantityArray{Float64}
745753
end
746754

747755
@testset "Broadcast scalars" begin
@@ -773,4 +781,16 @@ end
773781
msg2 = String(take!(io))
774782
@test msg2 == msg
775783
end
784+
785+
@testset "Extra test coverage" begin
786+
@test_throws ErrorException DynamicQuantities.materialize_first(())
787+
VERSION >= v"1.8" &&
788+
@test_throws "Unexpected broadcast" DynamicQuantities.materialize_first(())
789+
790+
# Not sure how to test this otherwise, but method is supposed to be
791+
# required for the broadcasting interface
792+
x = [1u"km/s"]
793+
ref = Base.RefValue(x)
794+
@test DynamicQuantities.materialize_first(ref) === x[1]
795+
end
776796
end

0 commit comments

Comments
 (0)