| //===--- UnsafeRawPointer.swift.gyb ---------------------------*- swift -*-===// |
| // |
| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors |
| // Licensed under Apache License v2.0 with Runtime Library Exception |
| // |
| // See http://swift.org/LICENSE.txt for license information |
| // See http://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 '' |
| |
| /// A raw pointer for accessing untyped data. This provides no |
| /// automatic memory management, no type safety, and no alignment |
| /// guarantees. This implements Strideable to provide a view |
| /// of byte-addressable memory. |
| @_fixed_layout |
| public struct Unsafe${Mutable}RawPointer : Strideable, Hashable, _Pointer { |
| /// The underlying raw pointer. |
| /// Implements conformance to the public protocol `_Pointer`. |
| public let _rawValue: Builtin.RawPointer |
| |
| /// Creates ${a_Self} from another `${Self}`. |
| @_transparent |
| public init(_ other: Unsafe${Mutable}RawPointer) { |
| self = other |
| } |
| |
| /// Creates ${a_Self} from another `${Self}`. |
| /// |
| /// Returns `nil` if `other` is `nil`. |
| @_transparent |
| public init?(_ other: Unsafe${Mutable}RawPointer?) { |
| guard let unwrapped = other else { return nil } |
| self = unwrapped |
| } |
| |
| /// Converts a builtin raw pointer to ${a_Self}. |
| @_transparent |
| public init(_ _rawValue: Builtin.RawPointer) { |
| self._rawValue = _rawValue |
| } |
| |
| /// Converts an opaque pointer to ${a_Self}. |
| @_transparent |
| public init(_ other: OpaquePointer) { |
| _rawValue = other._rawValue |
| } |
| |
| /// Converts an opaque pointer to ${a_Self}. |
| /// |
| /// Returns `nil` if `from` is `nil`. |
| @_transparent |
| public init?(_ other: OpaquePointer?) { |
| guard let unwrapped = other else { return nil } |
| _rawValue = unwrapped._rawValue |
| } |
| |
| /// Converts a pattern of bits to ${a_Self}. |
| /// |
| /// Returns `nil` if `bitPattern` is zero. |
| @_transparent |
| public init?(bitPattern: Int) { |
| if bitPattern == 0 { return nil } |
| _rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue) |
| } |
| |
| /// Converts a pattern of bits to ${a_Self}. |
| /// |
| /// Returns `nil` if `bitPattern` is zero. |
| @_transparent |
| public init?(bitPattern: UInt) { |
| if bitPattern == 0 { return nil } |
| _rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue) |
| } |
| |
| /// Converts an Unsafe${Mutable}Pointer to ${a_Self}. |
| @_transparent |
| public init<T>(_ other: Unsafe${Mutable}Pointer<T>) { |
| _rawValue = other._rawValue |
| } |
| |
| /// Converts an Unsafe${Mutable}Pointer to ${a_Self}. |
| /// |
| /// Returns `nil` if `other` is `nil`. |
| @_transparent |
| public init?<T>(_ other: Unsafe${Mutable}Pointer<T>?) { |
| guard let unwrapped = other else { return nil } |
| _rawValue = unwrapped._rawValue |
| } |
| |
| % if mutable: |
| /// Converts an UnsafeRawPointer to ${a_Self}. |
| @_transparent |
| public init(mutating other: UnsafeRawPointer) { |
| _rawValue = other._rawValue |
| } |
| |
| /// Converts an UnsafeRawPointer to ${a_Self}. |
| /// |
| /// Returns `nil` if `other` is `nil`. |
| @_transparent |
| public init?(mutating other: UnsafeRawPointer?) { |
| guard let unwrapped = other else { return nil } |
| _rawValue = unwrapped._rawValue |
| } |
| % else: # !mutable |
| /// Converts an UnsafeMutableRawPointer to ${a_Self}. |
| @_transparent |
| public init(_ other: UnsafeMutableRawPointer) { |
| _rawValue = other._rawValue |
| } |
| |
| /// Converts an UnsafeMutableRawPointer to ${a_Self}. |
| /// |
| /// Returns `nil` if `other` is `nil`. |
| @_transparent |
| public init?(_ other: UnsafeMutableRawPointer?) { |
| guard let unwrapped = other else { return nil } |
| _rawValue = unwrapped._rawValue |
| } |
| |
| /// Converts an UnsafeMutablePointer to ${a_Self}. |
| @_transparent |
| public init<T>(_ other: UnsafeMutablePointer<T>) { |
| _rawValue = other._rawValue |
| } |
| |
| /// Converts an UnsafeMutablePointer to ${a_Self}. |
| /// |
| /// Returns `nil` if `other` is `nil`. |
| @_transparent |
| public init?<T>(_ other: UnsafeMutablePointer<T>?) { |
| guard let unwrapped = other else { return nil } |
| _rawValue = unwrapped._rawValue |
| } |
| % end # !mutable |
| |
| % if mutable: |
| /// Allocates and points at uninitialized memory for `size` bytes with |
| /// `alignedTo` alignment. |
| /// |
| /// - Postcondition: The memory is allocated, but not initialized. |
| public static func allocate(bytes size: Int, alignedTo: Int) |
| -> UnsafeMutableRawPointer { |
| return UnsafeMutableRawPointer(Builtin.allocRaw( |
| size._builtinWordValue, alignedTo._builtinWordValue)) |
| } |
| % end # mutable |
| |
| /// Deallocates uninitialized memory allocated for `bytes` number of bytes |
| /// with `alignedTo` alignment. |
| /// |
| /// - Precondition: The memory is not initialized. |
| /// - Postcondition: The memory has been deallocated. |
| public func deallocate(bytes: Int, alignedTo: Int) { |
| Builtin.deallocRaw( |
| _rawValue, bytes._builtinWordValue, alignedTo._builtinWordValue) |
| } |
| |
| /// Binds the allocated memory to type `T` and returns an |
| /// `Unsafe${Mutable}Pointer<T>` to the bound memory at `self`. |
| /// |
| /// - Precondition: The memory is uninitialized. |
| /// - Postcondition: The memory is bound to 'T' starting at `self` continuing |
| /// through `self` + `count` * `MemoryLayout<T>.stride` |
| /// - Warning: Binding memory to a type is potentially undefined if the |
| /// memory is ever accessed as an unrelated type. |
| @_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) |
| } |
| |
| /// Converts from ${a_Self} to Unsafe${Mutable}Pointer<T> given that |
| /// the region of memory starting at `self` is already bound to type `T`. |
| /// |
| /// - Precondition: The memory is bound to 'T' starting at `self` for some |
| /// unspecified capacity. |
| /// |
| /// - Warning: Accessing memory via the returned pointer is undefined if the |
| /// if the memory has not been bound to `T`. |
| @_transparent |
| public func assumingMemoryBound<T>(to: T.Type) -> Unsafe${Mutable}Pointer<T> { |
| return Unsafe${Mutable}Pointer<T>(_rawValue) |
| } |
| |
| % if mutable: |
| /// Initializes this memory location `self + strideof(T) * index` |
| /// with `count` consecutive copies of `value` and binds the |
| /// initialized memory to type `T`. |
| /// |
| /// Returns an `UnsafeMutablePointer<T>` to this memory. |
| /// |
| /// - Precondition: The memory at |
| /// `self + index * strideof(T)..<self + (index + count) * strideof(T)` |
| /// is uninitialized. |
| /// |
| /// - Precondition: The underlying pointer is properly aligned for |
| /// accessing `T`. |
| /// |
| /// - Precondition: `index` is non-negative. |
| /// |
| /// - Precondition: `count` is non-negative. |
| /// |
| /// - Postcondition: The memory at |
| /// `(self + strideof(T) * index)..<(self + strideof(T) * index) + count` |
| /// is bound to type `T` and initialized; the value should eventually be |
| /// destroyed or moved from to avoid leaks. |
| @discardableResult |
| public func initializeMemory<T>(as type: T.Type, at index: Int = 0, |
| count: Int = 1, to value: T |
| ) -> UnsafeMutablePointer<T> { |
| _debugPrecondition(index >= 0, |
| "UnsafeMutableRawPointer.initializeMemory: negative index") |
| _debugPrecondition(count >= 0, |
| "UnsafeMutableRawPointer.initializeMemory: negative count") |
| |
| Builtin.bindMemory(_rawValue, count._builtinWordValue, type) |
| var nextPtr = self + index &* MemoryLayout<T>.stride |
| for _ in 0..<count { |
| Builtin.initialize(value, nextPtr._rawValue) |
| nextPtr += MemoryLayout<T>.stride |
| } |
| return UnsafeMutablePointer(_rawValue) |
| } |
| |
| /// Initializes memory starting at `self` with `count` `T` values beginning |
| /// at `source` and binds the initialized memory to type `T`. |
| /// |
| /// Returns an `UnsafeMutablePointer<T>` this memory. |
| /// |
| /// - Precondition: `count >= 0` |
| /// - Precondition: The memory regions `source..<source + count` and |
| /// `self..<self + count * MemoryLayout<T>.stride` do not overlap. |
| /// - Precondition: The memory at |
| /// `self..<self + count * MemoryLayout<T>.stride` is uninitialized, and |
| /// the `T` values at `source..<source + count` are initialized. |
| /// - Precondition: The underlying pointer is properly aligned for accessing |
| /// `T`. |
| /// - Postcondition: The memory at |
| /// `self..<self + count * MemoryLayout<T>.stride` is bound to type `T`. |
| /// - Postcondition: The `T` values at |
| /// `self..<self + count * MemoryLayout<T>.stride` and |
| /// `source..<source + count` are initialized. |
| @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 memory starting at `self` with the elements of |
| /// `source` and binds the initialized memory to type `T`. |
| /// |
| /// Returns an `UnsafeMutablePointer<T>` this memory. |
| /// |
| /// - Precondition: The memory at `self..<self + source.count * |
| /// MemoryLayout<T>.stride` is uninitialized. |
| /// |
| /// - Postcondition: The memory at `self..<self + source.count * |
| /// MemoryLayout<T>.stride` is bound to type `T`. |
| /// |
| /// - Postcondition: The `T` values at `self..<self + source.count * |
| /// MemoryLayout<T>.stride` are initialized. |
| /// |
| /// TODO: Optimize where `C` is a `ContiguousArrayBuffer`. |
| @discardableResult |
| public func initializeMemory<C : Collection>( |
| as: C.Iterator.Element.Type, from source: C |
| ) -> UnsafeMutablePointer<C.Iterator.Element> { |
| // Initialize and bind each element of the container. |
| for (index, element) in source.enumerated() { |
| self.initializeMemory(as: C.Iterator.Element.self, at: index, to: element) |
| } |
| return UnsafeMutablePointer(_rawValue) |
| } |
| |
| /// Initializes memory starting at `self` with `count` `T` values |
| /// beginning at `source`, binds the initialized memory to type `T`, |
| /// and returns the source memory to an uninitialized state. |
| /// |
| /// Returns an `UnsafeMutablePointer<T>` this memory. |
| /// |
| /// - Precondition: `count >= 0` |
| /// |
| /// - Precondition: The memory at `self..<self + count * |
| /// MemoryLayout<T>.stride` is uninitialized and the `T` values at |
| /// `source..<source + count` are initialized. |
| /// |
| /// - Postcondition: The memory at `self..<self + count * |
| /// MemoryLayout<T>.stride` is bound to type `T`. |
| /// |
| /// - Postcondition: The `T` values at `self..<self + count * |
| /// MemoryLayout<T>.stride` are initialized and the memory at |
| /// `source..<source + count` is uninitialized. |
| @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 |
| |
| /// Reads raw bytes from memory at `self + offset` and constructs a |
| /// value of type `T`. |
| /// |
| /// - Precondition: The underlying pointer plus `offset` is properly |
| /// aligned for accessing `T`. |
| /// |
| /// - Precondition: The memory is initialized to a value of some type, `U`, |
| /// such that `T` is layout compatible with `U`. |
| 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.load((self + offset)._rawValue) |
| } |
| |
| % if mutable: |
| /// Stores a value's bytes into raw memory at `self + offset`. |
| /// |
| /// - Precondition: The underlying pointer plus `offset` is properly |
| /// aligned for storing type `T`. |
| /// |
| /// - Precondition: `T` is a trivial type. |
| /// |
| /// - Precondition: The memory is uninitialized, or initialized to |
| /// some trivial type `U` such that `T` and `U` are mutually layout |
| /// compatible. |
| /// |
| /// - Postcondition: The memory is initialized to raw bytes. If the |
| /// memory is bound to type `U`, then it now contains a value of |
| /// type `U`. |
| /// |
| /// - 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. |
| /// |
| /// - Note: Storing a copy of a nontrivial value into memory |
| /// requires that the user know the type of value previously in |
| /// memory, and requires initialization or assignment of the |
| /// memory. This can be achieved via a typed `UnsafeMutablePointer` |
| /// or via a raw pointer `self`, as follows, where `U` is the |
| /// previous type and `T` is the copied value's type: |
| /// `let typedPtr = self.bindMemory(to: U.self, capacity: 1)` |
| /// `typedPtr.deinitialize(count: 1)` |
| /// `self.initializeMemory(as: T.self, to: newValue)` |
| public func storeBytes<T>( |
| of value: T, toByteOffset offset: Int = 0, as: 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(0)._value, |
| /*volatile:*/ false._value) |
| } |
| } |
| |
| /// Copies `count` bytes from `source` into memory at `self`. |
| /// |
| /// - Precondition: `count` is non-negative. |
| /// |
| /// - Precondition: The memory at `source..<source + count` is |
| /// initialized to some trivial type `T`. |
| /// |
| /// - Precondition: If the memory at `self..<self+count` is bound to |
| /// a type `U`, then `U` is a trivial type, the underlying |
| /// pointers `source` and `self` are properly aligned for type |
| /// `U`, and `count` is a multiple of `MemoryLayout<U>.stride`. |
| /// |
| /// - Postcondition: The memory at `self..<self+count` is |
| /// initialized to raw bytes. If the memory is bound to type `U`, |
| /// then it contains values of type `U`. |
| public func copyBytes(from source: UnsafeRawPointer, count: Int) { |
| _debugPrecondition( |
| count >= 0, "UnsafeMutableRawPointer.copyBytes with negative count") |
| |
| _memmove(dest: self, src: source, size: UInt(count)) |
| } |
| % end # mutable |
| |
| // |
| // Protocol conformance |
| // |
| |
| /// 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. |
| public var hashValue: Int { |
| return Int(bitPattern: self) |
| } |
| |
| /// Returns `x - self`. |
| public func distance(to x: ${Self}) -> Int { |
| return Int(Builtin.sub_Word(Builtin.ptrtoint_Word(x._rawValue), |
| Builtin.ptrtoint_Word(_rawValue))) |
| } |
| |
| /// Returns `self + n`. |
| public func advanced(by n: Int) -> ${Self} { |
| return ${Self}(Builtin.gep_Word(_rawValue, n._builtinWordValue)) |
| } |
| } |
| |
| /// - Note: This may be more efficient than Strideable's implementation |
| /// calling ${Self}.distance(). |
| @_transparent |
| public func == (lhs: ${Self}, rhs: ${Self}) -> Bool { |
| return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue)) |
| } |
| |
| /// - Note: This is an unsigned comparison unlike Strideable's implementation. |
| @_transparent |
| public func < (lhs: ${Self}, rhs: ${Self}) -> Bool { |
| return Bool(Builtin.cmp_ult_RawPointer(lhs._rawValue, rhs._rawValue)) |
| } |
| |
| extension Unsafe${Mutable}RawPointer : CustomDebugStringConvertible { |
| /// A textual representation of the pointer, suitable for debugging. |
| public var debugDescription: String { |
| return _rawPointerToString(_rawValue) |
| } |
| } |
| |
| extension Unsafe${Mutable}RawPointer : CustomReflectable { |
| 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 { |
| 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)))" |
| } |
| |
| public var customPlaygroundQuickLook: PlaygroundQuickLook { |
| return .text(summary) |
| } |
| } |
| |
| extension OpaquePointer { |
| public init(_ from: Unsafe${Mutable}RawPointer) { |
| self._rawValue = from._rawValue |
| } |
| |
| public init?(_ from: Unsafe${Mutable}RawPointer?) { |
| guard let unwrapped = from else { return nil } |
| self._rawValue = unwrapped._rawValue |
| } |
| } |
| |
| extension Int { |
| public init(bitPattern: Unsafe${Mutable}RawPointer?) { |
| if let bitPattern = bitPattern { |
| self = Int(Builtin.ptrtoint_Word(bitPattern._rawValue)) |
| } else { |
| self = 0 |
| } |
| } |
| } |
| |
| extension UInt { |
| public init(bitPattern: Unsafe${Mutable}RawPointer?) { |
| if let bitPattern = bitPattern { |
| self = UInt(Builtin.ptrtoint_Word(bitPattern._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 } |
| } |