Skip to content

Commit d1249fc

Browse files
committed
Generalize Data’s withUnsafeMutableBytes functions
1 parent 2e9f9cc commit d1249fc

File tree

6 files changed

+62
-22
lines changed

6 files changed

+62
-22
lines changed

Sources/FoundationEssentials/Data/Data.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -480,9 +480,16 @@ public struct Data : RandomAccessCollection, MutableCollection, RangeReplaceable
480480
}
481481
}
482482

483-
@inlinable // This is @inlinable as a generic, trivially forwarding function.
484-
public mutating func withUnsafeMutableBytes<ResultType>(_ body: (UnsafeMutableRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
485-
return try _representation.withUnsafeMutableBytes(body)
483+
@_alwaysEmitIntoClient
484+
public mutating func withUnsafeMutableBytes<E, ResultType: ~Copyable>(_ body: (UnsafeMutableRawBufferPointer) throws(E) -> ResultType) throws(E) -> ResultType {
485+
try _representation.withUnsafeMutableBytes(body)
486+
}
487+
488+
@abi(mutating func withUnsafeMutableBytes<R>(_: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R)
489+
@_spi(FoundationLegacyABI)
490+
@usableFromInline
491+
internal mutating func _legacy_withUnsafeMutableBytes<ResultType>(_ body: (UnsafeMutableRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
492+
try withUnsafeMutableBytes(body)
486493
}
487494

488495
// MARK: -

Sources/FoundationEssentials/Data/Representations/Data+Inline.swift

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,14 +140,20 @@ extension Data {
140140
try withUnsafeBytes(body)
141141
}
142142

143-
@inlinable // This is @inlinable as a generic, trivially forwarding function.
144-
mutating func withUnsafeMutableBytes<Result>(_ apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
145-
let count = Int(length)
146-
return try Swift.withUnsafeMutableBytes(of: &bytes) { (rawBuffer) throws -> Result in
147-
return try apply(UnsafeMutableRawBufferPointer(start: rawBuffer.baseAddress, count: count))
143+
@_alwaysEmitIntoClient
144+
mutating func withUnsafeMutableBytes<E, Result: ~Copyable>(_ apply: (UnsafeMutableRawBufferPointer) throws(E) -> Result) throws(E) -> Result {
145+
try Swift.withUnsafeMutableBytes(of: &bytes) { [count = Int(length)] (rawBuffer) throws(E) -> Result in
146+
try apply(UnsafeMutableRawBufferPointer(start: rawBuffer.baseAddress, count: count))
148147
}
149148
}
150-
149+
150+
@abi(mutating func withUnsafeMutableBytes<R>(_: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R)
151+
@_spi(FoundationLegacyABI)
152+
@usableFromInline
153+
internal mutating func _legacy_withUnsafeMutableBytes<ResultType>(_ body: (UnsafeMutableRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
154+
try withUnsafeMutableBytes(body)
155+
}
156+
151157
@inlinable // This is @inlinable as trivially computable.
152158
mutating func append(byte: UInt8) {
153159
let count = self.count

Sources/FoundationEssentials/Data/Representations/Data+InlineSlice.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,19 @@ extension Data {
169169
try withUnsafeBytes(body)
170170
}
171171

172-
@inlinable // This is @inlinable as a generic, trivially forwarding function.
173-
mutating func withUnsafeMutableBytes<Result>(_ apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
172+
@_alwaysEmitIntoClient
173+
mutating func withUnsafeMutableBytes<E, Result: ~Copyable>(_ apply: (UnsafeMutableRawBufferPointer) throws(E) -> Result) throws(E) -> Result {
174174
ensureUniqueReference()
175175
return try storage.withUnsafeMutableBytes(in: range, apply: apply)
176176
}
177-
177+
178+
@abi(mutating func withUnsafeMutableBytes<R>(_: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R)
179+
@_spi(FoundationLegacyABI)
180+
@usableFromInline
181+
internal mutating func _legacy_withUnsafeMutableBytes<ResultType>(_ body: (UnsafeMutableRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
182+
try withUnsafeMutableBytes(body)
183+
}
184+
178185
@inlinable // This is @inlinable as reasonably small.
179186
mutating func append(contentsOf buffer: UnsafeRawBufferPointer) {
180187
assert(endIndex + buffer.count < HalfInt.max)

Sources/FoundationEssentials/Data/Representations/Data+LargeSlice.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,19 @@ extension Data {
157157
try withUnsafeBytes(body)
158158
}
159159

160-
@inlinable // This is @inlinable as a generic, trivially forwarding function.
161-
mutating func withUnsafeMutableBytes<Result>(_ apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
160+
@_alwaysEmitIntoClient
161+
mutating func withUnsafeMutableBytes<E, Result: ~Copyable>(_ apply: (UnsafeMutableRawBufferPointer) throws(E) -> Result) throws(E) -> Result {
162162
ensureUniqueReference()
163163
return try storage.withUnsafeMutableBytes(in: range, apply: apply)
164164
}
165-
165+
166+
@abi(mutating func withUnsafeMutableBytes<R>(_: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R)
167+
@_spi(FoundationLegacyABI)
168+
@usableFromInline
169+
internal mutating func _legacy_withUnsafeMutableBytes<ResultType>(_ body: (UnsafeMutableRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
170+
try withUnsafeMutableBytes(body)
171+
}
172+
166173
@inlinable // This is @inlinable as reasonably small.
167174
mutating func append(contentsOf buffer: UnsafeRawBufferPointer) {
168175
ensureUniqueReference()

Sources/FoundationEssentials/Data/Representations/Data+Representation.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,8 @@ extension Data {
235235
try withUnsafeBytes(body)
236236
}
237237

238-
@inlinable // This is @inlinable as a generic, trivially forwarding function.
239-
mutating func withUnsafeMutableBytes<Result>(_ apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
238+
@_alwaysEmitIntoClient
239+
mutating func withUnsafeMutableBytes<E, Result: ~Copyable>(_ apply: (UnsafeMutableRawBufferPointer) throws(E) -> Result) throws(E) -> Result {
240240
switch self {
241241
case .empty:
242242
var empty = InlineData()
@@ -254,7 +254,14 @@ extension Data {
254254
return try slice.withUnsafeMutableBytes(apply)
255255
}
256256
}
257-
257+
258+
@abi(mutating func withUnsafeMutableBytes<R>(_: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R)
259+
@_spi(FoundationLegacyABI)
260+
@usableFromInline
261+
internal mutating func _legacy_withUnsafeMutableBytes<ResultType>(_ body: (UnsafeMutableRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
262+
try withUnsafeMutableBytes(body)
263+
}
264+
258265
@usableFromInline // This is not @inlinable as it is a non-trivial, non-generic function.
259266
func enumerateBytes(_ block: (_ buffer: UnsafeBufferPointer<UInt8>, _ byteIndex: Index, _ stop: inout Bool) -> Void) {
260267
switch self {

Sources/FoundationEssentials/Data/Representations/DataStorage.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,18 @@ internal final class __DataStorage : @unchecked Sendable {
109109
try withUnsafeBytes(in: range, apply: apply)
110110
}
111111

112-
@inlinable // This is @inlinable despite escaping the _DataStorage boundary layer because it is generic and trivially forwarding.
113-
@discardableResult
114-
func withUnsafeMutableBytes<Result>(in range: Range<Int>, apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
115-
return try apply(UnsafeMutableRawBufferPointer(start: _bytes!.advanced(by:range.lowerBound - _offset), count: Swift.min(range.upperBound - range.lowerBound, _length)))
112+
@_alwaysEmitIntoClient
113+
func withUnsafeMutableBytes<E, Result: ~Copyable>(in range: Range<Int>, apply: (UnsafeMutableRawBufferPointer) throws(E) -> Result) throws(E) -> Result {
114+
try apply(UnsafeMutableRawBufferPointer(start: _bytes!.advanced(by:range.lowerBound - _offset), count: Swift.min(range.upperBound - range.lowerBound, _length)))
116115
}
117116

117+
@abi(func withUnsafeMutableBytes<R>(in: Range<Int>, apply: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R)
118+
@_spi(FoundationLegacyABI)
119+
@usableFromInline
120+
internal func _legacy_withUnsafeMutableBytes<ResultType>(in range: Range<Int>, apply: (UnsafeMutableRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
121+
try withUnsafeMutableBytes(in: range, apply: apply)
122+
}
123+
118124
@inlinable // This is @inlinable as trivially computable.
119125
var mutableBytes: UnsafeMutableRawPointer? {
120126
return _bytes?.advanced(by: _offset &* -1) // _offset is guaranteed to be non-negative, so it can never overflow when negating

0 commit comments

Comments
 (0)