Files
swift-mirror/stdlib/public/core/ExistentialCollection.swift.gyb
Dave Abrahams ccb7ae0d0b [stdlib] Drop Type suffixes in comments
These suffixes were gone in the code long ago; help the comments catch
up.
2016-04-05 15:16:13 -07:00

803 lines
23 KiB
Swift

//===--- ExistentialCollection.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
//
//===----------------------------------------------------------------------===//
// TODO: swift-3-indexing-model: perform type erasure on the associated
// `Indices` type.
import SwiftShims
%{
traversals = ['Forward', 'Bidirectional', 'RandomAccess']
def collectionForTraversal(traversal):
if traversal == 'Forward':
return 'Collection'
if traversal == 'Bidirectional':
return 'BidirectionalCollection'
if traversal == 'RandomAccess':
return 'RandomAccessCollection'
assert False, "unknown traversal"
}%
@noreturn @inline(never)
internal func _abstract(file: StaticString = #file, line: UInt = #line) {
fatalError("Method must be overridden", file: file, line: line)
}
//===--- Iterator ---------------------------------------------------------===//
//===----------------------------------------------------------------------===//
/// A type-erased iterator of `Element`.
///
/// This iterator forwards its `next()` method to an arbitrary underlying
/// iterator having the same `Element` type, hiding the specifics of the
/// underlying `IteratorProtocol`.
///
/// - seealso:
/// - `struct AnySequence<S : Sequence>`
public struct AnyIterator<Element> : IteratorProtocol {
/// Create a `IteratorProtocol` instance that wraps `base` but whose type
/// depends only on the type of `I.Element`.
///
/// Example:
///
/// func digits() -> AnyIterator<String> {
/// let lazyStrings = (0..<10).lazy.map { String($0) }
///
/// // This is a really complicated type of no interest to our
/// // clients.
/// let iterator: MapSequenceIterator<RangeIterator<Int>, String>
/// = lazyStrings.makeIterator()
/// return AnyIterator(iterator)
/// }
public init<I : IteratorProtocol where I.Element == Element>(_ base: I) {
self._box = _IteratorBox(base)
}
/// Create a `IteratorProtocol` instance whose `next` method invokes
/// `body` and returns the result.
///
/// Example:
///
/// var x = 7
/// let iterator = AnyIterator { x < 15 ? x++ : nil }
/// let a = Array(iterator) // [ 7, 8, 9, 10, 11, 12, 13, 14 ]
public init(body: () -> Element?) {
self._box = _IteratorBox(_ClosureBasedIterator(body))
}
internal init(_box: _AnyIteratorBoxBase<Element>) {
self._box = _box
}
/// Advance to the next element and return it, or `nil` if no next
/// element exists.
public func next() -> Element? {
return _box.next()
}
internal let _box: _AnyIteratorBoxBase<Element>
}
/// Every `IteratorProtocol` can also be a `Sequence`. Note that
/// traversing the sequence consumes the iterator.
extension AnyIterator : Sequence {}
internal struct _ClosureBasedIterator<Element> : IteratorProtocol {
internal init(_ body: () -> Element?) {
self._body = body
}
internal func next() -> Element? { return _body() }
internal let _body: () -> Element?
}
internal class _AnyIteratorBoxBase<Element> : IteratorProtocol {
/// Advance to the next element and return it, or `nil` if no next
/// element exists.
///
/// - Note: Subclasses must override this method.
internal func next() -> Element? { _abstract() }
}
internal final class _IteratorBox<
Base : IteratorProtocol
> : _AnyIteratorBoxBase<Base.Element> {
internal init(_ base: Base) { self._base = base }
internal override func next() -> Base.Element? { return _base.next() }
internal var _base: Base
}
@warn_unused_result
internal func _typeID(instance: AnyObject) -> ObjectIdentifier {
return ObjectIdentifier(instance.dynamicType)
}
//===--- Sequence ---------------------------------------------------------===//
//===----------------------------------------------------------------------===//
internal class _AnySequenceBox<Element> {
@warn_unused_result
internal func makeIterator() -> AnyIterator<Element> { _abstract() }
internal var _underestimatedCount: Int { _abstract() }
@warn_unused_result
internal func _copyContents(initializing ptr: UnsafeMutablePointer<Element>)
-> UnsafeMutablePointer<Element> {
_abstract()
}
@warn_unused_result
internal func _copyToNativeArrayBuffer() -> _ContiguousArrayStorageBase {
_abstract()
}
@warn_unused_result
internal func _dropFirst(n: Int) -> _AnySequenceBox<Element> { _abstract() }
@warn_unused_result
internal func _prefix(maxLength: Int) -> _AnySequenceBox<Element> {
_abstract()
}
}
internal class _AnyCollectionBox<Element> : _AnySequenceBox<Element> {
internal subscript(i: _AnyIndexBox) -> Element { _abstract() }
internal subscript(start: _AnyIndexBox, end: _AnyIndexBox)
-> _AnyCollectionBox<Element> { _abstract() }
internal var _count: IntMax { _abstract() }
// TODO: swift-3-indexing-model: forward the following methods.
/*
internal func _failEarlyRangeCheck(
index: Index,
bounds: Range<Index>)
internal func _failEarlyRangeCheck(
range: Range<Index>,
bounds: Range<Index>)
var _indices: Indices
*/
@warn_unused_result
internal func _successor(of i: _AnyIndexBox) -> _AnyIndexBox { _abstract() }
internal func _formSuccessor(i: _AnyIndexBox) { _abstract() }
// TODO: swift-3-indexing-model: forward the following methods.
/*
@warn_unused_result
func prefix(upTo end: Index) -> SubSequence
@warn_unused_result
func suffix(from start: Index) -> SubSequence
@warn_unused_result
func prefix(through position: Index) -> SubSequence
var isEmpty: Bool { get }
var count: IndexDistance { get }
@warn_unused_result
func _customIndexOfEquatableElement(element: Iterator.Element) -> Index??
var first: Iterator.Element? { get }
@warn_unused_result
func index(n: IndexDistance, stepsFrom i: Index) -> Index
@warn_unused_result
func index(n: IndexDistance, stepsFrom i: Index, limitedBy limit: Index) -> Index
@warn_unused_result
func formIndex(n: IndexDistance, stepsFrom i: inout Index)
@warn_unused_result
func formIndex(n: IndexDistance, stepsFrom i: inout Index, limitedBy limit: Index)
@warn_unused_result
func distance(from start: Index, to end: Index) -> IndexDistance
*/
internal init(
_startIndex: _AnyIndexBox,
endIndex: _AnyIndexBox
) {
self._startIndex = _startIndex
self._endIndex = endIndex
}
internal let _startIndex: _AnyIndexBox
internal let _endIndex: _AnyIndexBox
}
internal class _AnyBidirectionalCollectionBox<Element>
: _AnyCollectionBox<Element> {
internal func _predecessor(of i: _AnyIndexBox) -> _AnyIndexBox { _abstract() }
internal func _formPredecessor(i: _AnyIndexBox) { _abstract() }
// TODO: swift-3-indexing-model: forward the following methods.
/*
var last: Iterator.Element? { _abstract() }
*/
internal override init(
_startIndex: _AnyIndexBox,
endIndex: _AnyIndexBox
) {
super.init(_startIndex: _startIndex, endIndex: endIndex)
}
}
internal class _AnyRandomAccessCollectionBox<Element>
: _AnyBidirectionalCollectionBox<Element> {
internal override init(
_startIndex: _AnyIndexBox,
endIndex: _AnyIndexBox
) {
super.init(_startIndex: _startIndex, endIndex: endIndex)
}
}
% for Kind in ['Sequence', 'Collection', 'BidirectionalCollection', 'RandomAccessCollection']:
internal final class _${Kind}Box<
S : ${Kind}
where
S.SubSequence : ${Kind},
S.SubSequence.Iterator.Element == S.Iterator.Element,
S.SubSequence.SubSequence == S.SubSequence
% if Kind != 'Sequence':
,
S.Indices : ${Kind},
S.Indices.Iterator.Element == S.Index,
S.Indices.Index == S.Index,
S.Indices.SubSequence == S.Indices
% end
> : _Any${Kind}Box<S.Iterator.Element> {
internal typealias Element = S.Iterator.Element
internal override func makeIterator() -> AnyIterator<Element> {
return AnyIterator(_base.makeIterator())
}
internal override var _underestimatedCount: Int {
return _base.underestimatedCount
}
internal override func _copyContents(initializing ptr: UnsafeMutablePointer<Element>)
-> UnsafeMutablePointer<Element> {
return _base._copyContents(initializing: ptr)
}
internal override func _copyToNativeArrayBuffer() -> _ContiguousArrayStorageBase {
return _base._copyToNativeArrayBuffer()._storage
}
% if Kind == 'Sequence':
internal override func _dropFirst(n: Int) -> _AnySequenceBox<Element> {
return _SequenceBox<S.SubSequence>(_base: _base.dropFirst(n))
}
internal override func _prefix(maxLength: Int) -> _AnySequenceBox<Element> {
return _SequenceBox<S.SubSequence>(_base: _base.prefix(maxLength))
}
% end
% if Kind == 'Sequence':
internal init(_base: S) {
self._base = _base
}
% else:
internal override var _count: IntMax {
return numericCast(_base.count)
}
internal func _unbox(
position: _AnyIndexBox, file: StaticString = #file, line: UInt = #line
) -> S.Index {
if let i = position._unbox() as S.Index? {
return i
}
fatalError("Index type mismatch!", file: file, line: line)
}
internal override subscript(position: _AnyIndexBox) -> Element {
return _base[_unbox(position)]
}
internal init(
_base: S,
startIndex: _AnyIndexBox,
endIndex: _AnyIndexBox
) {
self._base = _base
super.init(_startIndex: startIndex, endIndex: endIndex)
}
@warn_unused_result
internal override func _successor(of position: _AnyIndexBox) -> _AnyIndexBox {
return _IndexBox(_base: _base.successor(of: _unbox(position)))
}
internal override func _formSuccessor(position: _AnyIndexBox) {
if let p = position as? _IndexBox<S.Index> {
return _base.formSuccessor(&p._base)
}
fatalError("Index type mismatch!")
}
% if Kind in ['BidirectionalCollection', 'RandomAccessCollection']:
@warn_unused_result
internal override func _predecessor(of position: _AnyIndexBox) -> _AnyIndexBox {
return _IndexBox(_base: _base.predecessor(of: _unbox(position)))
}
internal override func _formPredecessor(position: _AnyIndexBox) {
if let p = position as? _IndexBox<S.Index> {
return _base.formPredecessor(&p._base)
}
fatalError("Index type mismatch!")
}
% end
% end
internal var _base: S
}
% end
internal struct _ClosureBasedSequence<Iterator : IteratorProtocol>
: Sequence {
internal init(_ makeUnderlyingIterator: () -> Iterator) {
self._makeUnderlyingIterator = makeUnderlyingIterator
}
internal func makeIterator() -> Iterator {
return _makeUnderlyingIterator()
}
internal var _makeUnderlyingIterator: () -> Iterator
}
/// A type-erased sequence.
///
/// Forwards operations to an arbitrary underlying sequence having the
/// same `Element` type, hiding the specifics of the underlying
/// `Sequence`.
///
/// - SeeAlso: `AnyIterator<Element>`.
public struct AnySequence<Element> : Sequence {
/// Wrap and forward operations to `base`.
public init<
S : Sequence
where
S.Iterator.Element == Element,
S.SubSequence : Sequence,
S.SubSequence.Iterator.Element == Element,
S.SubSequence.SubSequence == S.SubSequence
>(_ base: S) {
self._box = _SequenceBox(_base: base)
}
/// Create a sequence whose `makeIterator()` method forwards to
/// `makeUnderlyingIterator`.
public init<I : IteratorProtocol where I.Element == Element>(
_ makeUnderlyingIterator: () -> I
) {
self.init(_ClosureBasedSequence(makeUnderlyingIterator))
}
internal init(_box: _AnySequenceBox<Element>) {
self._box = _box
}
/// Returns an iterator over the elements of this sequence.
///
/// - Complexity: O(1).
public func makeIterator() -> AnyIterator<Element> {
return _box.makeIterator()
}
internal let _box: _AnySequenceBox<Element>
}
extension AnySequence {
@warn_unused_result
public func dropFirst(n: Int) -> AnySequence<Element> {
return AnySequence(_box: _box._dropFirst(n))
}
@warn_unused_result
public func prefix(maxLength: Int) -> AnySequence<Element> {
return AnySequence(_box: _box._prefix(maxLength))
}
}
% for Kind in ['Sequence', 'Collection', 'BidirectionalCollection', 'RandomAccessCollection']:
extension Any${Kind} {
public var underestimatedCount: Int {
return _box._underestimatedCount
}
public func _copyContents(initializing ptr: UnsafeMutablePointer<Element>)
-> UnsafeMutablePointer<Element> {
return _box._copyContents(initializing: ptr)
}
public func _copyToNativeArrayBuffer() -> _ContiguousArrayBuffer<Element> {
return _ContiguousArrayBuffer(self._box._copyToNativeArrayBuffer())
}
}
% end
//===--- Index ------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
internal protocol _AnyIndexBox : class {
var _typeID: ObjectIdentifier { get }
@warn_unused_result
func _unbox<T : Comparable>() -> T?
@warn_unused_result
func _equal(to rhs: _AnyIndexBox) -> Bool
@warn_unused_result
func _notEqual(to rhs: _AnyIndexBox) -> Bool
@warn_unused_result
func _less(than rhs: _AnyIndexBox) -> Bool
@warn_unused_result
func _lessOrEqual(to rhs: _AnyIndexBox) -> Bool
@warn_unused_result
func _greater(than rhs: _AnyIndexBox) -> Bool
@warn_unused_result
func _greaterOrEqual(to rhs: _AnyIndexBox) -> Bool
}
internal final class _IndexBox<
BaseIndex : Comparable
> : _AnyIndexBox {
internal var _base: BaseIndex
internal init(_base: BaseIndex) {
self._base = _base
}
@warn_unused_result
internal func _unsafeUnbox(other: _AnyIndexBox) -> BaseIndex {
return unsafeDowncast(other, to: _IndexBox.self)._base
}
internal var _typeID: ObjectIdentifier {
return Swift._typeID(self)
}
@warn_unused_result
internal func _unbox<T : Comparable>() -> T? {
return (self as _AnyIndexBox as? _IndexBox<T>)?._base
}
@warn_unused_result
internal func _equal(to rhs: _AnyIndexBox) -> Bool {
return _base == _unsafeUnbox(rhs)
}
@warn_unused_result
internal func _notEqual(to rhs: _AnyIndexBox) -> Bool {
return _base != _unsafeUnbox(rhs)
}
@warn_unused_result
internal func _less(than rhs: _AnyIndexBox) -> Bool {
return _base < _unsafeUnbox(rhs)
}
@warn_unused_result
internal func _lessOrEqual(to rhs: _AnyIndexBox) -> Bool {
return _base <= _unsafeUnbox(rhs)
}
@warn_unused_result
internal func _greater(than rhs: _AnyIndexBox) -> Bool {
return _base > _unsafeUnbox(rhs)
}
@warn_unused_result
internal func _greaterOrEqual(to rhs: _AnyIndexBox) -> Bool {
return _base >= _unsafeUnbox(rhs)
}
}
/// A wrapper over an underlying index that hides
/// the specific underlying type.
///
/// - SeeAlso: `AnyCollection`
public struct AnyIndex : Comparable {
/// Wrap and forward operations to `base`.
public init<BaseIndex : Comparable>(_ base: BaseIndex) {
self._box = _IndexBox(_base: base)
}
internal init(_box: _AnyIndexBox) {
self._box = _box
}
internal var _typeID: ObjectIdentifier {
return _box._typeID
}
internal var _box: _AnyIndexBox
}
/// Returns `true` iff `lhs` and `rhs` wrap equal underlying indices.
///
/// - Precondition: The types of indices wrapped by `lhs` and `rhs` are
/// identical.
@warn_unused_result
public func == (lhs: AnyIndex, rhs: AnyIndex) -> Bool {
precondition(lhs._typeID == rhs._typeID, "base index types differ")
return lhs._box._equal(to: rhs._box)
}
@warn_unused_result
public func != (lhs: AnyIndex, rhs: AnyIndex) -> Bool {
precondition(lhs._typeID == rhs._typeID, "base index types differ")
return lhs._box._notEqual(to: rhs._box)
}
@warn_unused_result
public func < (lhs: AnyIndex, rhs: AnyIndex) -> Bool {
precondition(lhs._typeID == rhs._typeID, "base index types differ")
return lhs._box._less(than: rhs._box)
}
@warn_unused_result
public func <= (lhs: AnyIndex, rhs: AnyIndex) -> Bool {
precondition(lhs._typeID == rhs._typeID, "base index types differ")
return lhs._box._lessOrEqual(to: rhs._box)
}
@warn_unused_result
public func > (lhs: AnyIndex, rhs: AnyIndex) -> Bool {
precondition(lhs._typeID == rhs._typeID, "base index types differ")
return lhs._box._greater(than: rhs._box)
}
@warn_unused_result
public func >= (lhs: AnyIndex, rhs: AnyIndex) -> Bool {
precondition(lhs._typeID == rhs._typeID, "base index types differ")
return lhs._box._greaterOrEqual(to: rhs._box)
}
//===--- Collections ------------------------------------------------------===//
//===----------------------------------------------------------------------===//
/// A protocol for `AnyCollection<Element>`,
/// `AnyBidirectionalCollection<Element>`, and
/// `AnyRandomAccessCollection<Element>`.
///
/// This protocol can be considered an implementation detail of the
/// `===` and `!==` implementations for these types.
public protocol AnyCollectionProtocol : Collection {
/// Identifies the underlying collection stored by `self`. Instances
/// copied from one another have the same `_underlyingCollectionID`.
var _underlyingCollectionID: ObjectIdentifier { get }
}
/// Returns `true` iff `lhs` and `rhs` store the same underlying collection.
@warn_unused_result
public func === <
L : AnyCollectionProtocol, R : AnyCollectionProtocol
>(lhs: L, rhs: R) -> Bool {
return lhs._underlyingCollectionID == rhs._underlyingCollectionID
}
/// Returns `false` iff `lhs` and `rhs` store the same underlying collection.
@warn_unused_result
public func !== <
L : AnyCollectionProtocol, R : AnyCollectionProtocol
>(lhs: L, rhs: R) -> Bool {
return lhs._underlyingCollectionID != rhs._underlyingCollectionID
}
% for (ti, Traversal) in enumerate(traversals):
% SelfProtocol = collectionForTraversal(Traversal)
% Self = 'Any' + SelfProtocol
/// A type-erased wrapper over any collection with indices that
/// support ${Traversal.lower().replace('omacc', 'om acc')} traversal.
///
/// Forwards operations to an arbitrary underlying collection having the
/// same `Element` type, hiding the specifics of the underlying
/// `Collection`.
///
/// - SeeAlso: ${', '.join('`Any%s`' % t for t in (2 * traversals)[ti + 1 : ti + 3]) }
public struct ${Self}<Element>
: AnyCollectionProtocol, ${SelfProtocol} {
% for SubTraversal in traversals[ti:]:
% SubProtocol = collectionForTraversal(SubTraversal)
/// Create an `${Self}` that
/// stores `base` as its underlying collection.
///
/// - Complexity: O(1).
public init<
C : ${SubProtocol}
where
C.Iterator.Element == Element,
// FIXME(compiler limitation): these constraints should be applied to
// associated types of Collection.
C.SubSequence : ${SubProtocol},
C.SubSequence.Iterator.Element == Element,
C.SubSequence.Index == C.Index,
C.SubSequence.SubSequence == C.SubSequence,
C.Indices : ${SubProtocol},
C.Indices.Iterator.Element == C.Index,
C.Indices.Index == C.Index,
C.Indices.SubSequence == C.Indices
>(_ base: C) {
// Traversal: ${Traversal}
// SubTraversal: ${SubTraversal}
self._box = _${SubProtocol}Box<C>(
_base: base,
startIndex: _IndexBox(_base: base.startIndex),
endIndex: _IndexBox(_base: base.endIndex))
}
/// Create an `Any${Traversal}Collection` having the same underlying
/// collection as `other`.
///
/// - Postcondition: The result is `===` to `other`.
///
/// - Complexity: O(1).
public init(
_ other: Any${SubProtocol}<Element>
) {
self._box = other._box
}
% end
% for SuperTraversal in traversals[:ti]:
/// If the underlying collection stored by `other` satisfies
/// `${SelfProtocol}`, create an `${Self}` having the same
/// underlying collection as `other`. Otherwise, the result is
/// `nil`.
///
/// - Complexity: O(1).
public init?(
_ other: Any${collectionForTraversal(SuperTraversal)}<Element>
) {
guard let box =
other._box as? _${Self}Box<Element> else {
return nil
}
self._box = box
}
% end
/// Returns an iterator over the elements of this collection.
///
/// - Complexity: O(1).
public func makeIterator() -> AnyIterator<Element> {
return _box.makeIterator()
}
public typealias Index = AnyIndex
public typealias IndexDistance = IntMax
/// The position of the first element in a non-empty collection.
///
/// In an empty collection, `startIndex == endIndex`.
public var startIndex: AnyIndex {
return AnyIndex(_box: _box._startIndex)
}
/// The collection's "past the end" position.
///
/// `endIndex` is not a valid argument to `subscript`, and is always
/// reachable from `startIndex` by zero or more applications of
/// `successor()`.
public var endIndex: AnyIndex {
return AnyIndex(_box: _box._endIndex)
}
/// Access the element indicated by `position`.
///
/// - Precondition: `position` indicates a valid position in `self` and
/// `position != endIndex`.
public subscript(position: AnyIndex) -> Element {
return _box[position._box]
}
public subscript(bounds: Range<AnyIndex>)
-> ${Self}<Element>
{
fatalError("FIXME: swift-3-indexing-model: implement")
}
/// The number of elements.
///
/// - Complexity: ${'O(1)' if Traversal == 'RandomAccess' else 'O(N)'}.
public var count: IntMax {
return _box._count
}
@warn_unused_result
public func successor(of i: AnyIndex) -> AnyIndex {
return AnyIndex(_box: _box._successor(of: i._box))
}
public func formSuccessor(i: inout AnyIndex) {
if _isUnique(&i._box) {
_box._formSuccessor(i._box)
}
else {
i = successor(of: i)
}
}
% if Traversal == 'Bidirectional' or Traversal == 'RandomAccess':
public func predecessor(of i: AnyIndex) -> AnyIndex {
return AnyIndex(_box: _box._predecessor(of: i._box))
}
public func formPredecessor(i: inout AnyIndex) {
if _isUnique(&i._box) {
_box._formPredecessor(i._box)
}
else {
i = predecessor(of: i)
}
}
% end
/// Uniquely identifies the stored underlying collection.
public // Due to language limitations only
var _underlyingCollectionID: ObjectIdentifier {
return ObjectIdentifier(_box)
}
internal let _box: _${Self}Box<Element>
}
% end
@available(*, unavailable, renamed: "AnyIterator")
public struct AnyGenerator<Element> {}
extension AnyIterator {
@available(*, unavailable, renamed: "makeIterator")
public func generate() -> AnyIterator<Element> {
fatalError("unavailable function can't be called")
}
}
% for Kind in ['Sequence', 'Collection', 'BidirectionalCollection', 'RandomAccessCollection']:
extension Any${Kind} {
@available(*, unavailable, message: "Please use underestimatedCount property instead.")
public var underestimateCount: Int {
fatalError("unavailable function can't be called")
}
}
%end
@available(*, unavailable, renamed: "AnyCollectionProtocol")
public typealias AnyCollectionType = AnyCollectionProtocol
extension AnyCollectionProtocol {
@available(*, unavailable, renamed: "makeIterator")
public func generate() -> AnyIterator<Iterator.Element> {
fatalError("unavailable function can't be called")
}
}