@@ -78,31 +78,38 @@ struct IdOffsetRange{T<:Integer,I<:AbstractUnitRange{T}} <: AbstractUnitRange{T}
78
78
offset:: T
79
79
80
80
IdOffsetRange {T,I} (r:: I , offset:: T ) where {T<: Integer ,I<: AbstractUnitRange{T} } = new {T,I} (r, offset)
81
+
82
+ #= This method is necessary to avoid a StackOverflowError in IdOffsetRange{T,I}(r::IdOffsetRange, offset::Integer).
83
+ The type signature in that method is more specific than IdOffsetRange{T,I}(r::I, offset::T),
84
+ so it ends up calling itself if I <: IdOffsetRange.
85
+ =#
86
+ function IdOffsetRange {T,IdOffsetRange{T,I}} (r:: IdOffsetRange{T,I} , offset:: T ) where {T<: Integer ,I<: AbstractUnitRange{T} }
87
+ new {T,IdOffsetRange{T,I}} (r, offset)
88
+ end
81
89
end
82
90
83
91
# Construction/coercion from arbitrary AbstractUnitRanges
84
92
function IdOffsetRange {T,I} (r:: AbstractUnitRange , offset:: Integer = 0 ) where {T<: Integer ,I<: AbstractUnitRange{T} }
85
93
rc, o = offset_coerce (I, r)
86
- return IdOffsetRange {T,I} (rc, convert (T, o+ offset))
94
+ return IdOffsetRange {T,I} (rc, convert (T, o+ offset):: T )
87
95
end
88
96
function IdOffsetRange {T} (r:: AbstractUnitRange , offset:: Integer = 0 ) where T<: Integer
89
- rc = convert (AbstractUnitRange{T}, r)
90
- return IdOffsetRange {T,typeof(rc)} (rc, convert (T, offset))
97
+ rc = convert (AbstractUnitRange{T}, r):: AbstractUnitRange{T}
98
+ return IdOffsetRange {T,typeof(rc)} (rc, convert (T, offset):: T )
91
99
end
92
100
IdOffsetRange (r:: AbstractUnitRange{T} , offset:: Integer = 0 ) where T<: Integer =
93
- IdOffsetRange {T,typeof(r)} (r, convert (T, offset))
101
+ IdOffsetRange {T,typeof(r)} (r, convert (T, offset):: T )
94
102
95
103
# Coercion from other IdOffsetRanges
96
104
IdOffsetRange {T,I} (r:: IdOffsetRange{T,I} ) where {T<: Integer ,I<: AbstractUnitRange{T} } = r
97
105
function IdOffsetRange {T,I} (r:: IdOffsetRange , offset:: Integer = 0 ) where {T<: Integer ,I<: AbstractUnitRange{T} }
98
106
rc, offset_rc = offset_coerce (I, r. parent)
99
- return IdOffsetRange {T,I} (rc, r. offset + offset + offset_rc)
107
+ return IdOffsetRange {T,I} (rc, convert (T, r. offset + offset + offset_rc) :: T )
100
108
end
101
109
function IdOffsetRange {T} (r:: IdOffsetRange , offset:: Integer = 0 ) where T<: Integer
102
110
return IdOffsetRange {T} (r. parent, r. offset + offset)
103
111
end
104
112
IdOffsetRange (r:: IdOffsetRange ) = r
105
- IdOffsetRange (r:: IdOffsetRange , offset:: Integer ) = typeof (r)(r. parent, offset + r. offset)
106
113
107
114
# TODO : uncomment these when Julia is ready
108
115
# # Conversion preserves both the values and the indexes, throwing an InexactError if this
@@ -123,12 +130,12 @@ end
123
130
124
131
# Fallback, specialze this method if `convert(I, r)` doesn't do what you need
125
132
offset_coerce (:: Type{I} , r:: AbstractUnitRange ) where I<: AbstractUnitRange =
126
- convert (I, r), 0
133
+ convert (I, r):: I , 0
127
134
128
135
@inline Base. parent (r:: IdOffsetRange ) = r. parent
129
136
@inline Base. axes (r:: IdOffsetRange ) = (Base. axes1 (r),)
130
137
@inline Base. axes1 (r:: IdOffsetRange ) = IdOffsetRange (Base. axes1 (r. parent), r. offset)
131
- @inline Base. unsafe_indices (r:: IdOffsetRange ) = (r ,)
138
+ @inline Base. unsafe_indices (r:: IdOffsetRange ) = (Base . axes1 (r) ,)
132
139
@inline Base. length (r:: IdOffsetRange ) = length (r. parent)
133
140
Base. reduced_index (i:: IdOffsetRange ) = typeof (i)(first (i): first (i))
134
141
# Workaround for #92 on Julia < 1.4
@@ -176,7 +183,7 @@ if VERSION < v"1.5.2"
176
183
# issue 100, 133: IdOffsetRange as another index-preserving case shouldn't comtribute offsets
177
184
# fixed by https://github.com/JuliaLang/julia/pull/37204
178
185
@inline Base. compute_offset1 (parent, stride1:: Integer , dims:: Tuple{Int} , inds:: Tuple{IdOffsetRange} , I:: Tuple ) =
179
- Base. compute_linindex (parent, I) - stride1* first (inds[1 ])
186
+ Base. compute_linindex (parent, I) - stride1* first (Base . axes1 ( inds[1 ]) )
180
187
end
181
188
182
189
# This was deemed "too private" to extend: see issue #184
0 commit comments