@@ -243,8 +243,8 @@ public struct UnsafePointer<Pointee>: _Pointer {
243
243
}
244
244
}
245
245
246
- /// Executes the given closure while temporarily binding the specified number
247
- /// of instances to the given type.
246
+ /// Executes the given closure while temporarily binding memory to
247
+ /// the specified number of instances of type `T` .
248
248
///
249
249
/// Use this method when you have a pointer to memory bound to one type and
250
250
/// you need to access that memory as instances of another type. Accessing
@@ -253,15 +253,20 @@ public struct UnsafePointer<Pointee>: _Pointer {
253
253
/// the same memory as an unrelated type without first rebinding the memory
254
254
/// is undefined.
255
255
///
256
- /// The region of memory starting at this pointer and covering `count`
257
- /// instances of the pointer's `Pointee` type must be initialized.
256
+ /// The region of memory that starts at this pointer and covers `count`
257
+ /// strides of `T` instances must be bound to `Pointee`.
258
+ /// Any instance of `T` within the re-bound region may be initialized or
259
+ /// uninitialized. If a given instance of `T` overlaps with memory previously
260
+ /// bound to an uninitialized `Pointee`, it shall be considered uninitialized
261
+ /// when executing `body`.
258
262
///
259
263
/// The following example temporarily rebinds the memory of a `UInt64`
260
264
/// pointer to `Int64`, then accesses a property on the signed integer.
261
265
///
262
266
/// let uint64Pointer: UnsafePointer<UInt64> = fetchValue()
263
- /// let isNegative = uint64Pointer.withMemoryRebound(to: Int64.self, capacity: 1) { ptr in
264
- /// return ptr.pointee < 0
267
+ /// let isNegative = uint64Pointer.withMemoryRebound(to: Int64.self,
268
+ /// capacity: 1) {
269
+ /// return $0.pointee < 0
265
270
/// }
266
271
///
267
272
/// Because this pointer's memory is no longer bound to its `Pointee` type
@@ -274,31 +279,43 @@ public struct UnsafePointer<Pointee>: _Pointer {
274
279
/// `Pointee` type.
275
280
///
276
281
/// - Note: Only use this method to rebind the pointer's memory to a type
277
- /// with the same size and stride as the currently bound `Pointee` type.
278
- /// To bind a region of memory to a type that is a different size, convert
279
- /// the pointer to a raw pointer and use the `bindMemory(to:capacity:)`
280
- /// method.
282
+ /// that is layout compatible with the `Pointee` type. The stride of the
283
+ /// temporary type (`T`) may be an integer multiple or a whole fraction
284
+ /// of `Pointee`'s stride, for example to point to one element of
285
+ /// an aggregate.
286
+ /// To bind a region of memory to a type that does not match these
287
+ /// requirements, convert the pointer to a raw pointer and use the
288
+ /// `bindMemory(to:)` method.
289
+ /// If `T` and `Pointee` have different alignments, this pointer
290
+ /// must be aligned with the larger of the two alignments.
281
291
///
282
292
/// - Parameters:
283
293
/// - type: The type to temporarily bind the memory referenced by this
284
- /// pointer. The type `T` must be the same size and be layout compatible
294
+ /// pointer. The type `T` must be layout compatible
285
295
/// with the pointer's `Pointee` type.
286
- /// - count: The number of instances of `Pointee` to bind to `type` .
287
- /// - body: A closure that takes a typed pointer to the
296
+ /// - count: The number of instances of `T` in the re-bound region .
297
+ /// - body: A closure that takes a typed pointer to the
288
298
/// same memory as this pointer, only bound to type `T`. The closure's
289
299
/// pointer argument is valid only for the duration of the closure's
290
300
/// execution. If `body` has a return value, that value is also used as
291
301
/// the return value for the `withMemoryRebound(to:capacity:_:)` method.
302
+ /// - pointer: The pointer temporarily bound to `T`.
292
303
/// - Returns: The return value, if any, of the `body` closure parameter.
293
304
@inlinable
294
- public func withMemoryRebound< T, Result> ( to type: T . Type , capacity count: Int ,
295
- _ body: ( UnsafePointer < T > ) throws -> Result
305
+ @_alwaysEmitIntoClient
306
+ public func withMemoryRebound< T, Result> (
307
+ to type: T . Type , capacity count: Int ,
308
+ _ body: ( _ pointer: UnsafePointer < T > ) throws -> Result
296
309
) rethrows -> Result {
297
- Builtin . bindMemory ( _rawValue, count. _builtinWordValue, T . self)
298
- defer {
299
- Builtin . bindMemory ( _rawValue, count. _builtinWordValue, Pointee . self)
300
- }
301
- return try body ( UnsafePointer < T > ( _rawValue) )
310
+ _debugPrecondition (
311
+ Int ( bitPattern: . init( _rawValue) ) & ( MemoryLayout < T > . alignment- 1 ) == 0 &&
312
+ MemoryLayout < Pointee > . stride > MemoryLayout< T> . stride
313
+ ? MemoryLayout< Pointee> . stride % MemoryLayout < T > . stride == 0
314
+ : MemoryLayout < T > . stride % MemoryLayout < Pointee > . stride == 0
315
+ )
316
+ let binding = Builtin . bindMemory ( _rawValue, count. _builtinWordValue, T . self)
317
+ defer { Builtin . rebindMemory ( _rawValue, binding) }
318
+ return try body ( . init( _rawValue) )
302
319
}
303
320
304
321
/// Accesses the pointee at the specified offset from this pointer.
@@ -894,8 +911,8 @@ public struct UnsafeMutablePointer<Pointee>: _Pointer {
894
911
return UnsafeMutableRawPointer ( self )
895
912
}
896
913
897
- /// Executes the given closure while temporarily binding the specified number
898
- /// of instances to the given type.
914
+ /// Executes the given closure while temporarily binding memory to
915
+ /// the specified number of instances of the given type.
899
916
///
900
917
/// Use this method when you have a pointer to memory bound to one type and
901
918
/// you need to access that memory as instances of another type. Accessing
@@ -904,15 +921,19 @@ public struct UnsafeMutablePointer<Pointee>: _Pointer {
904
921
/// the same memory as an unrelated type without first rebinding the memory
905
922
/// is undefined.
906
923
///
907
- /// The region of memory starting at this pointer and covering `count`
908
- /// instances of the pointer's `Pointee` type must be initialized.
924
+ /// The region of memory that starts at this pointer and covers `count`
925
+ /// strides of `T` instances must be bound to `Pointee`.
926
+ /// Any instance of `T` within the re-bound region may be initialized or
927
+ /// uninitialized. If a given instance of `T` overlaps with memory previously
928
+ /// bound to an uninitialized `Pointee`, it shall be considered uninitialized
929
+ /// when executing `body`.
909
930
///
910
931
/// The following example temporarily rebinds the memory of a `UInt64`
911
- /// pointer to `Int64`, then accesses a property on the signed integer.
932
+ /// pointer to `Int64`, then modifies the signed integer.
912
933
///
913
934
/// let uint64Pointer: UnsafeMutablePointer<UInt64> = fetchValue()
914
- /// let isNegative = uint64Pointer.withMemoryRebound(to: Int64.self, capacity: 1) { ptr in
915
- /// return ptr.pointee < 0
935
+ /// uint64Pointer.withMemoryRebound(to: Int64.self, capacity: 1) { ptr in
936
+ /// ptr.pointee.negate()
916
937
/// }
917
938
///
918
939
/// Because this pointer's memory is no longer bound to its `Pointee` type
@@ -925,31 +946,43 @@ public struct UnsafeMutablePointer<Pointee>: _Pointer {
925
946
/// `Pointee` type.
926
947
///
927
948
/// - Note: Only use this method to rebind the pointer's memory to a type
928
- /// with the same size and stride as the currently bound `Pointee` type.
929
- /// To bind a region of memory to a type that is a different size, convert
930
- /// the pointer to a raw pointer and use the `bindMemory(to:capacity:)`
931
- /// method.
949
+ /// that is layout compatible with the `Pointee` type. The stride of the
950
+ /// temporary type (`T`) may be an integer multiple or a whole fraction
951
+ /// of `Pointee`'s stride, for example to point to one element of
952
+ /// an aggregate.
953
+ /// To bind a region of memory to a type that does not match these
954
+ /// requirements, convert the pointer to a raw pointer and use the
955
+ /// `bindMemory(to:)` method.
956
+ /// If `T` and `Pointee` have different alignments, this pointer
957
+ /// must be aligned with the larger of the two alignments.
932
958
///
933
959
/// - Parameters:
934
960
/// - type: The type to temporarily bind the memory referenced by this
935
- /// pointer. The type `T` must be the same size and be layout compatible
961
+ /// pointer. The type `T` must be layout compatible
936
962
/// with the pointer's `Pointee` type.
937
- /// - count: The number of instances of `Pointee` to bind to `type` .
963
+ /// - count: The number of instances of `T` in the re-bound region .
938
964
/// - body: A closure that takes a mutable typed pointer to the
939
965
/// same memory as this pointer, only bound to type `T`. The closure's
940
966
/// pointer argument is valid only for the duration of the closure's
941
967
/// execution. If `body` has a return value, that value is also used as
942
968
/// the return value for the `withMemoryRebound(to:capacity:_:)` method.
969
+ /// - pointer: The pointer temporarily bound to `T`.
943
970
/// - Returns: The return value, if any, of the `body` closure parameter.
944
971
@inlinable
945
- public func withMemoryRebound< T, Result> ( to type: T . Type , capacity count: Int ,
946
- _ body: ( UnsafeMutablePointer < T > ) throws -> Result
972
+ @_alwaysEmitIntoClient
973
+ public func withMemoryRebound< T, Result> (
974
+ to type: T . Type , capacity count: Int ,
975
+ _ body: ( _ pointer: UnsafeMutablePointer < T > ) throws -> Result
947
976
) rethrows -> Result {
948
- Builtin . bindMemory ( _rawValue, count. _builtinWordValue, T . self)
949
- defer {
950
- Builtin . bindMemory ( _rawValue, count. _builtinWordValue, Pointee . self)
951
- }
952
- return try body ( UnsafeMutablePointer < T > ( _rawValue) )
977
+ _debugPrecondition (
978
+ Int ( bitPattern: . init( _rawValue) ) & ( MemoryLayout < T > . alignment- 1 ) == 0 &&
979
+ MemoryLayout < Pointee > . stride > MemoryLayout< T> . stride
980
+ ? MemoryLayout< Pointee> . stride % MemoryLayout < T > . stride == 0
981
+ : MemoryLayout < T > . stride % MemoryLayout < Pointee > . stride == 0
982
+ )
983
+ let binding = Builtin . bindMemory ( _rawValue, count. _builtinWordValue, T . self)
984
+ defer { Builtin . rebindMemory ( _rawValue, binding) }
985
+ return try body ( . init( _rawValue) )
953
986
}
954
987
955
988
/// Accesses the pointee at the specified offset from this pointer.
0 commit comments