Skip to content

Commit d93573c

Browse files
committed
[stdlib] add unaligned loads to UnsafeRawPointer
1 parent dba5320 commit d93573c

File tree

1 file changed

+59
-2
lines changed

1 file changed

+59
-2
lines changed

stdlib/public/core/UnsafeRawPointer.swift

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,6 @@ public struct UnsafeRawPointer: _Pointer {
424424
let rawPointer = (self + offset)._rawValue
425425

426426
#if compiler(>=5.5) && $BuiltinAssumeAlignment
427-
// TODO: to support misaligned raw loads, simply remove this assumption.
428427
let alignedPointer =
429428
Builtin.assumeAlignment(rawPointer,
430429
MemoryLayout<T>.alignment._builtinWordValue)
@@ -434,6 +433,35 @@ public struct UnsafeRawPointer: _Pointer {
434433
#endif
435434
}
436435

436+
/// Returns a new instance of the given type, constructed from the raw memory
437+
/// at the specified offset.
438+
///
439+
/// This function only supports loading trivial types.
440+
/// A trivial type does not contain any reference-counted property
441+
/// within its in-memory representation.
442+
/// The memory at this pointer plus `offset` must be laid out
443+
/// identically to the in-memory representation of `T`.
444+
///
445+
/// - Note: A trivial type can be copied with just a bit-for-bit copy without
446+
/// any indirection or reference-counting operations. Generally, native
447+
/// Swift types that do not contain strong or weak references or other
448+
/// forms of indirection are trivial, as are imported C structs and enums.
449+
///
450+
/// - Parameters:
451+
/// - offset: The offset from this pointer, in bytes. `offset` must be
452+
/// nonnegative. The default is zero.
453+
/// - type: The type of the instance to create.
454+
/// - Returns: A new instance of type `T`, read from the raw bytes at
455+
/// `offset`. The returned instance isn't associated
456+
/// with the value in the range of memory referenced by this pointer.
457+
@_alwaysEmitIntoClient
458+
public func loadUnaligned<T>(
459+
fromByteOffset offset: Int = 0,
460+
as type: T.Type
461+
) -> T {
462+
_debugPrecondition(_isPOD(T.self))
463+
return Builtin.loadRaw((self + offset)._rawValue)
464+
}
437465
}
438466

439467
extension UnsafeRawPointer: Strideable {
@@ -1120,7 +1148,6 @@ public struct UnsafeMutableRawPointer: _Pointer {
11201148
let rawPointer = (self + offset)._rawValue
11211149

11221150
#if compiler(>=5.5) && $BuiltinAssumeAlignment
1123-
// TODO: to support misaligned raw loads, simply remove this assumption.
11241151
let alignedPointer =
11251152
Builtin.assumeAlignment(rawPointer,
11261153
MemoryLayout<T>.alignment._builtinWordValue)
@@ -1130,6 +1157,36 @@ public struct UnsafeMutableRawPointer: _Pointer {
11301157
#endif
11311158
}
11321159

1160+
/// Returns a new instance of the given type, constructed from the raw memory
1161+
/// at the specified offset.
1162+
///
1163+
/// This function only supports loading trivial types.
1164+
/// A trivial type does not contain any reference-counted property
1165+
/// within its in-memory representation.
1166+
/// The memory at this pointer plus `offset` must be laid out
1167+
/// identically to the in-memory representation of `T`.
1168+
///
1169+
/// - Note: A trivial type can be copied with just a bit-for-bit copy without
1170+
/// any indirection or reference-counting operations. Generally, native
1171+
/// Swift types that do not contain strong or weak references or other
1172+
/// forms of indirection are trivial, as are imported C structs and enums.
1173+
///
1174+
/// - Parameters:
1175+
/// - offset: The offset from this pointer, in bytes. `offset` must be
1176+
/// nonnegative. The default is zero.
1177+
/// - type: The type of the instance to create.
1178+
/// - Returns: A new instance of type `T`, read from the raw bytes at
1179+
/// `offset`. The returned instance isn't associated
1180+
/// with the value in the range of memory referenced by this pointer.
1181+
@_alwaysEmitIntoClient
1182+
public func loadUnaligned<T>(
1183+
fromByteOffset offset: Int = 0,
1184+
as type: T.Type
1185+
) -> T {
1186+
_debugPrecondition(_isPOD(T.self))
1187+
return Builtin.loadRaw((self + offset)._rawValue)
1188+
}
1189+
11331190
/// Stores the given value's bytes into raw memory at the specified offset.
11341191
///
11351192
/// The type `T` to be stored must be a trivial type. The memory at this

0 commit comments

Comments
 (0)