Skip to content

Commit 7f4097a

Browse files
authored
improve implementations of the tuple_ functions, removing @pure (#22)
Bumped patch version to 1.4.2. The new method definitions make `Base.@pure` annotations for these methods unnecessary. Inference tested with Julia v1.9.2, the latest release; both with and without `--check-bounds=yes`. The script for testing inference is appended. `:consistent` (`+c`), `:effect_free` (`+e`) and `:terminates_globally` (`+t`) are successfully inferred in each case: ```julia using Test, StaticArraysCore const test_types = ( Tuple{}, Tuple{1}, Tuple{2}, Tuple{1,1}, Tuple{2,3}, Tuple{1,2,3,4,5,6,7,8,9,1,2,3}, Tuple{9,2,7,4,5,9,7,8,9,4,2,3}, ) const test_functions = ( StaticArraysCore.tuple_length, StaticArraysCore.tuple_prod, StaticArraysCore.tuple_minimum, StaticArraysCore.size_to_tuple, StaticArraysCore.Size, ) function test_func(f::F) where {F} for T ∈ test_types # Test return type inference @inferred f(T) end for T ∈ test_types # Test effect inference print(" ") display(Base.infer_effects(f, (Type{T},))) end nothing end function test_func() for f ∈ test_functions println(f, ":") test_func(f) println() end nothing end test_func() ```
1 parent b040cc3 commit 7f4097a

File tree

2 files changed

+18
-11
lines changed

2 files changed

+18
-11
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "StaticArraysCore"
22
uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c"
3-
version = "1.4.1"
3+
version = "1.4.2"
44

55
[compat]
66
julia = "1.6"

src/StaticArraysCore.jl

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,28 @@ const StaticVecOrMat{T} = Union{StaticVector{<:Any, T}, StaticMatrix{<:Any, <:An
4444
# The ::Tuple variants exist to make sure that anything that calls with a tuple
4545
# instead of a Tuple gets through to the constructor, so the user gets a nice
4646
# error message
47-
Base.@pure tuple_length(T::Type{<:Tuple}) = length(T.parameters)
48-
Base.@pure tuple_length(T::Tuple) = length(T)
49-
Base.@pure tuple_prod(T::Type{<:Tuple}) = length(T.parameters) == 0 ? 1 : *(T.parameters...)
50-
Base.@pure tuple_prod(T::Tuple) = prod(T)
51-
Base.@pure tuple_minimum(T::Type{<:Tuple}) = length(T.parameters) == 0 ? 0 : minimum(tuple(T.parameters...))
52-
Base.@pure tuple_minimum(T::Tuple) = minimum(T)
47+
tuple_length(T::Tuple) = length(T)
48+
tuple_prod(T::Tuple) = prod(T)
49+
tuple_minimum(T::Tuple) = minimum(T)
50+
51+
tuple_svec(::Type{T}) where {T<:Tuple} = T.parameters
52+
53+
# Julia `Base` provides a function for this purpose since v1.1: `fieldtypes`.
54+
# We don't use it yet, though, because it wrecks type inference with Julia
55+
# v1.6.
56+
Base.@pure tuple_tuple(::Type{T}) where {T<:Tuple} = (tuple_svec(T)...,)
57+
58+
tuple_length(::Type{<:NTuple{n, Any}}) where {n} = n
59+
tuple_prod(::Type{T}) where {T<:Tuple} = mapreduce(Int, *, tuple_tuple(T), init = 1)
60+
tuple_minimum(::Type{Tuple{}}) = 0
61+
tuple_minimum(::Type{T}) where {T<:Tuple{Any,Vararg}} = mapreduce(Int, min, tuple_tuple(T), init = typemax(Int))
5362

5463
"""
5564
size_to_tuple(::Type{S}) where S<:Tuple
5665
5766
Converts a size given by `Tuple{N, M, ...}` into a tuple `(N, M, ...)`.
5867
"""
59-
Base.@pure function size_to_tuple(::Type{S}) where S<:Tuple
60-
return tuple(S.parameters...)
61-
end
68+
size_to_tuple(::Type{T}) where {T<:Tuple} = tuple_tuple(T)
6269

6370
# Something doesn't match up type wise
6471
@generated function check_array_parameters(::Type{Size}, ::Type{T}, ::Type{Val{N}}, ::Type{Val{L}}) where {Size,T,N,L}
@@ -467,7 +474,7 @@ end
467474

468475
Base.@pure Size(s::Tuple{Vararg{StaticDimension}}) = Size{s}()
469476
Base.@pure Size(s::StaticDimension...) = Size{s}()
470-
Base.@pure Size(s::Type{<:Tuple}) = Size{tuple(s.parameters...)}()
477+
Size(::Type{T}) where {T<:Tuple} = Size{tuple_tuple(T)}()
471478

472479
Base.show(io::IO, ::Size{S}) where {S} = print(io, "Size", S)
473480

0 commit comments

Comments
 (0)