//===--- 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` public struct AnyIterator : IteratorProtocol { /// Create a `IteratorProtocol` instance that wraps `base` but whose type /// depends only on the type of `I.Element`. /// /// Example: /// /// func digits() -> AnyIterator { /// let lazyStrings = (0..<10).lazy.map { String($0) } /// /// // This is a really complicated type of no interest to our /// // clients. /// let iterator: MapSequenceIterator, String> /// = lazyStrings.makeIterator() /// return AnyIterator(iterator) /// } public init(_ 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) { 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 } /// Every `IteratorProtocol` can also be a `Sequence`. Note that /// traversing the sequence consumes the iterator. extension AnyIterator : Sequence {} internal struct _ClosureBasedIterator : IteratorProtocol { internal init(_ body: () -> Element?) { self._body = body } internal func next() -> Element? { return _body() } internal let _body: () -> Element? } internal class _AnyIteratorBoxBase : 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 { 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 { @warn_unused_result internal func makeIterator() -> AnyIterator { _abstract() } internal var _underestimatedCount: Int { _abstract() } @warn_unused_result internal func _copyContents(initializing ptr: UnsafeMutablePointer) -> UnsafeMutablePointer { _abstract() } @warn_unused_result internal func _copyToNativeArrayBuffer() -> _ContiguousArrayStorageBase { _abstract() } @warn_unused_result internal func _dropFirst(n: Int) -> _AnySequenceBox { _abstract() } @warn_unused_result internal func _prefix(maxLength: Int) -> _AnySequenceBox { _abstract() } } internal class _AnyCollectionBox : _AnySequenceBox { internal subscript(i: _AnyIndexBox) -> Element { _abstract() } internal subscript(start: _AnyIndexBox, end: _AnyIndexBox) -> _AnyCollectionBox { _abstract() } internal var _count: IntMax { _abstract() } // TODO: swift-3-indexing-model: forward the following methods. /* internal func _failEarlyRangeCheck( index: Index, bounds: Range) internal func _failEarlyRangeCheck( range: Range, bounds: Range) 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 advance(i: Index, by n: IndexDistance) -> Index @warn_unused_result func advance(i: Index, by n: IndexDistance, limit: Index) -> 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 : _AnyCollectionBox { 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 : _AnyBidirectionalCollectionBox { 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 { internal typealias Element = S.Iterator.Element internal override func makeIterator() -> AnyIterator { return AnyIterator(_base.makeIterator()) } internal override var _underestimatedCount: Int { return _base.underestimatedCount } internal override func _copyContents(initializing ptr: UnsafeMutablePointer) -> UnsafeMutablePointer { return _base._copyContents(initializing: ptr) } internal override func _copyToNativeArrayBuffer() -> _ContiguousArrayStorageBase { return _base._copyToNativeArrayBuffer()._storage } % if Kind == 'Sequence': internal override func _dropFirst(n: Int) -> _AnySequenceBox { return _SequenceBox(_base: _base.dropFirst(n)) } internal override func _prefix(maxLength: Int) -> _AnySequenceBox { return _SequenceBox(_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 { 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 { return _base.formPredecessor(&p._base) } fatalError("Index type mismatch!") } % end % end internal var _base: S } % end internal struct _ClosureBasedSequence : 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`. public struct AnySequence : Sequence { @available(*, unavailable, renamed: "Element") public typealias T = Element /// 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( _ makeUnderlyingIterator: () -> I ) { self.init(_ClosureBasedSequence(makeUnderlyingIterator)) } internal init(_box: _AnySequenceBox) { self._box = _box } /// Returns an iterator over the elements of this sequence. /// /// - Complexity: O(1). public func makeIterator() -> AnyIterator { return _box.makeIterator() } internal let _box: _AnySequenceBox } extension AnySequence { @warn_unused_result public func dropFirst(n: Int) -> AnySequence { return AnySequence(_box: _box._dropFirst(n)) } @warn_unused_result public func prefix(maxLength: Int) -> AnySequence { 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) -> UnsafeMutablePointer { return _box._copyContents(initializing: ptr) } public func _copyToNativeArrayBuffer() -> _ContiguousArrayBuffer { return _ContiguousArrayBuffer(self._box._copyToNativeArrayBuffer()) } } % end //===--- Index ------------------------------------------------------------===// //===----------------------------------------------------------------------===// internal protocol _AnyIndexBox : class { var _typeID: ObjectIdentifier { get } @warn_unused_result func _unbox() -> 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? { return (self as _AnyIndexBox as? _IndexBox)?._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(_ 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`, /// `AnyBidirectionalCollection`, and /// `AnyRandomAccessCollection`. /// /// 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%sType`' % t for t in (2 * traversals)[ti + 1 : ti + 3]) } public struct ${Self} : 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( _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} ) { 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)} ) { guard let box = other._box as? _${Self}Box else { return nil } self._box = box } % end /// Returns an iterator over the elements of this collection. /// /// - Complexity: O(1). public func makeIterator() -> AnyIterator { 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) -> ${Self} { 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 } % end @available(*, unavailable, renamed: "AnyIterator") public struct AnyGenerator {} extension AnyIterator { @available(*, unavailable, renamed: "iterator") public func generate() -> AnyIterator { 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: "iterator") public func generate() -> AnyIterator { fatalError("unavailable function can't be called") } }