@@ -729,6 +729,61 @@ extension Unsafe${Mutable}RawBufferPointer {
729
729
return Unsafe${ Mutable} BufferPointer< T> (
730
730
start: Unsafe ${ Mutable} Pointer< T> ( base. _rawValue) , count: capacity)
731
731
}
732
+
733
+ /// Executes the given closure while temporarily binding the buffer to
734
+ /// instances of type `T`.
735
+ ///
736
+ /// Use this method when you have a buffer to raw memory and you need
737
+ /// to access that memory as instances of a given type `T`. Accessing
738
+ /// memory as a type `T` requires that the memory be bound to that type.
739
+ /// A memory location may only be bound to one type at a time, so accessing
740
+ /// the same memory as an unrelated type without first rebinding the memory
741
+ /// is undefined.
742
+ ///
743
+ /// Any instance of `T` within the re-bound region may be initialized or
744
+ /// uninitialized. If a given instance of `T` within the re-bound region
745
+ /// overlaps with previously uninitialized memory, it shall be considered
746
+ /// uninitialized when executing `body`.
747
+ ///
748
+ /// After executing `body`, this method rebinds memory back to its original
749
+ /// binding state. This can be unbound memory, or bound to a different type.
750
+ ///
751
+ /// - Note: The buffer's base address must match the
752
+ /// alignment of `T` (as reported by `MemoryLayout<T>.alignment`).
753
+ /// That is, `Int(bitPattern: self.baseAddress) % MemoryLayout<T>.alignment`
754
+ /// must equal zero.
755
+ ///
756
+ /// - Parameters:
757
+ /// - type: The type to temporarily bind the memory referenced by this
758
+ /// pointer. This pointer must be a multiple of this type's alignment.
759
+ /// - count: The number of instances of `T` to bind to `type`.
760
+ /// - body: A closure that takes a typed pointer to the
761
+ /// same memory as this pointer, only bound to type `T`. The closure's
762
+ /// pointer argument is valid only for the duration of the closure's
763
+ /// execution. If `body` has a return value, that value is also used as
764
+ /// the return value for the `withMemoryRebound(to:capacity:_:)` method.
765
+ /// - buffer: The buffer temporarily bound to instances of `T`.
766
+ /// - Returns: The return value, if any, of the `body` closure parameter.
767
+ @inlinable
768
+ @_alwaysEmitIntoClient
769
+ public func withMemoryRebound< T, Result> (
770
+ to type: T . Type ,
771
+ _ body: ( _ buffer: Unsafe ${ Mutable} BufferPointer< T > ) throws -> Result
772
+ ) rethrows -> Result {
773
+ guard let s = _position else {
774
+ return try body ( . init( start: nil , count: 0 ) )
775
+ }
776
+ _debugPrecondition (
777
+ Int ( bitPattern: s) & ( MemoryLayout < T > . alignment- 1 ) == 0
778
+ )
779
+ // initializer ensures _end is nil only when _position is nil.
780
+ _internalInvariant ( _end != nil )
781
+ let c = _assumeNonNegative ( s. distance ( to: _end. _unsafelyUnwrappedUnchecked) )
782
+ let n = c / MemoryLayout< T> . stride
783
+ let binding = Builtin . bindMemory ( s. _rawValue, n. _builtinWordValue, T . self)
784
+ defer { Builtin . rebindMemory ( s. _rawValue, binding) }
785
+ return try body ( . init( start: . init( s. _rawValue) , count: n) )
786
+ }
732
787
}
733
788
734
789
extension Unsafe ${ Mutable} RawBufferPointer: CustomDebugStringConvertible {
0 commit comments