Skip to content

Commit 3924d1a

Browse files
authored
Merge pull request #25825 from numist/numist/diff-inverse-master
add `CollectionDifference.inverse()` and test coverage
2 parents 504e12c + 3ddfff9 commit 3924d1a

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

stdlib/public/core/CollectionDifference.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ public struct CollectionDifference<ChangeElement> {
154154
}
155155

156156
/// Internal initializer for use by algorithms that cannot produce invalid
157-
/// collections of changes. These include the Myers' diff algorithm and
158-
/// the move inferencer.
157+
/// collections of changes. These include the Myers' diff algorithm,
158+
/// self.inverse(), and the move inferencer.
159159
///
160160
/// If parameter validity cannot be guaranteed by the caller then
161161
/// `CollectionDifference.init?(_:)` should be used instead.
@@ -200,6 +200,17 @@ public struct CollectionDifference<ChangeElement> {
200200
removals = Array(sortedChanges[0..<firstInsertIndex])
201201
insertions = Array(sortedChanges[firstInsertIndex..<sortedChanges.count])
202202
}
203+
204+
public func inverse() -> Self {
205+
return CollectionDifference(_validatedChanges: self.map { c in
206+
switch c {
207+
case .remove(let o, let e, let a):
208+
return .insert(offset: o, element: e, associatedWith: a)
209+
case .insert(let o, let e, let a):
210+
return .remove(offset: o, element: e, associatedWith: a)
211+
}
212+
})
213+
}
203214
}
204215

205216
/// A CollectionDifference is itself a Collection.

test/stdlib/Diffing.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ if #available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) {
625625

626626
// Validate application
627627
expectEqual(b, a.applying(diff)!)
628+
expectEqual(a, b.applying(diff.inverse())!)
628629
}}}}}}
629630
}
630631

@@ -644,13 +645,15 @@ if #available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) {
644645
expectNotNil(applied)
645646
if let applied = applied {
646647
expectEqual(b, applied)
648+
expectEqual(a, applied.applying(d.inverse()))
647649
if (b != applied) {
648650
print("""
649651
// repro:
650652
let a = \(a)
651653
let b = \(b)
652654
let d = b.difference(from: a)
653655
expectEqual(b, a.applying(d))
656+
expectEqual(a, applied.applying(d.inverse()))
654657
""")
655658
break
656659
}

0 commit comments

Comments
 (0)