Files
swift-mirror/stdlib/public/core/UnsafePointer.swift.gyb
Nate Cook 51251dc133 Convert imperative function summaries to present.
i.e., "Return ..." -> "Returns ..."
2016-02-12 04:20:39 -06: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 - 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 pointer to an object of type `Memory`. This type provides no automated
/// memory management, and therefore the user must take care to allocate
/// and free memory appropriately.
///
/// The pointer should be aligned to `alignof(Memory.self)`.
///
/// 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}<Memory>
: RandomAccessIndexType, Hashable,
NilLiteralConvertible, _PointerType {
@available(*, unavailable, renamed="Memory")
public typealias T = Memory
public typealias Distance = Int
/// The underlying raw (untyped) pointer.
public var _rawValue : Builtin.RawPointer
/// Construct a null pointer.
@_transparent
public init() {
self._rawValue = _nilRawPointer
}
/// 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: Int) {
self._rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue)
}
/// Construct ${a_Self} from a given address in memory.
///
/// This is a fundamentally unsafe conversion.
@_transparent
public init(bitPattern: UInt) {
self._rawValue = Builtin.inttoptr_Word(bitPattern._builtinWordValue)
}
/// 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 = ${Self}()
}
% if mutable:
/// Allocate memory for `num` objects of type `Memory`.
///
/// - Postcondition: The memory is allocated, but not initialized.
@warn_unused_result
public static func alloc(num: Int) -> ${Self} {
let size = strideof(Memory.self) * num
return ${Self}(
Builtin.allocRaw(size._builtinWordValue, Builtin.alignof(Memory.self)))
}
/// Deallocate `num` objects.
///
/// - parameter 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) {
let size = strideof(Memory.self) * num
Builtin.deallocRaw(
_rawValue, size._builtinWordValue, Builtin.alignof(Memory.self))
}
% end
%{
if mutable:
comment = """\
/// Access the underlying raw memory, getting and setting values."""
else:
comment = """\
/// Access the underlying raw memory, getting values."""
}%
${comment}
public var memory: Memory {
% 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 initialized; the value should eventually
/// be destroyed or moved from to avoid leaks.
public func initialize(newvalue: Memory) {
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.
@warn_unused_result
public func move() -> Memory {
return Builtin.take(_rawValue)
}
/// 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, "assignFrom with negative count")
_debugPrecondition(
self < source || self >= source + count,
"assignFrom 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")
var i = count-1
while i >= 0 {
self[i] = source[i]
i -= 1
}
}
/// 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(
self < source || self >= source + count,
"${Self}.moveInitializeFrom non-following overlapping range; use moveInitializeBackwardFrom")
Builtin.takeArrayFrontToBack(
Memory.self, self._rawValue, source._rawValue, count._builtinWordValue)
// This builtin is equivalent to:
// for i in 0..<count {
// (self + i).initialize((source + i).move())
// }
}
/// 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")
Builtin.takeArrayBackToFront(
Memory.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((--src).move())
// }
}
/// Copy `count` values beginning at source into raw memory.
///
/// - Precondition: The memory is not initialized.
///
/// - Requires: `self` and `source` may not overlap.
public func initializeFrom(source: ${Self}, count: Int) {
_debugPrecondition(
count >= 0, "${Self}.initializeFrom with negative count")
_debugPrecondition(
self + count <= source || source + count <= self,
"${Self}.initializeFrom non-following overlapping range")
Builtin.copyArray(
Memory.self, self._rawValue, source._rawValue, count._builtinWordValue)
// This builtin is equivalent to:
// 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.Generator.Element == Memory
>(source: C) {
source._initializeTo(self)
}
/// Assign from `count` values beginning at `source` into initialized
/// memory, transforming the source values into raw memory.
///
/// - Requires: The `self` and `source` ranges may not overlap.
public func moveAssignFrom(source: ${Self}, count: Int) {
_debugPrecondition(
count >= 0, "moveAssignFrom with negative count")
_debugPrecondition(
self + count <= source || source + count <= self,
"moveAssignFrom overlapping range")
Builtin.destroyArray(Memory.self, self._rawValue, count._builtinWordValue)
Builtin.takeArrayFrontToBack(
Memory.self, self._rawValue, source._rawValue, count._builtinWordValue)
// These builtins are equivalent to:
// for i in 0..<count {
// self[i] = (source + i).move()
// }
}
/// 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(Memory.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(Memory.self, _rawValue, count._builtinWordValue)
}
% end
@_transparent public
var _isNull : Bool {
return self == nil
}
/// Access the `i`th element of the raw array starting at `self`.
public subscript(i: Int) -> Memory {
% 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: () -> Memory) {
if self != nil {
memory = 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 `Memory` which is written into buffer before this method returns.
@_transparent public
func _withBridgeObject<U : AnyObject, R>(
inout buffer: U?, @noescape body: AutoreleasingUnsafeMutablePointer<U?> -> 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<U, R>(
inout buffer: U, @noescape 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
}
public func distanceTo(x: ${Self}) -> Int {
return x - self
}
public func advancedBy(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 func 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 func customPlaygroundQuickLook() -> PlaygroundQuickLook {
return .Text(summary)
}
}
@_transparent
@warn_unused_result
public func == <Memory>(
lhs: ${Self}<Memory>, rhs: ${Self}<Memory>
) -> Bool {
return Bool(Builtin.cmp_eq_RawPointer(lhs._rawValue, rhs._rawValue))
}
@_transparent
@warn_unused_result
public func < <Memory>(lhs: ${Self}<Memory>, rhs: ${Self}<Memory>) -> Bool {
return Bool(Builtin.cmp_ult_RawPointer(lhs._rawValue, rhs._rawValue))
}
@_transparent
@warn_unused_result
public func + <Memory>(lhs: ${Self}<Memory>, rhs: Int) -> ${Self}<Memory> {
return ${Self}(Builtin.gep_Word(
lhs._rawValue, (rhs &* strideof(Memory.self))._builtinWordValue))
}
@_transparent
@warn_unused_result
public func + <Memory>(lhs: Int,
rhs: ${Self}<Memory>) -> ${Self}<Memory> {
return rhs + lhs
}
@_transparent
@warn_unused_result
public func - <Memory>(lhs: ${Self}<Memory>, rhs: Int) -> ${Self}<Memory> {
return lhs + -rhs
}
@_transparent
@warn_unused_result
public func - <Memory>(lhs: ${Self}<Memory>, rhs: ${Self}<Memory>) -> Int {
return
Int(Builtin.sub_Word(Builtin.ptrtoint_Word(lhs._rawValue),
Builtin.ptrtoint_Word(rhs._rawValue)))
/ strideof(Memory.self)
}
@_transparent
public func += <Memory>(inout lhs: ${Self}<Memory>, rhs: Int) {
lhs = lhs + rhs
}
@_transparent
public func -= <Memory>(inout lhs: ${Self}<Memory>, rhs: Int) {
lhs = lhs - rhs
}
% end # for mutable
/// A byte-sized thing that isn't designed to interoperate with
/// any other types; it makes a decent parameter to
/// `UnsafeMutablePointer<Memory>` when you just want to do bytewise
/// pointer arithmetic.
public struct RawByte {
let _inaccessible: UInt8
}
// ${'Local Variables'}:
// eval: (read-only-mode 1)
// End: