mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
1068 lines
42 KiB
Swift
1068 lines
42 KiB
Swift
//===--- UnsafePointer.swift.gyb ------------------------------*- swift -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
%import gyb
|
|
|
|
% for mutable in (True, False):
|
|
% Self = 'UnsafeMutablePointer' if mutable else 'UnsafePointer'
|
|
% a_Self = 'an `UnsafeMutablePointer`' if mutable else 'an `UnsafePointer`'
|
|
% Mutable = 'Mutable' if mutable else ''
|
|
/// A pointer for accessing ${'and manipulating' if mutable else ''} data of a
|
|
/// specific type.
|
|
///
|
|
/// You use instances of the `Unsafe${Mutable}Pointer` type to access data of a
|
|
/// specific type in memory. The type of data that a pointer can access is the
|
|
/// pointer's `Pointee` type. `Unsafe${Mutable}Pointer` provides no automated
|
|
/// memory management or alignment guarantees. You are responsible for
|
|
/// handling the life cycle of any memory you work with through unsafe
|
|
/// pointers to avoid leaks or undefined behavior.
|
|
///
|
|
/// Memory that you manually manage can be either *untyped* or *bound* to a
|
|
/// specific type. You use the `Unsafe${Mutable}Pointer` type to access and
|
|
/// manage memory that has been bound to a specific type.
|
|
///
|
|
/// Understanding a Pointer's Memory State
|
|
/// ======================================
|
|
///
|
|
/// The memory referenced by an `Unsafe${Mutable}Pointer` instance can be in
|
|
/// one of several states. Many pointer operations must only be applied to
|
|
/// pointers with memory in a specific state---you must keep track of the
|
|
/// state of the memory you are working with and understand the changes to
|
|
/// that state that different operations perform. Memory can be untyped and
|
|
/// uninitialized, bound to a type and uninitialized, or bound to a type and
|
|
/// initialized to a value. Finally, memory that was allocated previously may
|
|
/// have been deallocated, leaving existing pointers referencing unallocated
|
|
/// memory.
|
|
///
|
|
/// Uninitialized Memory
|
|
/// --------------------
|
|
///
|
|
/// Memory that has just been allocated through a typed pointer or has been
|
|
/// deinitialized is in an *uninitialized* state. Uninitialized memory must be
|
|
/// initialized before it can be accessed for reading.
|
|
///
|
|
%if mutable:
|
|
/// You can use methods like `initialize(to:count:)`, `initialize(from:)`, and
|
|
/// `moveInitialize(from:count:)` to initialize the memory referenced by a
|
|
/// pointer with a value or series of values.
|
|
///
|
|
% end
|
|
/// Initialized Memory
|
|
/// ------------------
|
|
///
|
|
/// *Initialized* memory has a value that can be read using a pointer's
|
|
/// `pointee` property or through subscript notation. In the following
|
|
/// example, `ptr` is a pointer to memory initialized with a value of `23`:
|
|
///
|
|
/// let ptr: Unsafe${Mutable}Pointer<Int> = ...
|
|
/// // ptr.pointee == 23
|
|
/// // ptr[0] == 23
|
|
///
|
|
/// Accessing a Pointer's Memory as a Different Type
|
|
/// ================================================
|
|
///
|
|
/// When you access memory through an `Unsafe${Mutable}Pointer` instance, the
|
|
/// `Pointee` type must be consistent with the bound type of the memory. If
|
|
/// you do need to access memory that is bound to one type as a different
|
|
/// type, Swift's pointer types provide type-safe ways to temporarily or
|
|
/// permanently change the bound type of the memory, or to load typed
|
|
/// instances directly from raw memory.
|
|
///
|
|
/// An `Unsafe${Mutable}Pointer<UInt8>` instance allocated with eight bytes of
|
|
/// memory, `uint8Pointer`, will be used for the examples below.
|
|
///
|
|
% if mutable:
|
|
/// let uint8Pointer = UnsafeMutablePointer<UInt8>.allocate(capacity: 8)
|
|
/// uint8Pointer.initialize(from: [39, 77, 111, 111, 102, 33, 39, 0])
|
|
% else:
|
|
/// let uint8Pointer: UnsafePointer<UInt8> = fetchEightBytes()
|
|
% end
|
|
///
|
|
/// When you only need to temporarily access a pointer's memory as a different
|
|
/// type, use the `withMemoryRebound(to:capacity:)` method. For example, you
|
|
/// can use this method to call an API that expects a pointer to a different
|
|
/// type that is layout compatible with your pointer's `Pointee`. The following
|
|
/// code temporarily rebinds the memory that `uint8Pointer` references from
|
|
/// `UInt8` to `Int8` to call the imported C `strlen` function.
|
|
///
|
|
/// // Imported from C
|
|
/// func strlen(_ __s: UnsafePointer<Int8>!) -> UInt
|
|
///
|
|
/// let length = uint8Pointer.withMemoryRebound(to: Int8.self, capacity: 8) {
|
|
/// return strlen($0)
|
|
/// }
|
|
/// // length == 7
|
|
///
|
|
/// When you need to permanently rebind memory to a different type, first
|
|
/// obtain a raw pointer to the memory and then call the
|
|
/// `bindMemory(to:capacity:)` method on the raw pointer. The following
|
|
/// example binds the memory referenced by `uint8Pointer` to one instance of
|
|
/// the `UInt64` type:
|
|
///
|
|
/// let uint64Pointer = Unsafe${Mutable}RawPointer(uint8Pointer)
|
|
/// .bindMemory(to: UInt64.self, capacity: 1)
|
|
///
|
|
/// After rebinding the memory referenced by `uint8Pointer` to `UInt64`,
|
|
/// accessing that pointer's referenced memory as a `UInt8` instance is
|
|
/// undefined.
|
|
///
|
|
/// var fullInteger = uint64Pointer.pointee // OK
|
|
/// var firstByte = uint8Pointer.pointee // undefined
|
|
///
|
|
% if mutable:
|
|
/// Alternatively, you can access the same memory as a different type without
|
|
/// rebinding through untyped memory access, so long as the bound type and the
|
|
/// destination type are trivial types. Convert your pointer to an
|
|
/// `UnsafeMutableRawPointer` instance and then use the raw pointer's
|
|
/// `load(fromByteOffset:as:)` and `storeBytes(of:toByteOffset:as:)` methods
|
|
/// to read and write values.
|
|
% else:
|
|
/// Alternatively, you can access the same memory as a different type without
|
|
/// rebinding through untyped memory access, so long as the bound type and the
|
|
/// destination type are trivial types. Convert your pointer to an
|
|
/// `UnsafeRawPointer` instance and then use the raw pointer's
|
|
/// `load(fromByteOffset:as:)` method to read values.
|
|
% end
|
|
///
|
|
/// let rawPointer = Unsafe${Mutable}RawPointer(uint64Pointer)
|
|
/// fullInteger = rawPointer.load(as: UInt64.self) // OK
|
|
/// firstByte = rawPointer.load(as: UInt8.self) // OK
|
|
///
|
|
/// Performing Typed Pointer Arithmetic
|
|
/// ===================================
|
|
///
|
|
/// Pointer arithmetic with a typed pointer is counted in strides of the
|
|
/// pointer's `Pointee` type. When you add to or subtract from an `${Self}`
|
|
/// instance, the result is a new pointer of the same type, offset by that
|
|
/// number of instances of the `Pointee` type.
|
|
///
|
|
/// // 'intPointer' points to memory initialized with [10, 20, 30, 40]
|
|
/// let intPointer: ${Self}<Int> = ...
|
|
///
|
|
/// // Load the first value in memory
|
|
/// let x = intPointer.pointee
|
|
/// // x == 10
|
|
///
|
|
/// // Load the third value in memory
|
|
/// let offsetPointer = intPointer + 2
|
|
/// let y = offsetPointer.pointee
|
|
/// // y == 30
|
|
///
|
|
/// You can also use subscript notation to access the value in memory at a
|
|
/// specific offset.
|
|
///
|
|
/// let z = intPointer[2]
|
|
/// // z == 30
|
|
///
|
|
/// Implicit Casting and Bridging
|
|
/// =============================
|
|
///
|
|
%if mutable:
|
|
/// When calling a function or method with an `${Self}` parameter, you can pass
|
|
/// an instance of that specific pointer type or use Swift's implicit bridging
|
|
/// to pass a compatible pointer.
|
|
///
|
|
/// For example, the `printInt(atAddress:)` function in the following code
|
|
/// sample expects an `${Self}<Int>` instance as its first parameter:
|
|
///
|
|
/// func printInt(atAddress p: ${Self}<Int>) {
|
|
/// print(p.pointee)
|
|
/// }
|
|
///
|
|
/// As is typical in Swift, you can call the `printInt(atAddress:)` function
|
|
/// with an `${Self}` instance. This example passes `intPointer`, a mutable
|
|
/// pointer to an `Int` value, to `print(address:)`.
|
|
///
|
|
/// printInt(atAddress: intPointer)
|
|
/// // Prints "42"
|
|
///
|
|
/// Alternatively, you can use Swift's *implicit bridging* to pass a pointer to
|
|
/// an instance or to the elements of an array. The following example passes a
|
|
/// pointer to the `value` variable by using inout syntax:
|
|
///
|
|
/// var value: Int = 23
|
|
/// printInt(atAddress: &value)
|
|
/// // Prints "23"
|
|
///
|
|
/// A mutable pointer to the elements of an array is implicitly created when
|
|
/// you pass the array using inout syntax. This example uses implicit bridging
|
|
/// to pass a pointer to the elements of `numbers` when calling
|
|
/// `printInt(atAddress:)`.
|
|
///
|
|
/// var numbers = [5, 10, 15, 20]
|
|
/// printInt(atAddress: &numbers)
|
|
/// // Prints "5"
|
|
///
|
|
/// No matter which way you call `printInt(atAddress:)`, Swift's type safety
|
|
/// guarantees that you can only pass a pointer to the type required by the
|
|
/// function---in this case, a pointer to an `Int`.
|
|
%else:
|
|
/// When calling a function or method with an `${Self}` parameter, you can pass
|
|
/// an instance of that specific pointer type, pass an instance of a
|
|
/// compatible pointer type, or use Swift's implicit bridging to pass a
|
|
/// compatible pointer.
|
|
///
|
|
/// For example, the `printInt(atAddress:)` function in the following code
|
|
/// sample expects an `${Self}<Int>` instance as its first parameter:
|
|
///
|
|
/// func printInt(atAddress p: ${Self}<Int>) {
|
|
/// print(p.pointee)
|
|
/// }
|
|
///
|
|
/// As is typical in Swift, you can call the `printInt(atAddress:)` function
|
|
/// with an `${Self}` instance. This example passes `intPointer`, a pointer to
|
|
/// an `Int` value, to `print(address:)`.
|
|
///
|
|
/// printInt(atAddress: intPointer)
|
|
/// // Prints "42"
|
|
///
|
|
/// Because a mutable typed pointer can be implicitly cast to an immutable
|
|
/// pointer with the same `Pointee` type when passed as a parameter, you can
|
|
/// also call `printInt(atAddress:)` with an `UnsafeMutablePointer` instance.
|
|
///
|
|
/// let mutableIntPointer = UnsafeMutablePointer(mutating: intPointer)
|
|
/// printInt(atAddress: mutableIntPointer)
|
|
/// // Prints "42"
|
|
///
|
|
/// Alternatively, you can use Swift's *implicit bridging* to pass a pointer to
|
|
/// an instance or to the elements of an array. The following example passes a
|
|
/// pointer to the `value` variable by using inout syntax:
|
|
///
|
|
/// var value: Int = 23
|
|
/// printInt(atAddress: &value)
|
|
/// // Prints "23"
|
|
///
|
|
/// An immutable pointer to the elements of an array is implicitly created when
|
|
/// you pass the array as an argument. This example uses implicit bridging to
|
|
/// pass a pointer to the elements of `numbers` when calling
|
|
/// `printInt(atAddress:)`.
|
|
///
|
|
/// let numbers = [5, 10, 15, 20]
|
|
/// printInt(atAddress: numbers)
|
|
/// // Prints "5"
|
|
///
|
|
/// You can also use inout syntax to pass a mutable pointer to the elements of
|
|
/// an array. Because `printInt(atAddress:)` requires an immutable pointer,
|
|
/// although this is syntactically valid, it isn't necessary.
|
|
///
|
|
/// var mutableNumbers = numbers
|
|
/// printInt(atAddress: &mutableNumbers)
|
|
///
|
|
/// No matter which way you call `printInt(atAddress:)`, Swift's type safety
|
|
/// guarantees that you can only pass a pointer to the type required by the
|
|
/// function---in this case, a pointer to an `Int`.
|
|
%end
|
|
///
|
|
/// - Important: The pointer created through implicit bridging of an instance
|
|
/// or of an array's elements is only valid during the execution of the
|
|
/// called function. Escaping the pointer to use after the execution of the
|
|
/// function is undefined behavior. In particular, do not use implicit
|
|
/// bridging when calling an `${Self}` initializer.
|
|
///
|
|
/// var number = 5
|
|
/// let numberPointer = Unsafe${Mutable}Pointer<Int>(&number)
|
|
/// // Accessing 'numberPointer' is undefined behavior.
|
|
@_fixed_layout
|
|
public struct ${Self}<Pointee>: _Pointer {
|
|
|
|
/// A type that represents the distance between two pointers.
|
|
public typealias Distance = Int
|
|
|
|
/// The underlying raw (untyped) pointer.
|
|
public let _rawValue: Builtin.RawPointer
|
|
|
|
/// Creates ${a_Self} from a builtin raw pointer.
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@_transparent
|
|
public init(_ _rawValue : Builtin.RawPointer) {
|
|
self._rawValue = _rawValue
|
|
}
|
|
|
|
/// Creates a new typed pointer from the given opaque pointer.
|
|
///
|
|
/// - Parameter from: The opaque pointer to convert to a typed pointer.
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@_transparent
|
|
public init(_ from : OpaquePointer) {
|
|
_rawValue = from._rawValue
|
|
}
|
|
|
|
/// Creates a new typed pointer from the given opaque pointer.
|
|
///
|
|
/// - Parameter from: The opaque pointer to convert to a typed pointer. If
|
|
/// `from` is `nil`, the result of this initializer is `nil`.
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@_transparent
|
|
public init?(_ from : OpaquePointer?) {
|
|
guard let unwrapped = from else { return nil }
|
|
self.init(unwrapped)
|
|
}
|
|
|
|
/// Creates a new typed pointer from the given address, specified as a bit
|
|
/// pattern.
|
|
///
|
|
/// The address passed as `bitPattern` must have the correct alignment for
|
|
/// the pointer's `Pointee` type. That is,
|
|
/// `bitPattern % MemoryLayout<Pointee>.alignment` must be `0`.
|
|
///
|
|
/// - Parameter bitPattern: A bit pattern to use for the address of the new
|
|
/// pointer. If `bitPattern` is zero, the result is `nil`.
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@_transparent
|
|
public init?(bitPattern: Int) {
|
|
if bitPattern == 0 { return nil }
|
|
self._rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue)
|
|
}
|
|
|
|
/// Creates a new typed pointer from the given address, specified as a bit
|
|
/// pattern.
|
|
///
|
|
/// The address passed as `bitPattern` must have the correct alignment for
|
|
/// the pointer's `Pointee` type. That is,
|
|
/// `bitPattern % MemoryLayout<Pointee>.alignment` must be `0`.
|
|
///
|
|
/// - Parameter bitPattern: A bit pattern to use for the address of the new
|
|
/// pointer. If `bitPattern` is zero, the result is `nil`.
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@_transparent
|
|
public init?(bitPattern: UInt) {
|
|
if bitPattern == 0 { return nil }
|
|
self._rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue)
|
|
}
|
|
|
|
/// Creates a new pointer from the given typed pointer.
|
|
///
|
|
/// - Parameter other: The typed pointer to convert.
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@_transparent
|
|
public init(_ other: ${Self}<Pointee>) {
|
|
self = other
|
|
}
|
|
|
|
/// Creates a new pointer from the given typed pointer.
|
|
///
|
|
/// - Parameter other: The typed pointer to convert. If `other` is `nil`, the
|
|
/// result is `nil`.
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@_transparent
|
|
public init?(_ other: ${Self}<Pointee>?) {
|
|
guard let unwrapped = other else { return nil }
|
|
self = unwrapped
|
|
}
|
|
|
|
% if mutable:
|
|
/// Creates a mutable typed pointer referencing the same memory as the given
|
|
/// immutable pointer.
|
|
///
|
|
/// - Parameter other: The immutable pointer to convert.
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@_transparent
|
|
public init(mutating other: UnsafePointer<Pointee>) {
|
|
self._rawValue = other._rawValue
|
|
}
|
|
|
|
/// Creates a mutable typed pointer referencing the same memory as the given
|
|
/// immutable pointer.
|
|
///
|
|
/// - Parameter other: The immutable pointer to convert. If `other` is `nil`,
|
|
/// the result is `nil`.
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@_transparent
|
|
public init?(mutating other: UnsafePointer<Pointee>?) {
|
|
guard let unwrapped = other else { return nil }
|
|
self.init(mutating: unwrapped)
|
|
}
|
|
% else:
|
|
/// Creates an immutable typed pointer referencing the same memory as the
|
|
/// given mutable pointer.
|
|
///
|
|
/// - Parameter other: The pointer to convert.
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@_transparent
|
|
public init(_ other: UnsafeMutablePointer<Pointee>) {
|
|
self._rawValue = other._rawValue
|
|
}
|
|
|
|
/// Creates an immutable typed pointer referencing the same memory as the
|
|
/// given mutable pointer.
|
|
///
|
|
/// - Parameter other: The pointer to convert. If `other` is `nil`, the
|
|
/// result is `nil`.
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@_transparent
|
|
public init?(_ other: UnsafeMutablePointer<Pointee>?) {
|
|
guard let unwrapped = other else { return nil }
|
|
self.init(unwrapped)
|
|
}
|
|
% end
|
|
|
|
% if mutable:
|
|
/// Allocates uninitialized memory for the specified number of instances of
|
|
/// type `Pointee`.
|
|
///
|
|
/// The resulting pointer references a region of memory that is bound to
|
|
/// `Pointee` and is `count * MemoryLayout<Pointee>.stride` bytes in size.
|
|
///
|
|
/// The following example allocates enough new memory to store four `Int`
|
|
/// instances and then initializes that memory with the elements of a range.
|
|
///
|
|
/// let intPointer = UnsafeMutablePointer<Int>.allocate(capacity: 4)
|
|
/// intPointer.initialize(from: 1...4)
|
|
/// print(intPointer.pointee)
|
|
/// // Prints "1"
|
|
///
|
|
/// When you allocate memory, always remember to deallocate once you're
|
|
/// finished.
|
|
///
|
|
/// intPointer.deallocate()
|
|
///
|
|
/// - Parameter count: The amount of memory to allocate, counted in instances
|
|
/// of `Pointee`.
|
|
@inlinable
|
|
public static func allocate(capacity count: Int)
|
|
-> UnsafeMutablePointer<Pointee> {
|
|
let size = MemoryLayout<Pointee>.stride * count
|
|
let rawPtr =
|
|
Builtin.allocRaw(size._builtinWordValue, Builtin.alignof(Pointee.self))
|
|
Builtin.bindMemory(rawPtr, count._builtinWordValue, Pointee.self)
|
|
return UnsafeMutablePointer(rawPtr)
|
|
}
|
|
|
|
@available(swift, deprecated: 4.1, obsoleted: 5.0.0, message: "Swift currently only supports freeing entire heap blocks, use deallocate() instead")
|
|
public func deallocate(capacity _: Int) {
|
|
self.deallocate()
|
|
}
|
|
|
|
% end
|
|
|
|
/// Deallocates the memory block previously allocated at this pointer.
|
|
///
|
|
/// This pointer must be a pointer to the start of a previously allocated memory
|
|
/// block. The memory must not be initialized or `Pointee` must be a trivial type.
|
|
@inlinable
|
|
public func deallocate() {
|
|
Builtin.deallocRaw(_rawValue, (-1)._builtinWordValue, (-1)._builtinWordValue)
|
|
}
|
|
|
|
/// Accesses the instance referenced by this pointer.
|
|
///
|
|
% if mutable:
|
|
/// When reading from the `pointee` property, the instance referenced by this
|
|
/// pointer must already be initialized. When `pointee` is used as the left
|
|
/// side of an assignment, the instance must be initialized or this
|
|
/// pointer's `Pointee` type must be a trivial type.
|
|
///
|
|
/// Do not assign an instance of a nontrivial type through `pointee` to
|
|
/// uninitialized memory. Instead, use an initializing method, such as
|
|
/// `initialize(to:count:)`.
|
|
% else:
|
|
/// When reading from the `pointee` property, the instance referenced by
|
|
/// this pointer must already be initialized.
|
|
% end
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
public var pointee: Pointee {
|
|
% if mutable:
|
|
@_transparent unsafeAddress {
|
|
return UnsafePointer(self)
|
|
}
|
|
@_transparent nonmutating unsafeMutableAddress {
|
|
return self
|
|
}
|
|
% else:
|
|
@_transparent unsafeAddress {
|
|
return self
|
|
}
|
|
% end
|
|
}
|
|
|
|
% if mutable:
|
|
@available(swift, deprecated: 4.1, obsoleted: 5.0.0, renamed: "initialize(repeating:count:)")
|
|
public func initialize(to newValue: Pointee, count: Int = 1) {
|
|
initialize(repeating: newValue, count: count)
|
|
}
|
|
|
|
/// Initializes this pointer's memory with the specified number of
|
|
/// consecutive copies of the given value.
|
|
///
|
|
/// The destination memory must be uninitialized or the pointer's `Pointee`
|
|
/// must be a trivial type. After a call to `initialize(repeating:count:)`, the
|
|
/// memory referenced by this pointer is initialized.
|
|
///
|
|
/// - Parameters:
|
|
/// - repeatedValue: The instance to initialize this pointer's memory with.
|
|
/// - count: The number of consecutive copies of `newValue` to initialize.
|
|
/// `count` must not be negative.
|
|
@inlinable
|
|
public func initialize(repeating repeatedValue: Pointee, count: Int) {
|
|
// FIXME: add tests (since the `count` has been added)
|
|
_debugPrecondition(count >= 0,
|
|
"${Self}.initialize(repeating:count:): negative count")
|
|
// Must not use `initializeFrom` with a `Collection` as that will introduce
|
|
// a cycle.
|
|
for offset in 0..<count {
|
|
Builtin.initialize(repeatedValue, (self + offset)._rawValue)
|
|
}
|
|
}
|
|
|
|
/// Initializes this pointer's memory with a single instance of the given value.
|
|
///
|
|
/// The destination memory must be uninitialized or the pointer's `Pointee`
|
|
/// must be a trivial type. After a call to `initialize(to:)`, the
|
|
/// memory referenced by this pointer is initialized. Calling this method is
|
|
/// roughly equivalent to calling `initialize(repeating:count:)` with a
|
|
/// `count` of 1.
|
|
///
|
|
/// - Parameters:
|
|
/// - value: The instance to initialize this pointer's pointee to.
|
|
@inlinable
|
|
public func initialize(to value: Pointee) {
|
|
Builtin.initialize(value, self._rawValue)
|
|
}
|
|
|
|
/// Retrieves and returns the referenced instance, returning the pointer's
|
|
/// memory to an uninitialized state.
|
|
///
|
|
/// Calling the `move()` method on a pointer `p` that references memory of
|
|
/// type `T` is equivalent to the following code, aside from any cost and
|
|
/// incidental side effects of copying and destroying the value:
|
|
///
|
|
/// let value: T = {
|
|
/// defer { p.deinitialize(count: 1) }
|
|
/// return p.pointee
|
|
/// }()
|
|
///
|
|
/// The memory referenced by this pointer must be initialized. After calling
|
|
/// `move()`, the memory is uninitialized.
|
|
///
|
|
/// - Returns: The instance referenced by this pointer.
|
|
@inlinable
|
|
public func move() -> Pointee {
|
|
return Builtin.take(_rawValue)
|
|
}
|
|
|
|
/// Replaces this pointer's memory with the specified number of
|
|
/// consecutive copies of the given value.
|
|
///
|
|
/// The region of memory starting at this pointer and covering `count`
|
|
/// instances of the pointer's `Pointee` type must be initialized or
|
|
/// `Pointee` must be a trivial type. After calling
|
|
/// `assign(repeating:count:)`, the region is initialized.
|
|
///
|
|
/// - Parameters:
|
|
/// - repeatedValue: The instance to assign this pointer's memory to.
|
|
/// - count: The number of consecutive copies of `newValue` to assign.
|
|
/// `count` must not be negative.
|
|
@inlinable
|
|
public func assign(repeating repeatedValue: Pointee, count: Int) {
|
|
_debugPrecondition(count >= 0, "${Self}.assign(repeating:count:) with negative count")
|
|
for i in 0..<count {
|
|
self[i] = repeatedValue
|
|
}
|
|
}
|
|
|
|
/// Replaces this pointer's initialized memory with the specified number of
|
|
/// instances from the given pointer's memory.
|
|
///
|
|
/// The region of memory starting at this pointer and covering `count`
|
|
/// instances of the pointer's `Pointee` type must be initialized or
|
|
/// `Pointee` must be a trivial type. After calling
|
|
/// `assign(from:count:)`, the region is initialized.
|
|
///
|
|
/// - Note: Returns without performing work if `self` and `source` are equal.
|
|
///
|
|
/// - Parameters:
|
|
/// - source: A pointer to at least `count` initialized instances of type
|
|
/// `Pointee`. The memory regions referenced by `source` and this
|
|
/// pointer may overlap.
|
|
/// - count: The number of instances to copy from the memory referenced by
|
|
/// `source` to this pointer's memory. `count` must not be negative.
|
|
@inlinable
|
|
public func assign(from source: UnsafePointer<Pointee>, count: Int) {
|
|
_debugPrecondition(
|
|
count >= 0, "${Self}.assign with negative count")
|
|
if UnsafePointer(self) < source || UnsafePointer(self) >= source + count {
|
|
// assign forward from a disjoint or following overlapping range.
|
|
Builtin.assignCopyArrayFrontToBack(
|
|
Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue)
|
|
// This builtin is equivalent to:
|
|
// for i in 0..<count {
|
|
// self[i] = source[i]
|
|
// }
|
|
}
|
|
else if UnsafePointer(self) != source {
|
|
// assign backward from a non-following overlapping range.
|
|
Builtin.assignCopyArrayBackToFront(
|
|
Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue)
|
|
// This builtin is equivalent to:
|
|
// var i = count-1
|
|
// while i >= 0 {
|
|
// self[i] = source[i]
|
|
// i -= 1
|
|
// }
|
|
}
|
|
}
|
|
|
|
/// Moves instances from initialized source memory into the uninitialized
|
|
/// memory referenced by this pointer, leaving the source memory
|
|
/// uninitialized and the memory referenced by this pointer initialized.
|
|
///
|
|
/// The region of memory starting at this pointer and covering `count`
|
|
/// instances of the pointer's `Pointee` type must be uninitialized or
|
|
/// `Pointee` must be a trivial type. After calling
|
|
/// `initialize(from:count:)`, the region is initialized and the memory
|
|
/// region `source..<(source + count)` is uninitialized.
|
|
///
|
|
/// - Parameters:
|
|
/// - source: A pointer to the values to copy. The memory region
|
|
/// `source..<(source + count)` must be initialized. The memory regions
|
|
/// referenced by `source` and this pointer may overlap.
|
|
/// - count: The number of instances to move from `source` to this
|
|
/// pointer's memory. `count` must not be negative.
|
|
@inlinable
|
|
public func moveInitialize(from source: ${Self}, count: Int) {
|
|
_debugPrecondition(
|
|
count >= 0, "${Self}.moveInitialize with negative count")
|
|
if self < source || self >= source + count {
|
|
// initialize forward from a disjoint or following overlapping range.
|
|
Builtin.takeArrayFrontToBack(
|
|
Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue)
|
|
// This builtin is equivalent to:
|
|
// for i in 0..<count {
|
|
// (self + i).initialize(to: (source + i).move())
|
|
// }
|
|
}
|
|
else {
|
|
// initialize backward from a non-following overlapping range.
|
|
Builtin.takeArrayBackToFront(
|
|
Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue)
|
|
// This builtin is equivalent to:
|
|
// var src = source + count
|
|
// var dst = self + count
|
|
// while dst != self {
|
|
// (--dst).initialize(to: (--src).move())
|
|
// }
|
|
}
|
|
}
|
|
|
|
/// Initializes the memory referenced by this pointer with the values
|
|
/// starting at the given pointer.
|
|
///
|
|
/// The region of memory starting at this pointer and covering `count`
|
|
/// instances of the pointer's `Pointee` type must be uninitialized or
|
|
/// `Pointee` must be a trivial type. After calling
|
|
/// `initialize(from:count:)`, the region is initialized.
|
|
///
|
|
/// - Parameters:
|
|
/// - source: A pointer to the values to copy. The memory region
|
|
/// `source..<(source + count)` must be initialized. The memory regions
|
|
/// referenced by `source` and this pointer must not overlap.
|
|
/// - count: The number of instances to move from `source` to this
|
|
/// pointer's memory. `count` must not be negative.
|
|
@inlinable
|
|
public func initialize(from source: UnsafePointer<Pointee>, count: Int) {
|
|
_debugPrecondition(
|
|
count >= 0, "${Self}.initialize with negative count")
|
|
_debugPrecondition(
|
|
UnsafePointer(self) + count <= source ||
|
|
source + count <= UnsafePointer(self),
|
|
"${Self}.initialize overlapping range")
|
|
Builtin.copyArray(
|
|
Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue)
|
|
// This builtin is equivalent to:
|
|
// for i in 0..<count {
|
|
// (self + i).initialize(to: source[i])
|
|
// }
|
|
}
|
|
|
|
/// Initializes memory starting at this pointer's address with the elements
|
|
/// of the given collection.
|
|
///
|
|
/// The region of memory starting at this pointer and covering `source.count`
|
|
/// instances of the pointer's `Pointee` type must be uninitialized or
|
|
/// `Pointee` must be a trivial type. After calling `initialize(from:)`, the
|
|
/// region is initialized.
|
|
///
|
|
/// - Parameter source: A collection of elements of the pointer's `Pointee`
|
|
/// type.
|
|
// This is fundamentally unsafe since collections can underreport their count.
|
|
@inlinable
|
|
@available(*, deprecated, message: "it will be removed in Swift 4.0. Please use 'UnsafeMutableBufferPointer.initialize(from:)' instead")
|
|
public func initialize<C : Collection>(from source: C)
|
|
where C.Element == Pointee {
|
|
let buf = UnsafeMutableBufferPointer(start: self, count: numericCast(source.count))
|
|
var (remainders,writtenUpTo) = source._copyContents(initializing: buf)
|
|
// ensure that exactly rhs.count elements were written
|
|
_precondition(remainders.next() == nil, "rhs underreported its count")
|
|
_precondition(writtenUpTo == buf.endIndex, "rhs overreported its count")
|
|
}
|
|
|
|
/// Replaces the memory referenced by this pointer with the values
|
|
/// starting at the given pointer, leaving the source memory uninitialized.
|
|
///
|
|
/// The region of memory starting at this pointer and covering `count`
|
|
/// instances of the pointer's `Pointee` type must be initialized or
|
|
/// `Pointee` must be a trivial type. After calling
|
|
/// `initialize(from:count:)`, the region is initialized and the memory
|
|
/// region `source..<(source + count)` is uninitialized.
|
|
///
|
|
/// - Parameters:
|
|
/// - source: A pointer to the values to copy. The memory region
|
|
/// `source..<(source + count)` must be initialized. The memory regions
|
|
/// referenced by `source` and this pointer must not overlap.
|
|
/// - count: The number of instances to move from `source` to this
|
|
/// pointer's memory. `count` must not be negative.
|
|
@inlinable
|
|
public func moveAssign(from source: ${Self}, count: Int) {
|
|
_debugPrecondition(
|
|
count >= 0, "${Self}.moveAssign(from:) with negative count")
|
|
_debugPrecondition(
|
|
self + count <= source || source + count <= self,
|
|
"moveAssign overlapping range")
|
|
Builtin.assignTakeArray(
|
|
Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue)
|
|
// These builtins are equivalent to:
|
|
// for i in 0..<count {
|
|
// self[i] = (source + i).move()
|
|
// }
|
|
}
|
|
|
|
@available(swift, deprecated: 4.1, obsoleted: 5.0.0, message: "the default argument to deinitialize(count:) has been removed, please specify the count explicitly")
|
|
@inlinable
|
|
@discardableResult
|
|
public func deinitialize() -> UnsafeMutableRawPointer {
|
|
return deinitialize(count: 1)
|
|
}
|
|
|
|
/// Deinitializes the specified number of values starting at this pointer.
|
|
///
|
|
/// The region of memory starting at this pointer and covering `count`
|
|
/// instances of the pointer's `Pointee` type must be initialized. After
|
|
/// calling `deinitialize(count:)`, the memory is uninitialized, but still
|
|
/// bound to the `Pointee` type.
|
|
///
|
|
/// - Parameter count: The number of instances to deinitialize. `count` must
|
|
/// not be negative.
|
|
/// - Returns: A raw pointer to the same address as this pointer. The memory
|
|
/// referenced by the returned raw pointer is still bound to `Pointee`.
|
|
@inlinable
|
|
@discardableResult
|
|
public func deinitialize(count: Int) -> UnsafeMutableRawPointer {
|
|
_debugPrecondition(count >= 0, "${Self}.deinitialize with negative count")
|
|
// FIXME: optimization should be implemented, where if the `count` value
|
|
// is 1, the `Builtin.destroy(Pointee.self, _rawValue)` gets called.
|
|
Builtin.destroyArray(Pointee.self, _rawValue, count._builtinWordValue)
|
|
return UnsafeMutableRawPointer(self)
|
|
}
|
|
% end
|
|
|
|
/// Executes the given closure while temporarily binding the specified number
|
|
/// of instances to the given type.
|
|
///
|
|
/// Use this method when you have a pointer to memory bound to one type and
|
|
/// you need to access that memory as instances of another type. Accessing
|
|
/// memory as type `T` requires that the memory be bound to that type. A
|
|
/// memory location may only be bound to one type at a time, so accessing
|
|
/// the same memory as an unrelated type without first rebinding the memory
|
|
/// is undefined.
|
|
///
|
|
/// The region of memory starting at this pointer and covering `count`
|
|
/// instances of the pointer's `Pointee` type must be initialized.
|
|
///
|
|
/// The following example temporarily rebinds the memory of a `UInt64`
|
|
/// pointer to `Int64`, then accesses a property on the signed integer.
|
|
///
|
|
/// let uint64Pointer: Unsafe${Mutable}Pointer<UInt64> = fetchValue()
|
|
/// let isNegative = uint64Pointer.withMemoryRebound(to: Int64.self) { ptr in
|
|
/// return ptr.pointee < 0
|
|
/// }
|
|
///
|
|
/// Because this pointer's memory is no longer bound to its `Pointee` type
|
|
/// while the `body` closure executes, do not access memory using the
|
|
/// original pointer from within `body`. Instead, use the `body` closure's
|
|
/// pointer argument to access the values in memory as instances of type
|
|
/// `T`.
|
|
///
|
|
/// After executing `body`, this method rebinds memory back to the original
|
|
/// `Pointee` type.
|
|
///
|
|
/// - Note: Only use this method to rebind the pointer's memory to a type
|
|
/// with the same size and stride as the currently bound `Pointee` type.
|
|
/// To bind a region of memory to a type that is a different size, convert
|
|
/// the pointer to a raw pointer and use the `bindMemory(to:capacity:)`
|
|
/// method.
|
|
///
|
|
/// - Parameters:
|
|
/// - type: The type to temporarily bind the memory referenced by this
|
|
/// pointer. The type `T` must be the same size and be layout compatible
|
|
/// with the pointer's `Pointee` type.
|
|
/// - count: The number of instances of `T` to bind to `type`.
|
|
/// - body: A closure that takes a ${Mutable.lower()} typed pointer to the
|
|
/// same memory as this pointer, only bound to type `T`. The closure's
|
|
/// pointer argument is valid only for the duration of the closure's
|
|
/// execution. If `body` has a return value, that value is also used as
|
|
/// the return value for the `withMemoryRebound(to:capacity:_:)` method.
|
|
/// - Returns: The return value, if any, of the `body` closure parameter.
|
|
@inlinable
|
|
public func withMemoryRebound<T, Result>(to type: T.Type, capacity count: Int,
|
|
_ body: (${Self}<T>) throws -> Result
|
|
) rethrows -> Result {
|
|
Builtin.bindMemory(_rawValue, count._builtinWordValue, T.self)
|
|
defer {
|
|
Builtin.bindMemory(_rawValue, count._builtinWordValue, Pointee.self)
|
|
}
|
|
return try body(${Self}<T>(_rawValue))
|
|
}
|
|
|
|
/// Accesses the pointee at the specified offset from this pointer.
|
|
///
|
|
% if mutable:
|
|
/// For a pointer `p`, the memory at `p + i` must be initialized when reading
|
|
/// the value by using the subscript. When the subscript is used as the left
|
|
/// side of an assignment, the memory at `p + i` must be initialized or
|
|
/// the pointer's `Pointee` type must be a trivial type.
|
|
///
|
|
/// Do not assign an instance of a nontrivial type through the subscript to
|
|
/// uninitialized memory. Instead, use an initializing method, such as
|
|
/// `initialize(to:count:)`.
|
|
% else:
|
|
///
|
|
/// For a pointer `p`, the memory at `p + i` must be initialized.
|
|
% end
|
|
///
|
|
/// - Parameter i: The offset from this pointer at which to access an
|
|
/// instance, measured in strides of the pointer's `Pointee` type.
|
|
@inlinable
|
|
public subscript(i: Int) -> Pointee {
|
|
% if mutable:
|
|
@_transparent
|
|
unsafeAddress {
|
|
return UnsafePointer(self + i)
|
|
}
|
|
@_transparent
|
|
nonmutating unsafeMutableAddress {
|
|
return self + i
|
|
}
|
|
% else:
|
|
@_transparent
|
|
unsafeAddress {
|
|
return self + i
|
|
}
|
|
% end
|
|
}
|
|
}
|
|
|
|
extension ${Self}: Equatable {
|
|
// - Note: Strideable's implementation is potentially less efficient and cannot
|
|
// handle misaligned pointers.
|
|
/// Returns a Boolean value indicating whether two pointers are equal.
|
|
///
|
|
/// - Parameters:
|
|
/// - lhs: A pointer.
|
|
/// - rhs: Another pointer.
|
|
/// - Returns: `true` if `lhs` and `rhs` reference the same memory address;
|
|
/// otherwise, `false`.
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@_transparent
|
|
public static func == (lhs: ${Self}<Pointee>, rhs: ${Self}<Pointee>) -> Bool {
|
|
return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue))
|
|
}
|
|
}
|
|
|
|
extension ${Self}: Comparable {
|
|
// - Note: Strideable's implementation is potentially less efficient and
|
|
// cannot handle misaligned pointers.
|
|
//
|
|
// - Note: This is an unsigned comparison unlike Strideable's implementation.
|
|
/// Returns a Boolean value indicating whether the first pointer references
|
|
/// an earlier memory location than the second pointer.
|
|
///
|
|
/// - Parameters:
|
|
/// - lhs: A pointer.
|
|
/// - rhs: Another pointer.
|
|
/// - Returns: `true` if `lhs` references a memory address earlier than
|
|
/// `rhs`; otherwise, `false`.
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@_transparent
|
|
public static func < (lhs: ${Self}<Pointee>, rhs: ${Self}<Pointee>) -> Bool {
|
|
return Bool(Builtin.cmp_ult_RawPointer(lhs._rawValue, rhs._rawValue))
|
|
}
|
|
}
|
|
extension ${Self}: Hashable {
|
|
/// The pointer's hash value.
|
|
///
|
|
/// The hash value is not guaranteed to be stable across different
|
|
/// invocations of the same program. Do not persist the hash value across
|
|
/// program runs.
|
|
@inlinable
|
|
public var hashValue: Int {
|
|
return _hashValue(for: self)
|
|
}
|
|
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
public func _hash(into hasher: inout _Hasher) {
|
|
hasher.combine(Int(bitPattern: self))
|
|
}
|
|
}
|
|
|
|
extension ${Self}: Strideable {
|
|
/// Returns a pointer to the next consecutive instance.
|
|
///
|
|
/// The resulting pointer must be within the bounds of the same allocation as
|
|
/// this pointer.
|
|
///
|
|
/// - Returns: A pointer advanced from this pointer by
|
|
/// `MemoryLayout<Pointee>.stride` bytes.
|
|
@inlinable
|
|
public func successor() -> ${Self} {
|
|
return advanced(by: 1)
|
|
}
|
|
|
|
/// Returns a pointer to the previous consecutive instance.
|
|
///
|
|
/// The resulting pointer must be within the bounds of the same allocation as
|
|
/// this pointer.
|
|
///
|
|
/// - Returns: A pointer shifted backward from this pointer by
|
|
/// `MemoryLayout<Pointee>.stride` bytes.
|
|
@inlinable
|
|
public func predecessor() -> ${Self} {
|
|
return self - 1
|
|
}
|
|
|
|
/// Returns the distance from this pointer to the given pointer, counted as
|
|
/// instances of the pointer's `Pointee` type.
|
|
///
|
|
/// With pointers `p` and `q`, the result of `p.distance(to: q)` is
|
|
/// equivalent to `q - p`.
|
|
///
|
|
/// Typed pointers are required to be properly aligned for their `Pointee`
|
|
/// type. Proper alignment ensures that the result of `distance(to:)`
|
|
/// accurately measures the distance between the two pointers, counted in
|
|
/// strides of `Pointee`. To find the distance in bytes between two
|
|
/// pointers, convert them to `UnsafeRawPointer` instances before calling
|
|
/// `distance(to:)`.
|
|
///
|
|
/// - Parameter end: The pointer to calculate the distance to.
|
|
/// - Returns: The distance from this pointer to `end`, in strides of the
|
|
/// pointer's `Pointee` type. To access the stride, use
|
|
/// `MemoryLayout<Pointee>.stride`.
|
|
@inlinable
|
|
public func distance(to end: ${Self}) -> Int {
|
|
return
|
|
Int(Builtin.sub_Word(Builtin.ptrtoint_Word(end._rawValue),
|
|
Builtin.ptrtoint_Word(_rawValue)))
|
|
/ MemoryLayout<Pointee>.stride
|
|
}
|
|
|
|
/// Returns a pointer offset from this pointer by the specified number of
|
|
/// instances.
|
|
///
|
|
/// With pointer `p` and distance `n`, the result of `p.advanced(by: n)` is
|
|
/// equivalent to `p + n`.
|
|
///
|
|
/// The resulting pointer must be within the bounds of the same allocation as
|
|
/// this pointer.
|
|
///
|
|
/// - Parameter n: The number of strides of the pointer's `Pointee` type to
|
|
/// offset this pointer. To access the stride, use
|
|
/// `MemoryLayout<Pointee>.stride`. `n` may be positive, negative, or
|
|
/// zero.
|
|
/// - Returns: A pointer offset from this pointer by `n` instances of the
|
|
/// `Pointee` type.
|
|
@inlinable
|
|
public func advanced(by n: Int) -> ${Self} {
|
|
return ${Self}(Builtin.gep_Word(
|
|
self._rawValue, n._builtinWordValue, Pointee.self))
|
|
}
|
|
}
|
|
|
|
extension ${Self} : CustomDebugStringConvertible {
|
|
/// A textual representation of the pointer, suitable for debugging.
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
public var debugDescription: String {
|
|
return _rawPointerToString(_rawValue)
|
|
}
|
|
}
|
|
|
|
extension ${Self} : CustomReflectable {
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
public var customMirror: Mirror {
|
|
let ptrValue = UInt64(bitPattern: Int64(Int(Builtin.ptrtoint_Word(_rawValue))))
|
|
return Mirror(self, children: ["pointerValue": ptrValue])
|
|
}
|
|
}
|
|
|
|
extension ${Self} : CustomPlaygroundQuickLookable {
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
internal var summary: String {
|
|
let selfType = "${Self}"
|
|
let ptrValue = UInt64(bitPattern: Int64(Int(Builtin.ptrtoint_Word(_rawValue))))
|
|
return ptrValue == 0 ? "\(selfType)(nil)" : "\(selfType)(0x\(_uint64ToString(ptrValue, radix:16, uppercase:true)))"
|
|
}
|
|
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
@available(*, deprecated, message: "${Self}.customPlaygroundQuickLook will be removed in a future Swift version")
|
|
public var customPlaygroundQuickLook: PlaygroundQuickLook {
|
|
return .text(summary)
|
|
}
|
|
}
|
|
|
|
extension Int {
|
|
/// Creates a new value with the bit pattern of the given pointer.
|
|
///
|
|
/// The new value represents the address of the pointer passed as `pointer`.
|
|
/// If `pointer` is `nil`, the result is `0`.
|
|
///
|
|
/// - Parameter pointer: The pointer to use as the source for the new
|
|
/// integer.
|
|
@inlinable
|
|
public init<U>(bitPattern pointer: ${Self}<U>?) {
|
|
if let pointer = pointer {
|
|
self = Int(Builtin.ptrtoint_Word(pointer._rawValue))
|
|
} else {
|
|
self = 0
|
|
}
|
|
}
|
|
}
|
|
|
|
extension UInt {
|
|
/// Creates a new value with the bit pattern of the given pointer.
|
|
///
|
|
/// The new value represents the address of the pointer passed as `pointer`.
|
|
/// If `pointer` is `nil`, the result is `0`.
|
|
///
|
|
/// - Parameter pointer: The pointer to use as the source for the new
|
|
/// integer.
|
|
@inlinable
|
|
public init<U>(bitPattern pointer: ${Self}<U>?) {
|
|
if let pointer = pointer {
|
|
self = UInt(Builtin.ptrtoint_Word(pointer._rawValue))
|
|
} else {
|
|
self = 0
|
|
}
|
|
}
|
|
}
|
|
|
|
extension ${Self} {
|
|
@inlinable // FIXME(sil-serialize-all)
|
|
internal static var _max : ${Self} {
|
|
return ${Self}(
|
|
bitPattern: 0 as Int &- MemoryLayout<Pointee>.stride
|
|
)._unsafelyUnwrappedUnchecked
|
|
}
|
|
}
|
|
% end # for mutable
|
|
|
|
// ${'Local Variables'}:
|
|
// eval: (read-only-mode 1)
|
|
// End:
|