@@ -86,42 +86,73 @@ extension Stride: Collection {
86
86
precondition ( i. base < base. endIndex, " Advancing past end index " )
87
87
return index ( i, offsetBy: 1 )
88
88
}
89
-
89
+
90
90
public func index(
91
91
_ i: Index ,
92
92
offsetBy n: Int ,
93
93
limitedBy limit: Index
94
94
) -> Index ? {
95
95
guard n != 0 else { return i }
96
96
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
109
118
}
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
114
129
}
115
130
}
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
+
117
149
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
120
151
}
121
152
122
153
public func distance( from start: Index , to end: Index ) -> Int {
123
154
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 ( )
125
156
}
126
157
127
158
public func index( _ i: Index , offsetBy distance: Int ) -> Index {
0 commit comments