Permalink
Switch branches/tags
type-name-lookup-fail swift-DEVELOPMENT-SNAPSHOT-2018-08-18-a swift-DEVELOPMENT-SNAPSHOT-2018-08-16-a swift-DEVELOPMENT-SNAPSHOT-2018-08-15-a swift-DEVELOPMENT-SNAPSHOT-2018-08-14-a swift-DEVELOPMENT-SNAPSHOT-2018-08-10-a swift-DEVELOPMENT-SNAPSHOT-2018-08-09-a swift-DEVELOPMENT-SNAPSHOT-2018-08-06-a swift-DEVELOPMENT-SNAPSHOT-2018-08-02-a swift-DEVELOPMENT-SNAPSHOT-2018-08-01-a swift-DEVELOPMENT-SNAPSHOT-2018-07-31-a swift-DEVELOPMENT-SNAPSHOT-2018-07-30-a swift-DEVELOPMENT-SNAPSHOT-2018-07-28-a swift-DEVELOPMENT-SNAPSHOT-2018-07-27-a swift-DEVELOPMENT-SNAPSHOT-2018-07-24-a swift-DEVELOPMENT-SNAPSHOT-2018-07-23-a swift-DEVELOPMENT-SNAPSHOT-2018-07-22-a swift-DEVELOPMENT-SNAPSHOT-2018-07-21-a swift-DEVELOPMENT-SNAPSHOT-2018-07-20-a swift-DEVELOPMENT-SNAPSHOT-2018-07-19-a swift-DEVELOPMENT-SNAPSHOT-2018-07-18-a swift-DEVELOPMENT-SNAPSHOT-2018-07-17-a swift-DEVELOPMENT-SNAPSHOT-2018-07-16-a swift-DEVELOPMENT-SNAPSHOT-2018-07-14-a swift-DEVELOPMENT-SNAPSHOT-2018-07-13-a swift-DEVELOPMENT-SNAPSHOT-2018-07-12-a swift-DEVELOPMENT-SNAPSHOT-2018-07-11-a swift-DEVELOPMENT-SNAPSHOT-2018-07-09-a swift-DEVELOPMENT-SNAPSHOT-2018-07-07-a swift-DEVELOPMENT-SNAPSHOT-2018-07-06-a swift-DEVELOPMENT-SNAPSHOT-2018-07-05-a swift-DEVELOPMENT-SNAPSHOT-2018-07-04-a swift-DEVELOPMENT-SNAPSHOT-2018-07-03-a swift-DEVELOPMENT-SNAPSHOT-2018-07-02-a swift-DEVELOPMENT-SNAPSHOT-2018-07-01-a swift-DEVELOPMENT-SNAPSHOT-2018-06-30-a swift-DEVELOPMENT-SNAPSHOT-2018-06-29-a swift-DEVELOPMENT-SNAPSHOT-2018-06-27-a swift-DEVELOPMENT-SNAPSHOT-2018-06-26-a swift-DEVELOPMENT-SNAPSHOT-2018-06-25-a swift-DEVELOPMENT-SNAPSHOT-2018-06-24-a swift-DEVELOPMENT-SNAPSHOT-2018-06-23-a swift-DEVELOPMENT-SNAPSHOT-2018-06-22-a swift-DEVELOPMENT-SNAPSHOT-2018-06-21-a swift-DEVELOPMENT-SNAPSHOT-2018-06-20-a swift-DEVELOPMENT-SNAPSHOT-2018-06-19-a swift-DEVELOPMENT-SNAPSHOT-2018-06-18-a swift-DEVELOPMENT-SNAPSHOT-2018-06-17-a swift-DEVELOPMENT-SNAPSHOT-2018-06-16-a swift-DEVELOPMENT-SNAPSHOT-2018-06-15-a swift-DEVELOPMENT-SNAPSHOT-2018-06-14-a swift-DEVELOPMENT-SNAPSHOT-2018-06-08-a swift-DEVELOPMENT-SNAPSHOT-2018-06-07-a swift-DEVELOPMENT-SNAPSHOT-2018-06-06-a swift-DEVELOPMENT-SNAPSHOT-2018-06-05-a swift-DEVELOPMENT-SNAPSHOT-2018-06-04-a swift-DEVELOPMENT-SNAPSHOT-2018-06-03-a swift-DEVELOPMENT-SNAPSHOT-2018-06-02-a swift-DEVELOPMENT-SNAPSHOT-2018-06-01-a swift-DEVELOPMENT-SNAPSHOT-2018-05-31-a swift-DEVELOPMENT-SNAPSHOT-2018-05-30-a swift-DEVELOPMENT-SNAPSHOT-2018-05-29-a swift-DEVELOPMENT-SNAPSHOT-2018-05-28-a swift-DEVELOPMENT-SNAPSHOT-2018-05-27-a swift-DEVELOPMENT-SNAPSHOT-2018-05-26-a swift-DEVELOPMENT-SNAPSHOT-2018-05-25-a swift-DEVELOPMENT-SNAPSHOT-2018-05-24-a swift-DEVELOPMENT-SNAPSHOT-2018-05-23-a swift-DEVELOPMENT-SNAPSHOT-2018-05-22-a swift-DEVELOPMENT-SNAPSHOT-2018-05-21-a swift-DEVELOPMENT-SNAPSHOT-2018-05-20-a swift-DEVELOPMENT-SNAPSHOT-2018-05-19-a swift-DEVELOPMENT-SNAPSHOT-2018-05-18-a swift-DEVELOPMENT-SNAPSHOT-2018-05-17-a swift-DEVELOPMENT-SNAPSHOT-2018-05-14-a swift-DEVELOPMENT-SNAPSHOT-2018-05-13-a swift-DEVELOPMENT-SNAPSHOT-2018-05-11-a swift-DEVELOPMENT-SNAPSHOT-2018-05-10-a swift-DEVELOPMENT-SNAPSHOT-2018-05-08-a swift-DEVELOPMENT-SNAPSHOT-2018-04-25-a swift-DEVELOPMENT-SNAPSHOT-2018-04-24-a swift-DEVELOPMENT-SNAPSHOT-2018-04-23-a swift-DEVELOPMENT-SNAPSHOT-2018-04-22-a swift-DEVELOPMENT-SNAPSHOT-2018-04-21-a swift-DEVELOPMENT-SNAPSHOT-2018-04-20-a swift-DEVELOPMENT-SNAPSHOT-2018-04-19-a swift-DEVELOPMENT-SNAPSHOT-2018-04-18-a swift-DEVELOPMENT-SNAPSHOT-2018-04-17-a swift-DEVELOPMENT-SNAPSHOT-2018-04-16-a swift-DEVELOPMENT-SNAPSHOT-2018-04-15-a swift-DEVELOPMENT-SNAPSHOT-2018-04-13-a swift-DEVELOPMENT-SNAPSHOT-2018-04-12-a swift-DEVELOPMENT-SNAPSHOT-2018-04-11-a swift-DEVELOPMENT-SNAPSHOT-2018-04-10-a swift-DEVELOPMENT-SNAPSHOT-2018-04-09-a swift-DEVELOPMENT-SNAPSHOT-2018-04-08-a swift-DEVELOPMENT-SNAPSHOT-2018-04-07-a swift-DEVELOPMENT-SNAPSHOT-2018-04-06-a swift-DEVELOPMENT-SNAPSHOT-2018-04-05-a swift-DEVELOPMENT-SNAPSHOT-2018-04-04-a
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
1476 lines (1391 sloc) 53.5 KB
//===----------------------------------------------------------------------===//
//
// 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 "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<Element>
where Element == SubSequence.Element,
SubSequence.SubSequence == SubSequence
/// 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 }
/// 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.
func map<T>(
_ transform: (Element) throws -> T
) rethrows -> [T]
/// Returns an array containing, in order, the elements of the sequence
/// that satisfy the given predicate.
///
/// In this example, `filter(_:)` is used to include only names shorter than
/// five characters.
///
/// let cast = ["Vivien", "Marlon", "Kim", "Karl"]
/// let shortNames = cast.filter { $0.count < 5 }
/// print(shortNames)
/// // Prints "["Kim", "Karl"]"
///
/// - Parameter isIncluded: 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 returned array.
/// - Returns: An array of the elements that `isIncluded` allowed.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
__consuming func filter(
_ isIncluded: (Element) throws -> Bool
) rethrows -> [Element]
/// 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.
func forEach(_ body: (Element) throws -> Void) rethrows
// Note: The complexity of Sequence.dropFirst(_:) requirement
// is documented as O(n) because Collection.dropFirst(_:) is
// implemented in O(n), even though the default
// implementation for Sequence.dropFirst(_:) is O(1).
/// Returns a subsequence containing all but the given number of initial
/// elements.
///
/// If the number of elements to drop exceeds the number of elements in
/// the sequence, the result is an empty subsequence.
///
/// let numbers = [1, 2, 3, 4, 5]
/// print(numbers.dropFirst(2))
/// // Prints "[3, 4, 5]"
/// print(numbers.dropFirst(10))
/// // Prints "[]"
///
/// - Parameter k: The number of elements to drop from the beginning of
/// the sequence. `k` must be greater than or equal to zero.
/// - Returns: A subsequence starting after the specified number of
/// elements.
///
/// - Complexity: O(*k*), where *k* is the number of elements to drop from
/// the beginning of the sequence.
__consuming func dropFirst(_ k: Int) -> SubSequence
/// Returns a subsequence containing all but the specified 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
/// subsequence.
///
/// let numbers = [1, 2, 3, 4, 5]
/// print(numbers.dropLast(2))
/// // Prints "[1, 2, 3]"
/// print(numbers.dropLast(10))
/// // Prints "[]"
///
/// - Parameter k: The number of elements to drop off the end of the
/// sequence. `k` must be greater than or equal to zero.
/// - Returns: A subsequence leaving off the specified number of elements.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
__consuming func dropLast(_ k: Int) -> SubSequence
/// Returns a subsequence by skipping elements while `predicate` returns
/// `true` and returning the remaining elements.
///
/// - 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.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
__consuming func drop(
while predicate: (Element) throws -> Bool
) rethrows -> SubSequence
/// Returns a subsequence, 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.
/// `maxLength` must be greater than or equal to zero.
/// - Returns: A subsequence starting at the beginning of this sequence
/// with at most `maxLength` elements.
///
/// - Complexity: O(*k*), where *k* is the number of elements to select from
/// the beginning of the sequence.
__consuming func prefix(_ maxLength: Int) -> SubSequence
/// Returns a subsequence 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 subsequence of the initial, consecutive elements that
/// satisfy `predicate`.
///
/// - Complexity: O(*k*), where *k* is the length of the result.
__consuming func prefix(
while predicate: (Element) throws -> Bool
) rethrows -> SubSequence
/// 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.
/// - Returns: A subsequence terminating at the end of this sequence with
/// at most `maxLength` elements.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
__consuming func suffix(_ maxLength: Int) -> SubSequence
/// Returns the longest possible subsequences of the sequence, in order, that
/// don't contain elements satisfying the given predicate.
///
/// 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 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 `false` for the `omittingEmptySubsequences`
/// 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.
__consuming func split(
maxSplits: Int, omittingEmptySubsequences: Bool,
whereSeparator isSeparator: (Element) throws -> Bool
) rethrows -> [SubSequence]
func _customContainsEquatableElement(
_ element: Element
) -> Bool?
/// If `self` is multi-pass (i.e., a `Collection`), invoke `preprocess` and
/// return its result. Otherwise, return `nil`.
func _preprocessingPass<R>(
_ preprocess: () throws -> R
) rethrows -> R?
/// Create a native array buffer containing the elements of `self`,
/// in the same order.
__consuming func _copyToContiguousArray() -> ContiguousArray<Element>
/// Copy `self` into an unsafe buffer, returning a partially-consumed
/// iterator with any elements that didn't fit remaining.
__consuming func _copyContents(
initializing ptr: UnsafeMutableBufferPointer<Element>
) -> (Iterator,UnsafeMutableBufferPointer<Element>.Index)
}
// 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 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.
@usableFromInline
@_fixed_layout
internal struct _DropFirstSequence<Base : IteratorProtocol>
: Sequence, IteratorProtocol {
@usableFromInline
internal var _iterator: Base
@usableFromInline
internal let _limit: Int
@usableFromInline
internal var _dropped: Int
@inlinable
internal init(_iterator: Base, limit: Int, dropped: Int = 0) {
self._iterator = _iterator
self._limit = limit
self._dropped = dropped
}
@inlinable
internal func makeIterator() -> _DropFirstSequence<Base> {
return self
}
@inlinable
internal mutating func next() -> Base.Element? {
while _dropped < _limit {
if _iterator.next() == nil {
_dropped = _limit
return nil
}
_dropped += 1
}
return _iterator.next()
}
@inlinable
internal func dropFirst(_ k: Int) -> AnySequence<Base.Element> {
// 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 AnySequence(
_DropFirstSequence(
_iterator: _iterator, limit: _limit + k, dropped: _dropped))
}
}
/// A sequence that only consumes up to `n` elements from an underlying
/// `Base` iterator.
///
/// The underlying iterator's sequence may be infinite.
@_fixed_layout
@usableFromInline
internal struct _PrefixSequence<Base : IteratorProtocol>
: Sequence, IteratorProtocol {
@usableFromInline
internal let _maxLength: Int
@usableFromInline
internal var _iterator: Base
@usableFromInline
internal var _taken: Int
@inlinable
internal init(_iterator: Base, maxLength: Int, taken: Int = 0) {
self._iterator = _iterator
self._maxLength = maxLength
self._taken = taken
}
@inlinable
internal func makeIterator() -> _PrefixSequence<Base> {
return self
}
@inlinable
internal mutating func next() -> Base.Element? {
if _taken >= _maxLength { return nil }
_taken += 1
if let next = _iterator.next() {
return next
}
_taken = _maxLength
return nil
}
@inlinable
internal func prefix(_ maxLength: Int) -> AnySequence<Base.Element> {
return AnySequence(
_PrefixSequence(
_iterator: _iterator,
maxLength: Swift.min(maxLength, self._maxLength),
taken: _taken))
}
}
/// 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.
@_fixed_layout
@usableFromInline
internal struct _DropWhileSequence<Base : IteratorProtocol>
: Sequence, IteratorProtocol {
@usableFromInline
typealias Element = Base.Element
@usableFromInline
internal var _iterator: Base
@usableFromInline
internal var _nextElement: Base.Element?
@inlinable
internal init(
iterator: Base,
nextElement: Base.Element?,
predicate: (Base.Element) throws -> Bool
) rethrows {
self._iterator = iterator
self._nextElement = nextElement ?? _iterator.next()
while try _nextElement.flatMap(predicate) == true {
_nextElement = _iterator.next()
}
}
@inlinable
internal func makeIterator() -> _DropWhileSequence<Base> {
return self
}
@inlinable
internal mutating func next() -> Element? {
guard _nextElement != nil else {
return _iterator.next()
}
let next = _nextElement
_nextElement = nil
return next
}
@inlinable
internal func drop(
while predicate: (Element) throws -> Bool
) rethrows -> AnySequence<Element> {
// If this is already a _DropWhileSequence, avoid multiple
// layers of wrapping and keep the same iterator.
return try AnySequence(
_DropWhileSequence(
iterator: _iterator, nextElement: _nextElement, 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<T>(
_ transform: (Element) throws -> T
) rethrows -> [T] {
let initialCapacity = underestimatedCount
var result = ContiguousArray<T>()
result.reserveCapacity(initialCapacity)
var iterator = self.makeIterator()
// Add elements up to the initial capacity without checking for regrowth.
for _ in 0..<initialCapacity {
result.append(try transform(iterator.next()!))
}
// Add remaining elements, if any.
while let element = iterator.next() {
result.append(try transform(element))
}
return Array(result)
}
/// Returns an array containing, in order, the elements of the sequence
/// that satisfy the given predicate.
///
/// In this example, `filter(_:)` is used to include only names shorter than
/// five characters.
///
/// let cast = ["Vivien", "Marlon", "Kim", "Karl"]
/// let shortNames = cast.filter { $0.count < 5 }
/// print(shortNames)
/// // Prints "["Kim", "Karl"]"
///
/// - Parameter isIncluded: 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 returned array.
/// - Returns: An array of the elements that `isIncluded` allowed.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable
public func filter(
_ isIncluded: (Element) throws -> Bool
) rethrows -> [Element] {
return try _filter(isIncluded)
}
@_transparent
public func _filter(
_ isIncluded: (Element) throws -> Bool
) rethrows -> [Element] {
var result = ContiguousArray<Element>()
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
public func _preprocessingPass<R>(
_ preprocess: () throws -> R
) rethrows -> R? {
return nil
}
@inlinable
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.
@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 func split(
separator: Element,
maxSplits: Int = Int.max,
omittingEmptySubsequences: Bool = true
) -> [SubSequence] {
return split(
maxSplits: maxSplits,
omittingEmptySubsequences: omittingEmptySubsequences,
whereSeparator: { $0 == separator })
}
}
extension Sequence where SubSequence == AnySequence<Element> {
/// 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 func split(
maxSplits: Int = Int.max,
omittingEmptySubsequences: Bool = true,
whereSeparator isSeparator: (Element) throws -> Bool
) rethrows -> [AnySequence<Element>] {
_precondition(maxSplits >= 0, "Must take zero or more splits")
var result: [AnySequence<Element>] = []
var subSequence: [Element] = []
@discardableResult
func appendSubsequence() -> Bool {
if subSequence.isEmpty && omittingEmptySubsequences {
return false
}
result.append(AnySequence(subSequence))
subSequence = []
return true
}
if maxSplits == 0 {
// We aren't really splitting the sequence. Convert `self` into an
// `Array` using a fast entry point.
subSequence = Array(self)
appendSubsequence()
return result
}
var iterator = self.makeIterator()
while let element = iterator.next() {
if try isSeparator(element) {
if !appendSubsequence() {
continue
}
if result.count == maxSplits {
break
}
} else {
subSequence.append(element)
}
}
while let element = iterator.next() {
subSequence.append(element)
}
appendSubsequence()
return result
}
/// 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 func suffix(_ maxLength: Int) -> AnySequence<Element> {
_precondition(maxLength >= 0, "Can't take a suffix of negative length from a sequence")
if maxLength == 0 { return AnySequence([]) }
// FIXME: <rdar://problem/21885650> Create reusable RingBuffer<T>
// Put incoming elements into a ring buffer to save space. Once all
// elements are consumed, reorder the ring buffer into an `Array`
// and return it. This saves memory for sequences particularly longer
// than `maxLength`.
var ringBuffer: [Element] = []
ringBuffer.reserveCapacity(Swift.min(maxLength, underestimatedCount))
var i = ringBuffer.startIndex
for element in self {
if ringBuffer.count < maxLength {
ringBuffer.append(element)
} else {
ringBuffer[i] = element
i += 1
i %= maxLength
}
}
if i != ringBuffer.startIndex {
let s0 = ringBuffer[i..<ringBuffer.endIndex]
let s1 = ringBuffer[0..<i]
return AnySequence([s0, s1].joined())
}
return AnySequence(ringBuffer)
}
/// Returns a subsequence containing all but the given number of initial
/// elements.
///
/// If the number of elements to drop exceeds the number of elements in
/// the sequence, the result is an empty subsequence.
///
/// let numbers = [1, 2, 3, 4, 5]
/// print(numbers.dropFirst(2))
/// // Prints "[3, 4, 5]"
/// print(numbers.dropFirst(10))
/// // Prints "[]"
///
/// - Parameter k: The number of elements to drop from the beginning of
/// the sequence. `k` must be greater than or equal to zero.
/// - Returns: A subsequence starting after the specified number of
/// elements.
///
/// - Complexity: O(1), with O(*k*) deferred to each iteration of the result,
/// where *k* is the number of elements to drop from the beginning of
/// the sequence.
@inlinable
public func dropFirst(_ k: Int) -> AnySequence<Element> {
_precondition(k >= 0, "Can't drop a negative number of elements from a sequence")
if k == 0 { return AnySequence(self) }
return AnySequence(_DropFirstSequence(_iterator: makeIterator(), limit: k))
}
/// Returns a subsequence 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
/// subsequence.
///
/// 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 subsequence leaving off the specified number of elements.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable
public func dropLast(_ k: Int) -> AnySequence<Element> {
_precondition(k >= 0, "Can't drop a negative number of elements from a sequence")
if k == 0 { return AnySequence(self) }
// FIXME: <rdar://problem/21885650> Create reusable RingBuffer<T>
// 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: [Element] = []
var ringBuffer: [Element] = []
var i = ringBuffer.startIndex
for element in self {
if ringBuffer.count < k {
ringBuffer.append(element)
} else {
result.append(ringBuffer[i])
ringBuffer[i] = element
i = ringBuffer.index(after: i) % k
}
}
return AnySequence(result)
}
/// Returns a subsequence 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 subsequence 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 func drop(
while predicate: (Element) throws -> Bool
) rethrows -> AnySequence<Element> {
return try AnySequence(
_DropWhileSequence(
iterator: makeIterator(), nextElement: nil, predicate: predicate))
}
/// Returns a subsequence, 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 subsequence starting at the beginning of this sequence
/// with at most `maxLength` elements.
///
/// - Complexity: O(1)
@inlinable
public func prefix(_ maxLength: Int) -> AnySequence<Element> {
_precondition(maxLength >= 0, "Can't take a prefix of negative length from a sequence")
if maxLength == 0 {
return AnySequence(EmptyCollection<Element>())
}
return AnySequence(
_PrefixSequence(_iterator: makeIterator(), maxLength: maxLength))
}
/// Returns a subsequence 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 subsequence of the initial, consecutive elements that
/// satisfy `predicate`.
///
/// - Complexity: O(*k*), where *k* is the length of the result.
@inlinable
public func prefix(
while predicate: (Element) throws -> Bool
) rethrows -> AnySequence<Element> {
var result: [Element] = []
for element in self {
guard try predicate(element) else {
break
}
result.append(element)
}
return AnySequence(result)
}
}
extension Sequence {
/// Returns a subsequence containing all but the first element of the
/// sequence.
///
/// The following example drops the first element from an array of integers.
///
/// let numbers = [1, 2, 3, 4, 5]
/// print(numbers.dropFirst())
/// // Prints "[2, 3, 4, 5]"
///
/// If the sequence has no elements, the result is an empty subsequence.
///
/// let empty: [Int] = []
/// print(empty.dropFirst())
/// // Prints "[]"
///
/// - Returns: A subsequence starting after the first element of the
/// sequence.
///
/// - Complexity: O(1)
@inlinable
public func dropFirst() -> SubSequence { return dropFirst(1) }
/// Returns a subsequence containing all but the last element of the
/// sequence.
///
/// The sequence must be finite.
///
/// let numbers = [1, 2, 3, 4, 5]
/// print(numbers.dropLast())
/// // Prints "[1, 2, 3, 4]"
///
/// If the sequence has no elements, the result is an empty subsequence.
///
/// let empty: [Int] = []
/// print(empty.dropLast())
/// // Prints "[]"
///
/// - Returns: A subsequence leaving off the last element of the sequence.
///
/// - Complexity: O(*n*), where *n* is the length of the sequence.
@inlinable
public func dropLast() -> SubSequence { return dropLast(1) }
}
extension Sequence {
/// Copies `self` into the supplied buffer.
///
/// - Precondition: The memory in `self` is uninitialized. The buffer must
/// contain sufficient uninitialized memory to accommodate `source.underestimatedCount`.
///
/// - Postcondition: The `Pointee`s at `buffer[startIndex..<returned index]` are
/// initialized.
@inlinable
public func _copyContents(
initializing buffer: UnsafeMutableBufferPointer<Element>
) -> (Iterator,UnsafeMutableBufferPointer<Element>.Index) {
var it = self.makeIterator()
guard var ptr = buffer.baseAddress else { return (it,buffer.startIndex) }
for idx in buffer.startIndex..<buffer.count {
guard let x = it.next() else {
return (it, idx)
}
ptr.initialize(to: x)
ptr += 1
}
return (it,buffer.endIndex)
}
}
// FIXME(ABI)#182
// Pending <rdar://problem/14011860> and <rdar://problem/14396120>,
// 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) { ... }
@_fixed_layout
public struct IteratorSequence<Base : IteratorProtocol> {
@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()
}
}