//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// /// A type that supplies the values of a sequence one at a time. /// /// The `IteratorProtocol` protocol is tightly linked with the `Sequence` /// protocol. Sequences provide access to their elements by creating an /// iterator, which keeps track of its iteration process and returns one /// element at a time as it advances through the sequence. /// /// Whenever you use a `for`-`in` loop with an array, set, or any other /// collection or sequence, you're using that type's iterator. Swift uses a /// sequence's or collection's iterator internally to enable the `for`-`in` /// loop language construct. /// /// Using a sequence's iterator directly gives you access to the same elements /// in the same order as iterating over that sequence using a `for`-`in` loop. /// For example, you might typically use a `for`-`in` loop to print each of /// the elements in an array. /// /// let animals = ["Antelope", "Butterfly", "Camel", "Dolphin"] /// for animal in animals { /// print(animal) /// } /// // Prints "Antelope" /// // Prints "Butterfly" /// // Prints "Camel" /// // Prints "Dolphin" /// /// Behind the scenes, Swift uses the `animals` array's iterator to loop over /// the contents of the array. /// /// var animalIterator = animals.makeIterator() /// while let animal = animalIterator.next() { /// print(animal) /// } /// // Prints "Antelope" /// // Prints "Butterfly" /// // Prints "Camel" /// // Prints "Dolphin" /// /// The call to `animals.makeIterator()` returns an instance of the array's /// iterator. Next, the `while` loop calls the iterator's `next()` method /// repeatedly, binding each element that is returned to `animal` and exiting /// when the `next()` method returns `nil`. /// /// Using Iterators Directly /// ======================== /// /// You rarely need to use iterators directly, because a `for`-`in` loop is the /// more idiomatic approach to traversing a sequence in Swift. Some /// algorithms, however, may call for direct iterator use. /// /// One example is the `reduce1(_:)` method. Similar to the `reduce(_:_:)` /// method defined in the standard library, which takes an initial value and a /// combining closure, `reduce1(_:)` uses the first element of the sequence as /// the initial value. /// /// Here's an implementation of the `reduce1(_:)` method. The sequence's /// iterator is used directly to retrieve the initial value before looping /// over the rest of the sequence. /// /// extension Sequence { /// func reduce1( /// _ nextPartialResult: (Element, Element) -> Element /// ) -> Element? /// { /// var i = makeIterator() /// guard var accumulated = i.next() else { /// return nil /// } /// /// while let element = i.next() { /// accumulated = nextPartialResult(accumulated, element) /// } /// return accumulated /// } /// } /// /// The `reduce1(_:)` method makes certain kinds of sequence operations /// simpler. Here's how to find the longest string in a sequence, using the /// `animals` array introduced earlier as an example: /// /// let longestAnimal = animals.reduce1 { current, element in /// if current.count > element.count { /// return current /// } else { /// return element /// } /// } /// print(longestAnimal) /// // Prints Optional("Butterfly") /// /// Using Multiple Iterators /// ======================== /// /// Whenever you use multiple iterators (or `for`-`in` loops) over a single /// sequence, be sure you know that the specific sequence supports repeated /// iteration, either because you know its concrete type or because the /// sequence is also constrained to the `Collection` protocol. /// /// Obtain each separate iterator from separate calls to the sequence's /// `makeIterator()` method rather than by copying. Copying an iterator is /// safe, but advancing one copy of an iterator by calling its `next()` method /// may invalidate other copies of that iterator. `for`-`in` loops are safe in /// this regard. /// /// Adding IteratorProtocol Conformance to Your Type /// ================================================ /// /// Implementing an iterator that conforms to `IteratorProtocol` is simple. /// Declare a `next()` method that advances one step in the related sequence /// and returns the current element. When the sequence has been exhausted, the /// `next()` method returns `nil`. /// /// For example, consider a custom `Countdown` sequence. You can initialize the /// `Countdown` sequence with a starting integer and then iterate over the /// count down to zero. The `Countdown` structure's definition is short: It /// contains only the starting count and the `makeIterator()` method required /// by the `Sequence` protocol. /// /// struct Countdown: Sequence { /// let start: Int /// /// func makeIterator() -> CountdownIterator { /// return CountdownIterator(self) /// } /// } /// /// The `makeIterator()` method returns another custom type, an iterator named /// `CountdownIterator`. The `CountdownIterator` type keeps track of both the /// `Countdown` sequence that it's iterating and the number of times it has /// returned a value. /// /// struct CountdownIterator: IteratorProtocol { /// let countdown: Countdown /// var times = 0 /// /// init(_ countdown: Countdown) { /// self.countdown = countdown /// } /// /// mutating func next() -> Int? { /// let nextNumber = countdown.start - times /// guard nextNumber > 0 /// else { return nil } /// /// times += 1 /// return nextNumber /// } /// } /// /// Each time the `next()` method is called on a `CountdownIterator` instance, /// it calculates the new next value, checks to see whether it has reached /// zero, and then returns either the number, or `nil` if the iterator is /// finished returning elements of the sequence. /// /// Creating and iterating over a `Countdown` sequence uses a /// `CountdownIterator` to handle the iteration. /// /// let threeTwoOne = Countdown(start: 3) /// for count in threeTwoOne { /// print("\(count)...") /// } /// // Prints "3..." /// // Prints "2..." /// // Prints "1..." public protocol IteratorProtocol { /// The type of element traversed by the iterator. associatedtype Element /// Advances to the next element and returns it, or `nil` if no next element /// exists. /// /// Repeatedly calling this method returns, in order, all the elements of the /// underlying sequence. As soon as the sequence has run out of elements, all /// subsequent calls return `nil`. /// /// You must not call this method if any other copy of this iterator has been /// advanced with a call to its `next()` method. /// /// The following example shows how an iterator can be used explicitly to /// emulate a `for`-`in` loop. First, retrieve a sequence's iterator, and /// then call the iterator's `next()` method until it returns `nil`. /// /// let numbers = [2, 3, 5, 7] /// var numbersIterator = numbers.makeIterator() /// /// while let num = numbersIterator.next() { /// print(num) /// } /// // Prints "2" /// // Prints "3" /// // Prints "5" /// // Prints "7" /// /// - Returns: The next element in the underlying sequence, if a next element /// exists; otherwise, `nil`. mutating func next() -> Element? } /// A type that provides sequential, iterated access to its elements. /// /// A sequence is a list of values that you can step through one at a time. The /// most common way to iterate over the elements of a sequence is to use a /// `for`-`in` loop: /// /// let oneTwoThree = 1...3 /// for number in oneTwoThree { /// print(number) /// } /// // Prints "1" /// // Prints "2" /// // Prints "3" /// /// While seemingly simple, this capability gives you access to a large number /// of operations that you can perform on any sequence. As an example, to /// check whether a sequence includes a particular value, you can test each /// value sequentially until you've found a match or reached the end of the /// sequence. This example checks to see whether a particular insect is in an /// array. /// /// let bugs = ["Aphid", "Bumblebee", "Cicada", "Damselfly", "Earwig"] /// var hasMosquito = false /// for bug in bugs { /// if bug == "Mosquito" { /// hasMosquito = true /// break /// } /// } /// print("'bugs' has a mosquito: \(hasMosquito)") /// // Prints "'bugs' has a mosquito: false" /// /// The `Sequence` protocol provides default implementations for many common /// operations that depend on sequential access to a sequence's values. For /// clearer, more concise code, the example above could use the array's /// `contains(_:)` method, which every sequence inherits from `Sequence`, /// instead of iterating manually: /// /// if bugs.contains("Mosquito") { /// print("Break out the bug spray.") /// } else { /// print("Whew, no mosquitos!") /// } /// // Prints "Whew, no mosquitos!" /// /// Repeated Access /// =============== /// /// The `Sequence` protocol makes no requirement on conforming types regarding /// whether they will be destructively consumed by iteration. As a /// consequence, don't assume that multiple `for`-`in` loops on a sequence /// will either resume iteration or restart from the beginning: /// /// for element in sequence { /// if ... some condition { break } /// } /// /// for element in sequence { /// // No defined behavior /// } /// /// In this case, you cannot assume either that a sequence will be consumable /// and will resume iteration, or that a sequence is a collection and will /// restart iteration from the first element. A conforming sequence that is /// not a collection is allowed to produce an arbitrary sequence of elements /// in the second `for`-`in` loop. /// /// To establish that a type you've created supports nondestructive iteration, /// add conformance to the `Collection` protocol. /// /// Conforming to the Sequence Protocol /// =================================== /// /// Making your own custom types conform to `Sequence` enables many useful /// operations, like `for`-`in` looping and the `contains` method, without /// much effort. To add `Sequence` conformance to your own custom type, add a /// `makeIterator()` method that returns an iterator. /// /// Alternatively, if your type can act as its own iterator, implementing the /// requirements of the `IteratorProtocol` protocol and declaring conformance /// to both `Sequence` and `IteratorProtocol` are sufficient. /// /// Here's a definition of a `Countdown` sequence that serves as its own /// iterator. The `makeIterator()` method is provided as a default /// implementation. /// /// struct Countdown: Sequence, IteratorProtocol { /// var count: Int /// /// mutating func next() -> Int? { /// if count == 0 { /// return nil /// } else { /// defer { count -= 1 } /// return count /// } /// } /// } /// /// let threeToGo = Countdown(count: 3) /// for i in threeToGo { /// print(i) /// } /// // Prints "3" /// // Prints "2" /// // Prints "1" /// /// Expected Performance /// ==================== /// /// A sequence should provide its iterator in O(1). The `Sequence` protocol /// makes no other requirements about element access, so routines that /// traverse a sequence should be considered O(*n*) unless documented /// otherwise. public protocol Sequence { /// A type representing the sequence's elements. associatedtype Element /// A type that provides the sequence's iteration interface and /// encapsulates its iteration state. associatedtype Iterator: IteratorProtocol where Iterator.Element == Element /// A type that represents a subsequence of some of the sequence's elements. // associatedtype SubSequence: Sequence = AnySequence // where Element == SubSequence.Element, // SubSequence.SubSequence == SubSequence // typealias SubSequence = AnySequence /// Returns an iterator over the elements of this sequence. __consuming func makeIterator() -> Iterator /// A value less than or equal to the number of elements in the sequence, /// calculated nondestructively. /// /// The default implementation returns 0. If you provide your own /// implementation, make sure to compute the value nondestructively. /// /// - Complexity: O(1), except if the sequence also conforms to `Collection`. /// In this case, see the documentation of `Collection.underestimatedCount`. var underestimatedCount: Int { get } func _customContainsEquatableElement( _ element: Element ) -> Bool? /// Create a native array buffer containing the elements of `self`, /// in the same order. __consuming func _copyToContiguousArray() -> ContiguousArray /// Copy `self` into an unsafe buffer, initializing its memory. /// /// The default implementation simply iterates over the elements of the /// sequence, initializing the buffer one item at a time. /// /// For sequences whose elements are stored in contiguous chunks of memory, /// it may be more efficient to copy them in bulk, using the /// `UnsafeMutablePointer.initialize(from:count:)` method. /// /// - Parameter ptr: An unsafe buffer addressing uninitialized memory. The /// buffer must be of sufficient size to accommodate /// `source.underestimatedCount` elements. (Some implementations trap /// if given a buffer that's smaller than this.) /// /// - Returns: `(it, c)`, where `c` is the number of elements copied into the /// buffer, and `it` is a partially consumed iterator that can be used to /// retrieve elements that did not fit into the buffer (if any). (This can /// only happen if `underestimatedCount` turned out to be an actual /// underestimate, and the buffer did not contain enough space to hold the /// entire sequence.) /// /// On return, the memory region in `buffer[0 ..< c]` is initialized to /// the first `c` elements in the sequence. __consuming func _copyContents( initializing ptr: UnsafeMutableBufferPointer ) -> (Iterator,UnsafeMutableBufferPointer.Index) /// Executes a closure on the sequence’s contiguous storage. /// /// This method calls `body(buffer)`, where `buffer` is a pointer to the /// collection’s contiguous storage. If the contiguous storage doesn't exist, /// the collection creates it. If the collection doesn’t support an internal /// representation in a form of contiguous storage, the method doesn’t call /// `body` --- it immediately returns `nil`. /// /// The optimizer can often eliminate bounds- and uniqueness-checking /// within an algorithm. When that fails, however, invoking the same /// algorithm on the `buffer` argument may let you trade safety for speed. /// /// Successive calls to this method may provide a different pointer on each /// call. Don't store `buffer` outside of this method. /// /// A `Collection` that provides its own implementation of this method /// must provide contiguous storage to its elements in the same order /// as they appear in the collection. This guarantees that it's possible to /// generate contiguous mutable storage to any of its subsequences by slicing /// `buffer` with a range formed from the distances to the subsequence's /// `startIndex` and `endIndex`, respectively. /// /// - Parameters: /// - body: A closure that receives an `UnsafeBufferPointer` to the /// sequence's contiguous storage. /// - Returns: The value returned from `body`, unless the sequence doesn't /// support contiguous storage, in which case the method ignores `body` and /// returns `nil`. func withContiguousStorageIfAvailable( _ body: (_ buffer: UnsafeBufferPointer) throws -> R ) rethrows -> R? } // Provides a default associated type witness for Iterator when the // Self type is both a Sequence and an Iterator. extension Sequence where Self: IteratorProtocol { // @_implements(Sequence, Iterator) public typealias _Default_Iterator = Self } /// A default makeIterator() function for `IteratorProtocol` instances that /// are declared to conform to `Sequence` extension Sequence where Self.Iterator == Self { /// Returns an iterator over the elements of this sequence. @inlinable public __consuming func makeIterator() -> Self { return self } } /// A sequence that lazily consumes and drops `n` elements from an underlying /// `Base` iterator before possibly returning the first available element. /// /// The underlying iterator's sequence may be infinite. @frozen public struct DropFirstSequence { @usableFromInline internal let _base: Base @usableFromInline internal let _limit: Int @inlinable public init(_ base: Base, dropping limit: Int) { _precondition(limit >= 0, "Can't drop a negative number of elements from a sequence") _base = base _limit = limit } } extension DropFirstSequence: Sequence { public typealias Element = Base.Element public typealias Iterator = Base.Iterator public typealias SubSequence = AnySequence @inlinable public __consuming func makeIterator() -> Iterator { var it = _base.makeIterator() var dropped = 0 while dropped < _limit, it.next() != nil { dropped &+= 1 } return it } @inlinable public __consuming func dropFirst(_ k: Int) -> DropFirstSequence { // If this is already a _DropFirstSequence, we need to fold in // the current drop count and drop limit so no data is lost. // // i.e. [1,2,3,4].dropFirst(1).dropFirst(1) should be equivalent to // [1,2,3,4].dropFirst(2). return DropFirstSequence(_base, dropping: _limit + k) } } /// A sequence that only consumes up to `n` elements from an underlying /// `Base` iterator. /// /// The underlying iterator's sequence may be infinite. @frozen public struct PrefixSequence { @usableFromInline internal var _base: Base @usableFromInline internal let _maxLength: Int @inlinable public init(_ base: Base, maxLength: Int) { _precondition(maxLength >= 0, "Can't take a prefix of negative length") _base = base _maxLength = maxLength } } extension PrefixSequence { @frozen public struct Iterator { @usableFromInline internal var _base: Base.Iterator @usableFromInline internal var _remaining: Int @inlinable internal init(_ base: Base.Iterator, maxLength: Int) { _base = base _remaining = maxLength } } } extension PrefixSequence.Iterator: IteratorProtocol { public typealias Element = Base.Element @inlinable public mutating func next() -> Element? { if _remaining != 0 { _remaining &-= 1 return _base.next() } else { return nil } } } extension PrefixSequence: Sequence { @inlinable public __consuming func makeIterator() -> Iterator { return Iterator(_base.makeIterator(), maxLength: _maxLength) } @inlinable public __consuming func prefix(_ maxLength: Int) -> PrefixSequence { let length = Swift.min(maxLength, self._maxLength) return PrefixSequence(_base, maxLength: length) } } /// A sequence that lazily consumes and drops `n` elements from an underlying /// `Base` iterator before possibly returning the first available element. /// /// The underlying iterator's sequence may be infinite. @frozen public struct DropWhileSequence { public typealias Element = Base.Element @usableFromInline internal var _iterator: Base.Iterator @usableFromInline internal var _nextElement: Element? @inlinable internal init(iterator: Base.Iterator, predicate: (Element) throws -> Bool) rethrows { _iterator = iterator _nextElement = _iterator.next() while let x = _nextElement, try predicate(x) { _nextElement = _iterator.next() } } @inlinable internal init(_ base: Base, predicate: (Element) throws -> Bool) rethrows { self = try DropWhileSequence(iterator: base.makeIterator(), predicate: predicate) } } extension DropWhileSequence { @frozen public struct Iterator { @usableFromInline internal var _iterator: Base.Iterator @usableFromInline internal var _nextElement: Element? @inlinable internal init(_ iterator: Base.Iterator, nextElement: Element?) { _iterator = iterator _nextElement = nextElement } } } extension DropWhileSequence.Iterator: IteratorProtocol { public typealias Element = Base.Element @inlinable public mutating func next() -> Element? { guard let next = _nextElement else { return nil } _nextElement = _iterator.next() return next } } extension DropWhileSequence: Sequence { @inlinable public func makeIterator() -> Iterator { return Iterator(_iterator, nextElement: _nextElement) } @inlinable public __consuming func drop( while predicate: (Element) throws -> Bool ) rethrows -> DropWhileSequence { guard let x = _nextElement, try predicate(x) else { return self } return try DropWhileSequence(iterator: _iterator, predicate: predicate) } } //===----------------------------------------------------------------------===// // Default implementations for Sequence //===----------------------------------------------------------------------===// extension Sequence { /// Returns an array containing the results of mapping the given closure /// over the sequence's elements. /// /// In this example, `map` is used first to convert the names in the array /// to lowercase strings and then to count their characters. /// /// let cast = ["Vivien", "Marlon", "Kim", "Karl"] /// let lowercaseNames = cast.map { $0.lowercased() } /// // 'lowercaseNames' == ["vivien", "marlon", "kim", "karl"] /// let letterCounts = cast.map { $0.count } /// // 'letterCounts' == [6, 6, 3, 4] /// /// - Parameter transform: A mapping closure. `transform` accepts an /// element of this sequence as its parameter and returns a transformed /// value of the same or of a different type. /// - Returns: An array containing the transformed elements of this /// sequence. /// /// - Complexity: O(*n*), where *n* is the length of the sequence. @inlinable public func map( _ transform: (Element) throws -> T ) rethrows -> [T] { let initialCapacity = underestimatedCount var result = ContiguousArray() result.reserveCapacity(initialCapacity) var iterator = self.makeIterator() // Add elements up to the initial capacity without checking for regrowth. for _ in 0.. Bool ) rethrows -> [Element] { return try _filter(isIncluded) } @_transparent public func _filter( _ isIncluded: (Element) throws -> Bool ) rethrows -> [Element] { var result = ContiguousArray() var iterator = self.makeIterator() while let element = iterator.next() { if try isIncluded(element) { result.append(element) } } return Array(result) } /// A value less than or equal to the number of elements in the sequence, /// calculated nondestructively. /// /// The default implementation returns 0. If you provide your own /// implementation, make sure to compute the value nondestructively. /// /// - Complexity: O(1), except if the sequence also conforms to `Collection`. /// In this case, see the documentation of `Collection.underestimatedCount`. @inlinable public var underestimatedCount: Int { return 0 } @inlinable @inline(__always) public func _customContainsEquatableElement( _ element: Iterator.Element ) -> Bool? { return nil } /// Calls the given closure on each element in the sequence in the same order /// as a `for`-`in` loop. /// /// The two loops in the following example produce the same output: /// /// let numberWords = ["one", "two", "three"] /// for word in numberWords { /// print(word) /// } /// // Prints "one" /// // Prints "two" /// // Prints "three" /// /// numberWords.forEach { word in /// print(word) /// } /// // Same as above /// /// Using the `forEach` method is distinct from a `for`-`in` loop in two /// important ways: /// /// 1. You cannot use a `break` or `continue` statement to exit the current /// call of the `body` closure or skip subsequent calls. /// 2. Using the `return` statement in the `body` closure will exit only from /// the current call to `body`, not from any outer scope, and won't skip /// subsequent calls. /// /// - Parameter body: A closure that takes an element of the sequence as a /// parameter. @_semantics("sequence.forEach") @inlinable public func forEach( _ body: (Element) throws -> Void ) rethrows { for element in self { try body(element) } } } extension Sequence { /// Returns the first element of the sequence that satisfies the given /// predicate. /// /// The following example uses the `first(where:)` method to find the first /// negative number in an array of integers: /// /// let numbers = [3, 7, 4, -2, 9, -6, 10, 1] /// if let firstNegative = numbers.first(where: { $0 < 0 }) { /// print("The first negative number is \(firstNegative).") /// } /// // Prints "The first negative number is -2." /// /// - Parameter predicate: A closure that takes an element of the sequence as /// its argument and returns a Boolean value indicating whether the /// element is a match. /// - Returns: The first element of the sequence that satisfies `predicate`, /// or `nil` if there is no element that satisfies `predicate`. /// /// - Complexity: O(*n*), where *n* is the length of the sequence. @inlinable public func first( where predicate: (Element) throws -> Bool ) rethrows -> Element? { for element in self { if try predicate(element) { return element } } return nil } } extension Sequence where Element: Equatable { /// Returns the longest possible subsequences of the sequence, in order, /// around elements equal to the given element. /// /// The resulting array consists of at most `maxSplits + 1` subsequences. /// Elements that are used to split the sequence are not returned as part of /// any subsequence. /// /// The following examples show the effects of the `maxSplits` and /// `omittingEmptySubsequences` parameters when splitting a string at each /// space character (" "). The first use of `split` returns each word that /// was originally separated by one or more spaces. /// /// let line = "BLANCHE: I don't want realism. I want magic!" /// print(line.split(separator: " ") /// .map(String.init)) /// // Prints "["BLANCHE:", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]" /// /// The second example passes `1` for the `maxSplits` parameter, so the /// original string is split just once, into two new strings. /// /// print(line.split(separator: " ", maxSplits: 1) /// .map(String.init)) /// // Prints "["BLANCHE:", " I don\'t want realism. I want magic!"]" /// /// The final example passes `false` for the `omittingEmptySubsequences` /// parameter, so the returned array contains empty strings where spaces /// were repeated. /// /// print(line.split(separator: " ", omittingEmptySubsequences: false) /// .map(String.init)) /// // Prints "["BLANCHE:", "", "", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]" /// /// - Parameters: /// - separator: The element that should be split upon. /// - maxSplits: The maximum number of times to split the sequence, or one /// less than the number of subsequences to return. If `maxSplits + 1` /// subsequences are returned, the last one is a suffix of the original /// sequence containing the remaining elements. `maxSplits` must be /// greater than or equal to zero. The default value is `Int.max`. /// - omittingEmptySubsequences: If `false`, an empty subsequence is /// returned in the result for each consecutive pair of `separator` /// elements in the sequence and for each instance of `separator` at the /// start or end of the sequence. If `true`, only nonempty subsequences /// are returned. The default value is `true`. /// - Returns: An array of subsequences, split from this sequence's elements. /// /// - Complexity: O(*n*), where *n* is the length of the sequence. @inlinable public __consuming func split( separator: Element, maxSplits: Int = Int.max, omittingEmptySubsequences: Bool = true ) -> [ArraySlice] { return split( maxSplits: maxSplits, omittingEmptySubsequences: omittingEmptySubsequences, whereSeparator: { $0 == separator }) } } extension Sequence { /// Returns the longest possible subsequences of the sequence, in order, that /// don't contain elements satisfying the given predicate. Elements that are /// used to split the sequence are not returned as part of any subsequence. /// /// The following examples show the effects of the `maxSplits` and /// `omittingEmptySubsequences` parameters when splitting a string using a /// closure that matches spaces. The first use of `split` returns each word /// that was originally separated by one or more spaces. /// /// let line = "BLANCHE: I don't want realism. I want magic!" /// print(line.split(whereSeparator: { $0 == " " }) /// .map(String.init)) /// // Prints "["BLANCHE:", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]" /// /// The second example passes `1` for the `maxSplits` parameter, so the /// original string is split just once, into two new strings. /// /// print( /// line.split(maxSplits: 1, whereSeparator: { $0 == " " }) /// .map(String.init)) /// // Prints "["BLANCHE:", " I don\'t want realism. I want magic!"]" /// /// The final example passes `true` for the `allowEmptySlices` parameter, so /// the returned array contains empty strings where spaces were repeated. /// /// print( /// line.split( /// omittingEmptySubsequences: false, /// whereSeparator: { $0 == " " } /// ).map(String.init)) /// // Prints "["BLANCHE:", "", "", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]" /// /// - Parameters: /// - maxSplits: The maximum number of times to split the sequence, or one /// less than the number of subsequences to return. If `maxSplits + 1` /// subsequences are returned, the last one is a suffix of the original /// sequence containing the remaining elements. `maxSplits` must be /// greater than or equal to zero. The default value is `Int.max`. /// - omittingEmptySubsequences: If `false`, an empty subsequence is /// returned in the result for each pair of consecutive elements /// satisfying the `isSeparator` predicate and for each element at the /// start or end of the sequence satisfying the `isSeparator` predicate. /// If `true`, only nonempty subsequences are returned. The default /// value is `true`. /// - isSeparator: A closure that returns `true` if its argument should be /// used to split the sequence; otherwise, `false`. /// - Returns: An array of subsequences, split from this sequence's elements. /// /// - Complexity: O(*n*), where *n* is the length of the sequence. @inlinable public __consuming func split( maxSplits: Int = Int.max, omittingEmptySubsequences: Bool = true, whereSeparator isSeparator: (Element) throws -> Bool ) rethrows -> [ArraySlice] { _precondition(maxSplits >= 0, "Must take zero or more splits") let whole = Array(self) return try whole.split( maxSplits: maxSplits, omittingEmptySubsequences: omittingEmptySubsequences, whereSeparator: isSeparator) } /// Returns a subsequence, up to the given maximum length, containing the /// final elements of the sequence. /// /// The sequence must be finite. If the maximum length exceeds the number of /// elements in the sequence, the result contains all the elements in the /// sequence. /// /// let numbers = [1, 2, 3, 4, 5] /// print(numbers.suffix(2)) /// // Prints "[4, 5]" /// print(numbers.suffix(10)) /// // Prints "[1, 2, 3, 4, 5]" /// /// - Parameter maxLength: The maximum number of elements to return. The /// value of `maxLength` must be greater than or equal to zero. /// /// - Complexity: O(*n*), where *n* is the length of the sequence. @inlinable public __consuming func suffix(_ maxLength: Int) -> [Element] { _precondition(maxLength >= 0, "Can't take a suffix of negative length from a sequence") guard maxLength != 0 else { return [] } // FIXME: Create reusable RingBuffer // Put incoming elements into a ring buffer to save space. Once all // elements are consumed, reorder the ring buffer into a copy and return it. // This saves memory for sequences particularly longer than `maxLength`. var ringBuffer = ContiguousArray() ringBuffer.reserveCapacity(Swift.min(maxLength, underestimatedCount)) var i = 0 for element in self { if ringBuffer.count < maxLength { ringBuffer.append(element) } else { ringBuffer[i] = element i = (i + 1) % maxLength } } if i != ringBuffer.startIndex { var rotated = ContiguousArray() rotated.reserveCapacity(ringBuffer.count) rotated += ringBuffer[i.. DropFirstSequence { return DropFirstSequence(self, dropping: k) } /// Returns a sequence containing all but the given number of final /// elements. /// /// The sequence must be finite. If the number of elements to drop exceeds /// the number of elements in the sequence, the result is an empty /// sequence. /// /// let numbers = [1, 2, 3, 4, 5] /// print(numbers.dropLast(2)) /// // Prints "[1, 2, 3]" /// print(numbers.dropLast(10)) /// // Prints "[]" /// /// - Parameter n: The number of elements to drop off the end of the /// sequence. `n` must be greater than or equal to zero. /// - Returns: A sequence leaving off the specified number of elements. /// /// - Complexity: O(*n*), where *n* is the length of the sequence. @inlinable public __consuming func dropLast(_ k: Int = 1) -> [Element] { _precondition(k >= 0, "Can't drop a negative number of elements from a sequence") guard k != 0 else { return Array(self) } // FIXME: Create reusable RingBuffer // Put incoming elements from this sequence in a holding tank, a ring buffer // of size <= k. If more elements keep coming in, pull them out of the // holding tank into the result, an `Array`. This saves // `k` * sizeof(Element) of memory, because slices keep the entire // memory of an `Array` alive. var result = ContiguousArray() var ringBuffer = ContiguousArray() var i = ringBuffer.startIndex for element in self { if ringBuffer.count < k { ringBuffer.append(element) } else { result.append(ringBuffer[i]) ringBuffer[i] = element i = (i + 1) % k } } return Array(result) } /// Returns a sequence by skipping the initial, consecutive elements that /// satisfy the given predicate. /// /// The following example uses the `drop(while:)` method to skip over the /// positive numbers at the beginning of the `numbers` array. The result /// begins with the first element of `numbers` that does not satisfy /// `predicate`. /// /// let numbers = [3, 7, 4, -2, 9, -6, 10, 1] /// let startingWithNegative = numbers.drop(while: { $0 > 0 }) /// // startingWithNegative == [-2, 9, -6, 10, 1] /// /// If `predicate` matches every element in the sequence, the result is an /// empty sequence. /// /// - Parameter predicate: A closure that takes an element of the sequence as /// its argument and returns a Boolean value indicating whether the /// element should be included in the result. /// - Returns: A sequence starting after the initial, consecutive elements /// that satisfy `predicate`. /// /// - Complexity: O(*k*), where *k* is the number of elements to drop from /// the beginning of the sequence. @inlinable public __consuming func drop( while predicate: (Element) throws -> Bool ) rethrows -> DropWhileSequence { return try DropWhileSequence(self, predicate: predicate) } /// Returns a sequence, up to the specified maximum length, containing the /// initial elements of the sequence. /// /// If the maximum length exceeds the number of elements in the sequence, /// the result contains all the elements in the sequence. /// /// let numbers = [1, 2, 3, 4, 5] /// print(numbers.prefix(2)) /// // Prints "[1, 2]" /// print(numbers.prefix(10)) /// // Prints "[1, 2, 3, 4, 5]" /// /// - Parameter maxLength: The maximum number of elements to return. The /// value of `maxLength` must be greater than or equal to zero. /// - Returns: A sequence starting at the beginning of this sequence /// with at most `maxLength` elements. /// /// - Complexity: O(1) @inlinable public __consuming func prefix(_ maxLength: Int) -> PrefixSequence { return PrefixSequence(self, maxLength: maxLength) } /// Returns a sequence containing the initial, consecutive elements that /// satisfy the given predicate. /// /// The following example uses the `prefix(while:)` method to find the /// positive numbers at the beginning of the `numbers` array. Every element /// of `numbers` up to, but not including, the first negative value is /// included in the result. /// /// let numbers = [3, 7, 4, -2, 9, -6, 10, 1] /// let positivePrefix = numbers.prefix(while: { $0 > 0 }) /// // positivePrefix == [3, 7, 4] /// /// If `predicate` matches every element in the sequence, the resulting /// sequence contains every element of the sequence. /// /// - Parameter predicate: A closure that takes an element of the sequence as /// its argument and returns a Boolean value indicating whether the /// element should be included in the result. /// - Returns: A sequence of the initial, consecutive elements that /// satisfy `predicate`. /// /// - Complexity: O(*k*), where *k* is the length of the result. @inlinable public __consuming func prefix( while predicate: (Element) throws -> Bool ) rethrows -> [Element] { var result = ContiguousArray() for element in self { guard try predicate(element) else { break } result.append(element) } return Array(result) } } extension Sequence { /// Copy `self` into an unsafe buffer, initializing its memory. /// /// The default implementation simply iterates over the elements of the /// sequence, initializing the buffer one item at a time. /// /// For sequences whose elements are stored in contiguous chunks of memory, /// it may be more efficient to copy them in bulk, using the /// `UnsafeMutablePointer.initialize(from:count:)` method. /// /// - Parameter ptr: An unsafe buffer addressing uninitialized memory. The /// buffer must be of sufficient size to accommodate /// `source.underestimatedCount` elements. (Some implementations trap /// if given a buffer that's smaller than this.) /// /// - Returns: `(it, c)`, where `c` is the number of elements copied into the /// buffer, and `it` is a partially consumed iterator that can be used to /// retrieve elements that did not fit into the buffer (if any). (This can /// only happen if `underestimatedCount` turned out to be an actual /// underestimate, and the buffer did not contain enough space to hold the /// entire sequence.) /// /// On return, the memory region in `buffer[0 ..< c]` is initialized to /// the first `c` elements in the sequence. @inlinable public __consuming func _copyContents( initializing buffer: UnsafeMutableBufferPointer ) -> (Iterator,UnsafeMutableBufferPointer.Index) { return _copySequenceContents(initializing: buffer) } @_alwaysEmitIntoClient internal __consuming func _copySequenceContents( initializing buffer: UnsafeMutableBufferPointer ) -> (Iterator,UnsafeMutableBufferPointer.Index) { var it = self.makeIterator() guard var ptr = buffer.baseAddress else { return (it,buffer.startIndex) } for idx in buffer.startIndex..( _ body: (UnsafeBufferPointer) throws -> R ) rethrows -> R? { return nil } } // FIXME(ABI)#182 // Pending and , // pass an IteratorProtocol through IteratorSequence to give it "Sequence-ness" /// A sequence built around an iterator of type `Base`. /// /// Useful mostly to recover the ability to use `for`...`in`, /// given just an iterator `i`: /// /// for x in IteratorSequence(i) { ... } @frozen public struct IteratorSequence { @usableFromInline internal var _base: Base /// Creates an instance whose iterator is a copy of `base`. @inlinable public init(_ base: Base) { _base = base } } extension IteratorSequence: IteratorProtocol, Sequence { /// Advances to the next element and returns it, or `nil` if no next element /// exists. /// /// Once `nil` has been returned, all subsequent calls return `nil`. /// /// - Precondition: `next()` has not been applied to a copy of `self` /// since the copy was made. @inlinable public mutating func next() -> Base.Element? { return _base.next() } } extension IteratorSequence: Sendable where Base: Sendable { } /* FIXME: ideally for compatibility we would declare extension Sequence { @available(swift, deprecated: 5, message: "") public typealias SubSequence = AnySequence } */