@@ -86,42 +86,73 @@ extension Stride: Collection {
8686 precondition ( i. base < base. endIndex, " Advancing past end index " )
8787 return index ( i, offsetBy: 1 )
8888 }
89-
89+
9090 public func index(
9191 _ i: Index ,
9292 offsetBy n: Int ,
9393 limitedBy limit: Index
9494 ) -> Index ? {
9595 guard n != 0 else { return i }
9696 guard limit != i else { return nil }
97- switch ( i, n) {
98- case ( endIndex, ..< 0 ) :
99- let baseEnd = base. index ( base. endIndex, offsetBy: - ( ( base. count - 1 ) % stride + 1 ) )
100- return Index ( base. index ( baseEnd, offsetBy: ( n - n. signum ( ) ) * stride, limitedBy: limit. base) )
101- case ( _, 1 ... ) :
102- let max = limit < i ? endIndex. base : limit. base
103- let idx = base. index ( i. base, offsetBy: n * stride, limitedBy: max)
104- if let idx = idx {
105- return idx > max ? endIndex : Index ( idx)
106- }
107- guard i >= limit || limit == endIndex else {
108- return nil
97+
98+ return n > 0
99+ ? offsetForward ( i, offsetBy: n, limitedBy: limit)
100+ : offsetBackward ( i, offsetBy: n, limitedBy: limit)
101+ }
102+
103+ private func offsetForward(
104+ _ i: Index ,
105+ offsetBy n: Int ,
106+ limitedBy limit: Index
107+ ) -> Index ? {
108+ if limit < i {
109+ if let idx = base. index (
110+ i. base,
111+ offsetBy: n * stride,
112+ limitedBy: base. endIndex
113+ ) {
114+ return Index ( idx)
115+ } else {
116+ assert ( distance ( from: i, to: endIndex) == n, " Advancing past end index " )
117+ return endIndex
109118 }
110- let isToEnd = distance ( from: i, to: endIndex) == n
111- return isToEnd ? endIndex : nil
112- case _:
113- return Index ( base. index ( i. base, offsetBy: n * stride, limitedBy: limit. base) )
119+ } else if let idx = base. index (
120+ i. base,
121+ offsetBy: n * stride,
122+ limitedBy: limit. base
123+ ) {
124+ return Index ( idx)
125+ } else {
126+ return distance ( from: i, to: limit) == n
127+ ? endIndex
128+ : nil
114129 }
115130 }
116-
131+
132+ private func offsetBackward(
133+ _ i: Index ,
134+ offsetBy n: Int ,
135+ limitedBy limit: Index
136+ ) -> Index ? {
137+ let distance = i == endIndex
138+ ? - ( ( base. count - 1 ) % stride + 1 ) + ( n + 1 ) * stride
139+ : n * stride
140+ return Index (
141+ base. index (
142+ i. base,
143+ offsetBy: distance,
144+ limitedBy: limit. base
145+ )
146+ )
147+ }
148+
117149 public var count : Int {
118- let limit = base. count - 1
119- return limit / stride + ( limit < 0 ? 0 : 1 )
150+ base. isEmpty ? 0 : ( base. count - 1 ) / stride + 1
120151 }
121152
122153 public func distance( from start: Index , to end: Index ) -> Int {
123154 let distance = base. distance ( from: start. base, to: end. base)
124- return distance / stride + ( abs ( distance % stride) > 0 ? distance . signum ( ) : 0 )
155+ return distance / stride + ( distance % stride) . signum ( )
125156 }
126157
127158 public func index( _ i: Index , offsetBy distance: Int ) -> Index {
0 commit comments