@@ -180,6 +180,7 @@ extension Processor {
180
180
// Returns whether the advance succeeded. On failure, our
181
181
// save point was restored
182
182
mutating func consume( _ n: Distance ) -> Bool {
183
+ // TODO: need benchmark coverage
183
184
guard let idx = input. index (
184
185
currentPosition, offsetBy: n. rawValue, limitedBy: end
185
186
) else {
@@ -192,6 +193,7 @@ extension Processor {
192
193
193
194
// Advances in unicode scalar view
194
195
mutating func consumeScalar( _ n: Distance ) -> Bool {
196
+ // TODO: need benchmark coverage
195
197
guard let idx = input. unicodeScalars. index (
196
198
currentPosition, offsetBy: n. rawValue, limitedBy: end
197
199
) else {
@@ -223,11 +225,6 @@ extension Processor {
223
225
func load( ) -> Element ? {
224
226
currentPosition < end ? input [ currentPosition] : nil
225
227
}
226
- func load( count: Int ) -> Input . SubSequence ? {
227
- let slice = self . slice [ currentPosition... ] . prefix ( count)
228
- guard slice. count == count else { return nil }
229
- return slice
230
- }
231
228
232
229
// Match against the current input element. Returns whether
233
230
// it succeeded vs signaling an error.
@@ -259,16 +256,21 @@ extension Processor {
259
256
isScalarMode: Bool
260
257
) -> Bool {
261
258
if isScalarMode {
262
- // TODO: sink to specialized method on string, needs benchmark
259
+ // TODO: needs benchmark coverage
263
260
for s in seq. unicodeScalars {
264
261
guard matchScalar ( s, boundaryCheck: false ) else { return false }
265
262
}
266
263
return true
267
264
}
268
265
269
- for e in seq {
270
- guard match ( e) else { return false }
266
+ guard let next = input. matchSeq (
267
+ seq, at: currentPosition, limitedBy: end
268
+ ) else {
269
+ signalFailure ( )
270
+ return false
271
271
}
272
+
273
+ currentPosition = next
272
274
return true
273
275
}
274
276
@@ -327,6 +329,7 @@ extension Processor {
327
329
mutating func matchBitsetScalar(
328
330
_ bitset: DSLTree . CustomCharacterClass . AsciiBitset
329
331
) -> Bool {
332
+ // TODO: needs benchmark coverage
330
333
guard let curScalar = loadScalar ( ) ,
331
334
bitset. matches ( scalar: curScalar) ,
332
335
let idx = input. unicodeScalars. index ( currentPosition, offsetBy: 1 , limitedBy: end) else {
@@ -718,6 +721,25 @@ extension String {
718
721
return idx
719
722
}
720
723
724
+ func matchSeq(
725
+ _ seq: Substring ,
726
+ at pos: Index ,
727
+ limitedBy end: Index
728
+ ) -> Index ? {
729
+ // TODO: This can be greatly sped up with string internals
730
+ // TODO: This is also very much quick-check-able
731
+ assert ( end <= endIndex)
732
+
733
+ var cur = pos
734
+ for e in seq {
735
+ guard cur < end, self [ cur] == e else { return nil }
736
+ self . formIndex ( after: & cur)
737
+ }
738
+
739
+ guard cur <= end else { return nil }
740
+ return cur
741
+ }
742
+
721
743
// func consumeScalar(_ n: Distance) -> Bool {
722
744
723
745
// }
0 commit comments