%# -*- mode: 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 // //===----------------------------------------------------------------------===// % for mutable in (True, False): % Self = 'UnsafePointer' if mutable else 'ConstUnsafePointer' % a_Self = 'an UnsafePointer' if mutable else 'a ConstUnsafePointer' /// This type stores a pointer to an object of type T. It provides no /// automated memory management, and therefore the user must take care /// to allocate and free memory appropriately. @public struct ${Self} : BidirectionalIndex, Comparable, Hashable, LogicValue, NilLiteralConvertible, _Pointer { /// The underlying raw (untyped) pointer. var value : Builtin.RawPointer /// Construct a null pointer. init() { self.value = Builtin.inttoptr_Word(0.value) } /// Construct ${a_Self} from a builtin raw pointer. init(_ value : Builtin.RawPointer) { self.value = value } /// Convert from an opaque C pointer to a typed pointer /// /// This is a fundamentally unsafe conversion. init(_ other : COpaquePointer) { value = other.value } /// Construct ${a_Self} from a given address in memory. /// /// This is a fundamentally unsafe conversion. init(_ value : Int) { self.value = Builtin.inttoptr_Word(value.value) } /// Convert from an UnsafePointer of a different type. /// /// This is a fundamentally unsafe conversion. init(_ from : UnsafePointer) { value = from.value } /// Convert from a ConstUnsafePointer of a different type. /// /// This is a fundamentally unsafe conversion. init(_ from : ConstUnsafePointer) { value = from.value } // Make nil work with ${Self}. @transparent static func convertFromNilLiteral() -> ${Self} { return .null() } static func null() -> ${Self} { return ${Self}() } % if mutable: static func alloc(num: Int) -> ${Self} { // Don't bother with overflow checking. var size = Int(Builtin.strideof(T.self)) * num return ${Self}(Builtin.allocRaw(size.value, Builtin.alignof(T.self))) } func dealloc(num: Int) { // Overflow checking is actually not required here. var size = Int(Builtin.strideof(T.self)) * num Builtin.deallocRaw(value, size.value, Builtin.alignof(T.self)) } % end /// Access the underlying raw memory, getting and /// setting values. var memory : T { @transparent get { return Builtin.load(value) } % if mutable: @transparent nonmutating set { Builtin.assign(newValue, value) } % end } % if mutable: /// Initialize the value the pointer points to, to construct /// an object where there was no object previously stored. func initialize(newvalue: T) { Builtin.initialize(newvalue, value) } /// Retrieve the value the pointer points to, moving it away /// from the location referenced in memory. /// /// Postcondition: The value has been destroyed and the memory must /// be initialized before being used again. func move() -> T { return Builtin.take(value) } /// 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`. 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. 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, "${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.GeneratorType.Element == T constraint here, because C._Element == // C.GeneratorType.Element in all cases, but doing so crashes the // type-checker. p++.initialize(reinterpretCast(x)) } } /// Destroy the object the pointer points to. func destroy() { Builtin.destroy(T.self, value) } /// Destroy the `count` objects the pointer points to. func destroy(count: Int) { _debugPrecondition(count >= 0, "${Self}.destroy with negative count") Builtin.destroyArray(T.self, value, count.value) } % end @transparent var _isNull : Bool { return self == ${Self}.null() } @transparent func getLogicValue() -> Bool { return !_isNull } subscript (i : Int) -> T { @transparent get { return (self + i).memory } % if mutable: @transparent nonmutating set { (self + i).memory = newValue } % end } % if mutable: /// If self was converted from nil, writes the result of invoking body into /// the pointee func _setIfNonNil(body: () -> T) { if self { memory = body() } } /// 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 func _withBridgeObject( inout buffer: U?, body: (AutoreleasingUnsafePointer)->R ) -> R { return self ? body(&buffer) : body(nil) } #if ENABLE_POINTER_CONVERSIONS /// Return the result of invoking body. If self was converted from /// nil, passes nil as the argument. Otherwise, passes the address /// of buffer @transparent func _withBridgeValue( inout buffer: U, body: (UnsafePointer)->R ) -> R { return self ? body(&buffer) : body(nil) } #endif % end // TODO: Remove this when staging is complete. func withUnsafePointer(f: UnsafePointer -> R) -> R { return f(UnsafePointer(self)) } // // Protocol conformance // var hashValue: Int { return Int(Builtin.ptrtoint_Word(value)) } func successor() -> ${Self} { return self + 1 } func predecessor() -> ${Self} { return self - 1 } #if !ENABLE_POINTER_CONVERSIONS // // Conversion to C argument pointers // // FIXME: Should be in an extension, but that doesn't work yet. @transparent @conversion func __conversion() -> CMutablePointer { return CMutablePointer(owner: _nilNativeObject, value: value) } func __conversion() -> CMutableVoidPointer { return CMutableVoidPointer(owner: _nilNativeObject, value: value) } @transparent @conversion func __conversion() -> CConstPointer { return CConstPointer(_nilNativeObject, value) } @transparent @conversion func __conversion() -> CConstVoidPointer { return CConstVoidPointer(_nilNativeObject, value) } @transparent @conversion func __conversion() -> AutoreleasingUnsafePointer { return AutoreleasingUnsafePointer(value) } /// Construct from a CConstPointer. /// /// This is an explicit construction because it is not always safe. /// It is only allowed to convert an unscoped pointer, that is, one /// that does not have a lifetime-guaranteeing owner reference. To use /// a scoped pointer as an UnsafePointer, the withUnsafePointer method /// must be used instead. init(_ cp: CConstPointer) { _precondition(!cp.scoped, "scoped CConstPointers must be converted using withUnsafePointer") self.value = cp.value } /// Construct from a CMutablePointer. /// /// This is an explicit construction because it is not always safe. /// It is only allowed to convert an unscoped pointer, that is, one /// that does not have a lifetime-guaranteeing owner reference. To use /// a scoped pointer as an UnsafePointer, the withUnsafePointer method /// must be used instead. init(_ cm: CMutablePointer) { _precondition(!cm.scoped, "scoped CMutablePointers must be converted using withUnsafePointer") self.value = cm.value } /// Construct from an AutoreleasingUnsafePointer. /// /// This is an explicit construction /// because it is unsafe--UnsafePointer's store operations assume that /// the pointed-to storage has strong ownership, whereas AutoreleasingUnsafePointers /// reference +0 storage. Any values stored through the resulting /// UnsafePointer must be autoreleased. init(_ op: AutoreleasingUnsafePointer) { self.value = op.value } /// Construct from a CConstVoidPointer. /// /// This is an explicit construction because it is not always safe. /// It is only allowed to convert an unscoped pointer, that is, one /// that does not have a lifetime-guaranteeing owner reference. To use /// a scoped pointer as an UnsafePointer, the withUnsafePointer method /// must be used instead. init(_ cp: CConstVoidPointer) { _precondition(!cp.scoped, "scoped CConstPointers must be converted using withUnsafePointer") self.value = cp.value } /// Construct from a CMutableVoidPointer. /// /// This is an explicit construction because it is not always safe. /// It is only allowed to convert an unscoped pointer, that is, one /// that does not have a lifetime-guaranteeing owner reference. To use /// a scoped pointer as an UnsafePointer, the withUnsafePointer method /// must be used instead. init(_ cp: CMutableVoidPointer) { _precondition(!cp.scoped, "scoped CMutableVoidPointers must be converted using withUnsafePointer") self.value = cp.value } #endif } @transparent @public func == (lhs: ${Self}, rhs: ${Self}) -> Bool { return Bool(Builtin.cmp_eq_RawPointer(lhs.value, rhs.value)) } @transparent @public func < (lhs: ${Self}, rhs: ${Self}) -> Bool { return Bool(Builtin.cmp_ult_RawPointer(lhs.value, rhs.value)) } @transparent @public func + (lhs: ${Self}, rhs: Int) -> ${Self} { return ${Self}( Builtin.gep_Word(lhs.value, (rhs * Int(Builtin.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.value), Builtin.ptrtoint_Word(rhs.value))) / Int(Builtin.strideof(T.self)) } @transparent @public @assignment func += (inout lhs: ${Self}, rhs: Int) { lhs = lhs + rhs } @transparent @public @assignment func -= (inout lhs: ${Self}, rhs: Int) { lhs = lhs - rhs } extension ${Self} : Printable { @public var description: String { return "" } } % end # for mutable /// A byte-sized thing that isn't designed to interoperate with /// any other types; it makes a decent parameter to UnsafePointer when /// you just want to do bytewise pointer arithmetic. @public struct RawByte { let _inaccessible: UInt8 }