|
49 | 49 | #endif
|
50 | 50 |
|
51 | 51 | internal import _FoundationCShims
|
| 52 | +import Builtin |
52 | 53 |
|
53 | 54 | #if canImport(Darwin)
|
54 | 55 | import Darwin
|
@@ -604,6 +605,7 @@ internal final class __DataStorage : @unchecked Sendable {
|
604 | 605 |
|
605 | 606 | @frozen
|
606 | 607 | @available(macOS 10.10, iOS 8.0, watchOS 2.0, tvOS 9.0, *)
|
| 608 | +@_addressableForDependencies |
607 | 609 | public struct Data : Equatable, Hashable, RandomAccessCollection, MutableCollection, RangeReplaceableCollection, MutableDataProtocol, ContiguousBytes, Sendable {
|
608 | 610 |
|
609 | 611 | public typealias Index = Int
|
@@ -2198,7 +2200,105 @@ public struct Data : Equatable, Hashable, RandomAccessCollection, MutableCollect
|
2198 | 2200 | public func withUnsafeBytes<ResultType>(_ body: (UnsafeRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
|
2199 | 2201 | return try _representation.withUnsafeBytes(body)
|
2200 | 2202 | }
|
2201 |
| - |
| 2203 | + |
| 2204 | +#if compiler(>=6.2) |
| 2205 | + @available(FoundationSpan 6.2, *) |
| 2206 | + public var bytes: RawSpan { |
| 2207 | + @lifetime(borrow self) |
| 2208 | + borrowing get { |
| 2209 | + let buffer: UnsafeRawBufferPointer |
| 2210 | + switch _representation { |
| 2211 | + case .empty: |
| 2212 | + buffer = UnsafeRawBufferPointer(_empty: ()) |
| 2213 | + case .inline: |
| 2214 | + buffer = unsafe UnsafeRawBufferPointer( |
| 2215 | + start: UnsafeRawPointer(Builtin.addressOfBorrow(self)), |
| 2216 | + count: _representation.count |
| 2217 | + ) |
| 2218 | + case .large(let slice): |
| 2219 | + buffer = unsafe UnsafeRawBufferPointer( |
| 2220 | + start: slice.storage.mutableBytes?.advanced(by: slice.startIndex), count: slice.count |
| 2221 | + ) |
| 2222 | + case .slice(let slice): |
| 2223 | + buffer = unsafe UnsafeRawBufferPointer( |
| 2224 | + start: slice.storage.mutableBytes?.advanced(by: slice.startIndex), count: slice.count |
| 2225 | + ) |
| 2226 | + } |
| 2227 | + let span = unsafe RawSpan(_unsafeBytes: buffer) |
| 2228 | + return unsafe _overrideLifetime(span, borrowing: self) |
| 2229 | + } |
| 2230 | + } |
| 2231 | + |
| 2232 | + @available(FoundationSpan 6.2, *) |
| 2233 | + public var span: Span<UInt8> { |
| 2234 | + @lifetime(borrow self) |
| 2235 | + borrowing get { |
| 2236 | + let span = unsafe bytes._unsafeView(as: UInt8.self) |
| 2237 | + return _overrideLifetime(span, borrowing: self) |
| 2238 | + } |
| 2239 | + } |
| 2240 | + |
| 2241 | + @available(FoundationSpan 6.2, *) |
| 2242 | + public var mutableBytes: MutableRawSpan { |
| 2243 | + @lifetime(&self) |
| 2244 | + mutating get { |
| 2245 | + let buffer: UnsafeMutableRawBufferPointer |
| 2246 | + switch _representation { |
| 2247 | + case .empty: |
| 2248 | + buffer = UnsafeMutableRawBufferPointer(_empty: ()) |
| 2249 | + case .inline: |
| 2250 | + buffer = unsafe UnsafeMutableRawBufferPointer( |
| 2251 | + start: UnsafeMutableRawPointer(Builtin.addressOfBorrow(self)), |
| 2252 | + count: _representation.count |
| 2253 | + ) |
| 2254 | + case .large(let slice): |
| 2255 | + buffer = unsafe UnsafeMutableRawBufferPointer( |
| 2256 | + start: slice.storage.mutableBytes?.advanced(by: slice.startIndex), count: slice.count |
| 2257 | + ) |
| 2258 | + case .slice(let slice): |
| 2259 | + buffer = unsafe UnsafeMutableRawBufferPointer( |
| 2260 | + start: slice.storage.mutableBytes?.advanced(by: slice.startIndex), count: slice.count |
| 2261 | + ) |
| 2262 | + } |
| 2263 | + let span = unsafe MutableRawSpan(_unsafeBytes: buffer) |
| 2264 | + return unsafe _overrideLifetime(span, mutating: &self) |
| 2265 | + } |
| 2266 | + } |
| 2267 | + |
| 2268 | + @available(FoundationSpan 6.2, *) |
| 2269 | + public var mutableSpan: MutableSpan<UInt8> { |
| 2270 | + @lifetime(&self) |
| 2271 | + mutating get { |
| 2272 | +#if false |
| 2273 | + var bytes = mutableBytes |
| 2274 | + let span = unsafe bytes._unsafeMutableView(as: UInt8.self) |
| 2275 | + return _overrideLifetime(span, mutating: &self) |
| 2276 | +#else |
| 2277 | + let buffer: UnsafeMutableRawBufferPointer |
| 2278 | + switch _representation { |
| 2279 | + case .empty: |
| 2280 | + buffer = UnsafeMutableRawBufferPointer(_empty: ()) |
| 2281 | + case .inline: |
| 2282 | + buffer = unsafe UnsafeMutableRawBufferPointer( |
| 2283 | + start: UnsafeMutableRawPointer(Builtin.addressOfBorrow(self)), |
| 2284 | + count: _representation.count |
| 2285 | + ) |
| 2286 | + case .large(let slice): |
| 2287 | + buffer = unsafe UnsafeMutableRawBufferPointer( |
| 2288 | + start: slice.storage.mutableBytes?.advanced(by: slice.startIndex), count: slice.count |
| 2289 | + ) |
| 2290 | + case .slice(let slice): |
| 2291 | + buffer = unsafe UnsafeMutableRawBufferPointer( |
| 2292 | + start: slice.storage.mutableBytes?.advanced(by: slice.startIndex), count: slice.count |
| 2293 | + ) |
| 2294 | + } |
| 2295 | + let span = unsafe MutableSpan<UInt8>(_unsafeBytes: buffer) |
| 2296 | + return unsafe _overrideLifetime(span, mutating: &self) |
| 2297 | +#endif |
| 2298 | + } |
| 2299 | + } |
| 2300 | +#endif |
| 2301 | + |
2202 | 2302 | @_alwaysEmitIntoClient
|
2203 | 2303 | public func withContiguousStorageIfAvailable<ResultType>(_ body: (_ buffer: UnsafeBufferPointer<UInt8>) throws -> ResultType) rethrows -> ResultType? {
|
2204 | 2304 | return try _representation.withUnsafeBytes {
|
@@ -2870,3 +2970,62 @@ extension Data : Codable {
|
2870 | 2970 | }
|
2871 | 2971 | }
|
2872 | 2972 | }
|
| 2973 | + |
| 2974 | +#if compiler(>=6.2) |
| 2975 | +// TODO: remove once _overrideLifetime is public in the standard library |
| 2976 | + |
| 2977 | +/// Unsafely discard any lifetime dependency on the `dependent` argument. Return |
| 2978 | +/// a value identical to `dependent` with a lifetime dependency on the caller's |
| 2979 | +/// borrow scope of the `source` argument. |
| 2980 | +@unsafe |
| 2981 | +@_unsafeNonescapableResult |
| 2982 | +@_alwaysEmitIntoClient |
| 2983 | +@_transparent |
| 2984 | +@lifetime(borrow source) |
| 2985 | +internal func _overrideLifetime< |
| 2986 | + T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable |
| 2987 | +>( |
| 2988 | + _ dependent: consuming T, borrowing source: borrowing U |
| 2989 | +) -> T { |
| 2990 | + // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence |
| 2991 | + // should be expressed by a builtin that is hidden within the function body. |
| 2992 | + dependent |
| 2993 | +} |
| 2994 | + |
| 2995 | +/// Unsafely discard any lifetime dependency on the `dependent` argument. Return |
| 2996 | +/// a value identical to `dependent` that inherits all lifetime dependencies from |
| 2997 | +/// the `source` argument. |
| 2998 | +@unsafe |
| 2999 | +@_unsafeNonescapableResult |
| 3000 | +@_alwaysEmitIntoClient |
| 3001 | +@_transparent |
| 3002 | +@lifetime(copy source) |
| 3003 | +internal func _overrideLifetime< |
| 3004 | + T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable |
| 3005 | +>( |
| 3006 | + _ dependent: consuming T, copying source: borrowing U |
| 3007 | +) -> T { |
| 3008 | + // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence |
| 3009 | + // should be expressed by a builtin that is hidden within the function body. |
| 3010 | + dependent |
| 3011 | +} |
| 3012 | + |
| 3013 | +/// Unsafely discard any lifetime dependency on the `dependent` argument. |
| 3014 | +/// Return a value identical to `dependent` with a lifetime dependency |
| 3015 | +/// on the caller's exclusive borrow scope of the `source` argument. |
| 3016 | +@unsafe |
| 3017 | +@_unsafeNonescapableResult |
| 3018 | +@_alwaysEmitIntoClient |
| 3019 | +@_transparent |
| 3020 | +@lifetime(&source) |
| 3021 | +internal func _overrideLifetime< |
| 3022 | + T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable |
| 3023 | +>( |
| 3024 | + _ dependent: consuming T, |
| 3025 | + mutating source: inout U |
| 3026 | +) -> T { |
| 3027 | + // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence |
| 3028 | + // should be expressed by a builtin that is hidden within the function body. |
| 3029 | + dependent |
| 3030 | +} |
| 3031 | +#endif |
0 commit comments