Looking for feedback before submitting a PR: 
https://github.com/karwa/swift-evolution/blob/corelibs-unsafebytes/proposals/xxxx-corelibs-unsafebytes.md

—

Change (Dispatch)Data.withUnsafeBytes to use UnsafeMutableBufferPointer

Proposal: SE-NNNN 
<https://github.com/karwa/swift-evolution/blob/corelibs-unsafebytes/proposals/NNNN-filename.md>
Authors: Karl Wagner <https://github.com/karwa>
Review Manager: TBD
Status: Awaiting review
During the review process, add the following fields as needed:

Decision Notes: Rationale <https://lists.swift.org/pipermail/swift-evolution/>, 
Additional Commentary <https://lists.swift.org/pipermail/swift-evolution/>
Bugs: SR-NNNN <https://bugs.swift.org/browse/SR-NNNN>, SR-MMMM 
<https://bugs.swift.org/browse/SR-MMMM>
Previous Revision: 1 
<https://github.com/apple/swift-evolution/blob/...commit-ID.../proposals/NNNN-filename.md>
Previous Proposal: SE-XXXX 
<https://github.com/karwa/swift-evolution/blob/corelibs-unsafebytes/proposals/XXXX-filename.md>
 
<https://github.com/karwa/swift-evolution/blob/corelibs-unsafebytes/proposals/xxxx-corelibs-unsafebytes.md#introduction>Introduction

The standard library's Array and ContiguousArray types expose the method 
withUnsafeBytes, which allows you to view their contents as a contiguous 
collection of bytes. The core libraries Foundation and Dispatch contain types 
which wrap some allocated data, but their withUnsafeBytes method only allows 
you to view the contents as a pointer to a contiguous memory location of a 
given type.

Swift-evolution thread: Discussion thread topic for that proposal 
<https://lists.swift.org/pipermail/swift-evolution/>
 
<https://github.com/karwa/swift-evolution/blob/corelibs-unsafebytes/proposals/xxxx-corelibs-unsafebytes.md#motivation>Motivation

The current situation makes it awkward to write generic code. Personally, I use 
the following extension in my projects to sort the naming confusion out:

protocol ContiguousByteCollection {
  func withUnsafeBytes<T>(_ body: (UnsafeRawBufferPointer) throws -> T) 
rethrows -> T
}

// stdlib types are fine.
extension Array: ContiguousByteCollection {}
extension ArraySlice: ContiguousByteCollection {}
extension ContiguousArray: ContiguousByteCollection {}

// corelibs types give us a pointer<T>, should be: { pointer<char>, count }
#if canImport(Dispatch)
  import Dispatch

  extension DispatchData : ContiguousByteCollection {
    func withUnsafeBytes<T>(_ body: (UnsafeRawBufferPointer) throws -> T) 
rethrows -> T {
      return try withUnsafeBytes { try body(UnsafeRawBufferPointer(start: $0, 
count: count)) }
    }
  }
#endif

#if canImport(Foundation)
  import Foundation

  extension Data : ContiguousByteCollection {
    func withUnsafeBytes<T>(_ body: (UnsafeRawBufferPointer) throws -> T) 
rethrows -> T {
      return try withUnsafeBytes { try body(UnsafeRawBufferPointer(start: $0, 
count: count)) }
    }
  }
#endif
Conceptually, the corelibs types are untyped regions of memory, and it would 
make sense for them to adopt the UnsafeRawBufferPointer model.

 
<https://github.com/karwa/swift-evolution/blob/corelibs-unsafebytes/proposals/xxxx-corelibs-unsafebytes.md#proposed-solution>Proposed
 solution

The proposed solution would be to deprecate the current methods on 
(Dispatch)Data (with 2 generic parameters), and replace them with methods with 
identical signatures to Array (with 1 generic parameter).

To be deprecated:

public func withUnsafeBytes<ResultType, ContentType>(_ body: 
(UnsafePointer<ContentType>) throws -> ResultType) rethrows -> ResultType
Replaced with:

public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) 
rethrows -> R
 
<https://github.com/karwa/swift-evolution/blob/corelibs-unsafebytes/proposals/xxxx-corelibs-unsafebytes.md#source-compatibility>Source
 compatibility

Source-breaking. Users binding a (Dispatch)Data to an UnsafePointer would 
instead have to call:

buffer.baseAddress!.assumingMemoryBound(to: T.self)
Which is a bit more to type, although maybe the deprecation of the old function 
could provide this replacement as a fix-it.

 
<https://github.com/karwa/swift-evolution/blob/corelibs-unsafebytes/proposals/xxxx-corelibs-unsafebytes.md#effect-on-api-resilience>Effect
 on API resilience

Source-breaking change to corelibs APIs.

 
<https://github.com/karwa/swift-evolution/blob/corelibs-unsafebytes/proposals/xxxx-corelibs-unsafebytes.md#alternatives-considered>Alternatives
 considered

A different method on Data and DispatchData, providing an 
UnsafeRawBufferPointer? There would still be a naming discrepency between the 
stdlib and corelibs types

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to