Skip to content

Commit b3f96e8

Browse files
committed
[stdlib] alignedUp(for:) and siblings for URP and UMRP
1 parent c9e86b4 commit b3f96e8

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed

stdlib/public/core/UnsafeRawPointer.swift

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,76 @@ extension UnsafeRawPointer: Strideable {
444444
}
445445
}
446446

447+
extension UnsafeRawPointer {
448+
/// Obtain the next pointer properly aligned to store a value of type `T`.
449+
///
450+
/// If `self` is properly aligned for accessing `T`,
451+
/// this function returns `self`.
452+
///
453+
/// - Parameters:
454+
/// - type: the type to be stored at the returned address.
455+
/// - Returns: a pointer properly aligned to store a value of type `T`.
456+
@inlinable
457+
@_alwaysEmitIntoClient
458+
public func alignedUp<T>(for type: T.Type) -> Self {
459+
let mask = UInt(Builtin.alignof(T.self)) &- 1
460+
let bits = (UInt(Builtin.ptrtoint_Word(_rawValue)) &+ mask) & ~mask
461+
return .init(Builtin.inttoptr_Word(bits._builtinWordValue))
462+
}
463+
464+
/// Obtain the preceding pointer properly aligned to store a value of type `T`.
465+
///
466+
/// If `self` is properly aligned for accessing `T`,
467+
/// this function returns `self`.
468+
///
469+
/// - Parameters:
470+
/// - type: the type to be stored at the returned address.
471+
/// - Returns: a pointer properly aligned to store a value of type `T`.
472+
@inlinable
473+
@_alwaysEmitIntoClient
474+
public func alignedDown<T>(for type: T.Type) -> Self {
475+
let mask = UInt(Builtin.alignof(T.self)) &- 1
476+
let bits = UInt(Builtin.ptrtoint_Word(_rawValue)) & ~mask
477+
return .init(Builtin.inttoptr_Word(bits._builtinWordValue))
478+
}
479+
480+
/// Obtain the next pointer whose bit pattern is a multiple of `alignment`.
481+
///
482+
/// If the bit pattern of `self` is a multiple of `alignment`,
483+
/// this function returns `self`.
484+
///
485+
/// - Parameters:
486+
/// - alignment: the alignment of the returned pointer, in bytes.
487+
/// `alignment` must be a whole power of 2.
488+
/// - Returns: a pointer aligned to `alignment`.
489+
@inlinable
490+
@_alwaysEmitIntoClient
491+
public func alignedUp(toMultipleOf alignment: Int) -> Self {
492+
let mask = alignment &- 1
493+
_debugPrecondition(alignment & mask == 0)
494+
let bits = (Int(Builtin.ptrtoint_Word(_rawValue)) &+ mask) & ~mask
495+
return .init(Builtin.inttoptr_Word(bits._builtinWordValue))
496+
}
497+
498+
/// Obtain the preceding pointer whose bit pattern is a multiple of `alignment`.
499+
///
500+
/// If the bit pattern of `self` is a multiple of `alignment`,
501+
/// this function returns `self`.
502+
///
503+
/// - Parameters:
504+
/// - alignment: the alignment of the returned pointer, in bytes.
505+
/// `alignment` must be a whole power of 2.
506+
/// - Returns: a pointer aligned to `alignment`.
507+
@inlinable
508+
@_alwaysEmitIntoClient
509+
public func alignedDown(toMultipleOf alignment: Int) -> Self {
510+
let mask = alignment &- 1
511+
_debugPrecondition(alignment & mask == 0)
512+
let bits = Int(Builtin.ptrtoint_Word(_rawValue)) & ~mask
513+
return .init(Builtin.inttoptr_Word(bits._builtinWordValue))
514+
}
515+
}
516+
447517
/// A raw pointer for accessing and manipulating
448518
/// untyped data.
449519
///
@@ -1145,6 +1215,76 @@ extension UnsafeMutableRawPointer: Strideable {
11451215
}
11461216
}
11471217

1218+
extension UnsafeMutableRawPointer {
1219+
/// Obtain the next pointer properly aligned to store a value of type `T`.
1220+
///
1221+
/// If `self` is properly aligned for accessing `T`,
1222+
/// this function returns `self`.
1223+
///
1224+
/// - Parameters:
1225+
/// - type: the type to be stored at the returned address.
1226+
/// - Returns: a pointer properly aligned to store a value of type `T`.
1227+
@inlinable
1228+
@_alwaysEmitIntoClient
1229+
public func alignedUp<T>(for type: T.Type) -> Self {
1230+
let mask = UInt(Builtin.alignof(T.self)) &- 1
1231+
let bits = (UInt(Builtin.ptrtoint_Word(_rawValue)) &+ mask) & ~mask
1232+
return .init(Builtin.inttoptr_Word(bits._builtinWordValue))
1233+
}
1234+
1235+
/// Obtain the preceding pointer properly aligned to store a value of type `T`.
1236+
///
1237+
/// If `self` is properly aligned for accessing `T`,
1238+
/// this function returns `self`.
1239+
///
1240+
/// - Parameters:
1241+
/// - type: the type to be stored at the returned address.
1242+
/// - Returns: a pointer properly aligned to store a value of type `T`.
1243+
@inlinable
1244+
@_alwaysEmitIntoClient
1245+
public func alignedDown<T>(for type: T.Type) -> Self {
1246+
let mask = UInt(Builtin.alignof(T.self)) &- 1
1247+
let bits = UInt(Builtin.ptrtoint_Word(_rawValue)) & ~mask
1248+
return .init(Builtin.inttoptr_Word(bits._builtinWordValue))
1249+
}
1250+
1251+
/// Obtain the next pointer whose bit pattern is a multiple of `alignment`.
1252+
///
1253+
/// If the bit pattern of `self` is a multiple of `alignment`,
1254+
/// this function returns `self`.
1255+
///
1256+
/// - Parameters:
1257+
/// - alignment: the alignment of the returned pointer, in bytes.
1258+
/// `alignment` must be a whole power of 2.
1259+
/// - Returns: a pointer aligned to `alignment`.
1260+
@inlinable
1261+
@_alwaysEmitIntoClient
1262+
public func alignedUp(toMultipleOf alignment: Int) -> Self {
1263+
let mask = alignment &- 1
1264+
_debugPrecondition(alignment & mask == 0)
1265+
let bits = (Int(Builtin.ptrtoint_Word(_rawValue)) &+ mask) & ~mask
1266+
return .init(Builtin.inttoptr_Word(bits._builtinWordValue))
1267+
}
1268+
1269+
/// Obtain the preceding pointer whose bit pattern is a multiple of `alignment`.
1270+
///
1271+
/// If the bit pattern of `self` is a multiple of `alignment`,
1272+
/// this function returns `self`.
1273+
///
1274+
/// - Parameters:
1275+
/// - alignment: the alignment of the returned pointer, in bytes.
1276+
/// `alignment` must be a whole power of 2.
1277+
/// - Returns: a pointer aligned to `alignment`.
1278+
@inlinable
1279+
@_alwaysEmitIntoClient
1280+
public func alignedDown(toMultipleOf alignment: Int) -> Self {
1281+
let mask = alignment &- 1
1282+
_debugPrecondition(alignment & mask == 0)
1283+
let bits = Int(Builtin.ptrtoint_Word(_rawValue)) & ~mask
1284+
return .init(Builtin.inttoptr_Word(bits._builtinWordValue))
1285+
}
1286+
}
1287+
11481288
extension OpaquePointer {
11491289
@_transparent
11501290
public init(@_nonEphemeral _ from: UnsafeMutableRawPointer) {

0 commit comments

Comments
 (0)