@@ -1612,50 +1612,17 @@ extension Array {
1612
1612
return try _buffer. withUnsafeBufferPointer ( body)
1613
1613
}
1614
1614
1615
- /// Calls the given closure with a pointer to the array's mutable contiguous
1616
- /// storage.
1617
- ///
1618
- /// Often, the optimizer can eliminate bounds checks within an array
1619
- /// algorithm, but when that fails, invoking the same algorithm on the
1620
- /// buffer pointer passed into your closure lets you trade safety for speed.
1621
- ///
1622
- /// The following example shows how modifying the contents of the
1623
- /// `UnsafeMutableBufferPointer` argument to `body` alters the contents of
1624
- /// the array:
1625
- ///
1626
- /// var numbers = [1, 2, 3, 4, 5]
1627
- /// numbers.withUnsafeMutableBufferPointer { buffer in
1628
- /// for i in stride(from: buffer.startIndex, to: buffer.endIndex - 1, by: 2) {
1629
- /// buffer.swapAt(i, i + 1)
1630
- /// }
1631
- /// }
1632
- /// print(numbers)
1633
- /// // Prints "[2, 1, 4, 3, 5]"
1634
- ///
1635
- /// The pointer passed as an argument to `body` is valid only during the
1636
- /// execution of `withUnsafeMutableBufferPointer(_:)`. Do not store or
1637
- /// return the pointer for later use.
1638
- ///
1639
- /// - Warning: Do not rely on anything about the array that is the target of
1640
- /// this method during execution of the `body` closure; it might not
1641
- /// appear to have its correct value. Instead, use only the
1642
- /// `UnsafeMutableBufferPointer` argument to `body`.
1643
- ///
1644
- /// - Parameter body: A closure with an `UnsafeMutableBufferPointer`
1645
- /// parameter that points to the contiguous storage for the array.
1646
- /// If no such storage exists, it is created. If `body` has a return value, that value is also
1647
- /// used as the return value for the `withUnsafeMutableBufferPointer(_:)`
1648
- /// method. The pointer argument is valid only for the duration of the
1649
- /// method's execution.
1650
- /// - Returns: The return value, if any, of the `body` closure parameter.
1615
+ // Superseded by the typed-throws version of this function, but retained
1616
+ // for ABI reasons.
1651
1617
@_semantics ( " array.withUnsafeMutableBufferPointer " )
1652
1618
@_effects ( notEscaping self. value**)
1653
1619
@inlinable // FIXME(inline-always)
1654
1620
@inline ( __always) // Performance: This method should get inlined into the
1655
1621
// caller such that we can combine the partial apply with the apply in this
1656
1622
// function saving on allocating a closure context. This becomes unnecessary
1657
1623
// once we allocate noescape closures on the stack.
1658
- public mutating func withUnsafeMutableBufferPointer< R> (
1624
+ @_silgen_name ( " $sSa30withUnsafeMutableBufferPointeryqd__qd__SryxGzKXEKlF " )
1625
+ mutating func __abi_withUnsafeMutableBufferPointer< R> (
1659
1626
_ body: ( inout UnsafeMutableBufferPointer < Element > ) throws -> R
1660
1627
) rethrows -> R {
1661
1628
_makeMutableAndUnique ( )
@@ -1679,6 +1646,37 @@ extension Array {
1679
1646
return try body ( & inoutBufferPointer)
1680
1647
}
1681
1648
1649
+ @_semantics ( " array.withUnsafeMutableBufferPointer " )
1650
+ @_effects ( notEscaping self. value**)
1651
+ @_alwaysEmitIntoClient
1652
+ @inline ( __always) // Performance: This method should get inlined into the
1653
+ // caller such that we can combine the partial apply with the apply in this
1654
+ // function saving on allocating a closure context. This becomes unnecessary
1655
+ // once we allocate noescape closures on the stack.
1656
+ public mutating func withUnsafeMutableBufferPointer< R, E> (
1657
+ _ body: ( inout UnsafeMutableBufferPointer < Element > ) throws ( E ) -> R
1658
+ ) throws ( E) -> R {
1659
+ _makeMutableAndUnique ( )
1660
+ let count = _buffer. mutableCount
1661
+
1662
+ // Create an UnsafeBufferPointer that we can pass to body
1663
+ let pointer = _buffer. mutableFirstElementAddress
1664
+ var inoutBufferPointer = UnsafeMutableBufferPointer (
1665
+ start: pointer, count: count)
1666
+
1667
+ defer {
1668
+ _precondition (
1669
+ inoutBufferPointer. baseAddress == pointer &&
1670
+ inoutBufferPointer. count == count,
1671
+ " Array withUnsafeMutableBufferPointer: replacing the buffer is not allowed " )
1672
+ _endMutation ( )
1673
+ _fixLifetime ( self )
1674
+ }
1675
+
1676
+ // Invoke the body.
1677
+ return try body ( & inoutBufferPointer)
1678
+ }
1679
+
1682
1680
@inlinable
1683
1681
public __consuming func _copyContents(
1684
1682
initializing buffer: UnsafeMutableBufferPointer < Element >
0 commit comments