Skip to content

Commit 29a76ec

Browse files
mateuszbaranthchr
andauthored
StaticArraysCore transition (#1045)
* StaticArraysCore transition * update error test * add StaticArraysCore docstrings to documentation * move StaticArraysCore re-exports * add StaticArraysCore to docs project dependencies * mention StaticArraysCore.jl in README * Update README.md Co-authored-by: Thomas Christensen <[email protected]> Co-authored-by: Thomas Christensen <[email protected]>
1 parent 982b4a1 commit 29a76ec

15 files changed

+35
-256
lines changed

Project.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
name = "StaticArrays"
22
uuid = "90137ffa-7385-5640-81b9-e52037218182"
3-
version = "1.4.7"
3+
version = "1.5.0"
44

55
[deps]
66
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
77
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
8+
StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c"
89
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
910

1011
[compat]
1112
julia = "1.6"
13+
StaticArraysCore = "1"
1214

1315
[extras]
1416
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ Further, the abstract `FieldVector` can be used to make fast `StaticVector`s
2323
out of any uniform Julia "struct".
2424
Full documentation can be found [here](https://JuliaArrays.github.io/StaticArrays.jl/stable/).
2525

26+
Most of the primary array types exported by StaticArrays.jl are defined in the small interface
27+
package [StaticArraysCore.jl](https://github.com/JuliaArrays/StaticArraysCore.jl). This includes
28+
e.g., the definitions of the abstract type `StaticArray` and the concrete types `SArray`,
29+
`MArray`, and `SizedArray` (as well as their dimension-specific aliases).
30+
This enables downstream packages to implement new methods for these types without depending
31+
on (and hence loading) the entirety of StaticArrays.jl, and thereby to avoid incurring the full
32+
load-time of StaticArrays.jl (which is on the order of 0.6 s for StaticArrays.jl v1.4 on Julia
33+
v1.7).
34+
2635
## Speed
2736

2837
The speed of *small* `SVector`s, `SMatrix`s and `SArray`s is often > 10 × faster

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[deps]
22
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
3+
StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c"
34

45
[compat]
56
Documenter = "~0.27"

docs/make.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
using Documenter
22
using StaticArrays
3+
using StaticArraysCore
34

45
# Setup for doctests in docstrings
56
DocMeta.setdocmeta!(StaticArrays, :DocTestSetup, :(using LinearAlgebra, StaticArrays))
67

78
makedocs(;
8-
modules = [StaticArrays],
9+
modules = [StaticArrays, StaticArraysCore],
910
format = Documenter.HTML(
1011
canonical = "https://JuliaArrays.github.io/StaticArrays.jl/stable/",
1112
assets = ["assets/favicon.ico"],

docs/src/pages/api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,5 +356,5 @@ faster!
356356
Pages = ["api.md"]
357357
```
358358
```@autodocs
359-
Modules = [StaticArrays]
359+
Modules = [StaticArrays, StaticArraysCore]
360360
```

src/MArray.jl

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,3 @@
1-
"""
2-
MArray{S, T, N, L}(undef)
3-
MArray{S, T, N, L}(x::NTuple{L})
4-
MArray{S, T, N, L}(x1, x2, x3, ...)
5-
6-
7-
Construct a statically-sized, mutable array `MArray`. The data may optionally be
8-
provided upon construction and can be mutated later. The `S` parameter is a Tuple-type
9-
specifying the dimensions, or size, of the array - such as `Tuple{3,4,5}` for a 3×4×5-sized
10-
array. The `N` parameter is the dimension of the array; the `L` parameter is the `length`
11-
of the array and is always equal to `prod(S)`. Constructors may drop the `L`, `N` and `T`
12-
parameters if they are inferrable from the input (e.g. `L` is always inferrable from `S`).
13-
14-
MArray{S}(a::Array)
15-
16-
Construct a statically-sized, mutable array of dimensions `S` (expressed as a `Tuple{...}`)
17-
using the data from `a`. The `S` parameter is mandatory since the size of `a` is unknown to
18-
the compiler (the element type may optionally also be specified).
19-
"""
20-
mutable struct MArray{S <: Tuple, T, N, L} <: StaticArray{S, T, N}
21-
data::NTuple{L,T}
22-
23-
function MArray{S,T,N,L}(x::NTuple{L,T}) where {S<:Tuple,T,N,L}
24-
check_array_parameters(S, T, Val{N}, Val{L})
25-
new{S,T,N,L}(x)
26-
end
27-
28-
function MArray{S,T,N,L}(x::NTuple{L,Any}) where {S<:Tuple,T,N,L}
29-
check_array_parameters(S, T, Val{N}, Val{L})
30-
new{S,T,N,L}(convert_ntuple(T, x))
31-
end
32-
33-
function MArray{S,T,N,L}(::UndefInitializer) where {S<:Tuple,T,N,L}
34-
check_array_parameters(S, T, Val{N}, Val{L})
35-
new{S,T,N,L}()
36-
end
37-
end
38-
39-
@inline MArray{S,T,N}(x::Tuple) where {S<:Tuple,T,N} = MArray{S,T,N,tuple_prod(S)}(x)
401

412
@generated function (::Type{MArray{S,T,N}})(::UndefInitializer) where {S,T,N}
423
return quote

src/MMatrix.jl

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,3 @@
1-
"""
2-
MMatrix{S1, S2, T, L}(undef)
3-
MMatrix{S1, S2, T, L}(x::NTuple{L, T})
4-
MMatrix{S1, S2, T, L}(x1, x2, x3, ...)
5-
6-
Construct a statically-sized, mutable matrix `MMatrix`. The data may optionally
7-
be provided upon construction and can be mutated later. The `L` parameter is the
8-
`length` of the array and is always equal to `S1 * S2`. Constructors may drop
9-
the `L`, `T` and even `S2` parameters if they are inferrable from the input
10-
(e.g. `L` is always inferrable from `S1` and `S2`).
11-
12-
MMatrix{S1, S2}(mat::Matrix)
13-
14-
Construct a statically-sized, mutable matrix of dimensions `S1 × S2` using the data from
15-
`mat`. The parameters `S1` and `S2` are mandatory since the size of `mat` is
16-
unknown to the compiler (the element type may optionally also be specified).
17-
"""
18-
const MMatrix{S1, S2, T, L} = MArray{Tuple{S1, S2}, T, 2, L}
191

202
@generated function (::Type{MMatrix{S1,S2,T}})(::UndefInitializer) where {S1,S2,T}
213
return quote

src/MVector.jl

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,3 @@
1-
"""
2-
MVector{S,T}(undef)
3-
MVector{S,T}(x::NTuple{S, T})
4-
MVector{S,T}(x1, x2, x3, ...)
5-
6-
Construct a statically-sized, mutable vector `MVector`. Data may optionally be
7-
provided upon construction, and can be mutated later. Constructors may drop the
8-
`T` and `S` parameters if they are inferrable from the input (e.g.
9-
`MVector(1,2,3)` constructs an `MVector{3, Int}`).
10-
11-
MVector{S}(vec::Vector)
12-
13-
Construct a statically-sized, mutable vector of length `S` using the data from
14-
`vec`. The parameter `S` is mandatory since the length of `vec` is unknown to the
15-
compiler (the element type may optionally also be specified).
16-
"""
17-
const MVector{S, T} = MArray{Tuple{S}, T, 1, S}
181

192
# Some more advanced constructor-like functions
203
@inline zeros(::Type{MVector{N}}) where {N} = zeros(MVector{N,Float64})

src/SArray.jl

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,3 @@
1-
"""
2-
SArray{S, T, N, L}(x::NTuple{L})
3-
SArray{S, T, N, L}(x1, x2, x3, ...)
4-
5-
Construct a statically-sized array `SArray`. Since this type is immutable, the data must be
6-
provided upon construction and cannot be mutated later. The `S` parameter is a Tuple-type
7-
specifying the dimensions, or size, of the array - such as `Tuple{3,4,5}` for a 3×4×5-sized
8-
array. The `N` parameter is the dimension of the array; the `L` parameter is the `length`
9-
of the array and is always equal to `prod(S)`. Constructors may drop the `L`, `N` and `T`
10-
parameters if they are inferrable from the input (e.g. `L` is always inferrable from `S`).
11-
12-
SArray{S}(a::Array)
13-
14-
Construct a statically-sized array of dimensions `S` (expressed as a `Tuple{...}`) using
15-
the data from `a`. The `S` parameter is mandatory since the size of `a` is unknown to the
16-
compiler (the element type may optionally also be specified).
17-
"""
18-
struct SArray{S <: Tuple, T, N, L} <: StaticArray{S, T, N}
19-
data::NTuple{L,T}
20-
21-
function SArray{S, T, N, L}(x::NTuple{L,T}) where {S<:Tuple, T, N, L}
22-
check_array_parameters(S, T, Val{N}, Val{L})
23-
new{S, T, N, L}(x)
24-
end
25-
26-
function SArray{S, T, N, L}(x::NTuple{L,Any}) where {S<:Tuple, T, N, L}
27-
check_array_parameters(S, T, Val{N}, Val{L})
28-
new{S, T, N, L}(convert_ntuple(T, x))
29-
end
30-
end
31-
32-
@inline SArray{S,T,N}(x::Tuple) where {S<:Tuple,T,N} = SArray{S,T,N,tuple_prod(S)}(x)
331

342
@noinline function generator_too_short_error(inds::CartesianIndices, i::CartesianIndex)
353
error("Generator produced too few elements: Expected exactly $(shape_string(inds)) elements, but generator stopped at $(shape_string(i))")

src/SMatrix.jl

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,3 @@
1-
"""
2-
SMatrix{S1, S2, T, L}(x::NTuple{L, T})
3-
SMatrix{S1, S2, T, L}(x1, x2, x3, ...)
4-
5-
Construct a statically-sized matrix `SMatrix`. Since this type is immutable,
6-
the data must be provided upon construction and cannot be mutated later. The
7-
`L` parameter is the `length` of the array and is always equal to `S1 * S2`.
8-
Constructors may drop the `L`, `T` and even `S2` parameters if they are inferrable
9-
from the input (e.g. `L` is always inferrable from `S1` and `S2`).
10-
11-
SMatrix{S1, S2}(mat::Matrix)
12-
13-
Construct a statically-sized matrix of dimensions `S1 × S2` using the data from
14-
`mat`. The parameters `S1` and `S2` are mandatory since the size of `mat` is
15-
unknown to the compiler (the element type may optionally also be specified).
16-
"""
17-
const SMatrix{S1, S2, T, L} = SArray{Tuple{S1, S2}, T, 2, L}
181

192
# Some more advanced constructor-like functions
203
@inline one(::Type{SMatrix{N}}) where {N} = one(SMatrix{N,N})

src/SVector.jl

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,3 @@
1-
"""
2-
SVector{S, T}(x::NTuple{S, T})
3-
SVector{S, T}(x1, x2, x3, ...)
4-
5-
Construct a statically-sized vector `SVector`. Since this type is immutable,
6-
the data must be provided upon construction and cannot be mutated later.
7-
Constructors may drop the `T` and `S` parameters if they are inferrable from the
8-
input (e.g. `SVector(1,2,3)` constructs an `SVector{3, Int}`).
9-
10-
SVector{S}(vec::Vector)
11-
12-
Construct a statically-sized vector of length `S` using the data from `vec`.
13-
The parameter `S` is mandatory since the length of `vec` is unknown to the
14-
compiler (the element type may optionally also be specified).
15-
"""
16-
const SVector{S, T} = SArray{Tuple{S}, T, 1, S}
171

182
# Some more advanced constructor-like functions
193
@inline zeros(::Type{SVector{N}}) where {N} = zeros(SVector{N,Float64})

src/SizedArray.jl

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,3 @@
1-
require_one_based_indexing(A...) = !Base.has_offset_axes(A...) ||
2-
throw(ArgumentError("offset arrays are not supported but got an array with index other than 1"))
3-
4-
"""
5-
SizedArray{Tuple{dims...}}(array)
6-
7-
Wraps an `AbstractArray` with a static size, so to take advantage of the (faster)
8-
methods defined by the static array package. The size is checked once upon
9-
construction to determine if the number of elements (`length`) match, but the
10-
array may be reshaped.
11-
12-
The aliases `SizedVector{N}` and `SizedMatrix{N,M}` are provided as more
13-
convenient names for one and two dimensional `SizedArray`s. For example, to
14-
wrap a 2x3 array `a` in a `SizedArray`, use `SizedMatrix{2,3}(a)`.
15-
"""
16-
struct SizedArray{S<:Tuple,T,N,M,TData<:AbstractArray{T,M}} <: StaticArray{S,T,N}
17-
data::TData
18-
19-
function SizedArray{S,T,N,M,TData}(a::TData) where {S<:Tuple,T,N,M,TData<:AbstractArray{T,M}}
20-
require_one_based_indexing(a)
21-
if size(a) != size_to_tuple(S) && size(a) != (tuple_prod(S),)
22-
throw(DimensionMismatch("Dimensions $(size(a)) don't match static size $S"))
23-
end
24-
return new{S,T,N,M,TData}(a)
25-
end
26-
27-
function SizedArray{S,T,N,1,TData}(::UndefInitializer) where {S<:Tuple,T,N,TData<:AbstractArray{T,1}}
28-
return new{S,T,N,1,TData}(TData(undef, tuple_prod(S)))
29-
end
30-
function SizedArray{S,T,N,N,TData}(::UndefInitializer) where {S<:Tuple,T,N,TData<:AbstractArray{T,N}}
31-
return new{S,T,N,N,TData}(TData(undef, size_to_tuple(S)...))
32-
end
33-
end
341

352
@inline function SizedArray{S,T,N,M}(a::AbstractArray) where {S<:Tuple,T,N,M}
363
if eltype(a) == T && (M == 1 || M == ndims(a))
@@ -130,10 +97,6 @@ Base.parent(sa::SizedArray) = sa.data
13097
Base.unsafe_convert(::Type{Ptr{T}}, sa::SizedArray) where {T} = Base.unsafe_convert(Ptr{T}, sa.data)
13198
Base.elsize(::Type{SizedArray{S,T,M,N,A}}) where {S,T,M,N,A} = Base.elsize(A)
13299

133-
const SizedVector{S,T} = SizedArray{Tuple{S},T,1,1}
134-
135-
const SizedMatrix{S1,S2,T} = SizedArray{Tuple{S1,S2},T,2}
136-
137100
Base.dataids(sa::SizedArray) = Base.dataids(sa.data)
138101

139102
function promote_rule(

src/StaticArrays.jl

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,28 @@ import LinearAlgebra: transpose, adjoint, dot, eigvals, eigen, lyap, tr,
2121
normalize!, Eigen, det, logdet, logabsdet, cross, diff, qr, \
2222
using LinearAlgebra: checksquare
2323

24-
export SOneTo
24+
# StaticArraysCore imports
25+
# there is intentionally no "using StaticArraysCore" to not take all symbols exported
26+
# from StaticArraysCore to make transitioning definitions to StaticArraysCore easier.
27+
using StaticArraysCore: StaticArraysCore, StaticArray, StaticScalar, StaticVector,
28+
StaticMatrix, StaticVecOrMat, tuple_length, tuple_prod,
29+
tuple_minimum, size_to_tuple, require_one_based_indexing
30+
import StaticArraysCore: SArray, SVector, SMatrix
31+
import StaticArraysCore: MArray, MVector, MMatrix
32+
import StaticArraysCore: SizedArray, SizedVector, SizedMatrix
33+
import StaticArraysCore: check_array_parameters, convert_ntuple
34+
35+
# end of StaticArraysCore imports
36+
# StaticArraysCore exports
2537
export StaticScalar, StaticArray, StaticVector, StaticMatrix
2638
export Scalar, SArray, SVector, SMatrix
2739
export MArray, MVector, MMatrix
28-
export FieldVector, FieldMatrix, FieldArray
2940
export SizedArray, SizedVector, SizedMatrix
41+
# end of StaticArraysCore exports
42+
43+
export SOneTo
44+
export Scalar
45+
export FieldVector, FieldMatrix, FieldArray
3046
export SDiagonal
3147
export SHermitianCompact
3248

@@ -41,41 +57,6 @@ export push, pop, pushfirst, popfirst, insert, deleteat, setindex
4157

4258
include("SOneTo.jl")
4359

44-
"""
45-
abstract type StaticArray{S, T, N} <: AbstractArray{T, N} end
46-
StaticScalar{T} = StaticArray{Tuple{}, T, 0}
47-
StaticVector{N,T} = StaticArray{Tuple{N}, T, 1}
48-
StaticMatrix{N,M,T} = StaticArray{Tuple{N,M}, T, 2}
49-
50-
`StaticArray`s are Julia arrays with fixed, known size.
51-
52-
## Dev docs
53-
54-
They must define the following methods:
55-
- Constructors that accept a flat tuple of data.
56-
- `getindex()` with an integer (linear indexing) (preferably `@inline` with `@boundscheck`).
57-
- `Tuple()`, returning the data in a flat Tuple.
58-
59-
It may be useful to implement:
60-
61-
- `similar_type(::Type{MyStaticArray}, ::Type{NewElType}, ::Size{NewSize})`, returning a
62-
type (or type constructor) that accepts a flat tuple of data.
63-
64-
For mutable containers you may also need to define the following:
65-
66-
- `setindex!` for a single element (linear indexing).
67-
- `similar(::Type{MyStaticArray}, ::Type{NewElType}, ::Size{NewSize})`.
68-
- In some cases, a zero-parameter constructor, `MyStaticArray{...}()` for unintialized data
69-
is assumed to exist.
70-
71-
(see also `SVector`, `SMatrix`, `SArray`, `MVector`, `MMatrix`, `MArray`, `SizedArray`, `FieldVector`, `FieldMatrix` and `FieldArray`)
72-
"""
73-
abstract type StaticArray{S <: Tuple, T, N} <: AbstractArray{T, N} end
74-
const StaticScalar{T} = StaticArray{Tuple{}, T, 0}
75-
const StaticVector{N, T} = StaticArray{Tuple{N}, T, 1}
76-
const StaticMatrix{N, M, T} = StaticArray{Tuple{N, M}, T, 2}
77-
const StaticVecOrMat{T} = Union{StaticVector{<:Any, T}, StaticMatrix{<:Any, <:Any, T}}
78-
7960
# Being a member of StaticMatrixLike, StaticVecOrMatLike, or StaticArrayLike implies that Size(A)
8061
# returns a static Size instance (none of the dimensions are Dynamic). The converse may not be true.
8162
# These are akin to aliases like StridedArray and in similarly bad taste, but the current approach

0 commit comments

Comments
 (0)