Skip to content

Commit ba6f11c

Browse files
committed
Improved: PatternTextStyle/reduce(_:with:) now uses the reduce method directly (faster).
1 parent 9850e6c commit ba6f11c

File tree

1 file changed

+47
-36
lines changed

1 file changed

+47
-36
lines changed

Sources/DiffableTextKitXPattern/Style.swift

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -140,35 +140,45 @@ extension PatternTextStyle {
140140
//=------------------------------------------------------------------------=
141141

142142
/// - Mismatches throw an error.
143-
@inlinable @inline(never) public func resolve(_ proposal:
143+
@inlinable public func resolve(_ proposal:
144144
Proposal, with cache: inout Void) throws -> Commit<Value> {
145-
var value = Value()
146-
//=--------------------------------------=
147-
// Content
148-
//=--------------------------------------=
149-
var nonvirtuals = proposal.lazy.merged().nonvirtuals().makeIterator()
150-
//=--------------------------------------=
151-
// Matches
152-
//=--------------------------------------=
153-
for character in pattern {
154-
guard let predicate = placeholders[character] else { continue }
155-
guard let nonvirtual = nonvirtuals.next() /**/ else { break }
156-
guard predicate(nonvirtual) else { throw Info([.mark(nonvirtual), "is invalid"]) }
145+
let nonvirtuals = proposal.lazy.merged().nonvirtuals()
146+
return try reduce(with: nonvirtuals, into: Commit()) {
147+
commit, virtuals, nonvirtual in
148+
commit.snapshot.append(contentsOf: virtuals, as: .phantom)
149+
commit.snapshot.append(nonvirtual)
150+
commit.value .append(nonvirtual)
151+
} none: {
152+
commit, virtuals in
153+
commit.snapshot.append(contentsOf: virtuals, as: .phantom)
154+
commit.snapshot.select(commit.snapshot.endIndex)
155+
} done: {
156+
commit, virtuals, mismatches in
157157
//=----------------------------------=
158-
// Some
158+
// Pattern
159159
//=----------------------------------=
160-
value.append(nonvirtual)
161-
}
162-
//=--------------------------------------=
163-
// Capacity
164-
//=--------------------------------------=
165-
guard nonvirtuals.next() == nil else {
166-
throw Info([.mark(proposal.merged().characters), "exceeded pattern capacity \(value.count)"])
160+
if !hidden {
161+
commit.snapshot.append(contentsOf: virtuals, as: .phantom)
162+
}
163+
//=----------------------------------=
164+
// Mismatches
165+
//=----------------------------------=
166+
if !mismatches.isEmpty {
167+
//=------------------------------=
168+
// Value <= Capacity
169+
//=------------------------------=
170+
if !virtuals.isEmpty {
171+
throw Info([.mark(mismatches.first!), "is invalid."])
172+
//=------------------------------=
173+
// Value >> Capacity
174+
//=------------------------------=
175+
} else {
176+
let capacity = Info.note(commit.value.count)
177+
let elements = Info.mark(commit.snapshot.characters + mismatches)
178+
throw Info(["\(elements) exceeded pattern capacity \(capacity)"])
179+
}
180+
}
167181
}
168-
//=--------------------------------------=
169-
// Interpret
170-
//=--------------------------------------=
171-
return interpret(value)
172182
}
173183
}
174184

@@ -182,38 +192,39 @@ extension PatternTextStyle {
182192
// MARK: Reduce
183193
//=------------------------------------------------------------------------=
184194

185-
@inlinable @inline(never) func reduce<Result>(
186-
with value: Value, into result: Result,
195+
@inlinable @inline(never) func reduce<Content, Result>(
196+
with content: Content, into result: Result,
187197
some: (inout Result, Substring, Character) -> Void,
188198
none: (inout Result, Substring) -> Void,
189-
done: (inout Result, Substring, Value.SubSequence) -> Void) -> Result {
199+
done: (inout Result, Substring, Content.SubSequence) throws -> Void)
200+
rethrows -> Result where Content: Collection<Character> {
190201
//=--------------------------------------=
191202
// State
192203
//=--------------------------------------=
193204
var result = result
194-
var vIndex = value .startIndex
205+
var cIndex = content.startIndex
195206
var pIndex = pattern.startIndex
196207
var qIndex = pIndex // position
197208
//=--------------------------------------=
198209
// Matches
199210
//=--------------------------------------=
200211
matches: while qIndex != pattern.endIndex {
201212
//=----------------------------------=
202-
// Placeholder
213+
// Position == Placeholder
203214
//=----------------------------------=
204215
if let predicate = placeholders[pattern[qIndex]] {
205-
guard vIndex != value.endIndex else { break matches }
206-
let nonvirtual = value[vIndex]
207-
guard predicate(nonvirtual) else { break matches }
216+
guard cIndex != content.endIndex else { break matches }
217+
let nonvirtual = content[cIndex]
218+
guard predicate(nonvirtual) /**/ else { break matches }
208219
//=------------------------------=
209220
// (!) Some
210221
//=------------------------------=
211222
some(&result, pattern[pIndex ..< qIndex], nonvirtual)
212-
value .formIndex(after: &vIndex)
223+
content.formIndex(after: &cIndex)
213224
pattern.formIndex(after: &qIndex)
214225
pIndex = qIndex
215226
//=----------------------------------=
216-
// Miscellaneous
227+
// Position != Placeholder
217228
//=----------------------------------=
218229
} else {
219230
pattern.formIndex(after: &qIndex)
@@ -239,7 +250,7 @@ extension PatternTextStyle {
239250
//=--------------------------------------=
240251
// (!) Done
241252
//=--------------------------------------=
242-
done(&result, pattern[pIndex...], value[vIndex...]); return result
253+
try done(&result, pattern[pIndex...], content[cIndex...]); return result
243254
}
244255
}
245256

0 commit comments

Comments
 (0)