@@ -12,26 +12,9 @@ struct OptionallyStaticUnitRange{F <: IntType, L <: IntType} <:
1212 start:: F
1313 stop:: L
1414
15- function OptionallyStaticUnitRange (start:: IntType ,
16- stop:: IntType )
15+ global function _OptionallyStaticUnitRange (start:: IntType , stop:: IntType )
1716 new {typeof(start), typeof(stop)} (start, stop)
1817 end
19- function OptionallyStaticUnitRange (start, stop)
20- OptionallyStaticUnitRange (IntType (start), IntType (stop))
21- end
22- OptionallyStaticUnitRange (@nospecialize x:: OptionallyStaticUnitRange ) = x
23- function OptionallyStaticUnitRange (x:: AbstractRange )
24- step (x) == 1 && return OptionallyStaticUnitRange (static_first (x), static_last (x))
25-
26- errmsg (x) = throw (ArgumentError (" step must be 1, got $(step (x)) " )) # avoid GC frame
27- errmsg (x)
28- end
29- function OptionallyStaticUnitRange {F, L} (x:: AbstractRange ) where {F, L}
30- OptionallyStaticUnitRange (x)
31- end
32- function OptionallyStaticUnitRange {StaticInt{F}, StaticInt{L}} () where {F, L}
33- new {StaticInt{F}, StaticInt{L}} ()
34- end
3518end
3619
3720"""
@@ -97,9 +80,20 @@ function OptionallyStaticStepRange(@nospecialize(start::IntType),
9780 end
9881end
9982OptionallyStaticStepRange (@nospecialize x:: OptionallyStaticStepRange ) = x
83+ function OptionallyStaticStepRange (x:: Union{Base.Slice, Base.IdentityUnitRange} )
84+ OptionallyStaticStepRange (x. indices)
85+ end
86+ function OptionallyStaticStepRange (x:: Base.OneTo )
87+ _OptionallyStaticStepRange (static (1 ), static (1 ), Int (last (x)))
88+ end
89+ function OptionallyStaticStepRange (x:: OptionallyStaticUnitRange )
90+ _OptionallyStaticStepRange (getfield (x, :start ), static (1 ), getfield (x, :stop ))
91+ end
92+ function OptionallyStaticStepRange (x:: AbstractUnitRange )
93+ _OptionallyStaticStepRange (Int (first (x)), static (1 ), Int (last (x)))
94+ end
10095function OptionallyStaticStepRange (x:: AbstractRange )
101- _OptionallyStaticStepRange (IntType (static_first (x)), IntType (static_step (x)),
102- IntType (static_last (x)))
96+ _OptionallyStaticStepRange (Int (first (x)), Int (step (x)), Int (last (x)))
10397end
10498
10599# to make StepRange constructor inlineable, so optimizer can see `step` value
129123 end
130124end
131125
126+ OptionallyStaticUnitRange (@nospecialize x:: OptionallyStaticUnitRange ) = x
127+ OptionallyStaticUnitRange (x:: Base.OneTo ) = OptionallyStaticUnitRange (static (1 ), Int (last (x)))
128+ function OptionallyStaticUnitRange (x:: Union{Base.Slice, Base.IdentityUnitRange} )
129+ OptionallyStaticUnitRange (x. indices)
130+ end
131+ function OptionallyStaticUnitRange (x:: OptionallyStaticStepRange )
132+ assert_unit_step (step (x))
133+ _OptionallyStaticUnitRange (getfield (x, :start ), getfield (x, :stop ))
134+ end
135+ function OptionallyStaticUnitRange (x:: AbstractRange )
136+ assert_unit_step (step (x))
137+ _OptionallyStaticUnitRange (first (x), last (x))
138+ end
139+ function OptionallyStaticUnitRange {F, L} (x:: AbstractRange ) where {F, L}
140+ OptionallyStaticUnitRange (x)
141+ end
142+ function OptionallyStaticUnitRange (start:: IntType , stop:: IntType )
143+ _OptionallyStaticUnitRange (start, stop)
144+ end
145+ function OptionallyStaticUnitRange (start, stop)
146+ OptionallyStaticUnitRange (IntType (start), IntType (stop))
147+ end
148+ function OptionallyStaticUnitRange {StaticInt{F}, StaticInt{L}} () where {F, L}
149+ _OptionallyStaticUnitRange (StaticInt {F} (), StaticInt {L} ())
150+ end
151+ function assert_unit_step (s:: Int )
152+ s == 1 && return nothing
153+ errmsg (x) = throw (ArgumentError (LazyString (" step must be 1, got " , s))) # avoid GC frame
154+ errmsg (s)
155+ end
156+
132157"""
133158 SUnitRange(start::Int, stop::Int)
134159
@@ -150,82 +175,6 @@ const OptionallyStaticRange{
150175 F, L} = Union{OptionallyStaticUnitRange{F, L},
151176 OptionallyStaticStepRange{F, <: Any , L}}
152177
153- """
154- static_first(x::AbstractRange)
155-
156- Attempt to return `static(first(x))`, if known at compile time. Otherwise, return
157- `first(x)`.
158-
159- See also: [`static_step`](@ref), [`static_last`](@ref)
160-
161- # Examples
162-
163- ```julia
164- julia> static_first(static(2):10)
165- static(2)
166-
167- julia> static_first(1:10)
168- 1
169-
170- julia> static_first(Base.OneTo(10))
171- static(1)
172-
173- ```
174- """
175- static_first (x:: Base.OneTo ) = StaticInt (1 )
176- static_first (x:: Union{Base.Slice, Base.IdentityUnitRange} ) = static_first (x. indices)
177- static_first (x:: OptionallyStaticRange ) = getfield (x, :start )
178- static_first (x) = first (x)
179-
180- """
181- static_step(x::AbstractRange)
182-
183- Attempt to return `static(step(x))`, if known at compile time. Otherwise, return
184- `step(x)`.
185-
186- See also: [`static_first`](@ref), [`static_last`](@ref)
187-
188- # Examples
189-
190- ```julia
191- julia> static_step(static(1):static(3):9)
192- static(3)
193-
194- julia> static_step(1:3:9)
195- 3
196-
197- julia> static_step(1:9)
198- static(1)
199-
200- ```
201- """
202- static_step (@nospecialize x:: AbstractUnitRange ) = StaticInt (1 )
203- static_step (x:: OptionallyStaticStepRange ) = getfield (x, :step )
204- static_step (x) = step (x)
205-
206- """
207- static_last(x::AbstractRange)
208-
209- Attempt to return `static(last(x))`, if known at compile time. Otherwise, return
210- `last(x)`.
211-
212- See also: [`static_first`](@ref), [`static_step`](@ref)
213-
214- # Examples
215-
216- ```julia
217- julia> static_last(static(1):static(10))
218- static(10)
219-
220- julia> static_last(static(1):10)
221- 10
222-
223- ```
224- """
225- static_last (x:: OptionallyStaticRange ) = getfield (x, :stop )
226- static_last (x) = last (x)
227- static_last (x:: Union{Base.Slice, Base.IdentityUnitRange} ) = static_last (x. indices)
228-
229178Base. first (x:: OptionallyStaticRange{Int} ) = getfield (x, :start )
230179Base. first (:: OptionallyStaticRange{StaticInt{F}} ) where {F} = F
231180Base. step (x:: OptionallyStaticStepRange{<:Any, Int} ) = getfield (x, :step )
@@ -285,12 +234,15 @@ function Base.checkindex(::Type{Bool},
285234 (F1:: Int <= F2:: Int ) && (L1:: Int >= L2:: Int )
286235end
287236
288- function Base. getindex (r:: OptionallyStaticUnitRange ,
289- s:: AbstractUnitRange{<:Integer} )
237+ function Base. getindex (
238+ r:: OptionallyStaticUnitRange ,
239+ i:: AbstractUnitRange{<:Integer} ,
240+ )
241+ s = OptionallyStaticUnitRange (i)
290242 @boundscheck checkbounds (r, s)
291- f = static_first (r )
243+ f = getfield (r, :start )
292244 fnew = f - one (f)
293- return (fnew + static_first (s )): (fnew + static_last (s ))
245+ return (fnew + getfield (s, :start )): (fnew + getfield (s, :stop ))
294246end
295247
296248function Base. getindex (x:: OptionallyStaticUnitRange{StaticInt{1}} , i:: Int )
@@ -320,11 +272,10 @@ end
320272
321273Base. AbstractUnitRange {Int} (r:: OptionallyStaticUnitRange ) = r
322274function Base. AbstractUnitRange {T} (r:: OptionallyStaticUnitRange ) where {T}
323- start = static_first (r)
324- if isa (start, StaticInt{1 }) && T <: Integer
325- return Base. OneTo {T} (T (static_last (r)))
275+ if isa (getfield (r, :start ), StaticInt{1 }) && T <: Integer
276+ return Base. OneTo {T} (T (last (r)))
326277 else
327- return UnitRange {T} (T (static_first (r)), T (static_last (r)))
278+ return UnitRange {T} (T (first (r)), T (last (r)))
328279 end
329280end
330281
373324Base. axes1 (x:: Base.Slice{<:OptionallyStaticUnitRange{One}} ) = x. indices
374325Base. axes1 (x:: Base.Slice{<:OptionallyStaticRange} ) = Base. IdentityUnitRange (x. indices)
375326
376- Base.:(- )(r:: OptionallyStaticRange ) = (- static_first (r)): (- static_step (r)): (- static_last (r))
327+ function Base.:(- )(r:: OptionallyStaticRange )
328+ s = isa (r, OptionallyStaticStepRange) ? - getfield (r, :step ) : - One ()
329+ (- getfield (r, :start )): s: (- getfield (r, :stop ))
330+ end
377331
378332function Base. reverse (x:: OptionallyStaticUnitRange )
379333 _OptionallyStaticStepRange (getfield (x, :stop ), StaticInt (- 1 ), getfield (x, :start ))
@@ -435,25 +389,25 @@ end
435389
436390function Base. first (x:: OptionallyStaticUnitRange , n:: IntType )
437391 n < 0 && throw (ArgumentError (" Number of elements must be nonnegative" ))
438- start = static_first (x )
439- OptionallyStaticUnitRange (start, min (start - one (start) + n, static_last (x )))
392+ start = getfield (x, :start )
393+ OptionallyStaticUnitRange (start, min (start - one (start) + n, getfield (x, :stop )))
440394end
441395function Base. first (x:: OptionallyStaticStepRange , n:: IntType )
442396 n < 0 && throw (ArgumentError (" Number of elements must be nonnegative" ))
443- start = static_first (x )
444- s = static_step (x )
445- stop = min (((n - one (n)) * s) + static_first (x), static_last (x ))
397+ start = getfield (x, :start )
398+ s = getfield (x, :step )
399+ stop = min (((n - one (n)) * s) + start, getfield (x, :stop ))
446400 OptionallyStaticStepRange (start, s, stop)
447401end
448402function Base. last (x:: OptionallyStaticUnitRange , n:: IntType )
449403 n < 0 && throw (ArgumentError (" Number of elements must be nonnegative" ))
450- stop = static_last (x )
451- OptionallyStaticUnitRange (max (stop + one (stop) - n, static_first (x )), stop)
404+ stop = getfield (x, :stop )
405+ OptionallyStaticUnitRange (max (stop + one (stop) - n, getfield (x, :start )), stop)
452406end
453407function Base. last (x:: OptionallyStaticStepRange , n:: IntType )
454408 n < 0 && throw (ArgumentError (" Number of elements must be nonnegative" ))
455- start = static_first (x )
456- s = static_step (x )
457- stop = static_last (x )
409+ start = getfield (x, :start )
410+ s = getfield (x, :step )
411+ stop = getfield (x, :stop )
458412 OptionallyStaticStepRange (max (stop + one (stop) - (n * s), start), s, stop)
459413end
0 commit comments