SE-0184 Part 1: Unsafe[Mutable][Raw][Buffer]Pointer: add missing methods, adjust existing labels for clarity, and remove deallocation size
Here I've listed the changes from SE-0184 that have been reviewed by the core team and are no longer considered controversial. Let's call this SE-1084 Part 1. The diff below summarizes SE-1084 Part 1 vs. Swift 4. The core team requests have been incorporated, and are annotated as "Amended" comments. The amendments are minor and almost exclusively revise the original Swift 3 API rather than calling into question anything newly introduced by SE-0184. Consequently, there's no need for those to go back to swift-evolution. The remainder of SE-0184, part 2, will introduce changes to the slice API in conjunction with the buffer API, so does need to go back to swift-evolution as a new proposal.
-
Kelvin's latest amendment before core team review: https://github.com/kelvin13/swift-evolution/blob/e888af466c9993de977f6999a131eadd33291b06/proposals/0184-unsafe-pointers-add-missing.md
-
Proposal: SE-0184
-
Author: Kelvin Ma (“Taylor Swift”)
-
Review Manager: Doug Gregor
-
Status: Active review (September 1...7, 2017)
-
Implementation: apple/swift#11464
struct UnsafePointer<Pointee>
{
+++ func deallocate()
func withMemoryRebound<T, Result>(to:T.Type, capacity:Int, _ body:(UnsafePointer<T>) -> Result)
-> Result
}
struct UnsafeMutablePointer<Pointee>
{
static func allocate<Pointee>(capacity:Int) -> UnsafeMutablePointer<Pointee>
--- func deallocate(capacity:Int)
+++ func deallocate()
}
struct UnsafeRawPointer
{
--- func deallocate(bytes:Int, alignedTo:Int)
+++ func deallocate()
}
struct UnsafeMutableRawPointer
{
--- static func allocate(bytes:Int, alignedTo:Int) -> UnsafeMutableRawPointer
// Amended: Renamed `bytes` to `byteCount`.
// Amended: Renamed `alignedTo` to `alignment`.
// Amended: Removed default alignment.
+++ static func allocate(byteCount:Int, alignment:Int) -> UnsafeMutableRawPointer
--- func deallocate(bytes:Int, alignedTo:Int)
+++ func deallocate()
}
struct UnsafeBufferPointer<Element>
{
+++ func deallocate()
}
struct UnsafeRawBufferPointer
{
func deallocate()
}
struct UnsafeMutableRawBufferPointer
{
// Amended: Renamed `bytes` to `byteCount`.
// Amended: Renamed `alignedTo` to `alignment`.
// Amended: Removed default alignment.
--- static func allocate(count:Int) -> UnsafeMutableRawBufferPointer
+++ static func allocate(byteCount:Int, alignment:Int) -> UnsafeMutableRawBufferPointer
func deallocate()
}
struct UnsafeBufferPointer<Element>
{
+++ init(_:UnsafeMutableBufferPointer<Element>)
}
struct UnsafeMutableBufferPointer<Element>
{
+++ init(mutating:UnsafeBufferPointer<Element>)
}
struct UnsafePointer<Pointee>
{
func withMemoryRebound<T, Result>(to:T.Type, capacity:Int, _ body:(UnsafePointer<T>) -> Result)
-> Result
}
struct UnsafeMutablePointer<Pointee>
{
--- func initialize(to:Pointee, count:Int = 1)
+++ func initialize(repeating:Pointee, count:Int) // No default count.
// Amended: Rename `initializePointee` to `initialize`.
+++ func initialize(to:Pointee)
func initialize(from:UnsafePointer<Pointee>, count:Int)
func moveInitialize(from:UnsafeMutablePointer<Pointee>, count:Int)
+++ func assign(repeating:Pointee, count:Int)
func assign(from:UnsafePointer<Pointee>, count:Int)
func moveAssign(from:UnsafeMutablePointer<Pointee>, count:Int)
func deinitialize(count:Int)
func withMemoryRebound<T, Result>(to:T.Type, capacity:Int, _ body:(UnsafeMutablePointer<T>) -> Result)
-> Result
}
struct UnsafeRawPointer
{
func bindMemory<T>(to:T.Type, count:Int) -> UnsafeMutablePointer<T>
}
struct UnsafeMutableRawPointer
{
--- func initializeMemory<T>(as:T.Type, at:Int = 0, count:Int = 1, to:T) -> UnsafeMutablePointer<T>
+++ func initializeMemory<T>(as:T.Type, repeating:T, count:Int) -> UnsafeMutablePointer<T>
func initializeMemory<T>(as:T.Type, from:UnsafePointer<T>, count:Int) -> UnsafeMutablePointer<T>
func moveInitializeMemory<T>(as:T.Type, from:UnsafeMutablePointer<T>, count:Int)
-> UnsafeMutablePointer<T>
func bindMemory<T>(to:T.Type, count:Int) -> UnsafeMutablePointer<T>
--- func copyBytes(from:UnsafeRawPointer, count:Int)
// Amended: Rename `bytes` to `byteCount`.
+++ func copyMemory(from:UnsafeRawPointer, byteCount:Int)
}
struct UnsafeBufferPointer<Element>
{
+++ func withMemoryRebound<T, Result>
+++ (to:T.Type, _ body:(UnsafeBufferPointer<T>) -> Result)
}
struct UnsafeMutableBufferPointer<Element>
{
+++ func initialize(repeating: Element) -> UnsafeMutableBufferPointer<T>
+++ func assign(repeating: Element)
+++ func withMemoryRebound<T, Result>
+++ (to:T.Type, _ body:(UnsafeMutableBufferPointer<T>) -> Result)
}
struct UnsafeRawBufferPointer
{
func deallocate()
+++ func bindMemory<T>(to:T.Type) -> UnsafeBufferPointer<T>
}
struct UnsafeMutableRawBufferPointer
{
+++ func initializeMemory<T>(as:T.Type, repeating:T) -> UnsafeMutableBufferPointer<T>
+++ func bindMemory<T>(to:T.Type) -> UnsafeMutableBufferPointer<T>
}
Everything is additive except the following. Can we deprecate all of the original functions in Swift 5, then drop those from the binary later in Swift 6?
- add
deallocate()
to all pointer types, replacing any existing deallocation methods
The migrator needs to drop the existing capacity
and alignedTo
arguments.
-
in
UnsafeMutableRawPointer.allocate(count:alignedTo:)
renamecount
tobyteCount
andalignedTo
toalignment
-
in
UnsafeMutableRawBufferPointer.allocate(count:)
renamecount
tobyteCount
and add analignment
parameter
This change is source breaking but can be trivially automigrated. The
alignment:
parameter can be filled in with MemoryLayout<UInt>.stride
.
- fix the arguments to
initialize(repeating:Pointee, count:Int)
Note: initialize(to:Pointee) is backward compatible whenever the
caller relied on a default count=1
.
An annotation could otherwise rename to
to repeating
, but we don't
want that to interfere with the default count case, so this might need to be a migrator rule.
- fix the ordering of the arguments in
initializeMemory<Element>(as:at:count:to:)
, renameto:
torepeating:
, and remove theat:
argument
This change is source breaking but can be trivially automigrated. The
to
argument changes position and is relabeled as repeating
.
The migrator could be taught to convert the at:
argument into
pointer arithmetic on self
. However, I found no code on github that
uses the at:
argument, so it is low priority.
- rename
copyBytes(from:count:)
tocopyMemory(from:byteCount:)
This change is source breaking but can be trivially automigrated.