blob: 5d0259c193e4f6593fff2647bb3815b53b5fc4c8 [file] [log] [blame]
//===--- UnsafeRawPointer.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 = 'UnsafeMutableRawPointer' if mutable else 'UnsafeRawPointer'
% a_Self = 'an `UnsafeMutableRawPointer`' if mutable else 'an `UnsafeRawPointer`'
% Mutable = 'Mutable' if mutable else ''
% ConvertibleTypes = '`UnsafeMutablePointer`' if mutable else '`UnsafeMutablePointer` or `UnsafePointer`'
/// A raw pointer for accessing ${'and manipulating' if mutable else ''}
/// untyped data.
///
/// The `${Self}` type provides no automated memory management, no type safety,
/// and no 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}RawPointer` type to access and
/// manage raw bytes in memory, whether or not that memory has been bound to a
/// specific type.
///
/// Understanding a Pointer's Memory State
/// ======================================
///
/// The memory referenced by an `${Self}` 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.
///
/// Raw, Uninitialized Memory
/// -------------------------
///
/// Raw memory that has just been allocated is in an *uninitialized, untyped*
/// state. Uninitialized memory must be initialized with values of a type
/// before it can be used with any typed operations.
///
%if mutable:
/// You can use methods like `initializeMemory(as:from:)` and
/// `moveInitializeMemory(as:from:count:)` to bind raw memory to a type and
/// initialize it with a value or series of values. To bind uninitialized
/// memory to a type without initializing it, use the `bindMemory(to:count:)`
/// method. These methods all return typed pointers for further typed access
/// to the memory.
% else:
/// To bind uninitialized memory to a type without initializing it, use the
/// `bindMemory(to:count:)` method. This method returns a typed pointer
/// for further typed access to the memory.
% end
///
/// Typed Memory
/// ------------
///
/// Memory that has been bound to a type, whether it is initialized or
/// uninitialized, is typically accessed using typed pointers---instances of
/// `UnsafePointer` and `UnsafeMutablePointer`. Initialization, assignment,
/// and deinitialization can be performed using `UnsafeMutablePointer`
/// methods.
///
/// Memory that has been bound to a type can be rebound to a different type
/// only after it has been deinitialized or if the bound type is a *trivial
/// type*. Deinitializing typed memory does not unbind that memory's type. The
/// deinitialized memory can be reinitialized with values of the same type,
/// bound to a new type, or deallocated.
///
/// - Note: A trivial type can be copied bit for bit with no indirection or
/// reference-counting operations. Generally, native Swift types that do not
/// contain strong or weak references or other forms of indirection are
/// trivial, as are imported C structs and enumerations.
///
/// When reading from ${'or writing to ' if mutable else ''} memory as raw
/// bytes when that memory is bound to a type, you must ensure that you
/// satisfy any alignment requirements.
%if mutable:
/// Writing to typed memory as raw bytes must only be performed when the bound
/// type is a trivial type.
%end
///
/// Raw Pointer Arithmetic
/// ======================
///
/// Pointer arithmetic with raw pointers is performed at the byte level. When
/// you add to or subtract from a raw pointer, the result is a new raw pointer
/// offset by that number of bytes. The following example allocates four bytes
/// of memory and stores `0xFF` in all four bytes:
///
/// let bytesPointer = UnsafeMutableRawPointer.allocate(byteCount: 4, alignment: 1)
/// bytesPointer.storeBytes(of: 0xFFFF_FFFF, as: UInt32.self)
///
/// // Load a value from the memory referenced by 'bytesPointer'
/// let x = bytesPointer.load(as: UInt8.self) // 255
///
/// // Load a value from the last two allocated bytes
/// let offsetPointer = bytesPointer + 2
/// let y = offsetPointer.load(as: UInt16.self) // 65535
///
/// The code above stores the value `0xFFFF_FFFF` into the four newly allocated
/// bytes, and then loads the first byte as a `UInt8` instance and the third
/// and fourth bytes as a `UInt16` instance.
///
/// Always remember to deallocate any memory that you allocate yourself.
///
/// bytesPointer.deallocate()
///
/// Implicit Casting and Bridging
/// =============================
///
/// 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 `print(address:as:)` function in the following code sample
/// takes an `${Self}` instance as its first parameter:
///
/// func print<T>(address p: Unsafe${Mutable}RawPointer, as type: T.Type) {
/// let value = p.load(as: type)
/// print(value)
/// }
///
/// As is typical in Swift, you can call the `print(address:as:)` function with
/// an `${Self}` instance. This example passes `rawPointer` as the initial
/// parameter.
///
/// // 'rawPointer' points to memory initialized with `Int` values.
/// let rawPointer: Unsafe${Mutable}RawPointer = ...
/// print(address: rawPointer, as: Int.self)
/// // Prints "42"
///
%if mutable:
/// Because typed pointers can be implicitly cast to raw pointers when passed
/// as a parameter, you can also call `print(address:as:)` with any mutable
/// typed pointer instance.
///
/// let intPointer: UnsafeMutablePointer<Int> = ...
/// print(address: intPointer, as: Int.self)
/// // Prints "42"
///
/// Alternatively, you can use Swift's *implicit bridging* to pass a pointer to
/// an instance or to the elements of an array. Use inout syntax to implicitly
/// create a pointer to an instance of any type. The following example uses
/// implicit bridging to pass a pointer to `value` when calling
/// `print(address:as:)`:
///
/// var value: Int = 23
/// print(address: &value, as: Int.self)
/// // 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
/// `print(address:as:)`.
///
/// var numbers = [5, 10, 15, 20]
/// print(address: &numbers, as: Int.self)
/// // Prints "5"
%else: #!mutable
/// Because typed pointers can be implicitly cast to raw pointers when passed
/// as a parameter, you can also call `print(address:as:)` with any mutable or
/// immutable typed pointer instance.
///
/// let intPointer: UnsafePointer<Int> = ...
/// print(address: intPointer, as: Int.self)
/// // Prints "42"
///
/// let mutableIntPointer = UnsafeMutablePointer(mutating: intPointer)
/// print(address: mutableIntPointer, as: Int.self)
/// // Prints "42"
///
/// Alternatively, you can use Swift's *implicit bridging* to pass a pointer to
/// an instance or to the elements of an array. Use inout syntax to implicitly
/// create a pointer to an instance of any type. The following example uses
/// implicit bridging to pass a pointer to `value` when calling
/// `print(address:as:)`:
///
/// var value: Int = 23
/// print(address: &value, as: Int.self)
/// // 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
/// `print(address:as:)`.
///
/// let numbers = [5, 10, 15, 20]
/// print(address: numbers, as: Int.self)
/// // Prints "5"
///
/// You can also use inout syntax to pass a mutable pointer to the elements of
/// an array. Because `print(address:as:)` requires an immutable pointer,
/// although this is syntactically valid, it isn't necessary.
///
/// var mutableNumbers = numbers
/// print(address: &mutableNumbers, as: Int.self)
%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 = ${Self}(&number)
/// // Accessing 'numberPointer' is undefined behavior.
@_fixed_layout
public struct Unsafe${Mutable}RawPointer: _Pointer {
/// The underlying raw pointer.
/// Implements conformance to the public protocol `_Pointer`.
public let _rawValue: Builtin.RawPointer
/// Creates a new raw pointer from the given raw or typed pointer.
///
/// Use this initializer to explicitly convert `other` to an `${Self}`
/// instance. This initializer creates a new pointer to the same address as
/// `other` and performs no allocation or copying.
///
/// - Parameter other: The pointer to convert.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public init(_ other: Unsafe${Mutable}RawPointer) {
self = other
}
/// Creates a new raw pointer from the given raw or typed pointer.
///
/// Use this initializer to explicitly convert `other` to an `${Self}`
/// instance. This initializer creates a new pointer to the same address as
/// `other` and performs no allocation or copying.
///
/// - Parameter other: The pointer to convert. If `other` is `nil`, the
/// result is `nil`.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public init?(_ other: Unsafe${Mutable}RawPointer?) {
guard let unwrapped = other else { return nil }
self = unwrapped
}
/// Creates a new raw pointer from a builtin raw pointer.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public init(_ _rawValue: Builtin.RawPointer) {
self._rawValue = _rawValue
}
/// Creates a new raw pointer from the given opaque pointer.
///
/// Use this initializer to explicitly convert `other` to an `${Self}`
/// instance. This initializer creates a new pointer to the same address as
/// `other` and performs no allocation or copying.
///
/// - Parameter other: The opaque pointer to convert.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public init(_ other: OpaquePointer) {
_rawValue = other._rawValue
}
/// Creates a new raw pointer from the given opaque pointer.
///
/// Use this initializer to explicitly convert `other` to an `${Self}`
/// instance. This initializer creates a new pointer to the same address as
/// `other` and performs no allocation or copying.
///
/// - Parameter other: The opaque pointer to convert. If `other` is `nil`,
/// the result is `nil`.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public init?(_ other: OpaquePointer?) {
guard let unwrapped = other else { return nil }
_rawValue = unwrapped._rawValue
}
/// Creates a new raw pointer from the given address, specified as a bit
/// pattern.
///
/// - Parameter bitPattern: A bit pattern to use for the address of the new
/// raw pointer. If `bitPattern` is zero, the result is `nil`.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public init?(bitPattern: Int) {
if bitPattern == 0 { return nil }
_rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue)
}
/// Creates a new raw pointer from the given address, specified as a bit
/// pattern.
///
/// - Parameter bitPattern: A bit pattern to use for the address of the new
/// raw pointer. If `bitPattern` is zero, the result is `nil`.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public init?(bitPattern: UInt) {
if bitPattern == 0 { return nil }
_rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue)
}
/// Creates a new raw pointer from the given typed pointer.
///
/// Use this initializer to explicitly convert `other` to an `${Self}`
/// instance. This initializer creates a new pointer to the same address as
/// `other` and performs no allocation or copying.
///
/// - Parameter other: The typed pointer to convert.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public init<T>(_ other: Unsafe${Mutable}Pointer<T>) {
_rawValue = other._rawValue
}
/// Creates a new raw pointer from the given typed pointer.
///
/// Use this initializer to explicitly convert `other` to an `${Self}`
/// instance. This initializer creates a new pointer to the same address as
/// `other` and performs no allocation or copying.
///
/// - Parameter other: The typed pointer to convert. If `other` is `nil`, the
/// result is `nil`.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public init?<T>(_ other: Unsafe${Mutable}Pointer<T>?) {
guard let unwrapped = other else { return nil }
_rawValue = unwrapped._rawValue
}
% if mutable:
/// Creates a new mutable raw pointer from the given immutable raw pointer.
///
/// Use this initializer to explicitly convert `other` to an `${Self}`
/// instance. This initializer creates a new pointer to the same address as
/// `other` and performs no allocation or copying.
///
/// - Parameter other: The immutable raw pointer to convert.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public init(mutating other: UnsafeRawPointer) {
_rawValue = other._rawValue
}
/// Creates a new mutable raw pointer from the given immutable raw pointer.
///
/// Use this initializer to explicitly convert `other` to an `${Self}`
/// instance. This initializer creates a new pointer to the same address as
/// `other` and performs no allocation or copying.
///
/// - Parameter other: The immutable raw pointer to convert. If `other` is
/// `nil`, the result is `nil`.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public init?(mutating other: UnsafeRawPointer?) {
guard let unwrapped = other else { return nil }
_rawValue = unwrapped._rawValue
}
% else: # !mutable
/// Creates a new raw pointer from the given mutable raw pointer.
///
/// Use this initializer to explicitly convert `other` to an `${Self}`
/// instance. This initializer creates a new pointer to the same address as
/// `other` and performs no allocation or copying.
///
/// - Parameter other: The mutable raw pointer to convert.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public init(_ other: UnsafeMutableRawPointer) {
_rawValue = other._rawValue
}
/// Creates a new raw pointer from the given mutable raw pointer.
///
/// Use this initializer to explicitly convert `other` to an `${Self}`
/// instance. This initializer creates a new pointer to the same address as
/// `other` and performs no allocation or copying.
///
/// - Parameter other: The mutable raw pointer to convert. If `other` is
/// `nil`, the result is `nil`.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public init?(_ other: UnsafeMutableRawPointer?) {
guard let unwrapped = other else { return nil }
_rawValue = unwrapped._rawValue
}
/// Creates a new raw pointer from the given typed pointer.
///
/// Use this initializer to explicitly convert `other` to an `${Self}`
/// instance. This initializer creates a new pointer to the same address as
/// `other` and performs no allocation or copying.
///
/// - Parameter other: The typed pointer to convert.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public init<T>(_ other: UnsafeMutablePointer<T>) {
_rawValue = other._rawValue
}
/// Creates a new raw pointer from the given typed pointer.
///
/// Use this initializer to explicitly convert `other` to an `${Self}`
/// instance. This initializer creates a new pointer to the same address as
/// `other` and performs no allocation or copying.
///
/// - Parameter other: The typed pointer to convert. If `other` is `nil`, the
/// result is `nil`.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public init?<T>(_ other: UnsafeMutablePointer<T>?) {
guard let unwrapped = other else { return nil }
_rawValue = unwrapped._rawValue
}
% end # !mutable
% if mutable:
@available(swift, deprecated: 4.1, obsoleted: 5.0.0, renamed: "allocate(byteCount:alignment:)")
@_inlineable
public static func allocate(
bytes size: Int, alignedTo alignment: Int
) -> UnsafeMutableRawPointer {
return UnsafeMutableRawPointer.allocate(byteCount: size, alignment: alignment)
}
/// Allocates uninitialized memory with the specified size and alignment.
///
/// You are in charge of managing the allocated memory. Be sure to deallocate
/// any memory that you manually allocate.
///
/// The allocated memory is not bound to any specific type and must be bound
/// before performing any typed operations. If you are using the memory for
/// a specific type, allocate memory using the
/// `UnsafeMutablePointer.allocate(capacity:)` static method instead.
///
/// - Parameters:
/// - byteCount: The number of bytes to allocate. `byteCount` must not be negative.
/// - alignment: The alignment of the new region of allocated memory, in
/// bytes.
/// - Returns: A pointer to a newly allocated region of memory. The memory is
/// allocated, but not initialized.
@_inlineable
public static func allocate(
byteCount: Int, alignment: Int
) -> UnsafeMutableRawPointer {
return UnsafeMutableRawPointer(Builtin.allocRaw(
byteCount._builtinWordValue, alignment._builtinWordValue))
}
% end # mutable
@available(swift, deprecated: 4.1, obsoleted: 5.0.0, message: "Swift currently only supports freeing entire heap blocks, use deallocate() instead")
public func deallocate(bytes _: Int, alignedTo _: Int) {
self.deallocate()
}
/// Deallocates the previously allocated memory block referenced by this pointer.
///
/// The memory to be deallocated must be uninitialized or initialized to a
/// trivial type.
@_inlineable
public func deallocate() {
Builtin.deallocRaw(_rawValue, (-1)._builtinWordValue, (-1)._builtinWordValue)
}
/// Binds the memory to the specified type and returns a typed pointer to the
/// bound memory.
///
/// Use the `bindMemory(to:capacity:)` method to bind the memory referenced
/// by this pointer to the type `T`. The memory must be uninitialized or
/// initialized to a type that is layout compatible with `T`. If the memory
/// is uninitialized, it is still uninitialized after being bound to `T`.
///
/// In this example, 100 bytes of raw memory are allocated for the pointer
/// `bytesPointer`, and then the first four bytes are bound to the `Int8`
/// type.
///
/// let count = 4
/// let bytesPointer = UnsafeMutableRawPointer.allocate(
/// bytes: 100,
/// alignedTo: MemoryLayout<Int8>.alignment)
/// let int8Pointer = bytesPointer.bindMemory(to: Int8.self, capacity: count)
///
/// After calling `bindMemory(to:capacity:)`, the first four bytes of the
/// memory referenced by `bytesPointer` are bound to the `Int8` type, though
/// they remain uninitialized. The remainder of the allocated region is
/// unbound raw memory. All 100 bytes of memory must eventually be
/// deallocated.
///
/// - Warning: A memory location may only be bound to one type at a time. The
/// behavior of accessing memory as a type unrelated to its bound type is
/// undefined.
///
/// - Parameters:
/// - type: The type `T` to bind the memory to.
/// - count: The amount of memory to bind to type `T`, counted as instances
/// of `T`.
/// - Returns: A typed pointer to the newly bound memory. The memory in this
/// region is bound to `T`, but has not been modified in any other way.
/// The number of bytes in this region is
/// `count * MemoryLayout<T>.stride`.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
@discardableResult
public func bindMemory<T>(
to type: T.Type, capacity count: Int
) -> Unsafe${Mutable}Pointer<T> {
Builtin.bindMemory(_rawValue, count._builtinWordValue, type)
return Unsafe${Mutable}Pointer<T>(_rawValue)
}
/// Returns a typed pointer to the memory referenced by this pointer,
/// assuming that the memory is already bound to the specified type.
///
/// Use this method when you have a raw pointer to memory that has *already*
/// been bound to the specified type. The memory starting at this pointer
/// must be bound to the type `T`. Accessing memory through the returned
/// pointer is undefined if the memory has not been bound to `T`. To bind
/// memory to `T`, use `bindMemory(to:capacity:)` instead of this method.
///
/// - Parameter to: The type `T` that the memory has already been bound to.
/// - Returns: A typed pointer to the same memory as this raw pointer.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public func assumingMemoryBound<T>(to: T.Type) -> Unsafe${Mutable}Pointer<T> {
return Unsafe${Mutable}Pointer<T>(_rawValue)
}
% if mutable:
@available(swift, deprecated: 4.1, obsoleted: 5.0.0, renamed: "initializeMemory(as:repeating:count:)")
@discardableResult
public func initializeMemory<T>(
as type: T.Type, at offset: Int = 0, count: Int = 1, to repeatedValue: T
) -> UnsafeMutablePointer<T> {
return (self + offset * MemoryLayout<T>.stride).initializeMemory(
as: type, repeating: repeatedValue, count: count)
}
/// Initializes the memory referenced by this pointer with the given value,
/// binds the memory to the value's type, and returns a typed pointer to the
/// initialized memory.
///
/// The memory referenced by this pointer must be uninitialized or
/// initialized to a trivial type, and must be properly aligned for
/// accessing `T`.
///
/// The following example allocates enough raw memory to hold four instances
/// of `Int8`, and then uses the `initializeMemory(as:repeating:count:)` method
/// to initialize the allocated memory.
///
/// let count = 4
/// let bytesPointer = UnsafeMutableRawPointer.allocate(
/// byteCount: count * MemoryLayout<Int8>.stride,
/// alignment: MemoryLayout<Int8>.alignment)
/// let int8Pointer = myBytes.initializeMemory(
/// as: Int8.self, repeating: 0, count: count)
///
/// // After using 'int8Pointer':
/// int8Pointer.deallocate()
///
/// After calling this method on a raw pointer `p`, the region starting at
/// `self` and continuing up to `p + count * MemoryLayout<T>.stride` is bound
/// to type `T` and initialized. If `T` is a nontrivial type, you must
/// eventually deinitialize or move from the values in this region to avoid leaks.
///
/// - Parameters:
/// - type: The type to bind this memory to.
/// - repeatedValue: The instance to copy into memory.
/// - count: The number of copies of `value` to copy into memory. `count`
/// must not be negative.
/// - Returns: A typed pointer to the memory referenced by this raw pointer.
@_inlineable
@discardableResult
public func initializeMemory<T>(
as type: T.Type, repeating repeatedValue: T, count: Int
) -> UnsafeMutablePointer<T> {
_debugPrecondition(count >= 0,
"UnsafeMutableRawPointer.initializeMemory: negative count")
Builtin.bindMemory(_rawValue, count._builtinWordValue, type)
var nextPtr = self
for _ in 0..<count {
Builtin.initialize(repeatedValue, nextPtr._rawValue)
nextPtr += MemoryLayout<T>.stride
}
return UnsafeMutablePointer(_rawValue)
}
/// Initializes the memory referenced by this pointer with the values
/// starting at the given pointer, binds the memory to the values' type, and
/// returns a typed pointer to the initialized memory.
///
/// The memory referenced by this pointer must be uninitialized or
/// initialized to a trivial type, and must be properly aligned for
/// accessing `T`.
///
/// The following example allocates enough raw memory to hold four instances
/// of `Int8`, and then uses the `initializeMemory(as:from:count:)` method
/// to initialize the allocated memory.
///
/// let count = 4
/// let bytesPointer = UnsafeMutableRawPointer.allocate(
/// bytes: count * MemoryLayout<Int8>.stride,
/// alignedTo: MemoryLayout<Int8>.alignment)
/// let values: [Int8] = [1, 2, 3, 4]
/// let int8Pointer = values.withUnsafeBufferPointer { buffer in
/// return bytesPointer.initializeMemory(as: Int8.self,
/// from: buffer.baseAddress!,
/// count: buffer.count)
/// }
/// // int8Pointer.pointee == 1
/// // (int8Pointer + 3).pointee == 4
///
/// // After using 'int8Pointer':
/// int8Pointer.deallocate(count)
///
/// After calling this method on a raw pointer `p`, the region starting at
/// `p` and continuing up to `p + count * MemoryLayout<T>.stride` is bound
/// to type `T` and initialized. If `T` is a nontrivial type, you must
/// eventually deinitialize or move from the values in this region to avoid
/// leaks. The instances in the region `source..<(source + count)` are
/// unaffected.
///
/// - Parameters:
/// - type: The type to bind this memory to.
/// - source: A pointer to the values to copy. The memory in the region
/// `source..<(source + count)` must be initialized to type `T` and must
/// not overlap the destination region.
/// - count: The number of copies of `value` to copy into memory. `count`
/// must not be negative.
/// - Returns: A typed pointer to the memory referenced by this raw pointer.
@_inlineable
@discardableResult
public func initializeMemory<T>(
as type: T.Type, from source: UnsafePointer<T>, count: Int
) -> UnsafeMutablePointer<T> {
_debugPrecondition(
count >= 0,
"UnsafeMutableRawPointer.initializeMemory with negative count")
_debugPrecondition(
(UnsafeRawPointer(self + count * MemoryLayout<T>.stride)
<= UnsafeRawPointer(source))
|| UnsafeRawPointer(source + count) <= UnsafeRawPointer(self),
"UnsafeMutableRawPointer.initializeMemory overlapping range")
Builtin.bindMemory(_rawValue, count._builtinWordValue, type)
Builtin.copyArray(
T.self, self._rawValue, source._rawValue, count._builtinWordValue)
// This builtin is equivalent to:
// for i in 0..<count {
// (self.assumingMemoryBound(to: T.self) + i).initialize(to: source[i])
// }
return UnsafeMutablePointer(_rawValue)
}
/// Initializes the memory referenced by this pointer with the values of the
/// given collection, binds the memory to the values' type, and returns a
/// typed pointer to the initialized memory.
///
/// The memory referenced by this pointer must be uninitialized or
/// initialized to a trivial type, and must be properly aligned for
/// accessing `T`.
///
/// The following example allocates enough raw memory to hold four instances
/// of `Int8`, and then uses the `initializeMemory(as:from:)` method to
/// initialize the allocated memory.
///
/// let count = 4
/// let bytesPointer = UnsafeMutableRawPointer.allocate(
/// bytes: count * MemoryLayout<Int8>.stride,
/// alignedTo: MemoryLayout<Int8>.alignment)
/// let values: [Int8] = [1, 2, 3, 4]
/// let int8Pointer = bytesPointer.initializeMemory(
/// as: Int8.self,
/// from: values)
/// // int8Pointer.pointee == 1
/// // (int8Pointer + 3).pointee == 4
///
/// // After using 'int8Pointer':
/// int8Pointer.deallocate(count)
///
/// After calling this method on a raw pointer `p`, the region starting at
/// `p` and continuing up to `p + count * MemoryLayout<T>.stride` is bound
/// to type `T` and initialized. If `T` is a nontrivial type, you must
/// eventually deinitialize or move from the values in this region to avoid
/// leaks.
///
/// - Parameters:
/// - type: The type to bind this memory to.
/// - source: A pointer to the values to copy. If `source` is an
/// `UnsafeBufferPointer` or `UnsafeMutableBufferPointer` instance, the
/// memory region referenced by `source` must not overlap the
/// destination region.
/// - Returns: A typed pointer to the memory referenced by this raw pointer.
// This is fundamentally unsafe since collections can underreport their count.
@_inlineable
@available(*, deprecated, message: "it will be removed in Swift 4.0. Please use 'UnsafeMutableRawBufferPointer.initialize(from:)' instead")
@discardableResult
public func initializeMemory<C : Collection>(
as type: C.Element.Type, from source: C
) -> UnsafeMutablePointer<C.Element> {
// TODO: Optimize where `C` is a `ContiguousArrayBuffer`.
// Initialize and bind each element of the container.
var ptr = self
for element in source {
ptr.initializeMemory(as: C.Element.self, repeating: element, count: 1)
ptr += MemoryLayout<C.Element>.stride
}
return UnsafeMutablePointer(_rawValue)
}
/// Initializes the memory referenced by this pointer with the values
/// starting at the given pointer, binds the memory to the values' type,
/// deinitializes the source memory, and returns a typed pointer to the
/// newly initialized memory.
///
/// The memory referenced by this pointer must be uninitialized or
/// initialized to a trivial type, and must be properly aligned for
/// accessing `T`.
///
/// The memory in the region `source..<(source + count)` may overlap with the
/// destination region. The `moveInitializeMemory(as:from:count:)` method
/// automatically performs a forward or backward copy of all instances from
/// the source region to their destination.
///
/// After calling this method on a raw pointer `p`, the region starting at
/// `p` and continuing up to `p + count * MemoryLayout<T>.stride` is bound
/// to type `T` and initialized. If `T` is a nontrivial type, you must
/// eventually deinitialize or move from the values in this region to avoid
/// leaks. Any memory in the region `source..<(source + count)` that does
/// not overlap with the destination region is returned to an uninitialized
/// state.
///
/// - Parameters:
/// - type: The type to bind this memory to.
/// - source: A pointer to the values to copy. The memory in the region
/// `source..<(source + count)` must be initialized to type `T`.
/// - count: The number of copies of `value` to copy into memory. `count`
/// must not be negative.
/// - Returns: A typed pointer to the memory referenced by this raw pointer.
@_inlineable
@discardableResult
public func moveInitializeMemory<T>(
as type: T.Type, from source: UnsafeMutablePointer<T>, count: Int
) -> UnsafeMutablePointer<T> {
_debugPrecondition(
count >= 0,
"UnsafeMutableRawPointer.moveInitializeMemory with negative count")
Builtin.bindMemory(_rawValue, count._builtinWordValue, type)
if self < UnsafeMutableRawPointer(source)
|| self >= UnsafeMutableRawPointer(source + count) {
// initialize forward from a disjoint or following overlapping range.
Builtin.takeArrayFrontToBack(
T.self, self._rawValue, source._rawValue, count._builtinWordValue)
// This builtin is equivalent to:
// for i in 0..<count {
// (self.assumingMemoryBound(to: T.self) + i)
// .initialize(to: (source + i).move())
// }
}
else {
// initialize backward from a non-following overlapping range.
Builtin.takeArrayBackToFront(
T.self, self._rawValue, source._rawValue, count._builtinWordValue)
// This builtin is equivalent to:
// var src = source + count
// var dst = self.assumingMemoryBound(to: T.self) + count
// while dst != self {
// (--dst).initialize(to: (--src).move())
// }
}
return UnsafeMutablePointer(_rawValue)
}
% end # mutable
/// Returns a new instance of the given type, constructed from the raw memory
/// at the specified offset.
///
/// The memory at this pointer plus `offset` must be properly aligned for
/// accessing `T` and initialized to `T` or another type that is layout
/// compatible with `T`.
///
/// - Parameters:
/// - offset: The offset from this pointer, in bytes. `offset` must be
/// nonnegative. The default is zero.
/// - type: The type of the instance to create.
/// - Returns: A new instance of type `T`, read from the raw bytes at
/// `offset`. The returned instance is memory-managed and unassociated
/// with the value in the memory referenced by this pointer.
@_inlineable
public func load<T>(fromByteOffset offset: Int = 0, as type: T.Type) -> T {
_debugPrecondition(0 == (UInt(bitPattern: self + offset)
& (UInt(MemoryLayout<T>.alignment) - 1)),
"load from misaligned raw pointer")
return Builtin.loadRaw((self + offset)._rawValue)
}
% if mutable:
/// Stores the given value's bytes into raw memory at the specified offset.
///
/// The type `T` to be stored must be a trivial type. The memory at this
/// pointer plus `offset` must be properly aligned for accessing `T`. The
/// memory must also be uninitialized, initialized to `T`, or initialized to
/// another trivial type that is layout compatible with `T`.
///
/// After calling `storeBytes(of:toByteOffset:as:)`, the memory is
/// initialized to the raw bytes of `value`. If the memory is bound to a
/// type `U` that is layout compatible with `T`, then it contains a value of
/// type `U`. Calling `storeBytes(of:toByteOffset:as:)` does not change the
/// bound type of the memory.
///
/// - Note: A trivial type can be copied with just a bit-for-bit copy without
/// any indirection or reference-counting operations. Generally, native
/// Swift types that do not contain strong or weak references or other
/// forms of indirection are trivial, as are imported C structs and enums.
///
/// If you need to store a copy of a nontrivial value into memory, or to
/// store a value into memory that contains a nontrivial value, you cannot
/// use the `storeBytes(of:toByteOffset:as:)` method. Instead, you must know
/// the type of value previously in memory and initialize or assign the
/// memory. For example, to replace a value stored in a raw pointer `p`,
/// where `U` is the current type and `T` is the new type, use a typed
/// pointer to access and deinitialize the current value before initializing
/// the memory with a new value.
///
/// let typedPointer = p.bindMemory(to: U.self, capacity: 1)
/// typedPointer.deinitialize(count: 1)
/// p.initializeMemory(as: T.self, to: newValue)
///
/// - Parameters:
/// - value: The value to store as raw bytes.
/// - offset: The offset from this pointer, in bytes. `offset` must be
/// nonnegative. The default is zero.
/// - type: The type of `value`.
@_inlineable
public func storeBytes<T>(
of value: T, toByteOffset offset: Int = 0, as type: T.Type
) {
_debugPrecondition(0 == (UInt(bitPattern: self + offset)
& (UInt(MemoryLayout<T>.alignment) - 1)),
"storeBytes to misaligned raw pointer")
var temp = value
withUnsafeMutablePointer(to: &temp) { source in
let rawSrc = UnsafeMutableRawPointer(source)._rawValue
// FIXME: to be replaced by _memcpy when conversions are implemented.
Builtin.int_memcpy_RawPointer_RawPointer_Int64(
(self + offset)._rawValue, rawSrc, UInt64(MemoryLayout<T>.size)._value,
/*alignment:*/ Int32()._value,
/*volatile:*/ false._value)
}
}
@available(swift, deprecated: 4.1, obsoleted: 5.0.0, renamed: "copyMemory(from:byteCount:)")
public func copyBytes(from source: UnsafeRawPointer, count: Int) {
copyMemory(from: source, byteCount: count)
}
/// Copies the specified number of bytes from the given raw pointer's memory
/// into this pointer's memory.
///
/// If the `byteCount` bytes of memory referenced by this pointer are bound to
/// a type `T`, then `T` must be a trivial type, this pointer and `source`
/// must be properly aligned for accessing `T`, and `byteCount` must be a
/// multiple of `MemoryLayout<T>.stride`.
///
/// After calling `copyMemory(from:byteCount:)`, the `byteCount` bytes of memory
/// referenced by this pointer are initialized to raw bytes. If the memory
/// is bound to type `T`, then it contains values of type `T`.
///
/// - Parameters:
/// - source: A pointer to the memory to copy bytes from. The memory in the
/// region `source..<(source + byteCount)` must be initialized to a trivial
/// type.
/// - byteCount: The number of bytes to copy. `byteCount` must not be negative.
@_inlineable
public func copyMemory(from source: UnsafeRawPointer, byteCount: Int) {
_debugPrecondition(
byteCount >= 0, "UnsafeMutableRawPointer.copyMemory with negative count")
_memmove(dest: self, src: source, size: UInt(byteCount))
}
% end # mutable
}
extension ${Self}: Strideable {
/// Returns the distance from this pointer to the given pointer.
///
/// With pointers `p` and `q`, the result of `p.distance(to: q)` is
/// equivalent to `q - p`.
///
/// - Parameter x: The pointer to calculate the distance to.
/// - Returns: The distance from this pointer to `x`, in bytes.
@_inlineable
public func distance(to x: ${Self}) -> Int {
return Int(Builtin.sub_Word(Builtin.ptrtoint_Word(x._rawValue),
Builtin.ptrtoint_Word(_rawValue)))
}
/// Returns a pointer offset from this pointer by the specified number of
/// bytes.
///
/// 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 bytes to offset this pointer. `n` may be
/// positive, negative, or zero.
/// - Returns: A pointer offset from this pointer by `n` bytes.
@_inlineable
public func advanced(by n: Int) -> ${Self} {
return ${Self}(Builtin.gepRaw_Word(_rawValue, n._builtinWordValue))
}
}
extension ${Self}: Equatable {
// - Note: This may be more efficient than Strideable's implementation
// calling ${Self}.distance().
/// 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`.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public static func == (lhs: ${Self}, rhs: ${Self}) -> Bool {
return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue))
}
}
extension ${Self}: Comparable {
// - 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`.
@_inlineable // FIXME(sil-serialize-all)
@_transparent
public static func < (lhs: ${Self}, rhs: ${Self}) -> 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.
@_inlineable
public var hashValue: Int {
return Int(bitPattern: self)
}
}
extension Unsafe${Mutable}RawPointer : CustomDebugStringConvertible {
/// A textual representation of the pointer, suitable for debugging.
@_inlineable // FIXME(sil-serialize-all)
public var debugDescription: String {
return _rawPointerToString(_rawValue)
}
}
extension Unsafe${Mutable}RawPointer : CustomReflectable {
@_inlineable // 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 Unsafe${Mutable}RawPointer : CustomPlaygroundQuickLookable {
@_inlineable // FIXME(sil-serialize-all)
@_versioned // FIXME(sil-serialize-all)
@available(*, deprecated, message: "Unsafe${Mutable}RawPointer.customPlaygroundQuickLook will be removed in a future Swift version")
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)))"
}
@_inlineable // FIXME(sil-serialize-all)
public var customPlaygroundQuickLook: PlaygroundQuickLook {
return .text(summary)
}
}
extension OpaquePointer {
@_inlineable
public init(_ from: Unsafe${Mutable}RawPointer) {
self._rawValue = from._rawValue
}
@_inlineable
public init?(_ from: Unsafe${Mutable}RawPointer?) {
guard let unwrapped = from else { return nil }
self._rawValue = unwrapped._rawValue
}
}
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.
@_inlineable
public init(bitPattern pointer: Unsafe${Mutable}RawPointer?) {
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.
@_inlineable
public init(bitPattern pointer: Unsafe${Mutable}RawPointer?) {
if let pointer = pointer {
self = UInt(Builtin.ptrtoint_Word(pointer._rawValue))
} else {
self = 0
}
}
}
% end # for mutable
extension UnsafeMutableRawPointer {
@available(*, unavailable, renamed: "init(mutating:)")
public init(_ from : UnsafeRawPointer) { Builtin.unreachable() }
@available(*, unavailable, renamed: "init(mutating:)")
public init?(_ from : UnsafeRawPointer?) { Builtin.unreachable(); return nil }
@available(*, unavailable, renamed: "init(mutating:)")
public init<T>(_ from : UnsafePointer<T>) { Builtin.unreachable() }
@available(*, unavailable, renamed: "init(mutating:)")
public init?<T>(_ from : UnsafePointer<T>?) { Builtin.unreachable(); return nil }
}