//===--- 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 `alignof(Pointee.self)`, i.e. /// `(UnsafePointer(self) - nil) % alignof(Pointee.self) == 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. public struct ${Self} : RandomAccessIndex, Hashable, NilLiteralConvertible, _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(_ other : OpaquePointer) { _rawValue = other._rawValue } /// Construct ${a_Self} with a given pattern of bits. @_transparent public init(bitPattern: Int) { self._rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue) } /// Construct ${a_Self} with a given pattern of bits. @_transparent public init(bitPattern: UInt) { self._rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue) } /// Convert from any `UnsafeMutablePointer`, possibly with a /// different `Pointee`. /// /// - Warning: the behavior of accesses to pointee as a type /// different from that to which it was initialized is undefined. @_transparent public init(_ from : UnsafeMutablePointer) { _rawValue = from._rawValue } /// Convert from any `UnsafePointer`, possibly with a /// different `Pointee`. /// /// - Warning: the behavior of accesses to pointee as a type /// different from that to which it was initialized is undefined. @_transparent public init(_ from : UnsafePointer) { _rawValue = from._rawValue } /// Create an instance initialized with `nil`. @_transparent public init(nilLiteral: ()) { self._rawValue = _nilRawPointer } % if mutable: /// Allocate and point at uninitialized aligned memory for `count` /// instances of `Pointee`. /// /// - Postcondition: The pointee is allocated, but not initialized. @warn_unused_result public init(allocatingCapacity count: Int) { let size = strideof(Pointee.self) * count self._rawValue = Builtin.allocRaw(size._builtinWordValue, Builtin.alignof(Pointee.self)) } /// Deallocate uninitialized memory allocated for `count` instances /// of `Pointee`. /// /// - Precondition: The memory is not initialized. /// /// - Postcondition: The memory has been deallocated. public func deallocateCapacity(num: Int) { let size = strideof(Pointee.self) * num 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. /// `count` is non-negative. /// /// - Postcondition: The pointee is initialized; the value should eventually /// be destroyed or moved from to avoid leaks. // FIXME: add tests (since the `count` has been added) public func initialize(with newValue: Pointee, count: Int = 1) { _stdlibAssert(count >= 0, "${Self}.initialize(with:): negative count") // Must not use `initializeFrom` with a `Collection` as that will introduce // a cycle. for offset in 0.. Pointee { return Builtin.take(_rawValue) } /// Replace `count` initialized `Pointee`s starting at `self` with /// the `count` `Pointee`s at `source`, proceeding forward from /// `self` to `self + count - 1`. /// /// - Precondition: `count >= 0` /// /// - Precondition: `self` either precedes `source` or follows /// `source + count - 1`. /// /// - Precondition: The `Pointee`s at `self..= 0, "${Self}.assignFrom with negative count") _stdlibAssert( self < source || self >= source + count, "assignFrom non-following overlapping range; use assignBackwardFrom") for i in 0..= 0` /// /// - Precondition: `source` either precedes `self` or follows /// `self + count - 1`. /// /// - Precondition: The `Pointee`s at `self..= 0, "${Self}.assignBackwardFrom with negative count") _stdlibAssert( source < self || source >= self + count, "${Self}.assignBackwardFrom non-preceding overlapping range; use assignFrom instead") 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`, proceeding forward from `self` to `self + /// count - 1`, and returning the source memory to an uninitialized /// state. /// /// - Precondition: `count >= 0` /// /// - Precondition: `self` either precedes `source` or follows `source + /// count - 1`. /// /// - Precondition: The memory at `self..= 0, "${Self}.moveInitializeFrom with negative count") _stdlibAssert( self < source || self >= source + count, "${Self}.moveInitializeFrom non-following overlapping range; use moveInitializeBackwardFrom") Builtin.takeArrayFrontToBack( Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue) // This builtin is equivalent to: // for i in 0..= 0` /// /// - Precondition: `source` either precedes `self` or follows /// `self + count - 1`. /// /// - Precondition: The memory at `self..= 0, "${Self}.moveInitializeBackwardFrom with negative count") _stdlibAssert( source < self || source >= self + count, "${Self}.moveInitializeBackwardFrom non-preceding overlapping range; use moveInitializeFrom instead") 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(with: (--src).move()) // } } /// Initialize memory starting at `self` with `count` `Pointee`s /// beginning at `source`, proceeding forward from `self` to `self + /// count - 1`. /// /// - Precondition: `count >= 0` /// /// - Precondition: `self` either precedes `source` or follows `source + /// count - 1`. /// /// - Precondition: The memory at `self..= 0, "${Self}.initializeFrom with negative count") _stdlibAssert( self + count <= source || source + count <= self, "${Self}.initializeFrom non-following overlapping range") Builtin.copyArray( Pointee.self, self._rawValue, source._rawValue, count._builtinWordValue) // This builtin is equivalent to: // for i in 0..(source: C) { 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 source and destination ranges do not overlap /// /// - Precondition: The `Pointee`s at `self..= 0, "${Self}.moveAssignFrom with negative count") _stdlibAssert( self + count <= source || source + count <= self, "moveAssignFrom 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..= 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) } % end @_transparent public var _isNull : Bool { return self == nil } /// 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 } % if mutable: /// If self was converted from `nil`, writes the result of invoking body into /// the pointee. public // SPI(Foundation) func _setIfNonNil(@noescape body: () -> Pointee) { if self != nil { pointee = body() } } #if _runtime(_ObjC) /// Returns the result of invoking body. If self was converted from /// `nil`, passes `nil` as the argument. Otherwise, passes the address /// of a `Pointee` which is written into buffer before this method returns. @_transparent public func _withBridgeObject( buffer: inout U?, @noescape body: AutoreleasingUnsafeMutablePointer -> R ) -> R { return self != nil ? body(&buffer) : body(nil) } #endif /// Returns the result of invoking body. If self was converted from /// `nil`, passes `nil` as the argument. Otherwise, passes the address /// of buffer. @_transparent public func _withBridgeValue( buffer: inout U, @noescape body: UnsafeMutablePointer -> R ) -> R { return self != nil ? body(&buffer) : body(nil) } % 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(Builtin.ptrtoint_Word(_rawValue)) } /// 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) } } @_transparent @warn_unused_result public func == ( lhs: ${Self}, rhs: ${Self} ) -> Bool { return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue)) } @_transparent @warn_unused_result public func < (lhs: ${Self}, rhs: ${Self}) -> Bool { return Bool(Builtin.cmp_ult_RawPointer(lhs._rawValue, rhs._rawValue)) } @_transparent @warn_unused_result public func + (lhs: ${Self}, rhs: Int) -> ${Self} { return ${Self}(Builtin.gep_Word( lhs._rawValue, (rhs &* strideof(Pointee.self))._builtinWordValue)) } @_transparent @warn_unused_result public func + (lhs: Int, rhs: ${Self}) -> ${Self} { return rhs + lhs } @_transparent @warn_unused_result public func - (lhs: ${Self}, rhs: Int) -> ${Self} { return lhs + -rhs } @_transparent @warn_unused_result public func - (lhs: ${Self}, rhs: ${Self}) -> Int { return Int(Builtin.sub_Word(Builtin.ptrtoint_Word(lhs._rawValue), Builtin.ptrtoint_Word(rhs._rawValue))) / strideof(Pointee.self) } @_transparent public func += (lhs: inout ${Self}, rhs: Int) { lhs = lhs + rhs } @_transparent public func -= (lhs: inout ${Self}, rhs: Int) { lhs = lhs - rhs } extension ${Self} { @available(*, unavailable, renamed="Pointee") public typealias Memory = Pointee @available(*, unavailable, message="use 'nil' literal") public init() { fatalError("unavailable function can't be called") } @available(*, unavailable, message="use the '${Self}(allocatingCapacity:)' initializer") public static func alloc(num: Int) -> ${Self} { fatalError("unavailable function can't be called") } @available(*, unavailable, renamed="deallocateCapacity") public func dealloc(num: Int) { fatalError("unavailable function can't be called") } @available(*, unavailable, renamed="pointee") public var memory: Pointee { get { fatalError("unavailable function can't be called") } set { fatalError("unavailable function can't be called") } } @available(*, unavailable, renamed="initialize(with:)") public func initialize(newvalue: Pointee) { fatalError("unavailable function can't be called") } @available(*, unavailable, renamed="deinitialize(count:)") public func destroy() { fatalError("unavailable function can't be called") } @available(*, unavailable, renamed="deinitialize(count:)") public func destroy(count: Int) { fatalError("unavailable function can't be called") } } % end # for mutable /// A byte-sized thing that isn't designed to interoperate with /// any other types; it makes a decent parameter to /// `UnsafeMutablePointer` when you just want to do bytewise /// pointer arithmetic. public // @testable struct _RawByte { let _inaccessible: UInt8 } // ${'Local Variables'}: // eval: (read-only-mode 1) // End: