//===--- UnsafePointer.swift.gyb ------------------------------*- swift -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2015 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 %TMirrorDecl = gyb.parseTemplate("../common/MirrorDecl.gyb") %TMirrorConformance = gyb.parseTemplate("../common/MirrorConformance.gyb") %TMirrorBoilerplate = gyb.parseTemplate("../common/MirrorBoilerplate.gyb") % for mutable in (True, False): % Self = 'UnsafeMutablePointer' if mutable else 'UnsafePointer' % a_Self = 'an `UnsafeMutablePointer`' if mutable else 'an `UnsafePointer`' % MirrorConformance = gyb.executeTemplate(TMirrorConformance,introspecteeType=Self,genericArgs=['T'],disposition='Struct') % MirrorDecl = gyb.executeTemplate(TMirrorDecl,introspecteeType=Self,genericArgs=['T'],disposition='Struct') % MirrorBoilerplate = gyb.executeTemplate(TMirrorBoilerplate,introspecteeType=Self,genericArgs=['T'],disposition='Struct') /// A pointer to an object of type `T`. This type provides no automated /// memory management, and therefore the user must take care to allocate /// and free memory appropriately. /// /// The pointer 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} : RandomAccessIndexType, Hashable, NilLiteralConvertible, _PointerType { /// The underlying raw (untyped) pointer. public var _rawValue : Builtin.RawPointer /// Construct a null pointer. @transparent public init() { self._rawValue = Builtin.inttoptr_Word(0.value) } /// Construct ${a_Self} from a builtin raw pointer. @transparent public init(_ _rawValue : Builtin.RawPointer) { self._rawValue = _rawValue } /// Convert from an opaque C pointer to a typed pointer /// /// This is a fundamentally unsafe conversion. @transparent public init(_ other : COpaquePointer) { _rawValue = other._rawValue } /// Construct ${a_Self} from a given address in memory. /// /// This is a fundamentally unsafe conversion. @transparent public init(bitPattern: Word) { self._rawValue = Builtin.inttoptr_Word(bitPattern.value) } /// Construct ${a_Self} from a given address in memory. /// /// This is a fundamentally unsafe conversion. @transparent public init(bitPattern: UWord) { self._rawValue = Builtin.inttoptr_Word(bitPattern.value) } /// Convert from an UnsafeMutablePointer of a different type. /// /// This is a fundamentally unsafe conversion. @transparent public init(_ from : UnsafeMutablePointer) { _rawValue = from._rawValue } /// Convert from a UnsafePointer of a different type. /// /// This is a fundamentally unsafe conversion. @transparent public init(_ from : UnsafePointer) { _rawValue = from._rawValue } /// Create an instance initialized with `nil`. @transparent public init(nilLiteral: ()) { self = .null() } /// Return a `nil` instance. @transparent public static func null() -> ${Self} { return ${Self}() } % if mutable: /// Allocate memory for `num` objects of type `T`. /// /// Postcondition: the memory is allocated, but not initialized. public static func alloc(num: Int) -> ${Self} { // Don't bother with overflow checking. var size = strideof(T.self) * num return ${Self}(Builtin.allocRaw(size.value, Builtin.alignof(T.self))) } /// Deallocate `num` objects. /// /// :param: num number of objects to deallocate. Should match exactly /// the value that was passed to `alloc()` (partial deallocations are not /// possible). /// /// Precondition: the memory is not initialized. /// /// Postcondition: the memory has been deallocated. public func dealloc(num: Int) { // Overflow checking is actually not required here. var size = strideof(T.self) * num Builtin.deallocRaw(_rawValue, size.value, Builtin.alignof(T.self)) } % end /// Access the underlying raw memory, getting and /// setting values. public var memory : T { % if mutable: @transparent address { return UnsafePointer(self) } @transparent nonmutating mutableAddress { return self } % else: @transparent address { return self } % end } % if mutable: /// Initialize the value the pointer points to, to construct /// an object where there was no object previously stored. /// /// Precondition: the memory is not initialized. /// /// Postcondition: the memory is initalized; the value should eventually /// be destroyed or moved from to avoid leaks. public func initialize(newvalue: T) { Builtin.initialize(newvalue, _rawValue) } /// Retrieve the value the pointer points to, moving it away /// from the location referenced in memory. /// /// Equivalent to reading `memory` property and calling `destroy()`, /// but more efficient. /// /// Precondition: the memory is initialized. /// /// Postcondition: the value has been destroyed and the memory must /// be initialized before being used again. public func move() -> T { return Builtin.take(_rawValue) } /// Move count values beginning at source into uninitialized memory, /// transforming the source values into raw memory, proceeding from /// the last value to the first. Use this for copying ranges into /// later memory that may overlap with the source range. /// /// Requires: either `source` precedes `self` or follows `self + count`. public func moveInitializeBackwardFrom(source: ${Self}, count: Int) { _debugPrecondition( count >= 0, "${Self}.moveInitializeBackwardFrom with negative count") _debugPrecondition( source <= self || source > self + count, "${Self}.moveInitializeBackwardFrom non-preceding overlapping range; use moveInitializeFrom instead") var src = source + count var dst = self + count while dst != self { (--dst).initialize((--src).move()) } } /// Assign from count values beginning at source into initialized /// memory, transforming the source values into raw memory. public func moveAssignFrom(source: ${Self}, count: Int) { _debugPrecondition( count >= 0, "moveAssignFrom with negative count") _debugPrecondition( source > self || source < self - count, "moveAssignFrom non-following overlapping range") for i in 0..= 0, "moveAssignFrom with negative count") _debugPrecondition( source > self || source < self - count, "moveAssignFrom non-following overlapping range; use assignBackwardFrom") for i in 0..= 0, "${Self}.assignBackwardFrom with negative count") _debugPrecondition( source <= self || source > self + count, "${Self}.assignBackwardFrom non-preceding overlapping range; use assignFrom instead") for var i = count; --i >= 0; { self[i] = source[i] } } /// Move count values beginning at source into raw memory, /// transforming the source values into raw memory. public func moveInitializeFrom(source: ${Self}, count: Int) { _debugPrecondition( count >= 0, "${Self}.moveInitializeFrom with negative count") _debugPrecondition( source >= self || source < self - count, "${Self}.moveInitializeFrom non-following overlapping range; use moveInitializeBackwardFrom") for i in 0..= 0, "${Self}.initializeFrom with negative count") _debugPrecondition( source >= self || source < self - count, "${Self}.initializeFrom non-following overlapping range") for i in 0..( source: C ) { var p = self for x in source { // FIXME: We should be able to use a // C.Generator.Element == T constraint here, because C._Element == // C.Generator.Element in all cases, but doing so crashes the // type-checker. p++.initialize(unsafeBitCast(x, T.self)) } } /// Destroy the object the pointer points to. /// /// Precondition: the memory is initialized. /// /// Postcondition: the value has been destroyed and the memory must /// be initialized before being used again. public func destroy() { Builtin.destroy(T.self, _rawValue) } /// Destroy the `count` objects the pointer points to. /// Precondition: the memory is initialized. /// /// Postcondition: the value has been destroyed and the memory must /// be initialized before being used again. public func destroy(count: Int) { _debugPrecondition(count >= 0, "${Self}.destroy with negative count") Builtin.destroyArray(T.self, _rawValue, count.value) } % end @transparent public var _isNull : Bool { return self == ${Self}.null() } /// Access the `i`\ th element of the raw array starting at `self`. public subscript (i : Int) -> T { % if mutable: @transparent address { return UnsafePointer(self + i) } @transparent nonmutating mutableAddress { return self + i } % else: @transparent address { return self + i } % end } % if mutable: /// If self was converted from nil, writes the result of invoking body into /// the pointee public func _setIfNonNil(body: () -> T) { if self != nil { memory = body() } } #if _runtime(_ObjC) /// Return the result of invoking body. If self was converted from /// nil, passes nil as the argument. Otherwise, passes the address /// of a T which is written into buffer before this method returns @transparent public func _withBridgeObject( inout buffer: U?, body: (AutoreleasingUnsafeMutablePointer)->R ) -> R { return self != nil ? body(&buffer) : body(nil) } #endif /// Return 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( inout buffer: U, 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 value after `self`. /// /// Requires: the next value is representable. public func successor() -> ${Self} { return self + 1 } /// Returns the previous consecutive value before `self`. /// /// Requires: the previous value is representable. public func predecessor() -> ${Self} { return self - 1 } /// Return the minimum number of applications of `successor` or /// `predecessor` required to reach `other` from `self`. /// /// Complexity: O(1). public func distanceTo(x: ${Self}) -> Int { return x - self } /// Return `self` offset by `n` steps. /// /// :returns: If `n > 0`, the result of applying `successor` to /// `self` `n` times. If `n < 0`, the result of applying /// `predecessor` to `self` `-n` times. Otherwise, `self`. /// /// Complexity: O(1) public func advancedBy(n: Int) -> ${Self} { return self + n } } extension ${Self} : DebugPrintable { /// A textual representation of `self`, suitable for debugging. public var debugDescription: String { return _rawPointerToString(_rawValue) } } ${MirrorDecl} { ${MirrorBoilerplate} var count: Int { return 1 } func _getPointerValue() -> UInt64 { return UInt64(Int(Builtin.ptrtoint_Word(_value._rawValue))) } subscript(i: Int) -> (String, MirrorType) { switch i { case 0: return ("pointerValue",reflect(_getPointerValue())) default: _preconditionFailure("cannot extract this child index") } } var summary: String { let selfType = "${Self}" let ptrValue = _getPointerValue() if ptrValue == 0 { return "\(selfType)(nil)" } return "\(selfType)(0x\(_uint64ToString(ptrValue, radix:16, uppercase:true)))" } var quickLookObject: QuickLookObject? { return .Some(.Text(summary)) } } ${MirrorConformance} @transparent public func == (lhs: ${Self}, rhs: ${Self}) -> Bool { return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue)) } @transparent public func < (lhs: ${Self}, rhs: ${Self}) -> Bool { return Bool(Builtin.cmp_ult_RawPointer(lhs._rawValue, rhs._rawValue)) } @transparent public func + (lhs: ${Self}, rhs: Int) -> ${Self} { return ${Self}( Builtin.gep_Word(lhs._rawValue, (rhs &* strideof(T.self)).value)) } @transparent public func + (lhs: Int, rhs: ${Self}) -> ${Self} { return rhs + lhs } @transparent public func - (lhs: ${Self}, rhs: Int) -> ${Self} { return lhs + -rhs } @transparent public func - (lhs: ${Self}, rhs: ${Self}) -> Int { return Int(Builtin.sub_Word(Builtin.ptrtoint_Word(lhs._rawValue), Builtin.ptrtoint_Word(rhs._rawValue))) / strideof(T.self) } @transparent public func += (inout lhs: ${Self}, rhs: Int) { lhs = lhs + rhs } @transparent public func -= (inout lhs: ${Self}, rhs: Int) { lhs = lhs - rhs } % end # for mutable extension UnsafeMutablePointer : SinkType { public mutating func put(x: T) { self.memory = x ++self } } /// 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 struct RawByte { let _inaccessible: UInt8 } // ${'Local Variables'}: // eval: (read-only-mode 1) // End: