//===--- UnsafePointer.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 https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// %import gyb % for mutable in (True, False): % Self = 'UnsafeMutablePointer' if mutable else 'UnsafePointer' % a_Self = 'an `UnsafeMutablePointer`' if mutable else 'an `UnsafePointer`' /// A raw pointer for accessing data of type `Pointee`. This type /// provides no automated memory management, and therefore must /// be handled with great care to ensure safety. /// /// Instances must be aligned to `MemoryLayout.alignment`, i.e. /// `(UnsafePointer(self) - nil) % MemoryLayout.alignment == 0` /// /// The memory referenced by an instance can be in one of the following states: /// /// - Memory is not allocated (for example, pointer is null, or memory has /// been deallocated previously). /// /// - Memory is allocated, but value has not been initialized. /// /// - Memory is allocated and value is initialized. @_fixed_layout public struct ${Self} : Strideable, Hashable, _Pointer { public typealias Distance = Int /// The underlying raw (untyped) pointer. public let _rawValue: Builtin.RawPointer /// Creates ${a_Self} from a builtin raw pointer. @_transparent public init(_ _rawValue : Builtin.RawPointer) { self._rawValue = _rawValue } /// Converts from an opaque pointer to a typed pointer. @_transparent public init(_ from : OpaquePointer) { _rawValue = from._rawValue } /// Converts from an opaque pointer to a typed pointer. /// /// Returns `nil` if `from` is `nil`. @_transparent public init?(_ from : OpaquePointer?) { guard let unwrapped = from else { return nil } self.init(unwrapped) } /// Creates ${a_Self} with a given pattern of bits. /// /// Returns `nil` if `bitPattern` is zero. @_transparent public init?(bitPattern: Int) { if bitPattern == 0 { return nil } self._rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue) } /// Creates ${a_Self} with a given pattern of bits. /// /// Returns `nil` if `bitPattern` is zero. @_transparent public init?(bitPattern: UInt) { if bitPattern == 0 { return nil } self._rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue) } /// Creates ${a_Self} from another `${Self}`. @_transparent public init(_ other: ${Self}) { self = other } /// Creates ${a_Self} from another `${Self}`. /// /// Returns `nil` if `other` is `nil`. @_transparent public init?(_ other: ${Self}?) { guard let unwrapped = other else { return nil } self = unwrapped } % if mutable: /// Converts from `UnsafePointer` to `UnsafeMutablePointer` of the same /// `Pointee`. @_transparent public init(mutating other: UnsafePointer) { self._rawValue = other._rawValue } /// Converts from `UnsafePointer` to `UnsafeMutablePointer` of the same /// `Pointee`. /// /// Returns nil if `bitPattern` is zero. @_transparent public init?(mutating other: UnsafePointer?) { guard let unwrapped = other else { return nil } self.init(mutating: unwrapped) } % else: /// Converts from `UnsafeMutablePointer` to ${a_Self} of the same `Pointee`. @_transparent public init(_ other: UnsafeMutablePointer) { self._rawValue = other._rawValue } /// Converts from `UnsafeMutablePointer` to ${a_Self} of the same `Pointee`. /// /// Returns nil if `from` is nil. @_transparent public init?(_ other: UnsafeMutablePointer?) { guard let unwrapped = other else { return nil } self.init(unwrapped) } % end % if mutable: /// Allocates and points at uninitialized aligned memory for `count` /// instances of `Pointee`. /// /// - Postcondition: The pointee is allocated, but not initialized. static public func allocate(capacity count: Int) -> UnsafeMutablePointer { let size = MemoryLayout.stride * count let rawPtr = Builtin.allocRaw(size._builtinWordValue, Builtin.alignof(Pointee.self)) Builtin.bindMemory(rawPtr, count._builtinWordValue, Pointee.self) return UnsafeMutablePointer(rawPtr) } /// Deallocates uninitialized memory allocated for `count` instances /// of `Pointee`. /// /// - Precondition: The memory is not initialized. /// /// - Postcondition: The memory has been deallocated. public func deallocate(capacity: Int) { let size = MemoryLayout.stride * capacity Builtin.deallocRaw( _rawValue, size._builtinWordValue, Builtin.alignof(Pointee.self)) } % end /// Accesses the `Pointee` instance referenced by `self`. /// /// - Precondition: Either the pointee has been initialized with an /// instance of type `Pointee`, or `pointee` is being assigned to /// and `Pointee` is a trivial type. public var pointee: Pointee { % if mutable: @_transparent unsafeAddress { return UnsafePointer(self) } @_transparent nonmutating unsafeMutableAddress { return self } % else: @_transparent unsafeAddress { return self } % end } % if mutable: /// Initializes `self.pointee` with `count` consecutive copies of `newValue` /// /// - Precondition: The pointee is not initialized. /// /// - Precondition: `count` is non-negative. /// /// - Postcondition: The pointee is initialized; the value should eventually /// be destroyed or moved from to avoid leaks. public func initialize(to newValue: Pointee, count: Int = 1) { // FIXME: add tests (since the `count` has been added) _debugPrecondition(count >= 0, "${Self}.initialize(to:): negative count") // Must not use `initializeFrom` with a `Collection` as that will introduce // a cycle. for offset in 0.. Pointee { return Builtin.take(_rawValue) } /// Replaces `count` initialized `Pointee`s starting at `self` with /// the `count` `Pointee`s at `source`. /// /// - Precondition: `count >= 0` /// /// - Precondition: The `Pointee`s at `source.., count: Int) { _debugPrecondition( count >= 0, "${Self}.assign with negative count") if UnsafePointer(self) < source || UnsafePointer(self) >= source + count { // assign forward from a disjoint or following overlapping range. for i in 0..= 0 { self[i] = source[i] i -= 1 } } } /// Initializes memory starting at `self` with `count` `Pointee`s /// beginning at `source`, and returning the source memory to an /// uninitialized state. /// /// - Precondition: `count >= 0` /// /// - Precondition: The memory at `self..= 0, "${Self}.moveInitialize with negative count") if self < source || self >= source + count { // initialize forward from a disjoint or following overlapping range. Builtin.takeArrayFrontToBack( Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue) // This builtin is equivalent to: // for i in 0..= 0` /// /// - Precondition: The memory regions `source.., count: Int) { _debugPrecondition( count >= 0, "${Self}.initialize with negative count") _debugPrecondition( UnsafePointer(self) + count <= source || source + count <= UnsafePointer(self), "${Self}.initialize overlapping range") Builtin.copyArray( Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue) // This builtin is equivalent to: // for i in 0..(from source: C) where C.Iterator.Element == Pointee { source._copyContents(initializing: self) } /// Replaces `count` initialized `Pointee`s starting at `self` with /// the `count` `Pointee`s starting at `source`, returning the /// source memory to an uninitialized state. /// /// - Precondition: `count >= 0` /// /// - Precondition: The memory regions `source..= 0, "${Self}.moveAssign(from:) with negative count") _debugPrecondition( self + count <= source || source + count <= self, "moveAssign overlapping range") Builtin.destroyArray(Pointee.self, self._rawValue, count._builtinWordValue) Builtin.takeArrayFrontToBack( Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue) // These builtins are equivalent to: // for i in 0.. UnsafeMutableRawPointer { _debugPrecondition(count >= 0, "${Self}.deinitialize with negative count") // FIXME: optimization should be implemented, where if the `count` value // is 1, the `Builtin.destroy(Pointee.self, _rawValue)` gets called. Builtin.destroyArray(Pointee.self, _rawValue, count._builtinWordValue) return UnsafeMutableRawPointer(self) } % end /// Rebinds memory at `self` to type `T` with capacity to hold `count` /// adjacent `T` values while executing the `body` closure. /// /// After executing the closure, rebinds memory back to `Pointee`. /// /// - Precondition: Type 'T' is layout compatible with type 'Pointee'. /// - Precondition: The memory `self...stride` /// is bound to `Pointee`. /// /// Accessing `${Self}.pointee` requires that the memory be "bound" to /// type `T`. A memory location may only be bound to one type at a time, so /// accessing the same memory as an unrelated type without first rebinding the /// memory is undefined. `self` may not be accessed within the `body` closure /// because memory is no longer bound to `Pointee` while it executes. The /// closure's `${Self}` argument must not escape the closure because memory /// is only temporarily bound to `T`. /// /// To persistently bind this memory to a different type, first obtain a /// raw pointer to the memory, then invoke the `bindMemory` API: /// `UnsafeRawPointer(typedPointer).bindMemory(to:capacity:)`. public func withMemoryRebound(to: T.Type, capacity count: Int, _ body: (${Self}) throws -> Result ) rethrows -> Result { Builtin.bindMemory(_rawValue, count._builtinWordValue, T.self) defer { Builtin.bindMemory(_rawValue, count._builtinWordValue, Pointee.self) } return try body(${Self}(_rawValue)) } /// Accesses the pointee at `self + i`. /// /// - Precondition: Either the pointee at `self + i` is initialized, or the /// subscript is the left side of an assignment and `Pointee` is a trivial /// type. public subscript(i: Int) -> Pointee { % if mutable: @_transparent unsafeAddress { return UnsafePointer(self + i) } @_transparent nonmutating unsafeMutableAddress { return self + i } % else: @_transparent unsafeAddress { return self + i } % end } // // 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 the next consecutive position. /// /// - Precondition: The result is within the bounds of the same allocation. public func successor() -> ${Self} { return self + 1 } /// Returns the previous consecutive position. /// /// - Precondition: The result is within the bounds of the same allocation. public func predecessor() -> ${Self} { return self - 1 } /// Returns `end - self`. /// /// - Precondition: The result is within the bounds of the same allocation. public func distance(to end: ${Self}) -> Int { return end - self } /// Returns `self + n`. /// /// - Precondition: The result is within the bounds of the same allocation. public func advanced(by n: Int) -> ${Self} { return self + n } } extension ${Self} : CustomDebugStringConvertible { /// A textual representation of the pointer, suitable for debugging. public var debugDescription: String { return _rawPointerToString(_rawValue) } } extension ${Self} : CustomReflectable { public var customMirror: Mirror { let ptrValue = UInt64(bitPattern: Int64(Int(Builtin.ptrtoint_Word(_rawValue)))) return Mirror(self, children: ["pointerValue": ptrValue]) } } extension ${Self} : 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 ${Self} { // - Note: Strideable's implementation is potentially less efficient and cannot // handle misaligned pointers. @_transparent public static func == (lhs: ${Self}, rhs: ${Self}) -> Bool { return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue)) } // - Note: Strideable's implementation is potentially less efficient and // cannot handle misaligned pointers. // // - Note: This is an unsigned comparison unlike Strideable's implementation. @_transparent public static func < (lhs: ${Self}, rhs: ${Self}) -> Bool { return Bool(Builtin.cmp_ult_RawPointer(lhs._rawValue, rhs._rawValue)) } // - Note: The following family of operator overloads are redundant // with Strideable. However, optimizer improvements are needed // before they can be removed without affecting performance. /// - Precondition: The result is within bounds of the same allocation. @_transparent public static func + (lhs: ${Self}, rhs: Int) -> ${Self} { return ${Self}(Builtin.gep_Word( lhs._rawValue, rhs._builtinWordValue, Pointee.self)) } /// - Precondition: The result is within the bounds of the same allocation. @_transparent public static func + (lhs: Int, rhs: ${Self}) -> ${Self} { return rhs + lhs } /// - Precondition: The result is within the bounds of the same allocation. @_transparent public static func - (lhs: ${Self}, rhs: Int) -> ${Self} { return lhs + -rhs } @_transparent public static func - (lhs: ${Self}, rhs: ${Self}) -> Int { return Int(Builtin.sub_Word(Builtin.ptrtoint_Word(lhs._rawValue), Builtin.ptrtoint_Word(rhs._rawValue))) / MemoryLayout.stride } /// - Precondition: The result is within the bounds of the same allocation. @_transparent public static func += (lhs: inout ${Self}, rhs: Int) { lhs = lhs + rhs } /// - Precondition: The result is within the bounds of the same allocation. @_transparent public static func -= (lhs: inout ${Self}, rhs: Int) { lhs = lhs - rhs } } extension ${Self} { @available(*, unavailable, message: "use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.") public init(_ from : UnsafeMutablePointer) { Builtin.unreachable() } @available(*, unavailable, message: "use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.") public init?(_ from : UnsafeMutablePointer?) { Builtin.unreachable(); return nil } @available(*, unavailable, message: "use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.") public init(_ from : UnsafePointer) { Builtin.unreachable() } @available(*, unavailable, message: "use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.") public init?(_ from : UnsafePointer?) { Builtin.unreachable(); return nil } % if mutable: @available(*, unavailable, renamed: "init(mutating:)") public init(_ from : UnsafePointer) { Builtin.unreachable() } @available(*, unavailable, renamed: "init(mutating:)") public init?(_ from : UnsafePointer?) { Builtin.unreachable(); return nil } % end @available(*, unavailable, renamed: "Pointee") public typealias Memory = Pointee @available(*, unavailable, message: "use 'nil' literal") public init() { Builtin.unreachable() } % if mutable: @available(*, unavailable, renamed: "allocate(capacity:)") public static func alloc(_ num: Int) -> ${Self} { Builtin.unreachable() } @available(*, unavailable, message: "use '${Self}.allocate(capacity:)'") public init(allocatingCapacity: Int) { Builtin.unreachable() } @available(*, unavailable, renamed: "deallocate(capacity:)") public func dealloc(_ num: Int) { Builtin.unreachable() } @available(*, unavailable, renamed: "deallocate(capacity:)") public func deallocateCapacity(_ num: Int) { Builtin.unreachable() } % end @available(*, unavailable, renamed: "pointee") public var memory: Pointee { get { Builtin.unreachable() } % if mutable: set { Builtin.unreachable() } % end } % if mutable: @available(*, unavailable, renamed: "initialize(to:)") public func initialize(_ newvalue: Pointee) { Builtin.unreachable() } @available(*, unavailable, renamed: "initialize(to:count:)") public func initialize(with newvalue: Pointee, count: Int = 1) { Builtin.unreachable() } @available(*, unavailable, renamed: "deinitialize(count:)") public func destroy() { Builtin.unreachable() } @available(*, unavailable, renamed: "deinitialize(count:)") public func destroy(_ count: Int) { Builtin.unreachable() } @available(*, unavailable, renamed: "initialize(from:)") public func initializeFrom(_ source: C) { Builtin.unreachable() } @available(*, unavailable, renamed: "initialize(from:count:)") public func initializeFrom(_ source: UnsafePointer, count: Int) { Builtin.unreachable() } @available(*, unavailable, renamed: "assign(from:count:)") public func assignFrom(_ source: UnsafePointer, count: Int) { Builtin.unreachable() } @available(*, unavailable, renamed: "assign(from:count:)") public func assignBackwardFrom(_ source: UnsafePointer, count: Int) { Builtin.unreachable() } @available(*, unavailable, renamed: "moveInitialize(from:count:)") public func moveInitializeFrom(_ source: UnsafePointer, count: Int) { Builtin.unreachable() } @available(*, unavailable, renamed: "moveInitialize(from:count:)") public func moveInitializeBackwardFrom(_ source: UnsafePointer, count: Int) { Builtin.unreachable() } @available(*, unavailable, renamed: "moveAssign(from:count:)") public func moveAssignFrom(_ source: UnsafePointer, count: Int) { Builtin.unreachable() } % end } extension Int { public init(bitPattern: ${Self}?) { if let bitPattern = bitPattern { self = Int(Builtin.ptrtoint_Word(bitPattern._rawValue)) } else { self = 0 } } } extension UInt { public init(bitPattern: ${Self}?) { if let bitPattern = bitPattern { self = UInt(Builtin.ptrtoint_Word(bitPattern._rawValue)) } else { self = 0 } } } % end # for mutable // ${'Local Variables'}: // eval: (read-only-mode 1) // End: