Files
swift-mirror/stdlib/core/UnsafePointer.swift.gyb
John McCall dc4431ebff Split addressors into unsafe, owning, and pinning variants.
Change all the existing addressors to the unsafe variant.

Update the addressor mangling to include the variant.

The addressor and mutable-addressor may be any of the
variants, independent of the choice for the other.

SILGen and code synthesis for the new variants is still
untested.

Swift SVN r24387
2015-01-13 03:09:16 +00:00

505 lines
15 KiB
Swift

//===--- 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}<T>
: 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<U>(_ from : UnsafeMutablePointer<U>) {
_rawValue = from._rawValue
}
/// Convert from a UnsafePointer of a different type.
///
/// This is a fundamentally unsafe conversion.
@transparent
public init<U>(_ from : UnsafePointer<U>) {
_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 unsafeAddress {
return UnsafePointer(self)
}
@transparent nonmutating unsafeMutableAddress {
return self
}
% else:
@transparent unsafeAddress {
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..<count {
self[i] = (source + i).move()
}
}
/// Assign from `count` values beginning at source into initialized
/// memory, proceeding from the first element to the last.
public func assignFrom(source: ${Self}, count: Int) {
_debugPrecondition(
count >= 0, "moveAssignFrom with negative count")
_debugPrecondition(
source > self || source < self - count,
"moveAssignFrom non-following overlapping range; use assignBackwardFrom")
for i in 0..<count {
self[i] = source[i]
}
}
/// Assign from `count` values beginning at `source` into
/// initialized memory, proceeding from the last value to the first.
/// Use this for assigning ranges into later memory that may overlap
/// with the source range.
///
/// Requires: either `source` precedes `self` or follows `self + count`.
public func assignBackwardFrom(source: ${Self}, count: Int) {
_debugPrecondition(
count >= 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..<count {
(self + i).initialize((source + i).move())
}
}
/// Copy count values beginning at source into raw memory.
///
/// Precondition: the memory is not initialized.
public func initializeFrom(source: ${Self}, count: Int) {
_debugPrecondition(
count >= 0, "${Self}.initializeFrom with negative count")
_debugPrecondition(
source >= self || source < self - count,
"${Self}.initializeFrom non-following overlapping range")
for i in 0..<count {
(self + i).initialize(source[i])
}
}
/// Copy the elements of `C` into raw memory.
///
/// Precondition: the memory is not initialized.
public func initializeFrom<
C: CollectionType where C._Element == T
>(
source: C
) {
var p = self
for x in source {
// FIXME: <rdar://problem/16951692> 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
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
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<U: AnyObject, R>(
inout buffer: U?, body: (AutoreleasingUnsafeMutablePointer<U?>)->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<U, R>(
inout buffer: U, body: (UnsafeMutablePointer<U>)->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 == <T> (lhs: ${Self}<T>, rhs: ${Self}<T>) -> Bool {
return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue))
}
@transparent
public func < <T>(lhs: ${Self}<T>, rhs: ${Self}<T>) -> Bool {
return Bool(Builtin.cmp_ult_RawPointer(lhs._rawValue, rhs._rawValue))
}
@transparent
public func + <T>(lhs: ${Self}<T>, rhs: Int) -> ${Self}<T> {
return ${Self}(
Builtin.gep_Word(lhs._rawValue, (rhs &* strideof(T.self)).value))
}
@transparent
public func + <T>(lhs: Int,
rhs: ${Self}<T>) -> ${Self}<T> {
return rhs + lhs
}
@transparent
public func - <T>(lhs: ${Self}<T>, rhs: Int) -> ${Self}<T> {
return lhs + -rhs
}
@transparent
public func - <T>(lhs: ${Self}<T>, rhs: ${Self}<T>) -> Int {
return
Int(Builtin.sub_Word(Builtin.ptrtoint_Word(lhs._rawValue),
Builtin.ptrtoint_Word(rhs._rawValue)))
/ strideof(T.self)
}
@transparent
public func += <T>(inout lhs: ${Self}<T>, rhs: Int) {
lhs = lhs + rhs
}
@transparent
public func -= <T>(inout lhs: ${Self}<T>, 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: