Skip to content

Commit 57f4afb

Browse files
committed
[stdlib] Update diffing code to match stdlib coding conventions
- Add an underscore to private/internal symbols - Make access levels explicit, even when they’re implied from context - Conform to max line length of 80 characters - Conformances declared on separate extensions that implement them - Arrange member declarations so that stored properties appear first - Expand single-letter function and type parameter names where there is an obvious name that’s more descriptive - RangeReplaceableCollection.fastApplicationEnumeration → CollectionDifference._fastEnumeratedApply
1 parent 9b45fc4 commit 57f4afb

File tree

2 files changed

+211
-170
lines changed

2 files changed

+211
-170
lines changed

stdlib/public/core/CollectionDifference.swift

Lines changed: 80 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public struct CollectionDifference<ChangeElement> {
2525
case remove(offset: Int, element: ChangeElement, associatedWith: Int?)
2626

2727
// Internal common field accessors
28-
var offset: Int {
28+
internal var _offset: Int {
2929
get {
3030
switch self {
3131
case .insert(offset: let o, element: _, associatedWith: _):
@@ -35,7 +35,7 @@ public struct CollectionDifference<ChangeElement> {
3535
}
3636
}
3737
}
38-
var element: ChangeElement {
38+
internal var _element: ChangeElement {
3939
get {
4040
switch self {
4141
case .insert(offset: _, element: let e, associatedWith: _):
@@ -45,7 +45,7 @@ public struct CollectionDifference<ChangeElement> {
4545
}
4646
}
4747
}
48-
var associatedOffset: Int? {
48+
internal var _associatedOffset: Int? {
4949
get {
5050
switch self {
5151
case .insert(offset: _, element: _, associatedWith: let o):
@@ -57,6 +57,12 @@ public struct CollectionDifference<ChangeElement> {
5757
}
5858
}
5959

60+
/// The `.insert` changes contained by this difference, from lowest offset to highest
61+
public let insertions: [Change]
62+
63+
/// The `.remove` changes contained by this difference, from lowest offset to highest
64+
public let removals: [Change]
65+
6066
/// The public initializer calls this function to ensure that its parameter
6167
/// meets the conditions set in its documentation.
6268
///
@@ -71,7 +77,9 @@ public struct CollectionDifference<ChangeElement> {
7177
/// 3. All associations between insertions and removals are symmetric
7278
///
7379
/// Complexity: O(`changes.count`)
74-
private static func validateChanges<C>(_ changes : C) -> Bool where C:Collection, C.Element == Change {
80+
private static func _validateChanges<Changes: Collection>(
81+
_ changes : Changes
82+
) -> Bool where Changes.Element == Change {
7583
if changes.count == 0 { return true }
7684

7785
var insertAssocToOffset = Dictionary<Int,Int>()
@@ -80,7 +88,7 @@ public struct CollectionDifference<ChangeElement> {
8088
var removeOffset = Set<Int>()
8189

8290
for c in changes {
83-
let offset = c.offset
91+
let offset = c._offset
8492
if offset < 0 { return false }
8593

8694
switch c {
@@ -92,7 +100,7 @@ public struct CollectionDifference<ChangeElement> {
92100
insertOffset.insert(offset)
93101
}
94102

95-
if let assoc = c.associatedOffset {
103+
if let assoc = c._associatedOffset {
96104
if assoc < 0 { return false }
97105
switch c {
98106
case .remove(_, _, _):
@@ -126,12 +134,14 @@ public struct CollectionDifference<ChangeElement> {
126134
///
127135
/// - Complexity: O(*n* * log(*n*)), where *n* is the length of the
128136
/// parameter.
129-
public init?<C>(_ c: C) where C:Collection, C.Element == Change {
130-
if !CollectionDifference<ChangeElement>.validateChanges(c) {
137+
public init?<Changes: Collection>(
138+
_ changes: Changes
139+
) where Changes.Element == Change {
140+
if !CollectionDifference<ChangeElement>._validateChanges(changes) {
131141
return nil
132142
}
133143

134-
self.init(validatedChanges: c)
144+
self.init(_validatedChanges: changes)
135145
}
136146

137147
/// Internal initializer for use by algorithms that cannot produce invalid
@@ -146,27 +156,29 @@ public struct CollectionDifference<ChangeElement> {
146156
///
147157
/// - Complexity: O(*n* * log(*n*)), where *n* is the length of the
148158
/// parameter.
149-
init<C>(validatedChanges c: C) where C:Collection, C.Element == Change {
150-
let changes = c.sorted { (a, b) -> Bool in
159+
internal init<Changes: Collection>(
160+
_validatedChanges changes: Changes
161+
) where Changes.Element == Change {
162+
let sortedChanges = changes.sorted { (a, b) -> Bool in
151163
switch (a, b) {
152164
case (.remove(_, _, _), .insert(_, _, _)):
153165
return true
154166
case (.insert(_, _, _), .remove(_, _, _)):
155167
return false
156168
default:
157-
return a.offset < b.offset
169+
return a._offset < b._offset
158170
}
159171
}
160172

161173
// Find first insertion via binary search
162174
let firstInsertIndex: Int
163-
if changes.count == 0 {
175+
if sortedChanges.count == 0 {
164176
firstInsertIndex = 0
165177
} else {
166-
var range = 0...changes.count
178+
var range = 0...sortedChanges.count
167179
while range.lowerBound != range.upperBound {
168180
let i = (range.lowerBound + range.upperBound) / 2
169-
switch changes[i] {
181+
switch sortedChanges[i] {
170182
case .insert(_, _, _):
171183
range = range.lowerBound...i
172184
case .remove(_, _, _):
@@ -176,15 +188,9 @@ public struct CollectionDifference<ChangeElement> {
176188
firstInsertIndex = range.lowerBound
177189
}
178190

179-
removals = Array(changes[0..<firstInsertIndex])
180-
insertions = Array(changes[firstInsertIndex..<changes.count])
191+
removals = Array(sortedChanges[0..<firstInsertIndex])
192+
insertions = Array(sortedChanges[firstInsertIndex..<sortedChanges.count])
181193
}
182-
183-
/// The `.insert` changes contained by this difference, from lowest offset to highest
184-
public let insertions: [Change]
185-
186-
/// The `.remove` changes contained by this difference, from lowest offset to highest
187-
public let removals: [Change]
188194
}
189195

190196
/// A CollectionDifference is itself a Collection.
@@ -207,47 +213,60 @@ public struct CollectionDifference<ChangeElement> {
207213
/// }
208214
/// }
209215
/// ```
210-
extension CollectionDifference : Collection {
211-
public typealias Element = CollectionDifference<ChangeElement>.Change
216+
extension CollectionDifference: Collection {
217+
public typealias Element = Change
212218

213-
// Opaque index type is isomorphic to Int
214-
public struct Index: Comparable, Hashable {
215-
public static func < (lhs: CollectionDifference<ChangeElement>.Index, rhs: CollectionDifference<ChangeElement>.Index) -> Bool {
216-
return lhs.i < rhs.i
217-
}
218-
219-
let i: Int
220-
init(_ index: Int) {
221-
i = index
219+
public struct Index {
220+
// Opaque index type is isomorphic to Int
221+
internal let _offset: Int
222+
223+
internal init(_offset offset: Int) {
224+
_offset = offset
222225
}
223226
}
224227

225-
public var startIndex: CollectionDifference<ChangeElement>.Index {
226-
return Index(0)
228+
public var startIndex: Index {
229+
return Index(_offset: 0)
227230
}
228231

229-
public var endIndex: CollectionDifference<ChangeElement>.Index {
230-
return Index(removals.count + insertions.count)
232+
public var endIndex: Index {
233+
return Index(_offset: removals.count + insertions.count)
231234
}
232235

233-
public func index(after index: CollectionDifference<ChangeElement>.Index) -> CollectionDifference<ChangeElement>.Index {
234-
return Index(index.i + 1)
236+
public func index(after index: Index) -> Index {
237+
return Index(_offset: index._offset + 1)
235238
}
236239

237-
public subscript(position: CollectionDifference<ChangeElement>.Index) -> Element {
238-
return position.i < removals.count ? removals[removals.count - (position.i + 1)] : insertions[position.i - removals.count]
240+
public subscript(position: Index) -> Element {
241+
if position._offset < removals.count {
242+
return removals[removals.count - (position._offset + 1)]
243+
}
244+
return insertions[position._offset - removals.count]
239245
}
240246

241-
public func index(before index: CollectionDifference<ChangeElement>.Index) -> CollectionDifference<ChangeElement>.Index {
242-
return Index(index.i - 1)
247+
public func index(before index: Index) -> Index {
248+
return Index(_offset: index._offset - 1)
243249
}
244250

245-
public func formIndex(_ index: inout CollectionDifference<ChangeElement>.Index, offsetBy distance: Int) {
246-
index = Index(index.i + distance)
251+
public func formIndex(_ index: inout Index, offsetBy distance: Int) {
252+
index = Index(_offset: index._offset + distance)
247253
}
248254

249-
public func distance(from start: CollectionDifference<ChangeElement>.Index, to end: CollectionDifference<ChangeElement>.Index) -> Int {
250-
return end.i - start.i
255+
public func distance(from start: Index, to end: Index) -> Int {
256+
return end._offset - start._offset
257+
}
258+
}
259+
260+
extension CollectionDifference.Index: Equatable {} // synthesized
261+
262+
extension CollectionDifference.Index: Hashable {} // synthesized
263+
264+
extension CollectionDifference.Index: Comparable {
265+
public static func < (
266+
lhs: CollectionDifference.Index,
267+
rhs: CollectionDifference.Index
268+
) -> Bool {
269+
return lhs._offset < rhs._offset
251270
}
252271
}
253272

@@ -257,8 +276,9 @@ extension CollectionDifference: Equatable where ChangeElement: Equatable {}
257276

258277
extension CollectionDifference.Change: Hashable where ChangeElement: Hashable {}
259278

260-
extension CollectionDifference: Hashable where ChangeElement: Hashable {
279+
extension CollectionDifference: Hashable where ChangeElement: Hashable {}
261280

281+
extension CollectionDifference where ChangeElement: Hashable {
262282
/// Infers which `ChangeElement`s have been both inserted and removed only
263283
/// once and returns a new difference with those associations.
264284
///
@@ -269,11 +289,11 @@ extension CollectionDifference: Hashable where ChangeElement: Hashable {
269289
let removeDict: [ChangeElement:Int?] = {
270290
var res = [ChangeElement:Int?](minimumCapacity: Swift.min(removals.count, insertions.count))
271291
for r in removals {
272-
let element = r.element
292+
let element = r._element
273293
if res[element] != .none {
274294
res[element] = .some(.none)
275295
} else {
276-
res[element] = .some(r.offset)
296+
res[element] = .some(r._offset)
277297
}
278298
}
279299
return res.filter { (_, v) -> Bool in v != .none }
@@ -282,17 +302,17 @@ extension CollectionDifference: Hashable where ChangeElement: Hashable {
282302
let insertDict: [ChangeElement:Int?] = {
283303
var res = [ChangeElement:Int?](minimumCapacity: Swift.min(removals.count, insertions.count))
284304
for i in insertions {
285-
let element = i.element
305+
let element = i._element
286306
if res[element] != .none {
287307
res[element] = .some(.none)
288308
} else {
289-
res[element] = .some(i.offset)
309+
res[element] = .some(i._offset)
290310
}
291311
}
292312
return res.filter { (_, v) -> Bool in v != .none }
293313
}()
294314

295-
return CollectionDifference.init(validatedChanges:map({ (c: CollectionDifference<ChangeElement>.Change) -> CollectionDifference<ChangeElement>.Change in
315+
return CollectionDifference(_validatedChanges: map({ (c: Change) -> Change in
296316
switch c {
297317
case .remove(offset: let o, element: let e, associatedWith: _):
298318
if removeDict[e] == nil {
@@ -315,15 +335,15 @@ extension CollectionDifference: Hashable where ChangeElement: Hashable {
315335
}
316336

317337
extension CollectionDifference.Change: Codable where ChangeElement: Codable {
318-
private enum CodingKeys: String, CodingKey {
338+
private enum _CodingKeys: String, CodingKey {
319339
case offset
320340
case element
321341
case associatedOffset
322342
case isRemove
323343
}
324344

325345
public init(from decoder: Decoder) throws {
326-
let values = try decoder.container(keyedBy: CodingKeys.self)
346+
let values = try decoder.container(keyedBy: _CodingKeys.self)
327347
let offset = try values.decode(Int.self, forKey: .offset)
328348
let element = try values.decode(ChangeElement.self, forKey: .element)
329349
let associatedOffset = try values.decode(Int?.self, forKey: .associatedOffset)
@@ -336,17 +356,17 @@ extension CollectionDifference.Change: Codable where ChangeElement: Codable {
336356
}
337357

338358
public func encode(to encoder: Encoder) throws {
339-
var container = encoder.container(keyedBy: CodingKeys.self)
359+
var container = encoder.container(keyedBy: _CodingKeys.self)
340360
switch self {
341361
case .remove(_, _, _):
342362
try container.encode(true, forKey: .isRemove)
343363
case .insert(_, _, _):
344364
try container.encode(false, forKey: .isRemove)
345365
}
346366

347-
try container.encode(offset, forKey: .offset)
348-
try container.encode(element, forKey: .element)
349-
try container.encode(associatedOffset, forKey: .associatedOffset)
367+
try container.encode(_offset, forKey: .offset)
368+
try container.encode(_element, forKey: .element)
369+
try container.encode(_associatedOffset, forKey: .associatedOffset)
350370
}
351371
}
352372

0 commit comments

Comments
 (0)