Skip to content

Commit

Permalink
IteratorSize for infinite AbstractFill (#205)
Browse files Browse the repository at this point in the history
* Forward IteratorSize to ProductIterator

* Add tests

* simplified implementation

* Add inference tests

* Any for Tuples

* Test on v1.9.0-beta3

* version bump to v0.13.7
  • Loading branch information
jishnub authored Jan 25, 2023
1 parent 617be46 commit 0075660
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 2 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ jobs:
version:
- '1.6'
- '1'
- '~1.9.0-0'
os:
- ubuntu-latest
- macOS-latest
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
18 changes: 18 additions & 0 deletions src/FillArrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,24 @@ 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)))

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 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
_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}()
end


"""
Fill{T, N, Axes} where {T,N,Axes<:Tuple{Vararg{AbstractUnitRange,N}}}
Expand Down
2 changes: 2 additions & 0 deletions test/infinitearrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 11 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -638,10 +638,20 @@ 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)
@testset "IteratorSize" begin
@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

Expand Down

2 comments on commit 0075660

@dlfivefifty
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/76329

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.13.7 -m "<description of version>" 0075660f6833d633e5ac92e73f09fcc774566db2
git push origin v0.13.7

Please sign in to comment.