mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
1041 lines
44 KiB
Swift
1041 lines
44 KiB
Swift
//===--- UnsafeRawPointer.swift -------------------------------*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// A raw pointer for accessing
|
|
/// untyped data.
|
|
///
|
|
/// The `UnsafeRawPointer` 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 `UnsafeRawPointer` 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 `UnsafeRawPointer` 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.
|
|
///
|
|
/// 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.
|
|
///
|
|
/// 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 memory as raw
|
|
/// bytes when that memory is bound to a type, you must ensure that you
|
|
/// satisfy any alignment requirements.
|
|
///
|
|
/// 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: 4)
|
|
/// 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 `UnsafeRawPointer` 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 `UnsafeRawPointer` instance as its first parameter:
|
|
///
|
|
/// func print<T>(address p: UnsafeRawPointer, 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 `UnsafeRawPointer` instance. This example passes `rawPointer` as the initial
|
|
/// parameter.
|
|
///
|
|
/// // 'rawPointer' points to memory initialized with `Int` values.
|
|
/// let rawPointer: UnsafeRawPointer = ...
|
|
/// print(address: rawPointer, as: Int.self)
|
|
/// // Prints "42"
|
|
///
|
|
/// 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)
|
|
///
|
|
/// - 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 `UnsafeRawPointer` initializer.
|
|
///
|
|
/// var number = 5
|
|
/// let numberPointer = UnsafeRawPointer(&number)
|
|
/// // Accessing 'numberPointer' is undefined behavior.
|
|
@frozen
|
|
public struct UnsafeRawPointer: _Pointer {
|
|
|
|
public typealias Pointee = UInt8
|
|
|
|
/// The underlying raw pointer.
|
|
/// Implements conformance to the public protocol `_Pointer`.
|
|
public let _rawValue: Builtin.RawPointer
|
|
|
|
/// Creates a new raw pointer from a builtin raw pointer.
|
|
@_transparent
|
|
public init(_ _rawValue: Builtin.RawPointer) {
|
|
self._rawValue = _rawValue
|
|
}
|
|
|
|
/// Creates a new raw pointer from the given typed pointer.
|
|
///
|
|
/// Use this initializer to explicitly convert `other` to an `UnsafeRawPointer`
|
|
/// 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.
|
|
@_transparent
|
|
public init<T>(@_nonEphemeral _ other: UnsafePointer<T>) {
|
|
_rawValue = other._rawValue
|
|
}
|
|
|
|
/// Creates a new raw pointer from the given typed pointer.
|
|
///
|
|
/// Use this initializer to explicitly convert `other` to an `UnsafeRawPointer`
|
|
/// 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`.
|
|
@_transparent
|
|
public init?<T>(@_nonEphemeral _ other: UnsafePointer<T>?) {
|
|
guard let unwrapped = other else { return nil }
|
|
_rawValue = unwrapped._rawValue
|
|
}
|
|
|
|
/// Creates a new raw pointer from the given mutable raw pointer.
|
|
///
|
|
/// Use this initializer to explicitly convert `other` to an `UnsafeRawPointer`
|
|
/// 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.
|
|
@_transparent
|
|
public init(@_nonEphemeral _ 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 `UnsafeRawPointer`
|
|
/// 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`.
|
|
@_transparent
|
|
public init?(@_nonEphemeral _ 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 `UnsafeRawPointer`
|
|
/// 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.
|
|
@_transparent
|
|
public init<T>(@_nonEphemeral _ 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 `UnsafeRawPointer`
|
|
/// 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`.
|
|
@_transparent
|
|
public init?<T>(@_nonEphemeral _ other: UnsafeMutablePointer<T>?) {
|
|
guard let unwrapped = other else { return nil }
|
|
_rawValue = unwrapped._rawValue
|
|
}
|
|
|
|
/// Deallocates the previously allocated memory block referenced by this pointer.
|
|
///
|
|
/// The memory to be deallocated must be uninitialized or initialized to a
|
|
/// trivial type.
|
|
@inlinable
|
|
public func deallocate() {
|
|
// Passing zero alignment to the runtime forces "aligned
|
|
// deallocation". Since allocation via `UnsafeMutable[Raw][Buffer]Pointer`
|
|
// always uses the "aligned allocation" path, this ensures that the
|
|
// runtime's allocation and deallocation paths are compatible.
|
|
Builtin.deallocRaw(_rawValue, (-1)._builtinWordValue, (0)._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(
|
|
/// byteCount: 100,
|
|
/// alignment: 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`.
|
|
@_transparent
|
|
@discardableResult
|
|
public func bindMemory<T>(
|
|
to type: T.Type, capacity count: Int
|
|
) -> UnsafePointer<T> {
|
|
Builtin.bindMemory(_rawValue, count._builtinWordValue, type)
|
|
return UnsafePointer<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.
|
|
@_transparent
|
|
public func assumingMemoryBound<T>(to: T.Type) -> UnsafePointer<T> {
|
|
return UnsafePointer<T>(_rawValue)
|
|
}
|
|
|
|
/// 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.
|
|
@inlinable
|
|
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")
|
|
|
|
let rawPointer = (self + offset)._rawValue
|
|
|
|
#if compiler(>=5.5) && $BuiltinAssumeAlignment
|
|
// TODO: to support misaligned raw loads, simply remove this assumption.
|
|
let alignedPointer =
|
|
Builtin.assumeAlignment(rawPointer,
|
|
MemoryLayout<T>.alignment._builtinWordValue)
|
|
return Builtin.loadRaw(alignedPointer)
|
|
#else
|
|
return Builtin.loadRaw(rawPointer)
|
|
#endif
|
|
}
|
|
|
|
}
|
|
|
|
extension UnsafeRawPointer: Strideable {
|
|
// custom version for raw pointers
|
|
@_transparent
|
|
public func advanced(by n: Int) -> UnsafeRawPointer {
|
|
return UnsafeRawPointer(Builtin.gepRaw_Word(_rawValue, n._builtinWordValue))
|
|
}
|
|
}
|
|
|
|
/// A raw pointer for accessing and manipulating
|
|
/// untyped data.
|
|
///
|
|
/// The `UnsafeMutableRawPointer` 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 `UnsafeMutableRawPointer` 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 `UnsafeMutableRawPointer` 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.
|
|
///
|
|
/// 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.
|
|
///
|
|
/// 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 memory as raw
|
|
/// bytes when that memory is bound to a type, you must ensure that you
|
|
/// satisfy any alignment requirements.
|
|
/// Writing to typed memory as raw bytes must only be performed when the bound
|
|
/// type is a trivial type.
|
|
///
|
|
/// 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 `UnsafeMutableRawPointer` 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 `UnsafeMutableRawPointer` instance as its first parameter:
|
|
///
|
|
/// func print<T>(address p: UnsafeMutableRawPointer, 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 `UnsafeMutableRawPointer` instance. This example passes `rawPointer` as the initial
|
|
/// parameter.
|
|
///
|
|
/// // 'rawPointer' points to memory initialized with `Int` values.
|
|
/// let rawPointer: UnsafeMutableRawPointer = ...
|
|
/// print(address: rawPointer, as: Int.self)
|
|
/// // Prints "42"
|
|
///
|
|
/// 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"
|
|
///
|
|
/// - 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 `UnsafeMutableRawPointer` initializer.
|
|
///
|
|
/// var number = 5
|
|
/// let numberPointer = UnsafeMutableRawPointer(&number)
|
|
/// // Accessing 'numberPointer' is undefined behavior.
|
|
@frozen
|
|
public struct UnsafeMutableRawPointer: _Pointer {
|
|
|
|
public typealias Pointee = UInt8
|
|
|
|
/// The underlying raw pointer.
|
|
/// Implements conformance to the public protocol `_Pointer`.
|
|
public let _rawValue: Builtin.RawPointer
|
|
|
|
/// Creates a new raw pointer from a builtin raw pointer.
|
|
@_transparent
|
|
public init(_ _rawValue: Builtin.RawPointer) {
|
|
self._rawValue = _rawValue
|
|
}
|
|
|
|
/// Creates a new raw pointer from the given typed pointer.
|
|
///
|
|
/// Use this initializer to explicitly convert `other` to an `UnsafeMutableRawPointer`
|
|
/// 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.
|
|
@_transparent
|
|
public init<T>(@_nonEphemeral _ 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 `UnsafeMutableRawPointer`
|
|
/// 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`.
|
|
@_transparent
|
|
public init?<T>(@_nonEphemeral _ other: UnsafeMutablePointer<T>?) {
|
|
guard let unwrapped = other else { return nil }
|
|
_rawValue = unwrapped._rawValue
|
|
}
|
|
|
|
/// Creates a new mutable raw pointer from the given immutable raw pointer.
|
|
///
|
|
/// Use this initializer to explicitly convert `other` to an `UnsafeMutableRawPointer`
|
|
/// 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.
|
|
@_transparent
|
|
public init(@_nonEphemeral 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 `UnsafeMutableRawPointer`
|
|
/// 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`.
|
|
@_transparent
|
|
public init?(@_nonEphemeral mutating other: UnsafeRawPointer?) {
|
|
guard let unwrapped = other else { return nil }
|
|
_rawValue = unwrapped._rawValue
|
|
}
|
|
|
|
/// 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. `alignment` must be a whole power of 2.
|
|
/// - Returns: A pointer to a newly allocated region of memory. The memory is
|
|
/// allocated, but not initialized.
|
|
@inlinable
|
|
public static func allocate(
|
|
byteCount: Int, alignment: Int
|
|
) -> UnsafeMutableRawPointer {
|
|
// For any alignment <= _minAllocationAlignment, force alignment = 0.
|
|
// This forces the runtime's "aligned" allocation path so that
|
|
// deallocation does not require the original alignment.
|
|
//
|
|
// The runtime guarantees:
|
|
//
|
|
// align == 0 || align > _minAllocationAlignment:
|
|
// Runtime uses "aligned allocation".
|
|
//
|
|
// 0 < align <= _minAllocationAlignment:
|
|
// Runtime may use either malloc or "aligned allocation".
|
|
var alignment = alignment
|
|
if alignment <= _minAllocationAlignment() {
|
|
alignment = 0
|
|
}
|
|
return UnsafeMutableRawPointer(Builtin.allocRaw(
|
|
byteCount._builtinWordValue, alignment._builtinWordValue))
|
|
}
|
|
|
|
/// Deallocates the previously allocated memory block referenced by this pointer.
|
|
///
|
|
/// The memory to be deallocated must be uninitialized or initialized to a
|
|
/// trivial type.
|
|
@inlinable
|
|
public func deallocate() {
|
|
// Passing zero alignment to the runtime forces "aligned
|
|
// deallocation". Since allocation via `UnsafeMutable[Raw][Buffer]Pointer`
|
|
// always uses the "aligned allocation" path, this ensures that the
|
|
// runtime's allocation and deallocation paths are compatible.
|
|
Builtin.deallocRaw(_rawValue, (-1)._builtinWordValue, (0)._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(
|
|
/// byteCount: 100,
|
|
/// alignment: 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`.
|
|
@_transparent
|
|
@discardableResult
|
|
public func bindMemory<T>(
|
|
to type: T.Type, capacity count: Int
|
|
) -> UnsafeMutablePointer<T> {
|
|
Builtin.bindMemory(_rawValue, count._builtinWordValue, type)
|
|
return UnsafeMutablePointer<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.
|
|
@_transparent
|
|
public func assumingMemoryBound<T>(to: T.Type) -> UnsafeMutablePointer<T> {
|
|
return UnsafeMutablePointer<T>(_rawValue)
|
|
}
|
|
|
|
/// 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 = bytesPointer.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.
|
|
@inlinable
|
|
@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(
|
|
/// byteCount: count * MemoryLayout<Int8>.stride,
|
|
/// alignment: 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()
|
|
///
|
|
/// 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.
|
|
@inlinable
|
|
@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
|
|
/// 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.
|
|
@inlinable
|
|
@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)
|
|
}
|
|
|
|
/// 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.
|
|
@inlinable
|
|
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")
|
|
|
|
let rawPointer = (self + offset)._rawValue
|
|
|
|
#if compiler(>=5.5) && $BuiltinAssumeAlignment
|
|
// TODO: to support misaligned raw loads, simply remove this assumption.
|
|
let alignedPointer =
|
|
Builtin.assumeAlignment(rawPointer,
|
|
MemoryLayout<T>.alignment._builtinWordValue)
|
|
return Builtin.loadRaw(alignedPointer)
|
|
#else
|
|
return Builtin.loadRaw(rawPointer)
|
|
#endif
|
|
}
|
|
|
|
/// 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, repeating: newValue, count: 1)
|
|
///
|
|
/// - 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`.
|
|
@inlinable
|
|
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,
|
|
/*volatile:*/ false._value)
|
|
}
|
|
}
|
|
|
|
/// 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`.
|
|
///
|
|
/// The memory in the region `source..<(source + byteCount)` may overlap with
|
|
/// the memory referenced by this pointer.
|
|
///
|
|
/// 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.
|
|
@inlinable
|
|
public func copyMemory(from source: UnsafeRawPointer, byteCount: Int) {
|
|
_debugPrecondition(
|
|
byteCount >= 0, "UnsafeMutableRawPointer.copyMemory with negative count")
|
|
|
|
_memmove(dest: self, src: source, size: UInt(byteCount))
|
|
}
|
|
}
|
|
|
|
extension UnsafeMutableRawPointer: Strideable {
|
|
// custom version for raw pointers
|
|
@_transparent
|
|
public func advanced(by n: Int) -> UnsafeMutableRawPointer {
|
|
return UnsafeMutableRawPointer(Builtin.gepRaw_Word(_rawValue, n._builtinWordValue))
|
|
}
|
|
}
|
|
|
|
extension OpaquePointer {
|
|
@_transparent
|
|
public init(@_nonEphemeral _ from: UnsafeMutableRawPointer) {
|
|
self._rawValue = from._rawValue
|
|
}
|
|
|
|
@_transparent
|
|
public init?(@_nonEphemeral _ from: UnsafeMutableRawPointer?) {
|
|
guard let unwrapped = from else { return nil }
|
|
self._rawValue = unwrapped._rawValue
|
|
}
|
|
|
|
@_transparent
|
|
public init(@_nonEphemeral _ from: UnsafeRawPointer) {
|
|
self._rawValue = from._rawValue
|
|
}
|
|
|
|
@_transparent
|
|
public init?(@_nonEphemeral _ from: UnsafeRawPointer?) {
|
|
guard let unwrapped = from else { return nil }
|
|
self._rawValue = unwrapped._rawValue
|
|
}
|
|
}
|