Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add virtual properties for values and indices #318

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions src/axes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,27 @@ julia> ro[3]
ERROR: BoundsError: attempt to access 3-element $(IdOffsetRange{Int, UnitRange{Int}}) with indices -1:1 at index [3]
```

The `values` and `indices` keywords can be extracted as properties or via the `values` and `eachindex` methods.
```jldoctest ior
julia> values(ro)
IdOffsetRange(values=9:11, indices=-1:1)

julia> ro.values
IdOffsetRange(values=9:11, indices=-1:1)

julia> UnitRange(ro.values)
9:11

julia> eachindex(ro)
IdOffsetRange(values=-1:1, indices=-1:1)

julia> ro.indices
IdOffsetRange(values=-1:1, indices=-1:1)

julia> ro.indices |> UnitRange
-1:1
```

# Extended help

Construction/coercion preserves the (shifted) values of the input range, but may modify
Expand Down Expand Up @@ -277,6 +298,17 @@ Broadcast.broadcasted(::Base.Broadcast.DefaultArrayStyle{1}, ::typeof(big), r::I

Base.show(io::IO, r::IdOffsetRange) = print(io, IdOffsetRange, "(values=",first(r), ':', last(r),", indices=",first(eachindex(r)),':',last(eachindex(r)), ")")


# Based on the constructor display above, allow for the keywords to be extracted as
# properties. The properties will be `IdOffsetRange` rather than `UnitRange`
@inline Base.getproperty(r::IdOffsetRange, s::Symbol) =
s == :values ? values(r) :
s == :indices ? eachindex(r) :
getfield(r, s)

@inline Base.propertynames(r::IdOffsetRange) =
(fieldnames(typeof(r))..., :values, :indices)

# Optimizations
@inline Base.checkindex(::Type{Bool}, inds::IdOffsetRange, i::Real) = Base.checkindex(Bool, inds.parent, i - inds.offset)

Expand Down
15 changes: 15 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ end
for i in eachindex(s)
@test r[s[i]] == r[s][i]
end
@test eachindex(s) === s.indices

# Indexing with UnitRange
s = 0:2
Expand Down Expand Up @@ -401,6 +402,20 @@ end
ind, st = iterate(ax, st)
@test C[ind] == C[5]
end

@testset "virtual properties" begin
_values = 5:8
_indices = 6:9
id = IdOffsetRange(values=_values, indices=_indices)
@test id.values === values(id)
@test id.values == _values
@test id.indices === eachindex(id)
@test id.indices == _indices
id2 = IdOffsetRange(; id.values, id.indices)
@test id == id2
id3 = IdOffsetRange(; id.indices, id.values)
@test id == id3
end
end

# used in testing the constructor
Expand Down