@@ -24,6 +24,56 @@ struct TupleOfRanges{N}
24
24
x :: NTuple{N, UnitRange{Int}}
25
25
end
26
26
27
+ # Useful for testing indexing
28
+ struct ZeroBasedRange{T,A<: AbstractRange{T} } <: AbstractRange{T}
29
+ a :: A
30
+ function ZeroBasedRange (a:: AbstractRange{T} ) where {T}
31
+ @assert ! Base. has_offset_axes (a)
32
+ new {T, typeof(a)} (a)
33
+ end
34
+ end
35
+
36
+ struct ZeroBasedUnitRange{T,A<: AbstractUnitRange{T} } <: AbstractUnitRange{T}
37
+ a :: A
38
+ function ZeroBasedUnitRange (a:: AbstractUnitRange{T} ) where {T}
39
+ @assert ! Base. has_offset_axes (a)
40
+ new {T, typeof(a)} (a)
41
+ end
42
+ end
43
+
44
+ for Z in [:ZeroBasedRange , :ZeroBasedUnitRange ]
45
+ @eval Base. parent (A:: $Z ) = A. a
46
+ @eval Base. first (A:: $Z ) = first (A. a)
47
+ @eval Base. length (A:: $Z ) = length (A. a)
48
+ @eval Base. last (A:: $Z ) = last (A. a)
49
+ @eval Base. size (A:: $Z ) = size (A. a)
50
+ @eval Base. axes (A:: $Z ) = map (x -> 0 : x- 1 , size (A. a))
51
+ @eval Base. getindex (A:: $Z , i:: Int ) = A. a[i + 1 ]
52
+ @eval Base. step (A:: $Z ) = step (A. a)
53
+ @eval OffsetArrays. no_offset_view (A:: $Z ) = A. a
54
+ @eval function Base. show (io:: IO , A:: $Z )
55
+ show (io, A. a)
56
+ print (io, " with indices $(axes (A,1 )) " )
57
+ end
58
+
59
+ for R in [:AbstractRange , :AbstractUnitRange , :StepRange ]
60
+ @eval @inline function Base. getindex (A:: $Z , r:: $R{<:Integer} )
61
+ @boundscheck checkbounds (A, r)
62
+ OffsetArray (A. a[r .+ 1 ], axes (r))
63
+ end
64
+ end
65
+ for R in [:UnitRange , :StepRange , :StepRangeLen , :LinRange ]
66
+ @eval @inline function Base. getindex (A:: $R , r:: $Z )
67
+ @boundscheck checkbounds (A, r)
68
+ OffsetArray (A[r. a], axes (r))
69
+ end
70
+ end
71
+ @eval @inline function Base. getindex (A:: StepRangeLen{<:Any,<:Base.TwicePrecision,<:Base.TwicePrecision} , r:: $Z )
72
+ @boundscheck checkbounds (A, r)
73
+ OffsetArray (A[r. a], axes (r))
74
+ end
75
+ end
76
+
27
77
function same_value (r1, r2)
28
78
length (r1) == length (r2) || return false
29
79
for (v1, v2) in zip (r1, r2)
722
772
end
723
773
end
724
774
775
+ _comp (:: Type{<:Integer} ) = ==
776
+ _comp (:: Type{<:Real} ) = ≈
777
+ function test_indexing_axes_and_vals (r1, r2)
778
+ r12 = r1[r2]
779
+ op = _comp (eltype (r1))
780
+ if axes (r12, 1 ) != axes (r2, 1 )
781
+ @show r1 r2 r12 axes (r12, 1 ) axes (r2, 1 )
782
+ end
783
+ @test axes (r12, 1 ) == axes (r2, 1 )
784
+ if axes (r12, 1 ) == axes (r2, 1 )
785
+ @test op (first (r12), r1[first (r2)])
786
+ @test op (last (r12), r1[last (r2)])
787
+ for i in eachindex (r2)
788
+ @test op (r12[i], r1[r2[i]])
789
+ end
790
+ end
791
+ end
792
+
725
793
@testset " Vector indexing" begin
726
794
A0 = [1 3 ; 2 4 ]
727
795
A = OffsetArray (A0, (- 1 ,2 ))
740
808
@test A[0 , 3 : 4 ] == S[0 , 3 : 4 ] == [1 ,3 ]
741
809
@test A[1 , [4 ,3 ]] == S[1 , [4 ,3 ]] == [4 ,2 ]
742
810
@test A[:, :] == S[:, :] == A
811
+
812
+ r1 = OffsetArray (IdentityUnitRange (100 : 1000 ), 3 )
813
+ r2 = r1[:]
814
+ @test r2 == r1
815
+
816
+ for r1 in [
817
+ # AbstractArrays
818
+ OffsetArray (10 : 1000 , 0 ), # 1-based index
819
+ OffsetArray (10 : 3 : 1000 , 3 ), # offset index
820
+ OffsetArray (10.0 : 3 : 1000.0 , 0 ), # 1-based index
821
+ OffsetArray (10.0 : 3 : 1000.0 , 3 ), # offset index
822
+ OffsetArray (IdOffsetRange (10 : 1000 , 1 ), - 1 ), # 1-based index
823
+ OffsetArray (IdOffsetRange (10 : 1000 , 1 ), 3 ), # offset index
824
+ OffsetArray (IdOffsetRange (IdOffsetRange (10 : 1000 , - 4 ), 1 ), 3 ), # 1-based index
825
+ OffsetArray (IdOffsetRange (IdOffsetRange (10 : 1000 , - 1 ), 1 ), 3 ), # offset index
826
+
827
+ # AbstractRanges
828
+ 1 : 1000 ,
829
+ 1 : 3 : 1000 ,
830
+ 1.0 : 3.0 : 1000.0 ,
831
+ IdOffsetRange (ZeroBasedUnitRange (1 : 1000 ), 1 ), # 1-based index
832
+ IdOffsetRange (ZeroBasedUnitRange (1 : 1000 ), 2 ), # offset index
833
+ ZeroBasedUnitRange (1 : 1000 ), # offset range
834
+ ZeroBasedRange (1 : 1000 ), # offset range
835
+ ZeroBasedRange (1 : 1 : 1000 ), # offset range
836
+ ]
837
+
838
+ # AbstractArrays with 1-based indices
839
+ for r2 in [
840
+ OffsetArray (5 : 80 , 0 ),
841
+ OffsetArray (5 : 2 : 80 , 0 ),
842
+ OffsetArray (IdentityUnitRange (5 : 80 ), - 4 ),
843
+ OffsetArray (IdOffsetRange (5 : 80 ), 0 ),
844
+ ]
845
+
846
+ test_indexing_axes_and_vals (r1, r2)
847
+ end
848
+
849
+ # AbstractRanges with 1-based indices
850
+ for r2 in [
851
+ 5 : 80 ,
852
+ 5 : 2 : 80 ,
853
+ IdOffsetRange (5 : 80 ),
854
+ IdOffsetRange (ZeroBasedUnitRange (4 : 79 ), 1 ),
855
+ ]
856
+
857
+ test_indexing_axes_and_vals (r1, r2)
858
+ end
859
+ end
743
860
end
744
861
745
862
@testset " Vector indexing with offset ranges" begin
765
882
for i in axes (ax,1 )
766
883
@test a[ax[i]] == a[ax][i]
767
884
end
885
+
886
+ for r1 in [
887
+ # AbstractArrays
888
+ OffsetArray (10 : 1000 , 0 ), # 1-based index
889
+ OffsetArray (10 : 1000 , 3 ), # offset index
890
+ OffsetArray (10 : 3 : 1000 , 0 ), # 1-based index
891
+ OffsetArray (10 : 3 : 1000 , 3 ), # offset index
892
+ OffsetArray (10.0 : 3 : 1000.0 , 0 ), # 1-based index
893
+ OffsetArray (10.0 : 3 : 1000.0 , 3 ), # offset index
894
+ OffsetArray (IdOffsetRange (10 : 1000 , - 3 ), 3 ), # 1-based index
895
+ OffsetArray (IdOffsetRange (10 : 1000 , 1 ), 3 ), # offset index
896
+ OffsetArray (IdOffsetRange (IdOffsetRange (10 : 1000 , - 4 ), 1 ), 3 ), # 1-based index
897
+ OffsetArray (IdOffsetRange (IdOffsetRange (10 : 1000 , - 1 ), 1 ), 3 ), # offset index
898
+
899
+ # AbstractRanges
900
+ 1 : 1000 ,
901
+ 1 : 2 : 2000 ,
902
+ 1.0 : 2.0 : 2000.0 ,
903
+ LinRange (1.0 , 2000.0 , 2000 ),
904
+ IdOffsetRange (1 : 1000 , 0 ), # 1-based index
905
+ IdOffsetRange (ZeroBasedUnitRange (1 : 1000 ), 1 ), # 1-based index
906
+ IdOffsetRange (ZeroBasedUnitRange (1 : 1000 ), 2 ), # offset index
907
+ IdentityUnitRange (ZeroBasedUnitRange (1 : 1000 )), # 1-based index
908
+ ZeroBasedUnitRange (1 : 1000 ), # offset index
909
+ ZeroBasedRange (1 : 1000 ), # offset index
910
+ ZeroBasedRange (1 : 1 : 1000 ), # offset index
911
+ ZeroBasedUnitRange (IdentityUnitRange (1 : 1000 )), # offset index
912
+ ]
913
+
914
+ # AbstractArrays with offset axes
915
+ for r2 in [OffsetArray (5 : 80 , 40 ), OffsetArray (5 : 2 : 80 , 40 ),
916
+ OffsetArray (IdentityUnitRange (5 : 80 ), 2 ),
917
+ OffsetArray (IdOffsetRange (5 : 80 , 1 ), 3 ),
918
+ OffsetArray (IdOffsetRange (IdOffsetRange (5 : 80 , 4 ), 1 ), 3 ),
919
+ OffsetArray (IdOffsetRange (IdentityUnitRange (5 : 80 ), 1 ), 3 ),
920
+ OffsetArray (IdentityUnitRange (IdOffsetRange (5 : 80 , 1 )), 3 ),
921
+ ]
922
+
923
+ test_indexing_axes_and_vals (r1, r2)
924
+ end
925
+
926
+ # AbstractRanges with offset axes
927
+ for r2 in [IdOffsetRange (5 : 80 , 1 ),
928
+ IdentityUnitRange (5 : 80 ),
929
+ IdOffsetRange (IdOffsetRange (5 : 80 , 2 ), 1 ),
930
+ IdOffsetRange (IdOffsetRange (IdOffsetRange (5 : 80 , - 1 ), 2 ), 1 ),
931
+ IdentityUnitRange (IdOffsetRange (1 : 10 , 5 )),
932
+ IdOffsetRange (IdentityUnitRange (15 : 20 ), - 2 ),
933
+ ZeroBasedUnitRange (5 : 80 ),
934
+ ZeroBasedRange (5 : 80 ),
935
+ ZeroBasedRange (5 : 2 : 80 ),
936
+ ]
937
+
938
+ test_indexing_axes_and_vals (r1, r2)
939
+ end
940
+ end
768
941
end
769
942
770
943
@testset " CartesianIndexing" begin
0 commit comments