Skip to content

Commit 02c1449

Browse files
committed
Rename FirstClass as SizeEltypeAdaptable
And convert comments to docstring.
1 parent 29dda2f commit 02c1449

File tree

1 file changed

+35
-22
lines changed

1 file changed

+35
-22
lines changed

src/convert.jl

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,34 +24,47 @@ _size1(::Type{<:StaticMatrix{M}}) where {M} = M
2424
return :($N)
2525
end
2626

27-
const FirstClass = Union{SArray, MArray, SHermitianCompact, SizedArray}
28-
2927
"""
30-
construct_type(::Type{<:StaticArray}, x)
28+
construct_type(::Type{SA}, x) where {SA<:StaticArray}
3129
3230
Returns a constructor for a statically-sized array based on `x`'s size and eltype.
33-
The first argument is returned by default.
31+
If no derivation rules are provided, the default return value is `SA` itself.
32+
33+
Offical `StaticArray`s have specific `construct_type` defined to support size/eltype
34+
adaptation during construction.
35+
36+
# `SA <: FieldArray`
37+
38+
`FieldArray`s should always be fully static-sized. We only derive the output's eltype using type promotion if needed.
39+
40+
# `SA <: Union{SArray, MArray, SHermitianCompact, SizedArray}`
41+
42+
These `StaticArray`s support size/eltype derivation during construction.
43+
The adaption rule could be summarized as:
44+
- SA(x::Tuple)
45+
If `SA` is fully static-sized, then we first try to fill `SA` with `x`'s elements.
46+
If failed and `length(SA) == 1`, then we try to fill `SA` with `x` itself.
47+
48+
If `SA` is not fully static-sized, then we always try to fill `SA` with `x`'s elements,
49+
and the constructor's `Size` is derived based on:
50+
1. If `SA <: StaticVector`, then we use `length(x)` as the output `Length`
51+
2. If `SA <: StaticMatrix{M}`, then we use `(M, N)` (`N = length(x) ÷ M`) as the output `Size`
52+
3. If `SA <: StaticMatrix{M,M} where M`, then we use `(N, N)` (`N = sqrt(length(x)`) as the output `Size`.
53+
- SA(x...)
54+
Similar to `Tuple`, but we never fill `SA` with `x` itself.
55+
- SA(x::StaticArray)
56+
We treat `x` as `Tuple` whenever possible. If failed, then try to inherit `x`'s `Size`.
57+
- SA(x::AbstractArray)
58+
`x` is used to provide eltype. Thus `SA` must be static sized.
3459
"""
3560
function construct_type(::Type{SA}, x) where {SA<:StaticArray}
3661
x isa BadArgs || return SA
3762
_no_precise_size(SA, x.args[1][1])
3863
end
3964

40-
# Here we define `construct_type(SA, x)` for `SArray`, `MArray`, `SHermitianCompact`, `SizedArray`
41-
# Different `x` has different rules, to summarize:
42-
# 1. Tuple
43-
# We try to fill `SA` with elements in `x` if `SA` is static-sized.
44-
# If `SA <: StaticVector`, the output `Length` is derived based on `length(x)`.
45-
# If `SA <: StaticMatrix{M}`, the output `Size` is derived based on `length(x)÷M`.
46-
# If `SA <: StaticMatrix{M,M} where M`, the output `Size` is derived based on `sqrt(length(x))`.
47-
# If `length(SA) == 1 && length(x) > 1`, then we tries to fill `SA` with `x` itself. (rewrapping)
48-
# 2. Args (`SA(x...)`)
49-
# Similar to `Tuple`, but rewrapping is not allowed.
50-
# 3. StaticArray
51-
# Treat `x` as `Tuple` whenever possible. If failed, then try to inherit `x`'s `Size`.
52-
# 4. AbstractArray
53-
# `x` is used to provide eltype. Thus `SA` must be static sized.
54-
function construct_type(::Type{SA}, x) where {SA<:FirstClass}
65+
# These StaticArrays support `size`/`eltype` adaption during construction.
66+
const SizeEltypeAdaptable = Union{SArray, MArray, SHermitianCompact, SizedArray}
67+
function construct_type(::Type{SA}, x) where {SA<:SizeEltypeAdaptable}
5568
SA′ = adapt_eltype_size(SA, x)
5669
check_parameters(SA′)
5770
x isa Tuple && SA === SA′ && error("Constructor for $SA is missing. Please file a bug.")
@@ -113,10 +126,10 @@ end
113126

114127
need_rewrap(::Type{<:StaticArray}, x) = false
115128
function need_rewrap(::Type{SA}, x::Union{Tuple,StaticArray}) where {SA <: StaticArray}
116-
has_size(SA) && length(SA) == 1 && length(x) > 1
129+
has_size(SA) && length(SA) == 1 && length(x) != 1
117130
end
118131

119-
check_parameters(::Type{<:FirstClass}) = nothing
132+
check_parameters(::Type{<:SizeEltypeAdaptable}) = nothing
120133
check_parameters(::Type{SArray{S,T,N,L}}) where {S<:Tuple,T,N,L} = check_array_parameters(S,T,Val{N},Val{L})
121134
check_parameters(::Type{MArray{S,T,N,L}}) where {S<:Tuple,T,N,L} = check_array_parameters(S,T,Val{N},Val{L})
122135
check_parameters(::Type{SHermitianCompact{N,T,L}}) where {N,T,L} = _check_hermitian_parameters(Val(N), Val(L))
@@ -127,7 +140,7 @@ _no_precise_size(SA, x::StaticArray) = throw(DimensionMismatch("No precise const
127140
_no_precise_size(SA, x) = throw(DimensionMismatch("No precise constructor for $SA found. Input is not static sized."))
128141

129142
@inline (::Type{SA})(x...) where {SA <: StaticArray} = construct_type(SA, Args(x))(x)
130-
@inline function (::Type{SA})(x::Tuple) where {SA <: FirstClass}
143+
@inline function (::Type{SA})(x::Tuple) where {SA <: SizeEltypeAdaptable}
131144
SA′ = construct_type(SA, x)
132145
need_rewrap(SA′, x) ? SA′((x,)) : SA′(x)
133146
end

0 commit comments

Comments
 (0)