//===--- 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 // //===----------------------------------------------------------------------===// import SwiftShims % traversals = ['Forward', 'Bidirectional', 'RandomAccess'] @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 // @testable 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 _AnyIteratorBase {} internal class _AnyIteratorBoxBase : _AnyIteratorBase, 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 { internal func makeIterator() -> AnyIterator { _abstract() } internal var _underestimatedCount: Int { _abstract() } internal func _copyContents(initializing ptr: UnsafeMutablePointer) -> UnsafeMutablePointer { _abstract() } internal func _copyToNativeArrayBuffer() -> _ContiguousArrayStorageBase { _abstract() } internal func _dropFirst(n: Int) -> _AnySequenceBox { _abstract() } internal func _prefix(maxLength: Int) -> _AnySequenceBox { _abstract() } } internal class _AnyCollectionBoxBase : _AnySequenceBox { internal init( startIndex: _ForwardIndexBoxProtocol, endIndex: _ForwardIndexBoxProtocol ) { self.startIndex = startIndex self.endIndex = endIndex } internal let startIndex: _ForwardIndexBoxProtocol internal let endIndex: _ForwardIndexBoxProtocol } % for Kind in ['Sequence', 'Collection']: // FIXME: can't make this a protocol due to internal final class _${Kind}Box< S : ${Kind} % if Kind == 'Sequence': where S.SubSequence : ${Kind}, S.SubSequence.Iterator.Element == S.Iterator.Element, S.SubSequence.SubSequence == S.SubSequence % end > : _Any${Kind}Box { typealias Element = S.Iterator.Element override func makeIterator() -> AnyIterator { return AnyIterator(_base.makeIterator()) } override var _underestimatedCount: Int { return _base.underestimatedCount } override func _copyContents(initializing ptr: UnsafeMutablePointer) -> UnsafeMutablePointer { return _base._copyContents(initializing: ptr) } override func _copyToNativeArrayBuffer() -> _ContiguousArrayStorageBase { return _base._copyToNativeArrayBuffer()._storage } % if Kind == 'Sequence': internal override func _dropFirst(n: Int) -> _AnySequenceBox { return _SequenceBox(_base.dropFirst(n)) } internal override func _prefix(maxLength: Int) -> _AnySequenceBox { return _SequenceBox(_base.prefix(maxLength)) } % end % if Kind == 'Collection': override func _count() -> IntMax { return numericCast(_base.count) } override subscript(position: _ForwardIndexBoxProtocol) -> Element { if let i = position._unbox() as S.Index? { return _base[i] } fatalError("Index type mismatch!") } init( _ base: S, startIndex: _ForwardIndexBoxProtocol, endIndex: _ForwardIndexBoxProtocol ) { self._base = base super.init(startIndex: startIndex, endIndex: endIndex) } % else: init(_ base: S) { self._base = base } % 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) { _box = _SequenceBox(base) } /// Create a sequence whose `makeIterator()` method forwards to /// `makeUnderlyingIterator`. public init( _ makeUnderlyingIterator: () -> I ) { self.init(_ClosureBasedSequence(makeUnderlyingIterator)) } internal init(_ box: _AnySequenceBox) { _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._dropFirst(n)) } @warn_unused_result public func prefix(maxLength: Int) -> AnySequence { return AnySequence(_box._prefix(maxLength)) } } % for Kind in ['Sequence'] + [t + 'Collection' for t in traversals]: 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 //===--- ForwardIndex -----------------------------------------------------===// //===----------------------------------------------------------------------===// internal protocol _ForwardIndexBoxProtocol : class { var typeID: ObjectIdentifier { get } @warn_unused_result func successor() -> _ForwardIndexBoxProtocol func _successorInPlace() @warn_unused_result func equals(other: _ForwardIndexBoxProtocol) -> Bool @warn_unused_result func _unbox() -> T? @warn_unused_result func _distance(to other: _ForwardIndexBoxProtocol) -> AnyForwardIndex.Distance // FIXME: Can't return Self from _advanced(by:) pending @warn_unused_result func _advanced(by distance: AnyForwardIndex.Distance) -> _ForwardIndexBoxProtocol @warn_unused_result func _advanced( by distance: AnyForwardIndex.Distance, limit: _ForwardIndexBoxProtocol ) -> _ForwardIndexBoxProtocol } internal class _ForwardIndexBox< BaseIndex: ForwardIndex > : _ForwardIndexBoxProtocol { required init(_ base: BaseIndex) { self.base = base } func successor() -> _ForwardIndexBoxProtocol { return self.dynamicType.init(self.base.successor()) } func _successorInPlace() { self.base._successorInPlace() } func unsafeUnbox(other: _ForwardIndexBoxProtocol) -> BaseIndex { return unsafeDowncast(other, to: _ForwardIndexBox.self).base } func equals(other: _ForwardIndexBoxProtocol) -> Bool { return base == unsafeUnbox(other) } func _distance(to other: _ForwardIndexBoxProtocol) -> AnyForwardIndex.Distance { return numericCast(base.distance(to: unsafeUnbox(other))) } func _advanced(by n: AnyForwardIndex.Distance) -> _ForwardIndexBoxProtocol { return self.dynamicType.init(base.advanced(by: numericCast(n))) } func _advanced( by n: AnyForwardIndex.Distance, limit: _ForwardIndexBoxProtocol ) -> _ForwardIndexBoxProtocol { return self.dynamicType.init( base.advanced(by: numericCast(n), limit: unsafeUnbox(limit))) } func _unbox() -> T? { if T.self is BaseIndex.Type { _sanityCheck(BaseIndex.self is T.Type) // This bit cast is really nothing as we have proven they are // the same type. return unsafeBitCast(base, to: T.self) } return nil } var typeID: ObjectIdentifier { return _typeID(self) } internal // private var base: BaseIndex } //===--- BidirectionalIndex -----------------------------------------------===// //===----------------------------------------------------------------------===// internal protocol _BidirectionalIndexBoxProtocol : _ForwardIndexBoxProtocol { func predecessor() -> _BidirectionalIndexBoxProtocol func _predecessorInPlace() } internal class _BidirectionalIndexBox< BaseIndex: BidirectionalIndex > : _ForwardIndexBox, _BidirectionalIndexBoxProtocol { required init(_ base: BaseIndex) { super.init(base) } override func successor() -> _ForwardIndexBoxProtocol { return self.dynamicType.init(self.base.successor()) } func predecessor() -> _BidirectionalIndexBoxProtocol { return self.dynamicType.init(self.base.predecessor()) } func _predecessorInPlace() { self.base._predecessorInPlace() } } //===--- RandomAccessIndex ------------------------------------------------===// //===----------------------------------------------------------------------===// internal protocol _RandomAccessIndexBoxProtocol : _BidirectionalIndexBoxProtocol {} internal final class _RandomAccessIndexBox< BaseIndex: RandomAccessIndex > : _BidirectionalIndexBox, _RandomAccessIndexBoxProtocol { required init(_ base: BaseIndex) { super.init(base) } } //===--- All Index Protocols ----------------------------------------------===// //===----------------------------------------------------------------------===// % for Traversal in traversals: % Self = 'Any%sIndex' % Traversal /// A wrapper over an underlying `${Traversal}Index` that hides /// the specific underlying type. /// /// - SeeAlso: `Any${Traversal}Collection` public struct ${Self} : ${Traversal}Index { public typealias Distance = IntMax /// Wrap and forward operations to `base`. public init(_ base: BaseIndex) { _box = _${Traversal}IndexBox(base) } /// Returns the next consecutive value in a discrete sequence of /// `${Self}` values. /// /// - Precondition: `self` has a well-defined successor. public func successor() -> ${Self} { return ${Self}(_box.successor()) } public mutating func _successorInPlace() { if _fastPath(_isUnique_native(&_box)) { _box._successorInPlace() } else { self = successor() } } % if Traversal != 'Forward': /// Returns the previous consecutive value in a discrete sequence of /// `${Self}` values. /// /// - Precondition: `self` has a well-defined predecessor. public func predecessor() -> ${Self} { return ${Self}(_box.predecessor()) } public mutating func _predecessorInPlace() { if _fastPath(_isUnique_native(&_box)) { _box._predecessorInPlace() } else { self = predecessor() } } % end % if Traversal == 'RandomAccess': public func distance(to other: ${Self}) -> Distance { return _box._distance(to: other._box) } public func advanced(by amount: Distance) -> ${Self} { return ${Self}(_box._advanced(by: amount)) } public func advanced(by amount: Distance, limit: ${Self}) -> ${Self} { return ${Self}(_box._advanced(by: amount, limit: limit._box)) } % end //===--- private --------------------------------------------------------===// internal var _typeID: ObjectIdentifier { return _box.typeID } internal init(_ box: _ForwardIndexBoxProtocol) { self._box = box${ '' if Traversal == 'Forward' else ' as! _%sIndexBoxProtocol' % Traversal} } // _box is passed inout to _isUnique. Although its value // is unchanged, it must appear mutable to the optimizer. internal var _box: _${Traversal}IndexBoxProtocol public func _distance(to other: ${Self}) -> ${Self}.Distance { precondition( self._typeID == other._typeID, "distance: base index types differ.") return self._box._distance(to: other._box) } } /// Returns `true` iff `lhs` and `rhs` wrap equal underlying /// `${Self}`s. /// /// - Precondition: The types of indices wrapped by `lhs` and `rhs` are /// identical. @warn_unused_result public func == (lhs: ${Self}, rhs: ${Self}) -> Bool { precondition(lhs._typeID == rhs._typeID, "base index types differ.") return lhs._box.equals(rhs._box) } % end //===--- Collections ------------------------------------------------------===// //===----------------------------------------------------------------------===// internal class _AnyCollectionBox : _AnyCollectionBoxBase { internal subscript(_: _ForwardIndexBoxProtocol) -> Element { _abstract() } internal func _count() -> IntMax { _abstract() } // FIXME: should be inherited, but a known bug prevents it since // this class is generic. internal override init( startIndex: _ForwardIndexBoxProtocol, endIndex: _ForwardIndexBoxProtocol ) { super.init(startIndex: startIndex, endIndex: endIndex) } } /// A protocol for `AnyForwardCollection`, /// `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): /// 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 Any${Traversal}Collection : AnyCollectionProtocol { typealias Box = _AnyCollectionBox % for SubTraversal in traversals[ti:]: /// Create an `Any${Traversal}Collection` that stores `base` as its /// underlying collection. /// /// - Complexity: O(1). public init< C : Collection where C.Index : ${SubTraversal}Index, C.Iterator.Element == Element >(_ base: C) { self._box = _CollectionBox( base, startIndex: _${SubTraversal}IndexBox(base.startIndex), endIndex: _${SubTraversal}IndexBox(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${SubTraversal}Collection) { self._box = other._box } % end % for SuperTraversal in traversals[:ti]: /// If the indices of the underlying collection stored by `other` /// satisfy `${Traversal}Index`, create an /// `Any${Traversal}Collection` having the same underlying /// collection as `other`. Otherwise, the result is `nil`. /// /// - Complexity: O(1). public init?(_ other: Any${SuperTraversal}Collection) { if !(other._box.startIndex is _${Traversal}IndexBoxProtocol) { return nil } _sanityCheck(other._box.endIndex is _${Traversal}IndexBoxProtocol) self._box = other._box } % end /// Returns an iterator over the elements of this collection. /// /// - Complexity: O(1). public func makeIterator() -> AnyIterator { return _box.makeIterator() } /// The position of the first element in a non-empty collection. /// /// In an empty collection, `startIndex == endIndex`. public var startIndex: Any${Traversal}Index { return Any${Traversal}Index(_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: Any${Traversal}Index { return Any${Traversal}Index(_box.endIndex) } /// Access the element indicated by `position`. /// /// - Precondition: `position` indicates a valid position in `self` and /// `position != endIndex`. public subscript(position: Any${Traversal}Index) -> Element { return _box[position._box] } /// The number of elements. /// /// - Complexity: ${'O(1)' if Traversal == 'RandomAccess' else 'O(N)'}. public var count: IntMax { return _box._count() } /// Uniquely identifies the stored underlying collection. public // Due to language limitations only var _underlyingCollectionID: ObjectIdentifier { return ObjectIdentifier(_box) } internal let _box: 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'] + [t + 'Collection' for t in traversals]: 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") } }