| //===--- 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 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 = '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<Pointee>.alignment`, i.e. |
| /// `(UnsafePointer<Int8>(self) - nil) % MemoryLayout<Pointee>.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}<Pointee> |
| : Strideable, Hashable, _Pointer { |
| |
| public typealias Distance = Int |
| |
| /// The underlying raw (untyped) pointer. |
| public let _rawValue: Builtin.RawPointer |
| |
| /// Construct ${a_Self} from a builtin raw pointer. |
| @_transparent |
| public init(_ _rawValue : Builtin.RawPointer) { |
| self._rawValue = _rawValue |
| } |
| |
| /// Convert from an opaque pointer to a typed pointer. |
| @_transparent |
| public init(_ from : OpaquePointer) { |
| _rawValue = from._rawValue |
| } |
| |
| /// Convert 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) |
| } |
| |
| /// Construct ${a_Self} with a given pattern of bits. |
| @_transparent |
| public init?(bitPattern: Int) { |
| if bitPattern == 0 { return nil } |
| self._rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue) |
| } |
| |
| /// Construct ${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) |
| } |
| |
| /// Construct ${a_Self} from another ${a_Self}. |
| @_transparent |
| public init(_ other: ${Self}<Pointee>) { |
| self = other |
| } |
| |
| /// Construct ${a_Self} from another ${a_Self}. |
| /// |
| /// Returns nil if `other` is nil. |
| @_transparent |
| public init?(_ other: ${Self}<Pointee>?) { |
| guard let unwrapped = other else { return nil } |
| self = unwrapped |
| } |
| |
| % if mutable: |
| /// Convert from `UnsafePointer` to `UnsafeMutablePointer` of the same |
| /// `Pointee`. |
| @_transparent |
| public init(mutating other: UnsafePointer<Pointee>) { |
| self._rawValue = other._rawValue |
| } |
| |
| /// Convert from `UnsafePointer` to `UnsafeMutablePointer` of the same |
| /// `Pointee`. |
| /// |
| /// Returns nil if `bitPattern` is zero. |
| @_transparent |
| public init?(mutating other: UnsafePointer<Pointee>?) { |
| guard let unwrapped = other else { return nil } |
| self.init(mutating: unwrapped) |
| } |
| % else: |
| /// Convert from `UnsafeMutablePointer` to ${a_Self} of the same `Pointee`. |
| @_transparent |
| public init(_ other: UnsafeMutablePointer<Pointee>) { |
| self._rawValue = other._rawValue |
| } |
| |
| /// Convert from `UnsafeMutablePointer` to ${a_Self} of the same `Pointee`. |
| /// |
| /// Returns nil if `from` is nil. |
| @_transparent |
| public init?(_ other: UnsafeMutablePointer<Pointee>?) { |
| guard let unwrapped = other else { return nil } |
| self.init(unwrapped) |
| } |
| % end |
| |
| % if mutable: |
| /// Allocate and point 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<Pointee> { |
| let size = MemoryLayout<Pointee>.stride * count |
| let rawPtr = |
| Builtin.allocRaw(size._builtinWordValue, Builtin.alignof(Pointee.self)) |
| Builtin.bindMemory(rawPtr, count._builtinWordValue, Pointee.self) |
| return UnsafeMutablePointer(rawPtr) |
| } |
| |
| /// Deallocate 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<Pointee>.stride * capacity |
| Builtin.deallocRaw( |
| _rawValue, size._builtinWordValue, Builtin.alignof(Pointee.self)) |
| } |
| % end |
| |
| /// Access the `Pointee` instance referenced by `self`. |
| /// |
| /// - Precondition: the pointee has been initialized with an instance of |
| /// type `Pointee`. |
| public var pointee: Pointee { |
| % if mutable: |
| @_transparent unsafeAddress { |
| return UnsafePointer(self) |
| } |
| @_transparent nonmutating unsafeMutableAddress { |
| return self |
| } |
| % else: |
| @_transparent unsafeAddress { |
| return self |
| } |
| % end |
| } |
| |
| % if mutable: |
| /// Initialize `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..<count { |
| Builtin.initialize(newValue, (self + offset)._rawValue) |
| } |
| } |
| |
| /// Retrieve the `pointee`, returning the referenced memory to an |
| /// uninitialized state. |
| /// |
| /// Equivalent to `{ defer { deinitialize() }; return pointee }()`, but |
| /// more efficient. |
| /// |
| /// - Precondition: The pointee is initialized. |
| /// |
| /// - Postcondition: The memory is uninitialized. |
| public func move() -> Pointee { |
| return Builtin.take(_rawValue) |
| } |
| |
| /// Replace `count` initialized `Pointee`s starting at `self` with |
| /// the `count` `Pointee`s at `source`. |
| /// |
| /// - Precondition: `count >= 0` |
| /// |
| /// - Precondition: The `Pointee`s at `self..<self + count` and |
| /// `source..<source + count` are initialized. |
| public func assign(from source: UnsafePointer<Pointee>, 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..<count { |
| self[i] = source[i] |
| } |
| } |
| else { |
| // assign backward from a non-following overlapping range. |
| var i = count-1 |
| while i >= 0 { |
| self[i] = source[i] |
| i -= 1 |
| } |
| } |
| } |
| |
| /// Initialize 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..<self + count` is uninitialized |
| /// and the `Pointees` at `source..<source + count` are |
| /// initialized. |
| /// |
| /// - Postcondition: The `Pointee`s at `self..<self + count` are |
| /// initialized and the memory at `source..<source + count` is |
| /// uninitialized. |
| public func moveInitialize(from source: ${Self}, count: Int) { |
| _debugPrecondition( |
| count >= 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..<count { |
| // (self + i).initialize(to: (source + i).move()) |
| // } |
| } |
| else { |
| // initialize backward from a non-following overlapping range. |
| Builtin.takeArrayBackToFront( |
| Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue) |
| // This builtin is equivalent to: |
| // var src = source + count |
| // var dst = self + count |
| // while dst != self { |
| // (--dst).initialize(to: (--src).move()) |
| // } |
| } |
| } |
| |
| /// Initialize memory starting at `self` with `count` `Pointee`s |
| /// beginning at `source`. |
| /// |
| /// - Precondition: `count >= 0` |
| /// |
| /// - Precondition: The memory regions `source..<source + count` |
| /// and `self..<self + count` do not overlap. |
| /// |
| /// - Precondition: The memory at `self..<self + count` is uninitialized |
| /// and the `Pointees` at `source..<source + count` are |
| /// initialized. |
| /// |
| /// - Postcondition: The `Pointee`s at `self..<self + count` and |
| /// `source..<source + count` are initialized. |
| public func initialize(from source: UnsafePointer<Pointee>, 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..<count { |
| // (self + i).initialize(to: source[i]) |
| // } |
| } |
| |
| /// Initialize memory starting at `self` with the elements of `source`. |
| /// |
| /// - Precondition: The memory at `self..<self + count` is |
| /// uninitialized. |
| /// |
| /// - Postcondition: The `Pointee`s at `self..<self + count` are |
| /// initialized. |
| public func initialize<C : Collection>(from source: C) |
| where C.Iterator.Element == Pointee { |
| source._copyContents(initializing: self) |
| } |
| |
| /// Replace `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..<source + count` |
| /// and `self..<self + count` do not overlap. |
| /// |
| /// - Precondition: The `Pointee`s at `self..<self + count` and |
| /// `source..<source + count` are initialized. |
| /// |
| /// - Postcondition: The `Pointee`s at `self..<self + count` are |
| /// initialized and the `Pointees` at `source..<source + count` |
| /// are uninitialized. |
| public func moveAssign(from source: ${Self}, count: Int) { |
| _debugPrecondition( |
| count >= 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..<count { |
| // self[i] = (source + i).move() |
| // } |
| } |
| |
| /// De-initialize the `count` `Pointee`s starting at `self`, returning |
| /// their memory to an uninitialized state. |
| /// |
| /// Returns an UnsafeMutableRawPointer to this memory. |
| /// |
| /// - Precondition: The `Pointee`s at `self..<self + count` are |
| /// initialized. |
| /// |
| /// - Postcondition: The memory is uninitialized. |
| @discardableResult |
| public func deinitialize(count: Int = 1) -> 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 |
| |
| /// Rebind memory at `self` to type `T` with capacity to hold `count` adjacent |
| /// `T` values while executing the `body` closure. After executing the |
| /// closure, rebind memory back to `Pointee`. |
| /// |
| /// - Precondition: Type 'T' is layout compatible with type 'Pointee'. |
| /// |
| /// - Precondition: The memory `self..<self + count * MemoryLayout<T>.stride` |
| /// is bound to `Pointee`. |
| public func withMemoryRebound<T, Result>(to: T.Type, capacity count: Int, |
| _ body: (UnsafeMutablePointer<T>) throws -> Result |
| ) rethrows -> Result { |
| Builtin.bindMemory(_rawValue, count._builtinWordValue, T.self) |
| defer { |
| Builtin.bindMemory(_rawValue, count._builtinWordValue, Pointee.self) |
| } |
| return try body(UnsafeMutablePointer<T>(_rawValue)) |
| } |
| |
| /// Access the pointee at `self + i`. |
| /// |
| /// - Precondition: the pointee at `self + i` is initialized. |
| 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 hash value. |
| /// |
| /// **Axiom:** `x == y` implies `x.hashValue == y.hashValue`. |
| /// |
| /// - Note: 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. |
| public func successor() -> ${Self} { |
| return self + 1 |
| } |
| |
| /// Returns the previous consecutive position. |
| public func predecessor() -> ${Self} { |
| return self - 1 |
| } |
| |
| /// Return `end - self`. |
| public func distance(to x: ${Self}) -> Int { |
| return x - self |
| } |
| |
| /// Return `self + n`. |
| public func advanced(by n: Int) -> ${Self} { |
| return self + n |
| } |
| } |
| |
| extension ${Self} : CustomDebugStringConvertible { |
| /// A textual representation of `self`, 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) |
| } |
| } |
| |
| /// - Note: Strideable's implementation is potentially less efficient and cannot |
| /// handle misaligned pointers. |
| @_transparent |
| public func == <Pointee>( |
| lhs: ${Self}<Pointee>, rhs: ${Self}<Pointee> |
| ) -> 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 func < <Pointee>(lhs: ${Self}<Pointee>, rhs: ${Self}<Pointee>) -> 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. |
| @_transparent |
| public func + <Pointee>(lhs: ${Self}<Pointee>, rhs: Int) -> ${Self}<Pointee> { |
| return ${Self}(Builtin.gep_Word( |
| lhs._rawValue, (rhs &* MemoryLayout<Pointee>.stride)._builtinWordValue)) |
| } |
| |
| @_transparent |
| public func + <Pointee>(lhs: Int, |
| rhs: ${Self}<Pointee>) -> ${Self}<Pointee> { |
| return rhs + lhs |
| } |
| |
| @_transparent |
| public func - <Pointee>(lhs: ${Self}<Pointee>, rhs: Int) -> ${Self}<Pointee> { |
| return lhs + -rhs |
| } |
| |
| @_transparent |
| public func - <Pointee>(lhs: ${Self}<Pointee>, rhs: ${Self}<Pointee>) -> Int { |
| return |
| Int(Builtin.sub_Word(Builtin.ptrtoint_Word(lhs._rawValue), |
| Builtin.ptrtoint_Word(rhs._rawValue))) |
| / MemoryLayout<Pointee>.stride |
| } |
| |
| @_transparent |
| public func += <Pointee>(lhs: inout ${Self}<Pointee>, rhs: Int) { |
| lhs = lhs + rhs |
| } |
| |
| @_transparent |
| public func -= <Pointee>(lhs: inout ${Self}<Pointee>, rhs: Int) { |
| lhs = lhs - rhs |
| } |
| |
| extension ${Self} { |
| @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:count:)") |
| public func initializeFrom(_ source: UnsafePointer<Pointee>, count: Int) { |
| Builtin.unreachable() |
| } |
| |
| @available(*, unavailable, renamed: "assign(from:count:)") |
| public func assignFrom(_ source: UnsafePointer<Pointee>, count: Int) { |
| Builtin.unreachable() |
| } |
| |
| @available(*, unavailable, renamed: "assign(from:count:)") |
| public func assignBackwardFrom(_ source: UnsafePointer<Pointee>, count: Int) { |
| Builtin.unreachable() |
| } |
| |
| @available(*, unavailable, renamed: "moveInitialize(from:count:)") |
| public func moveInitializeFrom(_ source: UnsafePointer<Pointee>, count: Int) { |
| Builtin.unreachable() |
| } |
| |
| @available(*, unavailable, renamed: "moveInitialize(from:count:)") |
| public func moveInitializeBackwardFrom(_ source: UnsafePointer<Pointee>, |
| count: Int) { |
| Builtin.unreachable() |
| } |
| |
| @available(*, unavailable, renamed: "moveAssign(from:count:)") |
| public func moveAssignFrom(_ source: UnsafePointer<Pointee>, count: Int) { |
| Builtin.unreachable() |
| } |
| % end |
| } |
| |
| extension Int { |
| public init<U>(bitPattern: ${Self}<U>?) { |
| if let bitPattern = bitPattern { |
| self = Int(Builtin.ptrtoint_Word(bitPattern._rawValue)) |
| } else { |
| self = 0 |
| } |
| } |
| } |
| |
| extension UInt { |
| public init<U>(bitPattern: ${Self}<U>?) { |
| 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: |