From 13b15cd95a59581de6de353a67e25c1cd63fa338 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Mon, 23 Jan 2023 14:19:33 +0400 Subject: [PATCH 1/7] Forward IteratorSize to ProductIterator --- src/FillArrays.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/FillArrays.jl b/src/FillArrays.jl index 156b928b..28289300 100644 --- a/src/FillArrays.jl +++ b/src/FillArrays.jl @@ -61,6 +61,12 @@ IndexStyle(::Type{<:AbstractFill{<:Any,N,<:NTuple{N,Base.OneTo{Int}}}}) where N issymmetric(F::AbstractFill{<:Any, 2}) = axes(F,1) == axes(F,2) ishermitian(F::AbstractFill{<:Any, 2}) = issymmetric(F) && iszero(imag(getindex_value(F))) +axestype(::Type{<:AbstractFill{<:Any,<:Any,Axes}}) where {Axes} = Axes + +Base.IteratorSize(::Type{A}) where {A<:AbstractFill} = + Base.IteratorSize(Iterators.ProductIterator{axestype(A)}) + + """ Fill{T, N, Axes} where {T,N,Axes<:Tuple{Vararg{AbstractUnitRange,N}}} From af6981cfa83d69f8321c2fef504cd1c19f379faa Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Mon, 23 Jan 2023 14:27:18 +0400 Subject: [PATCH 2/7] Add tests --- test/infinitearrays.jl | 2 ++ test/runtests.jl | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/test/infinitearrays.jl b/test/infinitearrays.jl index 9145c956..0b6f62db 100644 --- a/test/infinitearrays.jl +++ b/test/infinitearrays.jl @@ -35,6 +35,8 @@ module InfiniteArrays Base.last(r::AbstractInfUnitRange) = Infinity() Base.axes(r::AbstractInfUnitRange) = (OneToInf(),) + Base.IteratorSize(::Type{<:AbstractInfUnitRange}) = Base.IsInfinite() + """ OneToInf(n) Define an `AbstractInfUnitRange` that behaves like `1:∞`, with the added diff --git a/test/runtests.jl b/test/runtests.jl index 77923378..ac2d37d6 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -638,10 +638,13 @@ end @test_throws UndefKeywordError cumsum(Fill(1,1,5)) @testset "infinite arrays" begin - A = Ones{Int}((InfiniteArrays.OneToInf(),)) + r = InfiniteArrays.OneToInf() + A = Ones{Int}((r,)) @test isinf(sum(A)) @test sum(A) == length(A) @test sum(x->x^2, A) == sum(A.^2) + @test Base.IteratorSize(A) == Base.IsInfinite() + @test Base.IteratorSize(Fill(2, (1:2, r))) == Base.IsInfinite() end end From d89d3ccaded3fc5b83a7e27c197720009e19f820 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Mon, 23 Jan 2023 15:35:34 +0400 Subject: [PATCH 3/7] simplified implementation --- src/FillArrays.jl | 12 ++++++++---- test/runtests.jl | 11 +++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/FillArrays.jl b/src/FillArrays.jl index 28289300..9c4e11a9 100644 --- a/src/FillArrays.jl +++ b/src/FillArrays.jl @@ -61,10 +61,14 @@ IndexStyle(::Type{<:AbstractFill{<:Any,N,<:NTuple{N,Base.OneTo{Int}}}}) where N issymmetric(F::AbstractFill{<:Any, 2}) = axes(F,1) == axes(F,2) ishermitian(F::AbstractFill{<:Any, 2}) = issymmetric(F) && iszero(imag(getindex_value(F))) -axestype(::Type{<:AbstractFill{<:Any,<:Any,Axes}}) where {Axes} = Axes - -Base.IteratorSize(::Type{A}) where {A<:AbstractFill} = - Base.IteratorSize(Iterators.ProductIterator{axestype(A)}) +Base.IteratorSize(::Type{<:AbstractFill{T,N,Axes}}) where {T,N,Axes} = _IteratorSize(Axes) +_IteratorSize(::Type{Tuple{}}) = Base.HasShape{0}() +_IteratorSize(::Type{Tuple{T}}) where {T} = Base.IteratorSize(T) +function _IteratorSize(::Type{T}) where {T<:Tuple} + N = fieldcount(T) + s = ntuple(i-> Base.IteratorSize(fieldtype(T, i)), N) + any(x -> x isa Base.IsInfinite, s) ? Base.IsInfinite() : Base.HasShape{N}() +end """ diff --git a/test/runtests.jl b/test/runtests.jl index ac2d37d6..564716bf 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -643,8 +643,15 @@ end @test isinf(sum(A)) @test sum(A) == length(A) @test sum(x->x^2, A) == sum(A.^2) - @test Base.IteratorSize(A) == Base.IsInfinite() - @test Base.IteratorSize(Fill(2, (1:2, r))) == Base.IsInfinite() + @testset "IteratorSize" begin + @test Base.IteratorSize(Ones()) == Base.IteratorSize(ones()) + @test Base.IteratorSize(Ones(2)) == Base.IteratorSize(ones(2)) + @test Base.IteratorSize(Ones(r)) == Base.IsInfinite() + @test Base.IteratorSize(Fill(2, (1:2, 1:2))) == Base.HasShape{2}() + @test Base.IteratorSize(Fill(2, (1:2, r))) == Base.IsInfinite() + @test Base.IteratorSize(Fill(2, (r, 1:2))) == Base.IsInfinite() + @test Base.IteratorSize(Fill(2, (r, r))) == Base.IsInfinite() + end end end From 30464cf6ecdf80de572179f57d6bb9aec27019da Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Mon, 23 Jan 2023 15:39:44 +0400 Subject: [PATCH 4/7] Add inference tests --- test/runtests.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 564716bf..46272a80 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -644,13 +644,13 @@ end @test sum(A) == length(A) @test sum(x->x^2, A) == sum(A.^2) @testset "IteratorSize" begin - @test Base.IteratorSize(Ones()) == Base.IteratorSize(ones()) - @test Base.IteratorSize(Ones(2)) == Base.IteratorSize(ones(2)) - @test Base.IteratorSize(Ones(r)) == Base.IsInfinite() - @test Base.IteratorSize(Fill(2, (1:2, 1:2))) == Base.HasShape{2}() - @test Base.IteratorSize(Fill(2, (1:2, r))) == Base.IsInfinite() - @test Base.IteratorSize(Fill(2, (r, 1:2))) == Base.IsInfinite() - @test Base.IteratorSize(Fill(2, (r, r))) == Base.IsInfinite() + @test (@inferred Base.IteratorSize(Ones())) == Base.IteratorSize(ones()) + @test (@inferred Base.IteratorSize(Ones(2))) == Base.IteratorSize(ones(2)) + @test (@inferred Base.IteratorSize(Ones(r))) == Base.IsInfinite() + @test (@inferred Base.IteratorSize(Fill(2, (1:2, 1:2)))) == Base.HasShape{2}() + @test (@inferred Base.IteratorSize(Fill(2, (1:2, r)))) == Base.IsInfinite() + @test (@inferred Base.IteratorSize(Fill(2, (r, 1:2)))) == Base.IsInfinite() + @test (@inferred Base.IteratorSize(Fill(2, (r, r)))) == Base.IsInfinite() end end end From 2932389ff60b3fdfdb1321064d2216fa87878bc5 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Mon, 23 Jan 2023 17:04:10 +0400 Subject: [PATCH 5/7] Any for Tuples --- src/FillArrays.jl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/FillArrays.jl b/src/FillArrays.jl index 9c4e11a9..d9153d5d 100644 --- a/src/FillArrays.jl +++ b/src/FillArrays.jl @@ -64,10 +64,18 @@ ishermitian(F::AbstractFill{<:Any, 2}) = issymmetric(F) && iszero(imag(getindex_ Base.IteratorSize(::Type{<:AbstractFill{T,N,Axes}}) where {T,N,Axes} = _IteratorSize(Axes) _IteratorSize(::Type{Tuple{}}) = Base.HasShape{0}() _IteratorSize(::Type{Tuple{T}}) where {T} = Base.IteratorSize(T) +# Julia Base has an optimized any for Tuples for versions >= v1.9 +# For lower versions, a recursive implementation might be easier for type-inference +if VERSION >= v"1.9.0-beta3" + _any(f, t::Tuple) = any(f, t) +else + _any(f, ::Tuple{}) = false + _any(f, t::Tuple) = f(t[1]) || _any(f, Base.tail(t)) +end function _IteratorSize(::Type{T}) where {T<:Tuple} N = fieldcount(T) s = ntuple(i-> Base.IteratorSize(fieldtype(T, i)), N) - any(x -> x isa Base.IsInfinite, s) ? Base.IsInfinite() : Base.HasShape{N}() + _any(x -> x isa Base.IsInfinite, s) ? Base.IsInfinite() : Base.HasShape{N}() end From e26b6d0642ef0f684df8a34cea24540d27cc3a99 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Mon, 23 Jan 2023 17:13:37 +0400 Subject: [PATCH 6/7] Test on v1.9.0-beta3 --- .github/workflows/ci.yml | 1 + src/FillArrays.jl | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6367419b..af5b2447 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,7 @@ jobs: version: - '1.6' - '1' + - '~1.9.0-0' os: - ubuntu-latest - macOS-latest diff --git a/src/FillArrays.jl b/src/FillArrays.jl index d9153d5d..2e223101 100644 --- a/src/FillArrays.jl +++ b/src/FillArrays.jl @@ -64,8 +64,8 @@ ishermitian(F::AbstractFill{<:Any, 2}) = issymmetric(F) && iszero(imag(getindex_ Base.IteratorSize(::Type{<:AbstractFill{T,N,Axes}}) where {T,N,Axes} = _IteratorSize(Axes) _IteratorSize(::Type{Tuple{}}) = Base.HasShape{0}() _IteratorSize(::Type{Tuple{T}}) where {T} = Base.IteratorSize(T) -# Julia Base has an optimized any for Tuples for versions >= v1.9 -# For lower versions, a recursive implementation might be easier for type-inference +# Julia Base has an optimized any for Tuples on versions >= v1.9 +# On lower versions, a recursive implementation helps with type-inference if VERSION >= v"1.9.0-beta3" _any(f, t::Tuple) = any(f, t) else From dff7722bc0c928cbbc994f3a2cb1d26ed7de5044 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Wed, 25 Jan 2023 09:54:17 +0400 Subject: [PATCH 7/7] version bump to v0.13.7 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 245580c7..0399075e 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "FillArrays" uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "0.13.6" +version = "0.13.7" [deps] LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"