Skip to content

Commit 6ad0f30

Browse files
authored
Add UnsafeMutableRawPointer.init(mutating:) (#3722)
As proposed in SE-0107: UnsafeRawPointer. Allow immutable raw pointers to be explicitly cast into mutable raw pointers.
1 parent 386086c commit 6ad0f30

File tree

2 files changed

+40
-6
lines changed

2 files changed

+40
-6
lines changed

stdlib/public/core/UnsafeRawPointer.swift.gyb

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public struct Unsafe${Mutable}RawPointer : Strideable, Hashable, _Pointer {
6868
_rawValue = other._rawValue
6969
}
7070

71-
/// Convert an Unsafe${Mutable}Pointer ${a_Self}.
71+
/// Convert an Unsafe${Mutable}Pointer to ${a_Self}.
7272
///
7373
/// Returns nil if `other` is nil.
7474
@_transparent
@@ -77,14 +77,29 @@ public struct Unsafe${Mutable}RawPointer : Strideable, Hashable, _Pointer {
7777
_rawValue = unwrapped._rawValue
7878
}
7979

80-
% if not mutable:
81-
/// Convert an UnsafeMutableRawPointer ${a_Self}.
80+
% if mutable:
81+
/// Convert an UnsafeRawPointer to ${a_Self}.
82+
@_transparent
83+
public init(mutating other: UnsafeRawPointer) {
84+
_rawValue = other._rawValue
85+
}
86+
87+
/// Convert an UnsafeRawPointer to ${a_Self}.
88+
///
89+
/// Returns nil if `other` is nil.
90+
@_transparent
91+
public init?(mutating other: UnsafeRawPointer?) {
92+
guard let unwrapped = other else { return nil }
93+
_rawValue = unwrapped._rawValue
94+
}
95+
% else: # !mutable
96+
/// Convert an UnsafeMutableRawPointer to ${a_Self}.
8297
@_transparent
8398
public init(_ other: UnsafeMutableRawPointer) {
8499
_rawValue = other._rawValue
85100
}
86101

87-
/// Convert an UnsafeMutableRawPointer ${a_Self}.
102+
/// Convert an UnsafeMutableRawPointer to ${a_Self}.
88103
///
89104
/// Returns nil if `other` is nil.
90105
@_transparent
@@ -93,13 +108,13 @@ public struct Unsafe${Mutable}RawPointer : Strideable, Hashable, _Pointer {
93108
_rawValue = unwrapped._rawValue
94109
}
95110

96-
/// Convert an UnsafeMutablePointer ${a_Self}.
111+
/// Convert an UnsafeMutablePointer to ${a_Self}.
97112
@_transparent
98113
public init<T>(_ other: UnsafeMutablePointer<T>) {
99114
_rawValue = other._rawValue
100115
}
101116

102-
/// Convert an UnsafeMutablePointer ${a_Self}.
117+
/// Convert an UnsafeMutablePointer to ${a_Self}.
103118
///
104119
/// Returns nil if `other` is nil.
105120
@_transparent

test/1_stdlib/UnsafePointer.swift.gyb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,25 @@ ${SelfName}TestSuite.test("initFromOpaquePointer") {
7575

7676
% end
7777

78+
% for (SelfName, SelfType) in [
79+
% ('UnsafeRawPointer', 'UnsafeRawPointer'),
80+
% ('UnsafeMutableRawPointer', 'UnsafeMutableRawPointer')]:
81+
UnsafeMutableRawPointerTestSuite.test("initFromMutating") {
82+
let other = UnsafeRawPointer(bitPattern: 0x12345678)!
83+
let ptr = UnsafeMutableRawPointer(mutating: other)
84+
expectEqual(0x12345678, unsafeBitCast(ptr, to: Int.self))
85+
86+
let optionalOther: Optional = other
87+
let optionalPointer = UnsafeMutableRawPointer(mutating: optionalOther)
88+
expectNotEmpty(optionalPointer)
89+
expectEqual(0x12345678, unsafeBitCast(optionalPointer, to: Int.self))
90+
91+
let nilOther: Optional<UnsafeRawPointer> = nil
92+
let nilPointer = UnsafeMutableRawPointer(mutating: nilOther)
93+
expectEmpty(nilPointer)
94+
}
95+
% end
96+
7897
% for (SelfName, SelfType) in [
7998
% ('UnsafePointer', 'UnsafePointer<Float>'),
8099
% ('UnsafeMutablePointer', 'UnsafeMutablePointer<Float>'),

0 commit comments

Comments
 (0)