@@ -319,6 +319,64 @@ public struct UnsafeRawPointer: _Pointer {
319
319
return UnsafePointer < T > ( _rawValue)
320
320
}
321
321
322
+ /// Executes the given closure while temporarily binding memory to
323
+ /// the specified number of instances of type `T`.
324
+ ///
325
+ /// Use this method when you have a pointer to raw memory and you need
326
+ /// to access that memory as instances of a given type `T`. Accessing
327
+ /// memory as a type `T` requires that the memory be bound to that type. A
328
+ /// memory location may only be bound to one type at a time, so accessing
329
+ /// the same memory as an unrelated type without first rebinding the memory
330
+ /// is undefined.
331
+ ///
332
+ /// Any instance of `T` within the re-bound region may be initialized or
333
+ /// uninitialized. If a given instance of `T` within the re-bound region
334
+ /// overlaps with previously uninitialized memory, it shall be considered
335
+ /// uninitialized when executing `body`.
336
+ ///
337
+ /// The following example temporarily rebinds a raw memory pointer
338
+ /// to `Int64`, then accesses a property on the signed integer.
339
+ ///
340
+ /// let pointer: UnsafeRawPointer = fetchValue()
341
+ /// let isNegative = pointer.withMemoryRebound(to: Int64.self,
342
+ /// capacity: 1) {
343
+ /// return $0.pointee < 0
344
+ /// }
345
+ ///
346
+ /// After executing `body`, this method rebinds memory back to its original
347
+ /// binding state. This can be unbound memory, or bound to a different type.
348
+ ///
349
+ /// - Note: The region of memory starting at this pointer must match the
350
+ /// alignment of `T` (as reported by `MemoryLayout<T>.alignment`).
351
+ /// That is, `Int(bitPattern: self) % MemoryLayout<T>.alignment`
352
+ /// must equal zero.
353
+ ///
354
+ /// - Parameters:
355
+ /// - type: The type to temporarily bind the memory referenced by this
356
+ /// pointer. This pointer must be a multiple of this type's alignment.
357
+ /// - count: The number of instances of `T` in the re-bound region.
358
+ /// - body: A closure that takes a typed pointer to the
359
+ /// same memory as this pointer, only bound to type `T`. The closure's
360
+ /// pointer argument is valid only for the duration of the closure's
361
+ /// execution. If `body` has a return value, that value is also used as
362
+ /// the return value for the `withMemoryRebound(to:capacity:_:)` method.
363
+ /// - pointer: The pointer temporarily bound to `T`.
364
+ /// - Returns: The return value, if any, of the `body` closure parameter.
365
+ @inlinable
366
+ @_alwaysEmitIntoClient
367
+ public func withMemoryRebound< T, Result> (
368
+ to type: T . Type ,
369
+ capacity count: Int ,
370
+ _ body: ( _ pointer: UnsafePointer < T > ) throws -> Result
371
+ ) rethrows -> Result {
372
+ _debugPrecondition (
373
+ Int ( bitPattern: self ) & ( MemoryLayout < T > . alignment- 1 ) == 0
374
+ )
375
+ let binding = Builtin . bindMemory ( _rawValue, count. _builtinWordValue, T . self)
376
+ defer { Builtin . rebindMemory ( _rawValue, binding) }
377
+ return try body ( . init( _rawValue) )
378
+ }
379
+
322
380
/// Returns a typed pointer to the memory referenced by this pointer,
323
381
/// assuming that the memory is already bound to the specified type.
324
382
///
@@ -694,6 +752,63 @@ public struct UnsafeMutableRawPointer: _Pointer {
694
752
return UnsafeMutablePointer < T > ( _rawValue)
695
753
}
696
754
755
+ /// Executes the given closure while temporarily binding memory to
756
+ /// the specified number of instances of type `T`.
757
+ ///
758
+ /// Use this method when you have a pointer to raw memory and you need
759
+ /// to access that memory as instances of a given type `T`. Accessing
760
+ /// memory as a type `T` requires that the memory be bound to that type. A
761
+ /// memory location may only be bound to one type at a time, so accessing
762
+ /// the same memory as an unrelated type without first rebinding the memory
763
+ /// is undefined.
764
+ ///
765
+ /// Any instance of `T` within the re-bound region may be initialized or
766
+ /// uninitialized. If a given instance of `T` within the re-bound region
767
+ /// overlaps with previously uninitialized memory, it shall be considered
768
+ /// uninitialized when executing `body`.
769
+ ///
770
+ /// The following example temporarily rebinds a raw memory pointer
771
+ /// to `Int64`, then modifies the signed integer.
772
+ ///
773
+ /// let pointer: UnsafeMutableRawPointer = fetchValue()
774
+ /// pointer.withMemoryRebound(to: Int64.self, capacity: 1) {
775
+ /// ptr.pointee.negate()
776
+ /// }
777
+ ///
778
+ /// After executing `body`, this method rebinds memory back to its original
779
+ /// binding state. This can be unbound memory, or bound to a different type.
780
+ ///
781
+ /// - Note: The region of memory starting at this pointer must match the
782
+ /// alignment of `T` (as reported by `MemoryLayout<T>.alignment`).
783
+ /// That is, `Int(bitPattern: self) % MemoryLayout<T>.alignment`
784
+ /// must equal zero.
785
+ ///
786
+ /// - Parameters:
787
+ /// - type: The type to temporarily bind the memory referenced by this
788
+ /// pointer. This pointer must be a multiple of this type's alignment.
789
+ /// - count: The number of instances of `T` in the re-bound region.
790
+ /// - body: A closure that takes a typed pointer to the
791
+ /// same memory as this pointer, only bound to type `T`. The closure's
792
+ /// pointer argument is valid only for the duration of the closure's
793
+ /// execution. If `body` has a return value, that value is also used as
794
+ /// the return value for the `withMemoryRebound(to:capacity:_:)` method.
795
+ /// - pointer: The pointer temporarily bound to `T`.
796
+ /// - Returns: The return value, if any, of the `body` closure parameter.
797
+ @inlinable
798
+ @_alwaysEmitIntoClient
799
+ public func withMemoryRebound< T, Result> (
800
+ to type: T . Type ,
801
+ capacity count: Int ,
802
+ _ body: ( _ pointer: UnsafeMutablePointer < T > ) throws -> Result
803
+ ) rethrows -> Result {
804
+ _debugPrecondition (
805
+ Int ( bitPattern: self ) & ( MemoryLayout < T > . alignment- 1 ) == 0
806
+ )
807
+ let binding = Builtin . bindMemory ( _rawValue, count. _builtinWordValue, T . self)
808
+ defer { Builtin . rebindMemory ( _rawValue, binding) }
809
+ return try body ( . init( _rawValue) )
810
+ }
811
+
697
812
/// Returns a typed pointer to the memory referenced by this pointer,
698
813
/// assuming that the memory is already bound to the specified type.
699
814
///
0 commit comments