Skip to content

Commit 74c32fc

Browse files
committed
Generalize Data’s withUnsafeBytes() functions
1 parent 00563e2 commit 74c32fc

File tree

6 files changed

+61
-21
lines changed

6 files changed

+61
-21
lines changed

Sources/FoundationEssentials/Data/Data.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,9 +345,16 @@ public struct Data : RandomAccessCollection, MutableCollection, RangeReplaceable
345345
}
346346
}
347347

348-
@inlinable // This is @inlinable as a generic, trivially forwarding function.
349-
public func withUnsafeBytes<ResultType>(_ body: (UnsafeRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
350-
return try _representation.withUnsafeBytes(body)
348+
@_alwaysEmitIntoClient
349+
public func withUnsafeBytes<E, ResultType: ~Copyable>(_ body: (UnsafeRawBufferPointer) throws(E) -> ResultType) throws(E) -> ResultType {
350+
try _representation.withUnsafeBytes(body)
351+
}
352+
353+
@abi(func withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R)
354+
@_spi(FoundationLegacyABI)
355+
@usableFromInline
356+
internal func _legacy_withUnsafeBytes<ResultType>(_ body: (UnsafeRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
357+
try withUnsafeBytes(body)
351358
}
352359

353360
@available(macOS 10.14.4, iOS 12.2, watchOS 5.2, tvOS 12.2, *)

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,20 @@ extension Data {
126126
return count
127127
}
128128

129-
@inlinable // This is @inlinable as a generic, trivially forwarding function.
130-
func withUnsafeBytes<Result>(_ apply: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result {
131-
let count = Int(length)
132-
return try Swift.withUnsafeBytes(of: bytes) { (rawBuffer) throws -> Result in
133-
return try apply(UnsafeRawBufferPointer(start: rawBuffer.baseAddress, count: count))
129+
@_alwaysEmitIntoClient
130+
func withUnsafeBytes<E, Result: ~Copyable>(_ apply: (UnsafeRawBufferPointer) throws(E) -> Result) throws(E) -> Result {
131+
try Swift.withUnsafeBytes(of: bytes) { [count = Int(length)] (rawBuffer) throws(E) -> Result in
132+
try apply(UnsafeRawBufferPointer(start: rawBuffer.baseAddress, count: count))
134133
}
135134
}
136135

136+
@abi(func withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R)
137+
@_spi(FoundationLegacyABI)
138+
@usableFromInline
139+
internal func _legacy_withUnsafeBytes<ResultType>(_ body: (UnsafeRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
140+
try withUnsafeBytes(body)
141+
}
142+
137143
@inlinable // This is @inlinable as a generic, trivially forwarding function.
138144
mutating func withUnsafeMutableBytes<Result>(_ apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
139145
let count = Int(length)

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,18 @@ extension Data {
157157
}
158158
}
159159

160-
@inlinable // This is @inlinable as a generic, trivially forwarding function.
161-
func withUnsafeBytes<Result>(_ apply: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result {
162-
return try storage.withUnsafeBytes(in: range, apply: apply)
160+
@_alwaysEmitIntoClient
161+
func withUnsafeBytes<E, Result: ~Copyable>(_ apply: (UnsafeRawBufferPointer) throws(E) -> Result) throws(E) -> Result {
162+
try storage.withUnsafeBytes(in: range, apply: apply)
163163
}
164164

165+
@abi(func withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R)
166+
@_spi(FoundationLegacyABI)
167+
@usableFromInline
168+
internal func _legacy_withUnsafeBytes<ResultType>(_ body: (UnsafeRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
169+
try withUnsafeBytes(body)
170+
}
171+
165172
@inlinable // This is @inlinable as a generic, trivially forwarding function.
166173
mutating func withUnsafeMutableBytes<Result>(_ apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
167174
ensureUniqueReference()

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,18 @@ extension Data {
145145
return slice.range
146146
}
147147

148-
@inlinable // This is @inlinable as a generic, trivially forwarding function.
149-
func withUnsafeBytes<Result>(_ apply: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result {
150-
return try storage.withUnsafeBytes(in: range, apply: apply)
148+
@_alwaysEmitIntoClient
149+
func withUnsafeBytes<E, Result: ~Copyable>(_ apply: (UnsafeRawBufferPointer) throws(E) -> Result) throws(E) -> Result {
150+
try storage.withUnsafeBytes(in: range, apply: apply)
151151
}
152152

153+
@abi(func withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R)
154+
@_spi(FoundationLegacyABI)
155+
@usableFromInline
156+
internal func _legacy_withUnsafeBytes<ResultType>(_ body: (UnsafeRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
157+
try withUnsafeBytes(body)
158+
}
159+
153160
@inlinable // This is @inlinable as a generic, trivially forwarding function.
154161
mutating func withUnsafeMutableBytes<Result>(_ apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
155162
ensureUniqueReference()

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,8 @@ extension Data {
213213
}
214214
}
215215

216-
@inlinable // This is @inlinable as a generic, trivially forwarding function.
217-
func withUnsafeBytes<Result>(_ apply: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result {
216+
@_alwaysEmitIntoClient
217+
func withUnsafeBytes<E, Result: ~Copyable>(_ apply: (UnsafeRawBufferPointer) throws(E) -> Result) throws(E) -> Result {
218218
switch self {
219219
case .empty:
220220
let empty = InlineData()
@@ -227,7 +227,14 @@ extension Data {
227227
return try slice.withUnsafeBytes(apply)
228228
}
229229
}
230-
230+
231+
@abi(func withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R)
232+
@_spi(FoundationLegacyABI)
233+
@usableFromInline
234+
internal func _legacy_withUnsafeBytes<ResultType>(_ body: (UnsafeRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
235+
try withUnsafeBytes(body)
236+
}
237+
231238
@inlinable // This is @inlinable as a generic, trivially forwarding function.
232239
mutating func withUnsafeMutableBytes<Result>(_ apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
233240
switch self {

Sources/FoundationEssentials/Data/Representations/DataStorage.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,18 @@ internal final class __DataStorage : @unchecked Sendable {
9797
return UnsafeRawPointer(_bytes)?.advanced(by: -_offset)
9898
}
9999

100-
@inlinable // This is @inlinable despite escaping the _DataStorage boundary layer because it is generic and trivially forwarding.
101-
@discardableResult
102-
func withUnsafeBytes<Result>(in range: Range<Int>, apply: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result {
103-
return try apply(UnsafeRawBufferPointer(start: _bytes?.advanced(by: range.lowerBound - _offset), count: Swift.min(range.upperBound - range.lowerBound, _length)))
100+
@_alwaysEmitIntoClient
101+
func withUnsafeBytes<E, Result: ~Copyable>(in range: Range<Int>, apply: (UnsafeRawBufferPointer) throws(E) -> Result) throws(E) -> Result {
102+
try apply(UnsafeRawBufferPointer(start: _bytes?.advanced(by: range.lowerBound - _offset), count: Swift.min(range.upperBound - range.lowerBound, _length)))
104103
}
105104

105+
@abi(func withUnsafeBytes<R>(in: Range<Int>, apply: (UnsafeRawBufferPointer) throws -> R) rethrows -> R)
106+
@_spi(FoundationLegacyABI)
107+
@usableFromInline
108+
func _legacy_withUnsafeBytes<Result>(in range: Range<Int>, apply: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result {
109+
try withUnsafeBytes(in: range, apply: apply)
110+
}
111+
106112
@inlinable // This is @inlinable despite escaping the _DataStorage boundary layer because it is generic and trivially forwarding.
107113
@discardableResult
108114
func withUnsafeMutableBytes<Result>(in range: Range<Int>, apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {

0 commit comments

Comments
 (0)