//===--- Map.swift - Lazily map over a SequenceType -----------*- swift -*-===// // // 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 // //===----------------------------------------------------------------------===// /// The `GeneratorType` used by `MapSequence` and `MapCollection`. /// Produces each element by passing the output of the `Base` /// `GeneratorType` through a transform function returning `Element`. public struct MapGenerator< Base : GeneratorType, Element > : GeneratorType, SequenceType { @available(*, unavailable, renamed="Element") public typealias T = Element /// Advance to the next element and return it, or `nil` if no next /// element exists. /// /// - Requires: `next()` has not been applied to a copy of `self` /// since the copy was made, and no preceding call to `self.next()` /// has returned `nil`. public mutating func next() -> Element? { let x = _base.next() if x != nil { return _transform(x!) } return nil } /// `MapGenerator` is also a `SequenceType`, so it /// `generate`'s a copy of itself. public func generate() -> MapGenerator { return self } var _base: Base var _transform: (Base.Element)->Element } //===--- Sequences --------------------------------------------------------===// /// A `SequenceType` whose elements consist of those in a `Base` /// `SequenceType` passed through a transform function returning `Element`. /// These elements are computed lazily, each time they're read, by /// calling the transform function on a base element. public struct MapSequence : SequenceType { @available(*, unavailable, renamed="Element") public typealias T = Element /// Return a *generator* over the elements of this *sequence*. /// /// - Complexity: O(1). public func generate() -> MapGenerator { return MapGenerator( _base: _base.generate(), _transform: _transform) } public func underestimateCount() -> Int { return _base.underestimateCount() } var _base: Base var _transform: (Base.Generator.Element)->Element } /// Return an `Array` containing the results of mapping `transform` /// over `source`. @available(*, unavailable, message="call the 'map()' method on the sequence") public func map( source: S, _ transform: (S.Generator.Element) -> T ) -> [T] { fatalError("unavailable function can't be called") } /// Return an `Array` containing the results of mapping `transform` /// over `source` and flattening the result. @available(*, unavailable, message="call the 'flatMap()' method on the sequence") public func flatMap( source: S, @noescape _ transform: (S.Generator.Element) -> [T] ) -> [T] { fatalError("unavailable function can't be called") } //===--- Collections ------------------------------------------------------===// /// A `CollectionType` whose elements consist of those in a `Base` /// `CollectionType` passed through a transform function returning `Element`. /// These elements are computed lazily, each time they're read, by /// calling the transform function on a base element. public struct MapCollection : CollectionType { @available(*, unavailable, renamed="Element") public typealias T = Element /// The position of the first element in a non-empty collection. /// /// In an empty collection, `startIndex == endIndex`. public var startIndex: Base.Index { return _base.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: Base.Index { return _base.endIndex } /// Access the element at `position`. /// /// - Requires: `position` is a valid position in `self` and /// `position != endIndex`. public subscript(position: Base.Index) -> Element { return _transform(_base[position]) } /// Returns a *generator* over the elements of this *sequence*. /// /// - Complexity: O(1). public func generate() -> MapSequence.Generator { return MapGenerator(_base: _base.generate(), _transform: _transform) } public func underestimateCount() -> Int { return _base.underestimateCount() } var _base: Base var _transform: (Base.Generator.Element)->Element } /// Return an `Array` containing the results of mapping `transform` /// over `source`. @available(*, unavailable, message="call the 'map()' method on the sequence") public func map( source: C, _ transform: (C.Generator.Element) -> T ) -> [T] { fatalError("unavailable function can't be called") } /// Return an `Array` containing the results of mapping `transform` /// over `source` and flattening the result. @available(*, unavailable, message="call the 'flatMap()' method on the sequence") public func flatMap( source: C, _ transform: (C.Generator.Element) -> [T] ) -> [T] { fatalError("unavailable function can't be called") } //===--- Support for lazy(s) ----------------------------------------------===// % traversals = ('Forward', 'Bidirectional', 'RandomAccess') % for View, Self in [('MapSequence', 'LazySequence')] + [ % ('MapCollection', 'Lazy%sCollection' % t) for t in traversals % ]: extension ${Self} { /// Return a `${View}` over this `${Self}`. The elements of /// the result are computed lazily, each time they are read, by /// calling `transform` function on a base element. public func map( transform: (Base.Generator.Element) -> U ) -> ${Self}<${View}> { return ${Self}<${View}>( ${View}(_base: self._base, _transform: transform) ) } } % end @available(*, unavailable, renamed="MapGenerator") public struct MapSequenceGenerator {} @available(*, unavailable, renamed="MapSequence") public struct MapSequenceView {} @available(*, unavailable, renamed="MapCollection") public struct MapCollectionView {} // ${'Local Variables'}: // eval: (read-only-mode 1) // End: