//===--- ExistentialCollection.swift.gyb ----------------------------------===// // // 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 SwiftShims % traversals = ['Forward', 'Bidirectional', 'RandomAccess'] @noreturn @inline(never) internal func _abstract(file: StaticString = __FILE__, line: UWord = __LINE__) { fatalError("Method must be overridden", file: file, line: line) } //===--- Generator --------------------------------------------------------===// //===----------------------------------------------------------------------===// public class _AnyGeneratorBase {} /// An abstract `GeneratorType` base class over `Element` elements. /// /// Use this as a `Sequence`'s associated `Generator` type when you /// don't want to expose details of the concrete generator, a subclass. /// /// It is an error to create instances of `AnyGenerator` that are not /// also instances of an `AnyGenerator` subclass. /// /// - seealso: /// - `struct AnySequence` /// - `func anyGenerator(base: G) -> AnyGenerator` /// - `func anyGenerator(body: ()->Element?) -> AnyGenerator` public class AnyGenerator : _AnyGeneratorBase, GeneratorType { @available(*, unavailable, renamed="Element") public typealias T = Element /// Initialize the instance. May only be called from a subclass /// initializer. override public init() { super.init() _debugPrecondition( _typeID(self) != unsafeBitCast(AnyGenerator.self, ObjectIdentifier.self), "AnyGenerator instances can not be created; create a subclass instance instead.") } /// Advance to the next element and return it, or `nil` if no next /// element exists. /// /// - Note: Subclasses must override this method. public func next() -> Element? {_abstract()} } /// Every `GeneratorType` can also be a `SequenceType`. Note that /// traversing the sequence consumes the generator. extension AnyGenerator : SequenceType { /// Returns `self`. public func generate() -> AnyGenerator { return self } } //===--- Generic Factories ------------------------------------------------===// // The following two functions should be initializers, but we can't // yet express that in the language. /// Return a `GeneratorType` instance that wraps `base` but whose type /// depends only on the type of `G.Element`. /// /// Example: /// /// func countStrings() -> AnyGenerator { /// let lazyStrings = lazy(0..<10).map { String($0) } /// /// // This is a really complicated type of no interest to our /// // clients. /// let g: MapSequenceGenerator, String> /// = lazyStrings.generate() /// return anyGenerator(g) /// } public func anyGenerator(base: G) -> AnyGenerator { return _GeneratorBox(base) } internal class _FunctionGenerator : AnyGenerator { init(_ body: ()->Element?) { self.body = body } override func next() -> Element? { return body() } let body: ()->Element? } /// Return a `GeneratorType` instance whose `next` method invokes /// `body` and returns the result. /// /// Example: /// /// var x = 7 /// let g = anyGenerator { x < 15 ? x++ : nil } /// let a = Array(g) // [ 7, 8, 9, 10, 11, 12, 13, 14 ] public func anyGenerator(body: ()->Element?) -> AnyGenerator { return _FunctionGenerator(body) } internal final class _GeneratorBox< Base: GeneratorType > : AnyGenerator { init(_ base: Base) { self.base = base } override func next() -> Base.Element? { return base.next() } var base: Base } internal func _typeID(instance: AnyObject) -> ObjectIdentifier { return ObjectIdentifier(instance.dynamicType) } //===--- Sequence ---------------------------------------------------------===// //===----------------------------------------------------------------------===// internal class _AnySequenceBox { // FIXME: can't make _AnySequenceBox generic and return // _AnyGenerator here due to func generate() -> _AnyGeneratorBase {_abstract()} func _underestimateCount() -> Int {_abstract()} // FIXME: can't traffic in UnsafeMutablePointer and // _ContiguousArrayBuffer here due to func _initializeTo(ptr: UnsafeMutablePointer) {_abstract()} func _copyToNativeArrayBuffer() -> _ContiguousArrayStorageBase {_abstract()} } internal class _AnyCollectionBoxBase : _AnySequenceBox { init(startIndex: _ForwardIndexBoxType, endIndex: _ForwardIndexBoxType) { self.startIndex = startIndex self.endIndex = endIndex } let startIndex: _ForwardIndexBoxType let endIndex: _ForwardIndexBoxType } % for Kind in ['Sequence', 'Collection']: // FIXME: can't make this a protocol due to internal class _${Kind}Box : _Any${Kind}Box${''if Kind == 'Collection' else ''} { typealias Element = S.Generator.Element override func generate() -> _AnyGeneratorBase { // FIXME: an intermediate variable is a workaround for: // _GeneratorBox(_base.generate()) does // not compile when put into one expression let x = _base.generate() return _GeneratorBox(x) } override func _underestimateCount() -> Int { return _base.underestimateCount() } override func _initializeTo(ptr: UnsafeMutablePointer) { _base._initializeTo(UnsafeMutablePointer(ptr)) } override func _copyToNativeArrayBuffer() -> _ContiguousArrayStorageBase { return _base._copyToNativeArrayBuffer()._storage } % if Kind == 'Collection': override func _count() -> IntMax { return numericCast(_base.count) } override subscript(position: _ForwardIndexBoxType) -> Element { if let i = position._unbox() as S.Index? { return _base[i] } fatalError("Index type mismatch!") } init( _ base: S, startIndex: _ForwardIndexBoxType, endIndex: _ForwardIndexBoxType ) { 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 : SequenceType { internal init(_ makeUnderlyingGenerator: () -> Generator) { self._makeUnderlyingGenerator = makeUnderlyingGenerator } internal func generate() -> Generator { return _makeUnderlyingGenerator() } internal var _makeUnderlyingGenerator: () -> Generator } /// A type-erased sequence. /// /// Forwards operations to an arbitrary underlying sequence having the /// same `Element` type, hiding the specifics of the underlying /// `SequenceType`. /// /// - SeeAlso: `AnyGenerator`. public struct AnySequence : SequenceType { @available(*, unavailable, renamed="Element") public typealias T = Element /// Wrap and forward operations to to `base`. public init(_ base: S) { _box = _SequenceBox(base) } /// Create a sequence whose `generate()` method forwards to /// `makeUnderlyingGenerator`. public init( _ makeUnderlyingGenerator: () -> G ) { self.init(_ClosureBasedSequence(makeUnderlyingGenerator)) } /// Return a *generator* over the elements of this *sequence*. /// /// - Complexity: O(1). public func generate() -> AnyGenerator { return unsafeDowncast(_box.generate()) } internal let _box: _AnySequenceBox } % for Kind in ['Sequence'] + [t + 'Collection' for t in traversals]: extension Any${Kind} { public func underestimateCount() -> Int { return _box._underestimateCount() } public func _initializeTo(ptr: UnsafeMutablePointer) { _box._initializeTo(UnsafeMutablePointer(ptr)) } public func _copyToNativeArrayBuffer() -> _ContiguousArrayBuffer { return _ContiguousArrayBuffer(self._box._copyToNativeArrayBuffer()) } } % end //===--- ForwardIndex -----------------------------------------------------===// //===----------------------------------------------------------------------===// internal protocol _ForwardIndexBoxType : class { var typeID: ObjectIdentifier {get} func successor() -> _ForwardIndexBoxType func _successorInPlace() func equals(other: _ForwardIndexBoxType) -> Bool func _unbox() -> T? func _distanceTo(other: _ForwardIndexBoxType) -> AnyForwardIndex.Distance // FIXME: Can't return Self from _advancedBy pending func _advancedBy(distance: AnyForwardIndex.Distance) -> _ForwardIndexBoxType func _advancedBy( distance: AnyForwardIndex.Distance, _ limit: _ForwardIndexBoxType ) -> _ForwardIndexBoxType } internal class _ForwardIndexBox< BaseIndex: ForwardIndexType > : _ForwardIndexBoxType { required init(_ base: BaseIndex) { self.base = base } func successor() -> _ForwardIndexBoxType { return self.dynamicType.init(self.base.successor()) } func _successorInPlace() { self.base._successorInPlace() } func unsafeUnbox(other: _ForwardIndexBoxType) -> BaseIndex { return (unsafeDowncast(other) as _ForwardIndexBox).base } func equals(other: _ForwardIndexBoxType) -> Bool { return base == unsafeUnbox(other) } func _distanceTo(other: _ForwardIndexBoxType) -> AnyForwardIndex.Distance { return numericCast(distance(base, unsafeUnbox(other))) } func _advancedBy(n: AnyForwardIndex.Distance) -> _ForwardIndexBoxType { return self.dynamicType.init(advance(base, numericCast(n))) } func _advancedBy( n: AnyForwardIndex.Distance, _ limit: _ForwardIndexBoxType ) -> _ForwardIndexBoxType { return self.dynamicType.init(advance(base, numericCast(n), 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, T.self) } return nil } var typeID: ObjectIdentifier { return _typeID(self) } internal // private var base: BaseIndex } //===--- BidirectionalIndex -----------------------------------------------===// //===----------------------------------------------------------------------===// internal protocol _BidirectionalIndexBoxType : _ForwardIndexBoxType { func predecessor() -> _BidirectionalIndexBoxType func _predecessorInPlace() } internal class _BidirectionalIndexBox< BaseIndex: BidirectionalIndexType > : _ForwardIndexBox, _BidirectionalIndexBoxType { required init(_ base: BaseIndex) { super.init(base) } override func successor() -> _ForwardIndexBoxType { return self.dynamicType.init(self.base.successor()) } func predecessor() -> _BidirectionalIndexBoxType { return self.dynamicType.init(self.base.predecessor()) } func _predecessorInPlace() { self.base._predecessorInPlace() } } //===--- RandomAccessIndex -----------------------------------------------===// //===----------------------------------------------------------------------===// internal protocol _RandomAccessIndexBoxType : _BidirectionalIndexBoxType {} internal final class _RandomAccessIndexBox< BaseIndex: RandomAccessIndexType > : _BidirectionalIndexBox, _RandomAccessIndexBoxType { required init(_ base: BaseIndex) { super.init(base) } } //===--- All Index Protocols ----------------------------------------------===// //===----------------------------------------------------------------------===// % for Traversal in traversals: % Self = 'Any%sIndex' % Traversal /// A wrapper over an underlying `${Traversal}IndexType` that hides /// the specific underlying type. /// /// - SeeAlso: `Any${Traversal}Collection` public struct ${Self} : ${Traversal}IndexType { public typealias Distance = IntMax /// Wrap and forward operations to `base`. public init(_ base: BaseIndex) { _box = _${Traversal}IndexBox(base) } /// Return the next consecutive value in a discrete sequence of /// `${Self}` values. /// /// - Requires: `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': /// Return the previous consecutive value in a discrete sequence of /// `${Self}` values. /// /// - Requires: `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': /// Return the minimum number of applications of `successor` or /// `predecessor` required to reach `other` from `self`. /// /// - Requires: `self` and `other` wrap instances of the same type. public func distanceTo(other: ${Self}) -> Distance { return _box._distanceTo(other._box) } /// 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`. public func advancedBy(amount: Distance) -> ${Self} { return ${Self}(_box._advancedBy(amount)) } % end //===--- private --------------------------------------------------------===// internal var _typeID: ObjectIdentifier { return _box.typeID } internal init(_ box: _ForwardIndexBoxType) { self._box = box${ '' if Traversal == 'Forward' else ' as! _%sIndexBoxType' % Traversal} } // _box is passed inout to _isUnique. Although its value // is unchanged, it must appear mutable to the optimizer. internal var _box: _${Traversal}IndexBoxType public func _distanceTo(other: ${Self}) -> ${Self}.Distance { precondition( self._typeID == other._typeID, "distance: base index types differ.") return self._box._distanceTo(other._box) } } public func ~> ( start: ${Self}, distance : (_Advance, ${Self}.Distance) ) -> ${Self} { return ${Self}(start._box._advancedBy(distance.1)) } public func ~> ( start: ${Self}, args: (_Advance, (${Self}.Distance, ${Self})) ) -> ${Self} { precondition( start._typeID == args.1.1._typeID, "advance: base index types differ.") return ${Self}(start._box._advancedBy(args.1.0, args.1.1._box)) } /// Return true iff `lhs` and `rhs` wrap equal underlying /// `${Self}`s. /// /// - Requires: The types of indices wrapped by `lhs` and `rhs` are /// identical. 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 { subscript(_: _ForwardIndexBoxType) -> Element {_abstract()} func _count() -> IntMax {_abstract()} // FIXME: should be inherited, but a known bug prevents it since // this class is generic. override init( startIndex: _ForwardIndexBoxType, endIndex: _ForwardIndexBoxType ) { 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 AnyCollectionType : CollectionType { /// Identifies the underlying collection stored by `self`. Instances /// copied from one another have the same `_underlyingCollectionID`. var _underlyingCollectionID: ObjectIdentifier {get} } /// Return true iff `lhs` and `rhs` store the same underlying collection. public func === < L: AnyCollectionType, R: AnyCollectionType >(lhs: L, rhs: R) -> Bool { return lhs._underlyingCollectionID == rhs._underlyingCollectionID } /// Returns false iff `lhs` and `rhs` store the same underlying collection. public func !== < L: AnyCollectionType, R: AnyCollectionType >(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 /// `CollectionType`. /// /// - SeeAlso: ${', '.join('`Any%sType`' % t for t in (2 * traversals)[ti + 1 : ti + 3]) } public struct Any${Traversal}Collection : AnyCollectionType { @available(*, unavailable, renamed="Element") public typealias T = Element 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: CollectionType where C.Index: ${SubTraversal}IndexType, C.Generator.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}IndexType`, 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}IndexBoxType) { return nil } _sanityCheck(other._box.endIndex is _${Traversal}IndexBoxType) self._box = other._box } % end /// Returns a *generator* over the elements of this *collection*. /// /// - Complexity: O(1). public func generate() -> AnyGenerator { return unsafeDowncast(_box.generate()) } /// 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`. /// /// - Requires: `position` indicates a valid position in `self` and /// `position != endIndex`. public subscript(position: Any${Traversal}Index) -> Element { return _box[position._box] } /// Return 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