Skip to content

Commit 116de2b

Browse files
committed
non-mutating swapAt implementations for UnsafeMutable(Raw)BufferPointer
1 parent abbaa47 commit 116de2b

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

stdlib/public/core/UnsafeBufferPointer.swift.gyb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,27 @@ extension Unsafe${Mutable}BufferPointer: ${Mutable}Collection, RandomAccessColle
337337
}
338338
% end
339339
}
340+
% if mutable:
341+
342+
/// Exchanges the values at the specified indices of the buffer.
343+
///
344+
/// Both parameters must be valid indices of the buffer, and not
345+
/// equal to `endIndex`. Passing the same index as both `i` and `j` has no
346+
/// effect.
347+
///
348+
/// - Parameters:
349+
/// - i: The index of the first value to swap.
350+
/// - j: The index of the second value to swap.
351+
@_inlineable
352+
public func swapAt(_ i: Int, _ j: Int) {
353+
guard i != j else { return }
354+
let pi = (_position! + i)
355+
let pj = (_position! + j)
356+
let tmp = pi.move()
357+
pi.moveInitialize(from: pj, count: 1)
358+
pj.initialize(to: tmp, count: 1)
359+
}
360+
% end # mutable
340361
}
341362
342363
extension Unsafe${Mutable}BufferPointer {

stdlib/public/core/UnsafeRawBufferPointer.swift.gyb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,28 @@ extension Unsafe${Mutable}RawBufferPointer: ${Mutable}Collection {
223223
% end # mutable
224224
}
225225

226+
% if mutable:
227+
/// Exchanges the byte values at the specified indices
228+
/// in this buffer's memory.
229+
///
230+
/// Both parameters must be valid indices of the buffer, and not
231+
/// equal to `endIndex`. Passing the same index as both `i` and `j` has no
232+
/// effect.
233+
///
234+
/// - Parameters:
235+
/// - i: The index of the first byte to swap.
236+
/// - j: The index of the second byte to swap.
237+
@_inlineable
238+
public func swapAt(_ i: Int, _ j: Int) {
239+
guard i != j else { return }
240+
let pi = (_position! + i)
241+
let pj = (_position! + j)
242+
let tmp = pi.load(fromByteOffset: 0, as: UInt8.self)
243+
pi.copyMemory(from: pj, byteCount: MemoryLayout<UInt8>.size)
244+
pj.storeBytes(of: tmp, toByteOffset: 0, as: UInt8.self)
245+
}
246+
247+
% end # mutable
226248
/// The number of bytes in the buffer.
227249
///
228250
/// If the `baseAddress` of this buffer is `nil`, the count is zero. However,

validation-test/stdlib/UnsafeBufferPointer.swift.gyb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,40 @@ UnsafeMutable${'Raw' if IsRaw else ''}BufferPointerTestSuite.test("subscript/set
829829
expectEqual(1, buffer[3])
830830
}
831831

832+
UnsafeMutable${'Raw' if IsRaw else ''}BufferPointerTestSuite.test("nonmutating-swapAt") {
833+
% if IsRaw:
834+
let buffer = UnsafeMutableRawBufferPointer.allocate(count: 3)
835+
% else:
836+
let buffer = UnsafeMutableBufferPointer<Int>.allocate(capacity: 3)
837+
% end
838+
defer { buffer.deallocate() }
839+
840+
buffer[0] = 0
841+
buffer[1] = 1
842+
buffer[2] = 2
843+
844+
buffer.swapAt(0, 0)
845+
expectEqual(Array(buffer), [0, 1, 2])
846+
847+
buffer.swapAt(0, 2)
848+
expectEqual(Array(buffer), [2, 1, 0])
849+
}
850+
851+
% if not IsRaw:
852+
UnsafeMutableBufferPointerTestSuite.test("nonmutating-swapAt-withARC") {
853+
let buffer = UnsafeMutableBufferPointer<String>.allocate(capacity: 3)
854+
defer { buffer.deallocate() }
855+
856+
_ = buffer.initialize(from: (0..<3).map(String.init(describing:)))
857+
858+
buffer.swapAt(0, 0)
859+
expectEqual(Array(buffer), ["0", "1", "2"])
860+
861+
buffer.swapAt(0, 2)
862+
expectEqual(Array(buffer), ["2", "1", "0"])
863+
}
864+
% end
865+
832866
% end # SelfName
833867

834868
runAllTests()

0 commit comments

Comments
 (0)