Skip to content

Commit 1163ea7

Browse files
[stdlib] swapAt method (swiftlang#9119)
* Add swapAt method * Migrate sorting to swapAt * Migrate further stdlib usage
1 parent 0f24c5c commit 1163ea7

8 files changed

+36
-20
lines changed

stdlib/public/core/Arrays.swift.gyb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,7 +1710,7 @@ extension ${Self} {
17101710
/// var numbers = [1, 2, 3, 4, 5]
17111711
/// numbers.withUnsafeMutableBufferPointer { buffer in
17121712
/// for i in stride(from: buffer.startIndex, to: buffer.endIndex - 1, by: 2) {
1713-
/// swap(&buffer[i], &buffer[i + 1])
1713+
/// buffer.swapAt(i, i + 1)
17141714
/// }
17151715
/// }
17161716
/// print(numbers)
@@ -1756,7 +1756,7 @@ extension ${Self} {
17561756
// empty array.
17571757

17581758
var work = ${Self}()
1759-
swap(&work, &self)
1759+
(work, self) = (self, work)
17601760

17611761
// Create an UnsafeBufferPointer over work that we can pass to body
17621762
let pointer = work._buffer.firstElementAddress
@@ -1770,7 +1770,7 @@ extension ${Self} {
17701770
inoutBufferPointer.count == count,
17711771
"${Self} withUnsafeMutableBufferPointer: replacing the buffer is not allowed")
17721772

1773-
swap(&work, &self)
1773+
(work, self) = (self, work)
17741774
}
17751775

17761776
// Invoke the body.

stdlib/public/core/CollectionAlgorithms.swift.gyb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ extension MutableCollection {
165165
var i = index(after: pivot)
166166
while i < endIndex {
167167
if try !belongsInSecondPartition(self[i]) {
168-
swap(&self[i], &self[pivot])
168+
swapAt(i, pivot)
169169
formIndex(after: &pivot)
170170
}
171171
formIndex(after: &i)
@@ -217,7 +217,7 @@ extension MutableCollection where Self : BidirectionalCollection {
217217
break Loop
218218
} while false
219219

220-
swap(&self[lo], &self[hi])
220+
swapAt(lo, hi)
221221
formIndex(after: &lo)
222222
}
223223

stdlib/public/core/ContiguousArrayBuffer.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ internal func += <Element, C : Collection>(
582582
newLHS.firstElementAddress.moveInitialize(
583583
from: lhs.firstElementAddress, count: oldCount)
584584
lhs.count = 0
585-
swap(&lhs, &newLHS)
585+
(lhs, newLHS) = (newLHS, lhs)
586586
buf = UnsafeMutableBufferPointer(start: lhs.firstElementAddress + oldCount, count: numericCast(rhs.count))
587587
}
588588

@@ -746,7 +746,7 @@ internal struct _UnsafePartiallyInitializedContiguousArrayBuffer<Element> {
746746
newResult.firstElementAddress.moveInitialize(
747747
from: result.firstElementAddress, count: result.capacity)
748748
result.count = 0
749-
swap(&result, &newResult)
749+
(result, newResult) = (newResult, result)
750750
}
751751
addWithExistingCapacity(element)
752752
}
@@ -789,7 +789,7 @@ internal struct _UnsafePartiallyInitializedContiguousArrayBuffer<Element> {
789789
_sanityCheck(remainingCapacity == result.capacity - result.count,
790790
"_UnsafePartiallyInitializedContiguousArrayBuffer has incorrect count")
791791
var finalResult = _ContiguousArrayBuffer<Element>()
792-
swap(&finalResult, &result)
792+
(finalResult, result) = (result, finalResult)
793793
remainingCapacity = 0
794794
return ContiguousArray(_buffer: finalResult)
795795
}

stdlib/public/core/MutableCollection.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,11 @@ public protocol MutableCollection : _MutableIndexable, Collection {
309309
mutating func partition(
310310
by belongsInSecondPartition: (Iterator.Element) throws -> Bool
311311
) rethrows -> Index
312+
313+
/// Exchange the values at indices `i` and `j`.
314+
///
315+
/// Has no effect when `i` and `j` are equal.
316+
mutating func swapAt(_ i: Index, _ j: Index)
312317

313318
/// Call `body(p)`, where `p` is a pointer to the collection's
314319
/// mutable contiguous storage. If no such storage exists, it is
@@ -372,6 +377,17 @@ extension MutableCollection {
372377
_writeBackMutableSlice(&self, bounds: bounds, slice: newValue)
373378
}
374379
}
380+
381+
/// Exchange the values at indices `i` and `j`.
382+
///
383+
/// Has no effect when `i` and `j` are equal.
384+
@_inlineable
385+
public mutating func swapAt(_ i: Index, _ j: Index) {
386+
guard i != j else { return }
387+
let tmp = self[i]
388+
self[i] = self[j]
389+
self[j] = tmp
390+
}
375391
}
376392

377393
extension MutableCollection where Self: BidirectionalCollection {

stdlib/public/core/Reverse.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ extension MutableCollection where Self : BidirectionalCollection {
2727
var f = startIndex
2828
var l = index(before: endIndex)
2929
while f < l {
30-
swap(&self[f], &self[l])
30+
swapAt(f, l)
3131
formIndex(after: &f)
3232
formIndex(before: &l)
3333
}

stdlib/public/core/SequenceAlgorithms.swift.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ extension Sequence {
642642
var result = Array(self)
643643
let count = result.count
644644
for i in 0..<count/2 {
645-
swap(&result[i], &result[count - ((i + 1) as Int)])
645+
result.swapAt(i, count - ((i + 1) as Int))
646646
}
647647
return result
648648
}

stdlib/public/core/Sort.swift.gyb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -144,28 +144,28 @@ func _sort3<C>(
144144
case (true, true):
145145
// 1 swap: 321
146146
// swap(a, c): 312->123
147-
swap(&elements[a], &elements[c])
147+
elements.swapAt(a, c)
148148

149149
case (true, false):
150150
// 1 swap: 213, 212 --- 2 swaps: 312, 211
151151
// swap(a, b): 213->123, 212->122, 312->132, 211->121
152-
swap(&elements[a], &elements[b])
152+
elements.swapAt(a, b)
153153

154154
if ${cmp("elements[c]", "elements[b]", p)} {
155155
// 132 (started as 312), 121 (started as 211)
156156
// swap(b, c): 132->123, 121->112
157-
swap(&elements[b], &elements[c])
157+
elements.swapAt(b, c)
158158
}
159159

160160
case (false, true):
161161
// 1 swap: 132, 121 --- 2 swaps: 231, 221
162162
// swap(b, c): 132->123, 121->112, 231->213, 221->212
163-
swap(&elements[b], &elements[c])
163+
elements.swapAt(b, c)
164164

165165
if ${cmp("elements[b]", "elements[a]", p)} {
166166
// 213 (started as 231), 212 (started as 221)
167167
// swap(a, b): 213->123, 212->122
168-
swap(&elements[a], &elements[b])
168+
elements.swapAt(a, b)
169169
}
170170
}
171171
}
@@ -221,7 +221,7 @@ func _partition<C>(
221221
break Loop
222222
}
223223

224-
swap(&elements[lo], &elements[hi])
224+
elements.swapAt(lo, hi)
225225
}
226226

227227
return lo
@@ -334,7 +334,7 @@ func _siftDown<C>(
334334
// If a child is bigger than the current node, swap them and continue sifting
335335
// down.
336336
if largest != index {
337-
swap(&elements[index], &elements[largest])
337+
elements.swapAt(index, largest)
338338
${try_} _siftDown(
339339
&elements,
340340
index: largest,
@@ -393,7 +393,7 @@ func _heapSort<C>(
393393
${", by: areInIncreasingOrder" if p else ""})
394394
elements.formIndex(before: &hi)
395395
while hi != lo {
396-
swap(&elements[lo], &elements[hi])
396+
elements.swapAt(lo, hi)
397397
${try_} _siftDown(
398398
&elements,
399399
index: lo,

stdlib/public/core/StringCharacterView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ extension String {
124124
// exist at the point of mutation. Instead, temporarily move the
125125
// core of this string into a CharacterView.
126126
var tmp = CharacterView("")
127-
swap(&_core, &tmp._core)
127+
(_core, tmp._core) = (tmp._core, _core)
128128
let r = body(&tmp)
129-
swap(&_core, &tmp._core)
129+
(_core, tmp._core) = (tmp._core, _core)
130130
return r
131131
}
132132

0 commit comments

Comments
 (0)