//===--- 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 `MapSequenceView` and `MapCollectionView`. /// Produces each element by passing the output of the `Base` /// `GeneratorType` through a transform function returning `T` public struct MapSequenceGenerator< Base: GeneratorType, T >: GeneratorType, SequenceType { /// 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() -> T? { let x = _base.next() if x != nil { return _transform(x!) } return nil } /// `MapSequenceGenerator` is also a `SequenceType`, so it /// `generate`\ 's a copy of itself public func generate() -> MapSequenceGenerator { return self } var _base: Base var _transform: (Base.Element)->T } //===--- Sequences --------------------------------------------------------===// /// A `SequenceType` whose elements consist of those in a `Base` /// `SequenceType` passed through a transform function returning `T`. /// These elements are computed lazily, each time they're read, by /// calling the transform function on a base element. public struct MapSequenceView : SequenceType { /// Return a *generator* over the elements of this *sequence*. /// /// Complexity: O(1) public func generate() -> MapSequenceGenerator { return MapSequenceGenerator( _base: _base.generate(), _transform: _transform) } var _base: Base var _transform: (Base.Generator.Element)->T } /// Return an `Array` containing the results of mapping `transform` /// over `source`. public func map( source: S, transform: (S.Generator.Element) -> T ) -> [T] { return lazy(source).map(transform).array } //===--- Collections ------------------------------------------------------===// /// A `CollectionType` whose elements consist of those in a `Base` /// `CollectionType` passed through a transform function returning `T`. /// These elements are computed lazily, each time they're read, by /// calling the transform function on a base element. public struct MapCollectionView : CollectionType { /// The position of the first element in a non-empty collection. /// /// Identical to `endIndex` in an empty collection. 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) -> T { return _transform(_base[position]) } /// Return a *generator* over the elements of this *sequence*. /// /// Complexity: O(1) public func generate() -> MapSequenceView.Generator { return MapSequenceGenerator(_base: _base.generate(), _transform: _transform) } var _base: Base var _transform: (Base.Generator.Element)->T } /// Return an `Array` containing the results of mapping `transform` /// over `source`. public func map( source: C, transform: (C.Generator.Element) -> T ) -> [T] { return lazy(source).map(transform).array } //===--- Support for lazy(s) ----------------------------------------------===// % traversals = ('Forward', 'Bidirectional', 'RandomAccess') % for View, Self in [('MapSequenceView', 'LazySequence')] + [ % ('MapCollectionView', '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: (S.Generator.Element) -> U ) -> ${Self}<${View}> { return ${Self}<${View}>( ${View}(_base: self._base, _transform: transform) ) } } % end // ${'Local Variables'}: // eval: (read-only-mode 1) // End: