//===----------------------------------------------------------------------===// // // 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 // //===----------------------------------------------------------------------===// /// Encapsulates iteration state and interface for iteration over a /// *sequence*. /// /// - Note: While it is safe to copy a *generator*, advancing one /// copy may invalidate the others. /// /// Any code that uses multiple generators (or `for`...`in` loops) /// over a single *sequence* should have static knowledge that the /// specific *sequence* is multi-pass, either because its concrete /// type is known or because it is constrained to `CollectionType`. /// Also, the generators must be obtained by distinct calls to the /// *sequence's* `generate()` method, rather than by copying. public protocol GeneratorType { /// The type of element generated by `self`. typealias 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`. Specific implementations of this protocol /// are encouraged to respond to violations of this requirement by /// calling `preconditionFailure("...")`. mutating func next() -> Element? } /// A type that can be iterated with a `for`...`in` loop. /// /// `SequenceType` makes no requirement on conforming types regarding /// whether they will be destructively "consumed" by iteration. To /// ensure non-destructive iteration, constrain your *sequence* to /// `CollectionType`. public protocol SequenceType { /// A type that provides the *sequence*'s iteration interface and /// encapsulates its iteration state. typealias Generator : GeneratorType /// Return a *generator* over the elements of this *sequence*. /// /// - Complexity: O(1). func generate() -> Generator /// Return a value less than or equal to the number of elements in /// `self`, **nondestructively**. /// /// - Complexity: O(N). func underestimateCount() -> Int /// Return an `Array` containing the results of mapping `transform` /// over `self`. /// /// - Complexity: O(N). func map( @noescape transform: (Generator.Element) -> T ) -> [T] /// Return an `Array` containing the elements of `self`, /// in order, that satisfy the predicate `includeElement`. func filter( @noescape includeElement: (Generator.Element) -> Bool ) -> [Generator.Element] func _customContainsEquatableElement( element: Generator.Element ) -> Bool? /// If `self` is multi-pass (i.e., a `CollectionType`), invoke /// `preprocess` on `self` and return its result. Otherwise, return /// `nil`. func _preprocessingPass(preprocess: (Self)->R) -> R? /// Create a native array buffer containing the elements of `self`, /// in the same order. func _copyToNativeArrayBuffer() -> _ContiguousArrayBuffer /// Copy a Sequence into an array. func _initializeTo(ptr: UnsafeMutablePointer) } extension SequenceType { /// Return a value less than or equal to the number of elements in /// `self`, **nondestructively**. /// /// - Complexity: O(N). public func underestimateCount() -> Int { return 0 } public func _preprocessingPass(preprocess: (Self)->R) -> R? { return nil } } extension SequenceType { /// Return an `Array` containing the results of mapping `transform` /// over `self`. /// /// - Complexity: O(N). public func map( @noescape transform: (Generator.Element) -> T ) -> [T] { // Cast away @noescape. typealias Transform = (Generator.Element) -> T let escapableTransform = unsafeBitCast(transform, Transform.self) return Array(lazy(self).map(escapableTransform)) } } extension SequenceType { /// Return an `Array` containing the elements of `self`, /// in order, that satisfy the predicate `includeElement`. public func filter( @noescape includeElement: (Generator.Element) -> Bool ) -> [Generator.Element] { // Cast away @noescape. typealias IncludeElement = (Generator.Element) -> Bool let escapableIncludeElement = unsafeBitCast(includeElement, IncludeElement.self) return Array(lazy(self).filter(escapableIncludeElement)) } } extension SequenceType { public func _customContainsEquatableElement( element: Generator.Element ) -> Bool? { return nil } } /// Return an underestimate of the number of elements in the given /// sequence, without consuming the sequence. For Sequences that are /// actually Collections, this will return `x.count`. @available(*, unavailable, message="call the 'underestimateCount()' method on the sequence") public func underestimateCount(x: T) -> Int { fatalError("unavailable function can't be called") } extension SequenceType { public func _initializeTo(ptr: UnsafeMutablePointer) { var p = UnsafeMutablePointer(ptr) for x in GeneratorSequence(self.generate()) { p++.initialize(x) } } } // Pending and , // pass a GeneratorType through GeneratorSequence to give it "SequenceType-ness" /// A sequence built around a generator of type `G`. /// /// Useful mostly to recover the ability to use `for`...`in`, /// given just a generator `g`: /// /// for x in GeneratorSequence(g) { ... } public struct GeneratorSequence< Base : GeneratorType > : GeneratorType, SequenceType { @available(*, unavailable, renamed="Base") public typealias G = Base /// Construct an instance whose generator is a copy of `base`. public init(_ base: Base) { _base = base } /// 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() -> Base.Element? { return _base.next() } /// Returns a *generator* over the elements of this *sequence*. /// /// - Complexity: O(1). public func generate() -> GeneratorSequence { return self } internal var _base: Base }