Skip to content

Commit

Permalink
SE-0138: Add UnsafeRawBufferPointer and UnsafeMutableRawBufferPointer. (
Browse files Browse the repository at this point in the history
swiftlang#4954)

https://github.com/apple/swift-evolution/blob/master/proposals/0138-unsaferawbufferpointer.md

Unsafe[Mutable]RawBufferPointer is a non-owning view over a region of memory as
a Collection of bytes independent of the type of values held in that
memory. Each 8-bit byte in memory is viewed as a `UInt8` value.

Reads and writes on memory via `Unsafe[Mutable]RawBufferPointer` are untyped
operations. Accessing this Collection's bytes does not bind the
underlying memory to `UInt8`. The underlying memory must be bound
to some trivial type whenever it is accessed via a typed operation.

In addition to the `Collection` interface, the following methods from
`Unsafe[Mutable]RawPointer`'s interface to raw memory are
provided with debug mode bounds checks: `load(fromByteOffset:as:)`,
`storeBytes(of:toByteOffset:as:)`, and `copyBytes(from:count:)`.

This is only a view into memory and does not own the memory. Copying a value of
type `UnsafeMutableRawBufferPointer` does not copy the underlying
memory. Assigning an `Unsafe[Mutable]RawBufferPointer` into a value-based
collection, such as `[UInt8]` copies bytes out of memory. Assigning into a
subscript range of UnsafeMutableRawBufferPointer copies into memory.
  • Loading branch information
atrick authored Sep 23, 2016
1 parent 3170c65 commit f70a2e0
Show file tree
Hide file tree
Showing 6 changed files with 864 additions and 1 deletion.
66 changes: 66 additions & 0 deletions stdlib/public/core/Arrays.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -2111,6 +2111,72 @@ public func != <Element : Equatable>(
) -> Bool {
return !(lhs == rhs)
}

extension ${Self} {
/// Calls a closure with a view of the array's underlying bytes of memory as a
/// Collection of `UInt8`.
/// ${contiguousCaveat}
///
/// - Precondition: `Pointee` is a trivial type.
///
/// The following example shows how you copy bytes into an array:
///
/// var numbers = [Int32](repeating: 0, count: 2)
/// var byteValues: [UInt8] = [0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00]
/// numbers.withUnsafeMutableBytes { destBytes in
/// byteValues.withUnsafeBytes { srcBytes in
/// destBytes.copyBytes(from: srcBytes)
/// }
/// }
///
/// - Parameter body: A closure with an `UnsafeRawBufferPointer` parameter
/// that points to the contiguous storage for the array. If `body` has a
/// return value, it is used as the return value for the
/// `withUnsafeBytes(_:)` method. The argument is valid only for the
/// duration of the closure's execution.
/// - Returns: The return value of the `body` closure parameter, if any.
///
/// - SeeAlso: `withUnsafeBytes`, `UnsafeMutableRawBufferPointer`
public mutating func withUnsafeMutableBytes<R>(
_ body: (inout UnsafeMutableRawBufferPointer) throws -> R
) rethrows -> R {
return try self.withUnsafeMutableBufferPointer {
var bytes = UnsafeMutableRawBufferPointer($0)
return try body(&bytes)
}
}

/// Calls a closure with a view of the array's underlying bytes of memory
/// as a Collection of `UInt8`.
/// ${contiguousCaveat}
///
/// - Precondition: `Pointee` is a trivial type.
///
/// The following example shows how you copy the contents of an array into a
/// buffer of `UInt8`:
///
/// let numbers = [1, 2, 3]
/// var byteBuffer = [UInt8]()
/// numbers.withUnsafeBytes {
/// byteBuffer += $0
/// }
///
/// - Parameter body: A closure with an `UnsafeRawBufferPointer` parameter
/// that points to the contiguous storage for the array. If `body` has a
/// return value, it is used as the return value for the
/// `withUnsafeBytes(_:)` method. The argument is valid only for the
/// duration of the closure's execution.
/// - Returns: The return value of the `body` closure parameter, if any.
///
/// - SeeAlso: `withUnsafeBytes`, `UnsafeRawBufferPointer`
public mutating func withUnsafeBytes<R>(
_ body: (UnsafeRawBufferPointer) throws -> R
) rethrows -> R {
return try self.withUnsafeBufferPointer {
try body(UnsafeRawBufferPointer($0))
}
}
}
%end

#if _runtime(_ObjC)
Expand Down
1 change: 1 addition & 0 deletions stdlib/public/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ set(SWIFTLIB_ESSENTIAL
Unmanaged.swift
UnsafeBitMap.swift
UnsafeBufferPointer.swift.gyb
UnsafeRawBufferPointer.swift.gyb
UnsafePointer.swift.gyb
UnsafeRawPointer.swift.gyb
WriteBackMutableSlice.swift
Expand Down
3 changes: 2 additions & 1 deletion stdlib/public/core/GroupInfo.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@
"Pointer.swift",
"UnsafePointer.swift",
"UnsafeRawPointer.swift",
"UnsafeBufferPointer.swift"
"UnsafeBufferPointer.swift",
"UnsafeRawBufferPointer.swift"
],
"Protocols": [
"CompilerProtocols.swift",
Expand Down
Loading

0 comments on commit f70a2e0

Please sign in to comment.