//===--- 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(_ other: Unsafe${Mutable}Pointer) { _rawValue = other._rawValue } /// Converts an Unsafe${Mutable}Pointer to ${a_Self}. /// /// Returns `nil` if `other` is `nil`. @_transparent public init?(_ other: Unsafe${Mutable}Pointer?) { 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(_ other: UnsafeMutablePointer) { _rawValue = other._rawValue } /// Converts an UnsafeMutablePointer to ${a_Self}. /// /// Returns `nil` if `other` is `nil`. @_transparent public init?(_ other: UnsafeMutablePointer?) { 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 uninitialized or initialized to a /// trivial type. /// - 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` to the bound memory at `self`. /// /// - Precondition: The memory is uninitialized or initialized to a type /// that is layout compatible with `T`. /// - Postcondition: The memory is bound to 'T' starting at `self` continuing /// through `self` + `count` * `MemoryLayout.stride` /// - Warning: A memory location may only be bound to one type at a time. /// The behavior of accessing memory as type `U` while it is bound to an /// unrelated type `T` is undefined. @_transparent @discardableResult public func bindMemory(to type: T.Type, capacity count: Int) -> Unsafe${Mutable}Pointer { Builtin.bindMemory(_rawValue, count._builtinWordValue, type) return Unsafe${Mutable}Pointer(_rawValue) } /// Converts from ${a_Self} to Unsafe${Mutable}Pointer 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 /// memory has not been bound to `T`. @_transparent public func assumingMemoryBound(to: T.Type) -> Unsafe${Mutable}Pointer { return Unsafe${Mutable}Pointer(_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` to this memory. /// /// - Precondition: The memory at /// `self + index * strideof(T)..(as type: T.Type, at index: Int = 0, count: Int = 1, to value: T ) -> UnsafeMutablePointer { _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.stride for _ in 0...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` this memory. /// /// - Precondition: `count >= 0` /// - Precondition: The memory regions `source...stride` do not overlap. /// - Precondition: The memory at /// `self...stride` is uninitialized or /// initialized to a trivial type, and the `T` values at /// `source...stride` is bound to type `T`. /// - Postcondition: The `T` values at /// `self...stride` and /// `source..( as type: T.Type, from source: UnsafePointer, count: Int ) -> UnsafeMutablePointer { _debugPrecondition( count >= 0, "UnsafeMutableRawPointer.initializeMemory with negative count") _debugPrecondition( (UnsafeRawPointer(self + count * MemoryLayout.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..` this memory. /// /// - Precondition: The memory at `self...stride` is uninitialized or initialized to a /// trivial type. /// /// - Postcondition: The memory at `self...stride` is bound to type `T`. /// /// - Postcondition: The `T` values at `self...stride` are initialized. /// /// TODO: Optimize where `C` is a `ContiguousArrayBuffer`. @discardableResult public func initializeMemory( as: C.Iterator.Element.Type, from source: C ) -> UnsafeMutablePointer { // 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` this memory. /// /// - Precondition: `count >= 0` /// /// - Precondition: The memory at `self...stride` is uninitialized or initialized to a /// trivial type and the `T` values at /// `source...stride` is bound to type `T`. /// /// - Postcondition: The `T` values at `self...stride` are initialized and the memory at /// `source..( as type: T.Type, from source: UnsafeMutablePointer, count: Int ) -> UnsafeMutablePointer { _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..(fromByteOffset offset: Int = 0, as type: T.Type) -> T { _debugPrecondition(0 == (UInt(bitPattern: self + offset) & (UInt(MemoryLayout.alignment) - 1)), "load from misaligned raw pointer") return Builtin.loadRaw((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( of value: T, toByteOffset offset: Int = 0, as: T.Type ) { _debugPrecondition(0 == (UInt(bitPattern: self + offset) & (UInt(MemoryLayout.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.size)._value, /*alignment:*/ Int32()._value, /*volatile:*/ false._value) } } /// Copies `count` bytes from `source` into memory at `self`. /// /// - Precondition: `count` is non-negative. /// /// - Precondition: The memory at `source...stride`. /// /// - Postcondition: The memory at `self..= 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.gepRaw_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(_ from : UnsafePointer) { Builtin.unreachable() } @available(*, unavailable, renamed: "init(mutating:)") public init?(_ from : UnsafePointer?) { Builtin.unreachable(); return nil } }