From 2945d61f4fd10071e3b33a44b92d4761466a8ad6 Mon Sep 17 00:00:00 2001 From: Mark Kittisopikul Date: Sun, 25 Dec 2022 06:52:18 -0500 Subject: [PATCH] Add virtual properties for values and indices --- src/axes.jl | 32 ++++++++++++++++++++++++++++++++ test/runtests.jl | 15 +++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/axes.jl b/src/axes.jl index 519f0dac..a230e918 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -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 @@ -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) diff --git a/test/runtests.jl b/test/runtests.jl index 7cd56bfb..7e10077e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -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 @@ -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