-
-
Save muukii/c14f2cf93083768a51745c684716a378 to your computer and use it in GitHub Desktop.
Concurrency module interface
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Common protocol to which all actors conform. | |
/// | |
/// The \c Actor protocol generalizes over all actor types. Actor types | |
/// implicitly conform to this protocol. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public protocol Actor : AnyObject, Sendable { | |
} | |
/// An asynchronous sequence that maps a given closure over the asynchronous | |
/// sequence’s elements, omitting results that don't return a value. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct AsyncCompactMapSequence<Base, ElementOfResult> where Base : AsyncSequence { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncCompactMapSequence : AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
/// | |
/// The compact map sequence produces whatever type of element its | |
/// transforming closure produces. | |
public typealias Element = ElementOfResult | |
/// The type of iterator that produces elements of the sequence. | |
public typealias AsyncIterator = AsyncCompactMapSequence<Base, ElementOfResult>.Iterator | |
/// The iterator that produces elements of the compact map sequence. | |
public struct Iterator : AsyncIteratorProtocol { | |
public typealias Element = ElementOfResult | |
/// Produces the next element in the compact map sequence. | |
/// | |
/// This iterator calls `next()` on its base iterator; if this call returns | |
/// `nil`, `next()` returns `nil`. Otherwise, `next()` calls the | |
/// transforming closure on the received element, returning it if the | |
/// transform returns a non-`nil` value. If the transform returns `nil`, | |
/// this method continues to wait for further elements until it gets one | |
/// that transforms to a non-`nil` value. | |
@inlinable public mutating func next() async rethrows -> ElementOfResult? | |
} | |
@inlinable public func makeAsyncIterator() -> AsyncCompactMapSequence<Base, ElementOfResult>.Iterator | |
} | |
/// An asynchronous sequence which omits a specified number of elements from the | |
/// base asynchronous sequence, then passes through all remaining elements. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct AsyncDropFirstSequence<Base> where Base : AsyncSequence { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncDropFirstSequence : AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
/// | |
/// The drop-first sequence produces whatever type of element its base | |
/// iterator produces. | |
public typealias Element = Base.Element | |
/// The type of iterator that produces elements of the sequence. | |
public typealias AsyncIterator = AsyncDropFirstSequence<Base>.Iterator | |
/// The iterator that produces elements of the drop-first sequence. | |
public struct Iterator : AsyncIteratorProtocol { | |
/// Produces the next element in the drop-first sequence. | |
/// | |
/// Until reaching the number of elements to drop, this iterator calls | |
/// `next()` on its base iterator and discards the result. If the base | |
/// iterator returns `nil`, indicating the end of the sequence, this | |
/// iterator returns `nil`. After reaching the number of elements to | |
/// drop, this iterator passes along the result of calling `next()` on | |
/// the base iterator. | |
@inlinable public mutating func next() async rethrows -> Base.Element? | |
public typealias Element = Base.Element | |
} | |
@inlinable public func makeAsyncIterator() -> AsyncDropFirstSequence<Base>.Iterator | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncDropFirstSequence { | |
/// Omits a specified number of elements from the base asynchronous sequence, | |
/// then passes through all remaining elements. | |
/// | |
/// When you call `dropFirst(_:)` on an asynchronous sequence that is already | |
/// an `AsyncDropFirstSequence`, the returned sequence simply adds the new | |
/// drop count to the current drop count. | |
@inlinable public func dropFirst(_ count: Int = 1) -> AsyncDropFirstSequence<Base> | |
} | |
/// An asynchronous sequence which omits elements from the base sequence until a | |
/// given closure returns false, after which it passes through all remaining | |
/// elements. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct AsyncDropWhileSequence<Base> where Base : AsyncSequence { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncDropWhileSequence : AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
/// | |
/// The drop-while sequence produces whatever type of element its base | |
/// sequence produces. | |
public typealias Element = Base.Element | |
/// The type of iterator that produces elements of the sequence. | |
public typealias AsyncIterator = AsyncDropWhileSequence<Base>.Iterator | |
/// The iterator that produces elements of the drop-while sequence. | |
public struct Iterator : AsyncIteratorProtocol { | |
/// Produces the next element in the drop-while sequence. | |
/// | |
/// This iterator calls `next()` on its base iterator and evaluates the | |
/// result with the `predicate` closure. As long as the predicate returns | |
/// `true`, this method returns `nil`. After the predicate returns `false`, | |
/// for a value received from the base iterator, this method returns that | |
/// value. After that, the iterator returns values received from its | |
/// base iterator as-is, and never executes the predicate closure again. | |
@inlinable public mutating func next() async rethrows -> Base.Element? | |
public typealias Element = Base.Element | |
} | |
/// Creates an instance of the drop-while sequence iterator. | |
@inlinable public func makeAsyncIterator() -> AsyncDropWhileSequence<Base>.Iterator | |
} | |
/// An asynchronous sequence that contains, in order, the elements of | |
/// the base sequence that satisfy a given predicate. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct AsyncFilterSequence<Base> where Base : AsyncSequence { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncFilterSequence : AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
/// | |
/// The filter sequence produces whatever type of element its base | |
/// sequence produces. | |
public typealias Element = Base.Element | |
/// The type of iterator that produces elements of the sequence. | |
public typealias AsyncIterator = AsyncFilterSequence<Base>.Iterator | |
/// The iterator that produces elements of the filter sequence. | |
public struct Iterator : AsyncIteratorProtocol { | |
/// Produces the next element in the filter sequence. | |
/// | |
/// This iterator calls `next()` on its base iterator; if this call returns | |
/// `nil`, `next()` returns nil. Otherwise, `next()` evaluates the | |
/// result with the `predicate` closure. If the closure returns `true`, | |
/// `next()` returns the received element; otherwise it awaits the next | |
/// element from the base iterator. | |
@inlinable public mutating func next() async rethrows -> Base.Element? | |
public typealias Element = Base.Element | |
} | |
@inlinable public func makeAsyncIterator() -> AsyncFilterSequence<Base>.Iterator | |
} | |
/// An asynchronous sequence that concatenates the results of calling a given | |
/// transformation with each element of this sequence. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct AsyncFlatMapSequence<Base, SegmentOfResult> where Base : AsyncSequence, SegmentOfResult : AsyncSequence { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncFlatMapSequence : AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
/// | |
/// The flat map sequence produces the type of element in the asynchronous | |
/// sequence produced by the `transform` closure. | |
public typealias Element = SegmentOfResult.Element | |
/// The type of iterator that produces elements of the sequence. | |
public typealias AsyncIterator = AsyncFlatMapSequence<Base, SegmentOfResult>.Iterator | |
/// The iterator that produces elements of the flat map sequence. | |
public struct Iterator : AsyncIteratorProtocol { | |
/// Produces the next element in the flat map sequence. | |
/// | |
/// This iterator calls `next()` on its base iterator; if this call returns | |
/// `nil`, `next()` returns `nil`. Otherwise, `next()` calls the | |
/// transforming closure on the received element, takes the resulting | |
/// asynchronous sequence, and creates an asynchronous iterator from it. | |
/// `next()` then consumes values from this iterator until it terminates. | |
/// At this point, `next()` is ready to receive the next value from the base | |
/// sequence. | |
@inlinable public mutating func next() async rethrows -> SegmentOfResult.Element? | |
public typealias Element = SegmentOfResult.Element | |
} | |
@inlinable public func makeAsyncIterator() -> AsyncFlatMapSequence<Base, SegmentOfResult>.Iterator | |
} | |
/// A type that that asychronously supplies the values of a sequence one at a | |
/// time. | |
/// | |
/// The `AsyncIteratorProtocol` defines the type returned by the | |
/// `makeAsyncIterator()` method of the `AsyncSequence` protocol. In short, | |
/// the iterator is what produces the asynchronous sequence's values. The | |
/// protocol defines a single asynchronous method, `next()`, which either | |
/// produces the next element of the sequence, or returns `nil` to signal | |
/// the end of the sequence. | |
/// | |
/// To implement your own `AsyncSequence`, implement a wrapped type that | |
/// conforms to `AsyncIteratorProtocol`. The following example shows a `Counter` | |
/// type that uses an inner iterator to monotonically generate `Int` values | |
/// until reaching a `howHigh` value. While this example isn't itself | |
/// asychronous, it shows the shape of a custom sequence and iterator, and how | |
/// to use it as if it were asynchronous: | |
/// | |
/// struct Counter : AsyncSequence { | |
/// typealias Element = Int | |
/// let howHigh: Int | |
/// | |
/// struct AsyncIterator : AsyncIteratorProtocol { | |
/// let howHigh: Int | |
/// var current = 1 | |
/// mutating func next() async -> Int? { | |
/// // A genuinely asychronous implementation uses the `Task` | |
/// // API to check for cancellation here and return early. | |
/// guard current <= howHigh else { | |
/// return nil | |
/// } | |
/// | |
/// let result = current | |
/// current += 1 | |
/// return result | |
/// } | |
/// } | |
/// | |
/// func makeAsyncIterator() -> AsyncIterator { | |
/// return AsyncIterator(howHigh: howHigh) | |
/// } | |
/// } | |
/// | |
/// At the call site, this looks like: | |
/// | |
/// for await i in Counter(howHigh: 10) { | |
/// print(i, terminator: " ") | |
/// } | |
/// // Prints: 1 2 3 4 5 6 7 8 9 10 | |
/// | |
/// ### End of Iteration | |
/// | |
/// The iterator returns `nil` to indicate the end of the sequence. After | |
/// returning `nil` (or throwing an error) from `next()`, the iterator enters | |
/// a terminal state, and all future calls to `next()` must return `nil`. | |
/// | |
/// ### Cancellation | |
/// | |
/// Types conforming to `AsyncIteratorProtocol` should use the cancellation | |
/// primitives provided by Swift's `Task` API. The iterator can choose how to | |
/// handle and respond to cancellation, including: | |
/// | |
/// - Checking the `isCancelled` value of the current `Task` inside `next()` | |
/// and returning `nil` to terminate the sequence. | |
/// - Calling `checkCancellation()` on the `Task`, which throws a | |
/// `CancellationError`. | |
/// - Implementing `next()` with a | |
/// `withTaskCancellationHandler(handler:operation:)` invocation to | |
/// immediately react to cancellation. | |
/// | |
/// If the iterator needs to clean up on cancellation, it can do so after | |
/// checking for cancellation as described above, or in `deinit` if it's | |
/// a reference type. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
@rethrows public protocol AsyncIteratorProtocol { | |
associatedtype Element | |
/// Asynchronously advances to the next element and returns it, or ends the | |
/// sequence if there is no next element. | |
/// | |
/// - Returns: The next element, if it exists, or `nil` to signal the end of | |
/// the sequence. | |
mutating func next() async throws -> Self.Element? | |
} | |
/// An asynchronous sequence that maps the given closure over the asynchronous | |
/// sequence’s elements. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct AsyncMapSequence<Base, Transformed> where Base : AsyncSequence { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncMapSequence : AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
/// | |
/// The map sequence produces whatever type of element its transforming | |
/// closure produces. | |
public typealias Element = Transformed | |
/// The type of iterator that produces elements of the sequence. | |
public typealias AsyncIterator = AsyncMapSequence<Base, Transformed>.Iterator | |
/// The iterator that produces elements of the map sequence. | |
public struct Iterator : AsyncIteratorProtocol { | |
/// Produces the next element in the map sequence. | |
/// | |
/// This iterator calls `next()` on its base iterator; if this call returns | |
/// `nil`, `next()` returns `nil`. Otherwise, `next()` returns the result of | |
/// calling the transforming closure on the received element. | |
@inlinable public mutating func next() async rethrows -> Transformed? | |
public typealias Element = Transformed | |
} | |
@inlinable public func makeAsyncIterator() -> AsyncMapSequence<Base, Transformed>.Iterator | |
} | |
/// An asynchronous sequence, up to a specified maximum length, | |
/// containing the initial elements of a base asynchronous sequence. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct AsyncPrefixSequence<Base> where Base : AsyncSequence { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncPrefixSequence : AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
/// | |
/// The prefix sequence produces whatever type of element its base iterator | |
/// produces. | |
public typealias Element = Base.Element | |
/// The type of iterator that produces elements of the sequence. | |
public typealias AsyncIterator = AsyncPrefixSequence<Base>.Iterator | |
/// The iterator that produces elements of the prefix sequence. | |
public struct Iterator : AsyncIteratorProtocol { | |
/// Produces the next element in the prefix sequence. | |
/// | |
/// Until reaching the number of elements to include, this iterator calls | |
/// `next()` on its base iterator and passes through the result. After | |
/// reaching the maximum number of elements, subsequent calls to `next()` | |
/// return `nil`. | |
@inlinable public mutating func next() async rethrows -> Base.Element? | |
public typealias Element = Base.Element | |
} | |
@inlinable public func makeAsyncIterator() -> AsyncPrefixSequence<Base>.Iterator | |
} | |
/// An asynchronous sequence, containing the initial, consecutive | |
/// elements of the base sequence that satisfy a given predicate. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct AsyncPrefixWhileSequence<Base> where Base : AsyncSequence { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncPrefixWhileSequence : AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
/// | |
/// The prefix-while sequence produces whatever type of element its base | |
/// iterator produces. | |
public typealias Element = Base.Element | |
/// The type of iterator that produces elements of the sequence. | |
public typealias AsyncIterator = AsyncPrefixWhileSequence<Base>.Iterator | |
/// The iterator that produces elements of the prefix-while sequence. | |
public struct Iterator : AsyncIteratorProtocol { | |
/// Produces the next element in the prefix-while sequence. | |
/// | |
/// If the predicate hasn't yet failed, this method gets the next element | |
/// from the base sequence and calls the predicate with it. If this call | |
/// succeeds, this method passes along the element. Otherwise, it returns | |
/// `nil`, ending the sequence. | |
@inlinable public mutating func next() async rethrows -> Base.Element? | |
public typealias Element = Base.Element | |
} | |
@inlinable public func makeAsyncIterator() -> AsyncPrefixWhileSequence<Base>.Iterator | |
} | |
/// A type that provides asynchronous, sequential, iterated access to its | |
/// elements. | |
/// | |
/// An `AsyncSequence` resembles the `Sequence` type --- offering a list of | |
/// values you can step through one at a time --- and adds asynchroncity. An | |
/// `AsyncSequence` may have all, some, or none of its values available when | |
/// you first use it. Instead, you use `await` to receive values as they become | |
/// available. | |
/// | |
/// As with `Sequence`, you typically iterate through an `AsyncSequence` with a | |
/// `for await`-`in` loop. However, because the caller must potentially wait for values, | |
/// you use the `await` keyword. The following example shows how to iterate | |
/// over `Counter`, a custom `AsyncSequence` that produces `Int` values from | |
/// `1` up to a `howHigh` value: | |
/// | |
/// for await i in Counter(howHigh: 10) { | |
/// print(i, terminator: " ") | |
/// } | |
/// // Prints: 1 2 3 4 5 6 7 8 9 10 | |
/// | |
/// An `AsyncSequence` doesn't generate or contain the values; it just defines | |
/// how you access them. Along with defining the type of values as an associated | |
/// type called `Element`, the `AsyncSequence` defines a `makeAsyncIterator()` | |
/// method. This returns an instance of type `AsyncIterator`. Like the standard | |
/// `IteratorProtocol`, the `AsyncIteratorProtocol` defines a single `next()` | |
/// method to produce elements. The difference is that the `AsyncIterator` | |
/// defines its `next()` method as `async`, which requires a caller to wait for | |
/// the next value with the `await` keyword. | |
/// | |
/// `AsyncSequence` also defines methods for processing the elements you | |
/// receive, modeled on the operations provided by the basic `Sequence` in the | |
/// standard library. There are two categories of methods: those that return a | |
/// single value, and those that return another `AsyncSequence`. | |
/// | |
/// Single-value methods eliminate the need for a `for await`-`in` loop, and instead | |
/// let you make a single `await` call. For example, the `contains(_:)` method | |
/// returns a Boolean value that indicates if a given value exists in the | |
/// `AsyncSequence`. Given the `Counter` sequence from the previous example, | |
/// you can test for the existence of a sequence member with a one-line call: | |
/// | |
/// let found = await Counter(howHigh: 10).contains(5) // true | |
/// | |
/// Methods that return another `AsyncSequence` return a type specific to the | |
/// method's semantics. For example, the `.map(_:)` method returns a | |
/// `AsyncMapSequence` (or a `AsyncThrowingMapSequence`, if the closure you | |
/// provide to the `map(_:)` method can throw an error). These returned | |
/// sequences don't eagerly await the next member of the sequence, which allows | |
/// the caller to decide when to start work. Typically, you'll iterate over | |
/// these sequences with `for await`-`in`, like the base `AsyncSequence` you started | |
/// with. In the following example, the `map(_:)` method transforms each `Int` | |
/// received from a `Counter` sequence into a `String`: | |
/// | |
/// let stream = Counter(howHigh: 10) | |
/// .map { $0 % 2 == 0 ? "Even" : "Odd" } | |
/// for await s in stream { | |
/// print(s, terminator: " ") | |
/// } | |
/// // Prints: Odd Even Odd Even Odd Even Odd Even Odd Even | |
/// | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
@rethrows public protocol AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
associatedtype AsyncIterator : AsyncIteratorProtocol | |
/// Creates the asynchronous iterator that produces elements of this | |
/// asynchronous sequence. | |
/// | |
/// - Returns: An instance of the `AsyncIterator` type used to produce | |
/// elements of the asynchronous sequence. | |
associatedtype Element where Self.Element == Self.AsyncIterator.Element | |
func makeAsyncIterator() -> Self.AsyncIterator | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Creates an asynchronous sequence that maps the given closure over the | |
/// asynchronous sequence’s elements, omitting results that don't return a | |
/// value. | |
/// | |
/// Use the `compactMap(_:)` method to transform every element received from | |
/// a base asynchronous sequence, while also discarding any `nil` results | |
/// from the closure. Typically, you use this to transform from one type of | |
/// element to another. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `5`. The closure provided to the `compactMap(_:)` | |
/// method takes each `Int` and looks up a corresponding `String` from a | |
/// `romanNumeralDict` dictionary. Because there is no key for `4`, the closure | |
/// returns `nil` in this case, which `compactMap(_:)` omits from the | |
/// transformed asynchronous sequence. | |
/// | |
/// let romanNumeralDict: [Int : String] = | |
/// [1: "I", 2: "II", 3: "III", 5: "V"] | |
/// | |
/// let stream = Counter(howHigh: 5) | |
/// .compactMap { romanNumeralDict[$0] } | |
/// for await numeral in stream { | |
/// print("\(numeral) ", terminator: " ") | |
/// } | |
/// // Prints: I II III V | |
/// | |
/// - 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 asynchronous sequence that contains, in order, the | |
/// non-`nil` elements produced by the `transform` closure. | |
@inlinable public func compactMap<ElementOfResult>(_ transform: @escaping (Self.Element) async -> ElementOfResult?) -> AsyncCompactMapSequence<Self, ElementOfResult> | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Omits a specified number of elements from the base asynchronous sequence, | |
/// then passes through all remaining elements. | |
/// | |
/// Use `dropFirst(_:)` when you want to drop the first *n* elements from the | |
/// base sequence and pass through the remaining elements. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `10`. The `dropFirst(_:)` method causes the modified | |
/// sequence to ignore the values `0` through `4`, and instead emit `5` through `10`: | |
/// | |
/// for await number in Counter(howHigh: 10).dropFirst(3) { | |
/// print("\(number) ", terminator: " ") | |
/// } | |
/// // prints "4 5 6 7 8 9 10" | |
/// | |
/// If the number of elements to drop exceeds the number of elements in the | |
/// sequence, the result is an empty sequence. | |
/// | |
/// - Parameter count: The number of elements to drop from the beginning of | |
/// the sequence. `count` must be greater than or equal to zero. | |
/// - Returns: An asynchronous sequence that drops the first `count` | |
/// elements from the base sequence. | |
@inlinable public func dropFirst(_ count: Int = 1) -> AsyncDropFirstSequence<Self> | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Omits elements from the base asynchronous sequence until a given closure | |
/// returns false, after which it passes through all remaining elements. | |
/// | |
/// Use `drop(while:)` to omit elements from an asynchronous sequence until | |
/// the element received meets a condition you specify. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `10`. The `drop(while:)` method causes the modified | |
/// sequence to ignore received values until it encounters one that is | |
/// divisible by `3`: | |
/// | |
/// let stream = Counter(howHigh: 10) | |
/// .drop { $0 % 3 != 0 } | |
/// for await number in stream { | |
/// print("\(number) ", terminator: " ") | |
/// } | |
/// // prints "3 4 5 6 7 8 9 10" | |
/// | |
/// After the predicate returns `false`, the sequence never executes it again, | |
/// and from then on the sequence passes through elements from its underlying | |
/// sequence as-is. | |
/// | |
/// - Parameter predicate: A closure that takes an element as a parameter and | |
/// returns a Boolean value indicating whether to drop the element from the | |
/// modified sequence. | |
/// - Returns: An asynchronous sequence that skips over values from the | |
/// base sequence until the provided closure returns `false`. | |
@inlinable public func drop(while predicate: @escaping (Self.Element) async -> Bool) -> AsyncDropWhileSequence<Self> | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Creates an asynchronous sequence that contains, in order, the elements of | |
/// the base sequence that satisfy the given predicate. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `10`. The `filter(_:)` method returns `true` for even | |
/// values and `false` for odd values, thereby filtering out the odd values: | |
/// | |
/// let stream = Counter(howHigh: 10) | |
/// .filter { $0 % 2 == 0 } | |
/// for await number in stream { | |
/// print("\(number) ", terminator: " ") | |
/// } | |
/// // Prints: 2 4 6 8 10 | |
/// | |
/// - Parameter isIncluded: A closure that takes an element of the | |
/// asynchronous sequence as its argument and returns a Boolean value | |
/// that indicates whether to include the element in the filtered sequence. | |
/// - Returns: An asynchronous sequence that contains, in order, the elements | |
/// of the base sequence that satisfy the given predicate. | |
@inlinable public func filter(_ isIncluded: @escaping (Self.Element) async -> Bool) -> AsyncFilterSequence<Self> | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Creates an asynchronous sequence that concatenates the results of calling | |
/// the given transformation with each element of this sequence. | |
/// | |
/// Use this method to receive a single-level asynchronous sequence when your | |
/// transformation produces an asynchronous sequence for each element. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `5`. The transforming closure takes the received `Int` | |
/// and returns a new `Counter` that counts that high. For example, when the | |
/// transform receives `3` from the base sequence, it creates a new `Counter` | |
/// that produces the values `1`, `2`, and `3`. The `flatMap(_:)` method | |
/// "flattens" the resulting sequence-of-sequences into a single | |
/// `AsyncSequence`. | |
/// | |
/// let stream = Counter(howHigh: 5) | |
/// .flatMap { Counter(howHigh: $0) } | |
/// for await number in stream { | |
/// print("\(number)", terminator: " ") | |
/// } | |
/// // Prints: 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5 | |
/// | |
/// - Parameter transform: A mapping closure. `transform` accepts an element | |
/// of this sequence as its parameter and returns an `AsyncSequence`. | |
/// - Returns: A single, flattened asynchronous sequence that contains all | |
/// elements in all the asychronous sequences produced by `transform`. | |
@inlinable public func flatMap<SegmentOfResult>(_ transform: @escaping (Self.Element) async -> SegmentOfResult) -> AsyncFlatMapSequence<Self, SegmentOfResult> where SegmentOfResult : AsyncSequence | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Creates an asynchronous sequence that maps the given closure over the | |
/// asynchronous sequence’s elements. | |
/// | |
/// Use the `map(_:)` method to transform every element received from a base | |
/// asynchronous sequence. Typically, you use this to transform from one type | |
/// of element to another. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `5`. The closure provided to the `map(_:)` method | |
/// takes each `Int` and looks up a corresponding `String` from a | |
/// `romanNumeralDict` dictionary. This means the outer `for await in` loop | |
/// iterates over `String` instances instead of the underlying `Int` values | |
/// that `Counter` produces: | |
/// | |
/// let romanNumeralDict: [Int: String] = | |
/// [1: "I", 2: "II", 3: "III", 5: "V"] | |
/// | |
/// let stream = Counter(howHigh: 5) | |
/// .map { romanNumeralDict[$0] ?? "(unknown)" } | |
/// for await numeral in stream { | |
/// print("\(numeral) ", terminator: " ") | |
/// } | |
/// // Prints: I II III (unknown) V | |
/// | |
/// - 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 asynchronous sequence that contains, in order, the elements | |
/// produced by the `transform` closure. | |
@inlinable public func map<Transformed>(_ transform: @escaping (Self.Element) async -> Transformed) -> AsyncMapSequence<Self, Transformed> | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Returns an asynchronous sequence, up to the specified maximum length, | |
/// containing the initial elements of the base asynchronous sequence. | |
/// | |
/// Use `prefix(_:)` to reduce the number of elements produced by the | |
/// asynchronous sequence. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `10`. The `prefix(_:)` method causes the modified | |
/// sequence to pass through the first six values, then end. | |
/// | |
/// for await number in Counter(howHigh: 10).prefix(6) { | |
/// print("\(number) ") | |
/// } | |
/// // prints "1 2 3 4 5 6" | |
/// | |
/// If the count passed to `prefix(_:)` exceeds the number of elements in the | |
/// base sequence, the result contains all of the elements in the sequence. | |
/// | |
/// - Parameter count: The maximum number of elements to return. The value of | |
/// `count` must be greater than or equal to zero. | |
/// - Returns: An asynchronous sequence starting at the beginning of the | |
/// base sequence with at most `count` elements. | |
@inlinable public func prefix(_ count: Int) -> AsyncPrefixSequence<Self> | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Returns an asynchronous sequence, containing the initial, consecutive | |
/// elements of the base sequence that satisfy the given predicate. | |
/// | |
/// Use `prefix(while:)` to produce values while elements from the base | |
/// sequence meet a condition you specify. The modified sequence ends when | |
/// the predicate closure returns `false`. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `10`. The `prefix(while:)` method causes the modified | |
/// sequence to pass along values so long as they aren’t divisible by `2` and | |
/// `3`. Upon reaching `6`, the sequence ends: | |
/// | |
/// let stream = Counter(howHigh: 10) | |
/// .prefix { $0 % 2 != 0 || $0 % 3 != 0 } | |
/// for try await number in stream { | |
/// print("\(number) ", terminator: " ") | |
/// } | |
/// // prints "1 2 3 4 5" | |
/// | |
/// - Parameter predicate: A closure that takes an element as a parameter and | |
/// returns a Boolean value indicating whether the element should be | |
/// included in the modified sequence. | |
/// - Returns: An asynchronous sequence of the initial, consecutive | |
/// elements that satisfy `predicate`. | |
@inlinable public func prefix(while predicate: @escaping (Self.Element) async -> Bool) rethrows -> AsyncPrefixWhileSequence<Self> | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Returns the result of combining the elements of the asynchronous sequence | |
/// using the given closure. | |
/// | |
/// Use the `reduce(_:_:)` method to produce a single value from the elements of | |
/// an entire sequence. For example, you can use this method on an sequence of | |
/// numbers to find their sum or product. | |
/// | |
/// The `nextPartialResult` closure executes sequentially with an accumulating | |
/// value initialized to `initialResult` and each element of the sequence. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `4`. The `reduce(_:_:)` method sums the values | |
/// received from the asynchronous sequence. | |
/// | |
/// let sum = await Counter(howHigh: 4) | |
/// .reduce(0) { | |
/// $0 + $1 | |
/// } | |
/// print(sum) | |
/// // Prints: 10 | |
/// | |
/// | |
/// - Parameters: | |
/// - initialResult: The value to use as the initial accumulating value. | |
/// The `nextPartialResult` closure receives `initialResult` the first | |
/// time the closure runs. | |
/// - nextPartialResult: A closure that combines an accumulating value and | |
/// an element of the asynchronous sequence into a new accumulating value, | |
/// for use in the next call of the `nextPartialResult` closure or | |
/// returned to the caller. | |
/// - Returns: The final accumulated value. If the sequence has no elements, | |
/// the result is `initialResult`. | |
@inlinable public func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (_ partialResult: Result, Self.Element) async throws -> Result) async rethrows -> Result | |
/// Returns the result of combining the elements of the asynchronous sequence | |
/// using the given closure, given a mutable initial value. | |
/// | |
/// Use the `reduce(into:_:)` method to produce a single value from the | |
/// elements of an entire sequence. For example, you can use this method on a | |
/// sequence of numbers to find their sum or product. | |
/// | |
/// The `nextPartialResult` closure executes sequentially with an accumulating | |
/// value initialized to `initialResult` and each element of the sequence. | |
/// | |
/// Prefer this method over `reduce(_:_:)` for efficiency when the result is | |
/// a copy-on-write type, for example an `Array` or `Dictionary`. | |
/// | |
/// - Parameters: | |
/// - initialResult: The value to use as the initial accumulating value. | |
/// The `nextPartialResult` closure receives `initialResult` the first | |
/// time the closure executes. | |
/// - nextPartialResult: A closure that combines an accumulating value and | |
/// an element of the asynchronous sequence into a new accumulating value, | |
/// for use in the next call of the `nextPartialResult` closure or | |
/// returned to the caller. | |
/// - Returns: The final accumulated value. If the sequence has no elements, | |
/// the result is `initialResult`. | |
@inlinable public func reduce<Result>(into initialResult: Result, _ updateAccumulatingResult: (_ partialResult: inout Result, Self.Element) async throws -> Void) async rethrows -> Result | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Returns a Boolean value that indicates whether the asynchronous sequence | |
/// contains an element that satisfies the given predicate. | |
/// | |
/// You can use the predicate to check for an element of a type that doesn’t | |
/// conform to the `Equatable` protocol, or to find an element that satisfies | |
/// a general condition. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `10`. The `contains(where:)` method checks to see | |
/// whether the sequence produces a value divisible by `3`: | |
/// | |
/// let containsDivisibleByThree = await Counter(howHigh: 10) | |
/// .contains { $0 % 3 == 0 } | |
/// print(containsDivisibleByThree) | |
/// // Prints: true | |
/// | |
/// The predicate executes each time the asynchronous sequence produces an | |
/// element, until either the predicate finds a match or the sequence ends. | |
/// | |
/// - Parameter predicate: A closure that takes an element of the asynchronous | |
/// sequence as its argument and returns a Boolean value that indicates | |
/// whether the passed element represents a match. | |
/// - Returns: `true` if the sequence contains an element that satisfies | |
/// predicate; otherwise, `false`. | |
@inlinable public func contains(where predicate: (Self.Element) async throws -> Bool) async rethrows -> Bool | |
/// Returns a Boolean value that indicates whether all elements produced by the | |
/// asynchronous sequence satisfies the given predicate. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `10`. The `allSatisfy(_:)` method checks to see whether | |
/// all elements produced by the sequence are less than `10`. | |
/// | |
/// let allLessThanTen = await Counter(howHigh: 10) | |
/// .allSatisfy { $0 < 10 } | |
/// print(allLessThanTen) | |
/// // Prints: false | |
/// | |
/// The predicate executes each time the asynchronous sequence produces an | |
/// element, until either the predicate returns `false` or the sequence ends. | |
/// | |
/// - Parameter predicate: A closure that takes an element of the asynchronous | |
/// sequence as its argument and returns a Boolean value that indicates | |
/// whether the passed element satisfies a condition. | |
/// - Returns: `true` if the sequence contains only elements that satisfy | |
/// `predicate`; otherwise, `false`. | |
@inlinable public func allSatisfy(_ predicate: (Self.Element) async throws -> Bool) async rethrows -> Bool | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence where Self.Element : Equatable { | |
/// Returns a Boolean value that indicates whether the asynchronous sequence | |
/// contains the given element. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `10`. The `contains(_:)` method checks to see whether | |
/// the sequence produces the value `5`: | |
/// | |
/// let containsFive = await Counter(howHigh: 10) | |
/// .contains(5) | |
/// print(containsFive) | |
/// // Prints: true | |
/// | |
/// - Parameter search: The element to find in the asynchronous sequence. | |
/// - Returns: `true` if the method found the element in the asynchronous | |
/// sequence; otherwise, `false`. | |
@inlinable public func contains(_ search: Self.Element) async rethrows -> Bool | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Returns the first element of the sequence that satisfies the given | |
/// predicate. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `10`. The `first(where:)` method returns the first | |
/// member of the sequence that's evenly divisible by both `2` and `3`. | |
/// | |
/// let divisibleBy2And3 = await Counter(howHigh: 10) | |
/// .first { $0 % 2 == 0 && $0 % 3 == 0 } | |
/// print(divisibleBy2And3 ?? "none") | |
/// // Prints: 6 | |
/// | |
/// The predicate executes each time the asynchronous sequence produces an | |
/// element, until either the predicate finds a match or the sequence ends. | |
/// | |
/// - Parameter predicate: A closure that takes an element of the asynchronous | |
/// sequence as its argument and returns a Boolean value that indicates | |
/// 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`. | |
@inlinable public func first(where predicate: (Self.Element) async throws -> Bool) async rethrows -> Self.Element? | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Returns the minimum element in the asynchronous sequence, using the given | |
/// predicate as the comparison between elements. | |
/// | |
/// Use this method when the asynchronous sequence's values don't conform | |
/// to `Comparable`, or when you want to apply a custom ordering to the | |
/// sequence. | |
/// | |
/// The predicate must be a *strict weak ordering* over the elements. That is, | |
/// for any elements `a`, `b`, and `c`, the following conditions must hold: | |
/// | |
/// - `areInIncreasingOrder(a, a)` is always `false`. (Irreflexivity) | |
/// - If `areInIncreasingOrder(a, b)` and `areInIncreasingOrder(b, c)` are | |
/// both `true`, then `areInIncreasingOrder(a, c)` is also | |
/// `true`. (Transitive comparability) | |
/// - Two elements are *incomparable* if neither is ordered before the other | |
/// according to the predicate. If `a` and `b` are incomparable, and `b` | |
/// and `c` are incomparable, then `a` and `c` are also incomparable. | |
/// (Transitive incomparability) | |
/// | |
/// The following example uses an enumeration of playing cards ranks, `Rank`, | |
/// which ranges from `ace` (low) to `king` (high). An asynchronous sequence | |
/// called `RankCounter` produces all elements of the array. The predicate | |
/// provided to the `min(by:)` method sorts ranks based on their `rawValue`: | |
/// | |
/// enum Rank: Int { | |
/// case ace = 1, two, three, four, five, six, seven, eight, nine, ten, jack, queen, king | |
/// } | |
/// | |
/// let min = await RankCounter() | |
/// .min { $0.rawValue < $1.rawValue } | |
/// print(min ?? "none") | |
/// // Prints: ace | |
/// | |
/// - Parameter areInIncreasingOrder: A predicate that returns `true` if its | |
/// first argument should be ordered before its second argument; otherwise, | |
/// `false`. | |
/// - Returns: The sequence’s minimum element, according to | |
/// `areInIncreasingOrder`. If the sequence has no elements, returns `nil`. | |
@warn_unqualified_access | |
@inlinable public func min(by areInIncreasingOrder: (Self.Element, Self.Element) async throws -> Bool) async rethrows -> Self.Element? | |
/// Returns the maximum element in the asynchronous sequence, using the given | |
/// predicate as the comparison between elements. | |
/// | |
/// Use this method when the asynchronous sequence's values don't conform | |
/// to `Comparable`, or when you want to apply a custom ordering to the | |
/// sequence. | |
/// | |
/// The predicate must be a *strict weak ordering* over the elements. That is, | |
/// for any elements `a`, `b`, and `c`, the following conditions must hold: | |
/// | |
/// - `areInIncreasingOrder(a, a)` is always `false`. (Irreflexivity) | |
/// - If `areInIncreasingOrder(a, b)` and `areInIncreasingOrder(b, c)` are | |
/// both `true`, then `areInIncreasingOrder(a, c)` is also | |
/// `true`. (Transitive comparability) | |
/// - Two elements are *incomparable* if neither is ordered before the other | |
/// according to the predicate. If `a` and `b` are incomparable, and `b` | |
/// and `c` are incomparable, then `a` and `c` are also incomparable. | |
/// (Transitive incomparability) | |
/// | |
/// The following example uses an enumeration of playing cards ranks, `Rank`, | |
/// which ranges from `ace` (low) to `king` (high). An asynchronous sequence | |
/// called `RankCounter` produces all elements of the array. The predicate | |
/// provided to the `max(by:)` method sorts ranks based on their `rawValue`: | |
/// | |
/// enum Rank: Int { | |
/// case ace = 1, two, three, four, five, six, seven, eight, nine, ten, jack, queen, king | |
/// } | |
/// | |
/// let max = await RankCounter() | |
/// .max { $0.rawValue < $1.rawValue } | |
/// print(max ?? "none") | |
/// // Prints: king | |
/// | |
/// - Parameter areInIncreasingOrder: A predicate that returns `true` if its | |
/// first argument should be ordered before its second argument; otherwise, | |
/// `false`. | |
/// - Returns: The sequence’s minimum element, according to | |
/// `areInIncreasingOrder`. If the sequence has no elements, returns `nil`. | |
@warn_unqualified_access | |
@inlinable public func max(by areInIncreasingOrder: (Self.Element, Self.Element) async throws -> Bool) async rethrows -> Self.Element? | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence where Self.Element : Comparable { | |
/// Returns the minimum element in an asynchronous sequence of comparable | |
/// elements. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `10`. The `min()` method returns the minimum value | |
/// of the sequence. | |
/// | |
/// let min = await Counter(howHigh: 10) | |
/// .min() | |
/// print(min ?? "none") | |
/// // Prints: 1 | |
/// | |
/// - Returns: The sequence’s minimum element. If the sequence has no | |
/// elements, returns `nil`. | |
@warn_unqualified_access | |
@inlinable public func min() async rethrows -> Self.Element? | |
/// Returns the maximum element in an asynchronous sequence of comparable | |
/// elements. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `10`. The `max()` method returns the max value | |
/// of the sequence. | |
/// | |
/// let max = await Counter(howHigh: 10) | |
/// .max() | |
/// print(max ?? "none") | |
/// // Prints: 10 | |
/// | |
/// - Returns: The sequence’s maximum element. If the sequence has no | |
/// elements, returns `nil`. | |
@warn_unqualified_access | |
@inlinable public func max() async rethrows -> Self.Element? | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Creates an asynchronous sequence that maps an error-throwing closure over | |
/// the base sequence’s elements, omitting results that don't return a value. | |
/// | |
/// Use the `compactMap(_:)` method to transform every element received from | |
/// a base asynchronous sequence, while also discarding any `nil` results | |
/// from the closure. Typically, you use this to transform from one type of | |
/// element to another. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `5`. The closure provided to the `compactMap(_:)` | |
/// method takes each `Int` and looks up a corresponding `String` from a | |
/// `romanNumeralDict` dictionary. Since there is no key for `4`, the closure | |
/// returns `nil` in this case, which `compactMap(_:)` omits from the | |
/// transformed asynchronous sequence. When the value is `5`, the closure | |
/// throws `MyError`, terminating the sequence. | |
/// | |
/// let romanNumeralDict: [Int : String] = | |
/// [1: "I", 2: "II", 3: "III", 5: "V"] | |
/// | |
/// do { | |
/// let stream = Counter(howHigh: 5) | |
/// .compactMap { (value) throws -> String? in | |
/// if value == 5 { | |
/// throw MyError() | |
/// } | |
/// return romanNumeralDict[value] | |
/// } | |
/// for try await numeral in stream { | |
/// print("\(numeral) ", terminator: " ") | |
/// } | |
/// } catch { | |
/// print("Error: \(error)") | |
/// } | |
/// // Prints: I II III Error: MyError() | |
/// | |
/// - Parameter transform: An error-throwing 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. If `transform` | |
/// throws an error, the sequence ends. | |
/// - Returns: An asynchronous sequence that contains, in order, the | |
/// non-`nil` elements produced by the `transform` closure. The sequence | |
/// ends either when the base sequence ends or when `transform` throws an | |
/// error. | |
@inlinable public func compactMap<ElementOfResult>(_ transform: @escaping (Self.Element) async throws -> ElementOfResult?) -> AsyncThrowingCompactMapSequence<Self, ElementOfResult> | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Omits elements from the base sequence until a given error-throwing closure | |
/// returns false, after which it passes through all remaining elements. | |
/// | |
/// Use `drop(while:)` to omit elements from an asynchronous sequence until | |
/// the element received meets a condition you specify. If the closure you | |
/// provide throws an error, the sequence produces no elements and throws | |
/// the error instead. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `10`. The predicate passed to the `drop(while:)` | |
/// method throws an error if it encounters an even number, and otherwise | |
/// returns `true` while it receives elements less than `5`. Because the | |
/// predicate throws when it receives `2` from the base sequence, this example | |
/// throws without ever printing anything. | |
/// | |
/// do { | |
/// let stream = Counter(howHigh: 10) | |
/// .drop { | |
/// if $0 % 2 == 0 { | |
/// throw EvenError() | |
/// } | |
/// return $0 < 5 | |
/// } | |
/// for try await number in stream { | |
/// print("\(number) ") | |
/// } | |
/// } catch { | |
/// print ("\(error)") | |
/// } | |
/// // Prints: EvenError() | |
/// | |
/// After the predicate returns `false`, the sequence never executes it again, | |
/// and from then on the sequence passes through elements from its underlying | |
/// sequence. A predicate that throws an error also never executes again. | |
/// | |
/// - Parameter predicate: An error-throwing closure that takes an element as | |
/// a parameter and returns a Boolean value indicating whether to drop the | |
/// element from the modified sequence. | |
/// - Returns: An asynchronous sequence that skips over values until the | |
/// provided closure returns `false` or throws an error. | |
@inlinable public func drop(while predicate: @escaping (Self.Element) async throws -> Bool) -> AsyncThrowingDropWhileSequence<Self> | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Creates an asynchronous sequence that contains, in order, the elements of | |
/// the base sequence that satisfy the given error-throwing predicate. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `10`. The `filter(_:)` method returns `true` for even | |
/// values and `false` for odd values, thereby filtering out the odd values, | |
/// but also throws an error for values divisible by 5: | |
/// | |
/// do { | |
/// let stream = Counter(howHigh: 10) | |
/// .filter { | |
/// if $0 % 5 == 0 { | |
/// throw MyError() | |
/// } | |
/// return $0 % 2 == 0 | |
/// } | |
/// for try await number in stream { | |
/// print("\(number) ", terminator: " ") | |
/// } | |
/// } catch { | |
/// print("Error: \(error)") | |
/// } | |
/// // Prints: 2 4 Error: MyError() | |
/// | |
/// - Parameter isIncluded: An error-throwing closure that takes an element | |
/// of the asynchronous sequence as its argument and returns a Boolean value | |
/// that indicates whether to include the element in the filtered sequence. | |
/// - Returns: An asynchronous sequence that contains, in order, the elements | |
/// of the base sequence that satisfy the given predicate. If the predicate | |
/// throws an error, the sequence contains only values produced prior to | |
/// the error. | |
@inlinable public func filter(_ isIncluded: @escaping (Self.Element) async throws -> Bool) -> AsyncThrowingFilterSequence<Self> | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Creates an asynchronous sequence that concatenates the results of calling | |
/// the given error-throwing transformation with each element of this | |
/// sequence. | |
/// | |
/// Use this method to receive a single-level asynchronous sequence when your | |
/// transformation produces an asynchronous sequence for each element. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `5`. The transforming closure takes the received `Int` | |
/// and returns a new `Counter` that counts that high. For example, when the | |
/// transform receives `3` from the base sequence, it creates a new `Counter` | |
/// that produces the values `1`, `2`, and `3`. The `flatMap(_:)` method | |
/// "flattens" the resulting sequence-of-sequences into a single | |
/// `AsyncSequence`. However, when the closure receives `4`, it throws an | |
/// error, terminating the sequence. | |
/// | |
/// do { | |
/// let stream = Counter(howHigh: 5) | |
/// .flatMap { (value) -> Counter in | |
/// if value == 4 { | |
/// throw MyError() | |
/// } | |
/// return Counter(howHigh: value) | |
/// } | |
/// for try await number in stream { | |
/// print ("\(number)", terminator: " ") | |
/// } | |
/// } catch { | |
/// print(error) | |
/// } | |
/// // Prints: 1 1 2 1 2 3 MyError() | |
/// | |
/// - Parameter transform: An error-throwing mapping closure. `transform` | |
/// accepts an element of this sequence as its parameter and returns an | |
/// `AsyncSequence`. If `transform` throws an error, the sequence ends. | |
/// - Returns: A single, flattened asynchronous sequence that contains all | |
/// elements in all the asychronous sequences produced by `transform`. The | |
/// sequence ends either when the the last sequence created from the last | |
/// element from base sequence ends, or when `transform` throws an error. | |
@inlinable public func flatMap<SegmentOfResult>(_ transform: @escaping (Self.Element) async throws -> SegmentOfResult) -> AsyncThrowingFlatMapSequence<Self, SegmentOfResult> where SegmentOfResult : AsyncSequence | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Creates an asynchronous sequence that maps the given error-throwing | |
/// closure over the asynchronous sequence’s elements. | |
/// | |
/// Use the `map(_:)` method to transform every element received from a base | |
/// asynchronous sequence. Typically, you use this to transform from one type | |
/// of element to another. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `5`. The closure provided to the `map(_:)` method | |
/// takes each `Int` and looks up a corresponding `String` from a | |
/// `romanNumeralDict` dictionary. This means the outer `for await in` loop | |
/// iterates over `String` instances instead of the underlying `Int` values | |
/// that `Counter` produces. Also, the dictionary doesn't provide a key for | |
/// `4`, and the closure throws an error for any key it can't look up, so | |
/// receiving this value from `Counter` ends the modified sequence with an | |
/// error. | |
/// | |
/// let romanNumeralDict: [Int : String] = | |
/// [1: "I", 2: "II", 3: "III", 5: "V"] | |
/// | |
/// do { | |
/// let stream = Counter(howHigh: 5) | |
/// .map { (value) throws -> String in | |
/// guard let roman = romanNumeralDict[value] else { | |
/// throw MyError() | |
/// } | |
/// return roman | |
/// } | |
/// for try await numeral in stream { | |
/// print("\(numeral) ", terminator: " ") | |
/// } | |
/// } catch { | |
/// print ("Error: \(error)") | |
/// } | |
/// // Prints: I II III Error: MyError() | |
/// | |
/// - 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. `transform` can also throw an error, which | |
/// ends the transformed sequence. | |
/// - Returns: An asynchronous sequence that contains, in order, the elements | |
/// produced by the `transform` closure. | |
@inlinable public func map<Transformed>(_ transform: @escaping (Self.Element) async throws -> Transformed) -> AsyncThrowingMapSequence<Self, Transformed> | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncSequence { | |
/// Returns an asynchronous sequence, containing the initial, consecutive | |
/// elements of the base sequence that satisfy the given error-throwing | |
/// predicate. | |
/// | |
/// Use `prefix(while:)` to produce values while elements from the base | |
/// sequence meet a condition you specify. The modified sequence ends when | |
/// the predicate closure returns `false` or throws an error. | |
/// | |
/// In this example, an asynchronous sequence called `Counter` produces `Int` | |
/// values from `1` to `10`. The `prefix(_:)` method causes the modified | |
/// sequence to pass through values less than `8`, but throws an | |
/// error when it receives a value that's divisible by `5`: | |
/// | |
/// do { | |
/// let stream = try Counter(howHigh: 10) | |
/// .prefix { | |
/// if $0 % 5 == 0 { | |
/// throw MyError() | |
/// } | |
/// return $0 < 8 | |
/// } | |
/// for try await number in stream { | |
/// print("\(number) ", terminator: " ") | |
/// } | |
/// } catch { | |
/// print("Error: \(error)") | |
/// } | |
/// // Prints: 1 2 3 4 Error: MyError() | |
/// | |
/// - Parameter isIncluded: A error-throwing closure that takes an element of | |
/// the asynchronous sequence as its argument and returns a Boolean value | |
/// that indicates whether to include the element in the modified sequence. | |
/// - Returns: An asynchronous sequence that contains, in order, the elements | |
/// of the base sequence that satisfy the given predicate. If the predicate | |
/// throws an error, the sequence contains only values produced prior to | |
/// the error. | |
@inlinable public func prefix(while predicate: @escaping (Self.Element) async throws -> Bool) rethrows -> AsyncThrowingPrefixWhileSequence<Self> | |
} | |
/// An asynchronous sequence that maps an error-throwing closure over the base | |
/// sequence’s elements, omitting results that don't return a value. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct AsyncThrowingCompactMapSequence<Base, ElementOfResult> where Base : AsyncSequence { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncThrowingCompactMapSequence : AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
/// | |
/// The compact map sequence produces whatever type of element its | |
/// transforming closure produces. | |
public typealias Element = ElementOfResult | |
/// The type of iterator that produces elements of the sequence. | |
public typealias AsyncIterator = AsyncThrowingCompactMapSequence<Base, ElementOfResult>.Iterator | |
/// The iterator that produces elements of the compact map sequence. | |
public struct Iterator : AsyncIteratorProtocol { | |
public typealias Element = ElementOfResult | |
/// Produces the next element in the compact map sequence. | |
/// | |
/// This iterator calls `next()` on its base iterator; if this call returns | |
/// `nil`, `next()` returns `nil`. Otherwise, `next()` calls the | |
/// transforming closure on the received element, returning it if the | |
/// transform returns a non-`nil` value. If the transform returns `nil`, | |
/// this method continues to wait for further elements until it gets one | |
/// that transforms to a non-`nil` value. If calling the closure throws an | |
/// error, the sequence ends and `next()` rethrows the error. | |
@inlinable public mutating func next() async throws -> ElementOfResult? | |
} | |
@inlinable public func makeAsyncIterator() -> AsyncThrowingCompactMapSequence<Base, ElementOfResult>.Iterator | |
} | |
/// An asynchronous sequence which omits elements from the base sequence until a | |
/// given error-throwing closure returns false, after which it passes through | |
/// all remaining elements. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct AsyncThrowingDropWhileSequence<Base> where Base : AsyncSequence { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncThrowingDropWhileSequence : AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
/// | |
/// The drop-while sequence produces whatever type of element its base | |
/// sequence produces. | |
public typealias Element = Base.Element | |
/// The type of iterator that produces elements of the sequence. | |
public typealias AsyncIterator = AsyncThrowingDropWhileSequence<Base>.Iterator | |
/// The iterator that produces elements of the drop-while sequence. | |
public struct Iterator : AsyncIteratorProtocol { | |
/// Produces the next element in the drop-while sequence. | |
/// | |
/// This iterator calls `next()` on its base iterator and evaluates the | |
/// result with the `predicate` closure. As long as the predicate returns | |
/// `true`, this method returns `nil`. After the predicate returns `false`, | |
/// for a value received from the base iterator, this method returns that | |
/// value. After that, the iterator returns values received from its | |
/// base iterator as-is, and never executes the predicate closure again. | |
/// If calling the closure throws an error, the sequence ends and `next()` | |
/// rethrows the error. | |
@inlinable public mutating func next() async throws -> Base.Element? | |
public typealias Element = Base.Element | |
} | |
@inlinable public func makeAsyncIterator() -> AsyncThrowingDropWhileSequence<Base>.Iterator | |
} | |
/// An asynchronous sequence that contains, in order, the elements of | |
/// the base sequence that satisfy the given error-throwing predicate. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct AsyncThrowingFilterSequence<Base> where Base : AsyncSequence { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncThrowingFilterSequence : AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
/// | |
/// The filter sequence produces whatever type of element its base | |
/// sequence produces. | |
public typealias Element = Base.Element | |
/// The type of iterator that produces elements of the sequence. | |
public typealias AsyncIterator = AsyncThrowingFilterSequence<Base>.Iterator | |
/// The iterator that produces elements of the filter sequence. | |
public struct Iterator : AsyncIteratorProtocol { | |
/// Produces the next element in the filter sequence. | |
/// | |
/// This iterator calls `next()` on its base iterator; if this call returns | |
/// `nil`, `next()` returns nil. Otherwise, `next()` evaluates the | |
/// result with the `predicate` closure. If the closure returns `true`, | |
/// `next()` returns the received element; otherwise it awaits the next | |
/// element from the base iterator. If calling the closure throws an error, | |
/// the sequence ends and `next()` rethrows the error. | |
@inlinable public mutating func next() async throws -> Base.Element? | |
public typealias Element = Base.Element | |
} | |
@inlinable public func makeAsyncIterator() -> AsyncThrowingFilterSequence<Base>.Iterator | |
} | |
/// An asynchronous sequence that concatenates the results of calling a given | |
/// error-throwing transformation with each element of this sequence. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct AsyncThrowingFlatMapSequence<Base, SegmentOfResult> where Base : AsyncSequence, SegmentOfResult : AsyncSequence { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncThrowingFlatMapSequence : AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
/// | |
/// The flat map sequence produces the type of element in the asynchronous | |
/// sequence produced by the `transform` closure. | |
public typealias Element = SegmentOfResult.Element | |
/// The type of iterator that produces elements of the sequence. | |
public typealias AsyncIterator = AsyncThrowingFlatMapSequence<Base, SegmentOfResult>.Iterator | |
/// The iterator that produces elements of the flat map sequence. | |
public struct Iterator : AsyncIteratorProtocol { | |
/// Produces the next element in the flat map sequence. | |
/// | |
/// This iterator calls `next()` on its base iterator; if this call returns | |
/// `nil`, `next()` returns `nil`. Otherwise, `next()` calls the | |
/// transforming closure on the received element, takes the resulting | |
/// asynchronous sequence, and creates an asynchronous iterator from it. | |
/// `next()` then consumes values from this iterator until it terminates. | |
/// At this point, `next()` is ready to receive the next value from the base | |
/// sequence. If `transform` throws an error, the sequence terminates. | |
@inlinable public mutating func next() async throws -> SegmentOfResult.Element? | |
public typealias Element = SegmentOfResult.Element | |
} | |
@inlinable public func makeAsyncIterator() -> AsyncThrowingFlatMapSequence<Base, SegmentOfResult>.Iterator | |
} | |
/// An asynchronous sequence that maps the given error-throwing closure over the | |
/// asynchronous sequence’s elements. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct AsyncThrowingMapSequence<Base, Transformed> where Base : AsyncSequence { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncThrowingMapSequence : AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
/// | |
/// The map sequence produces whatever type of element its the transforming | |
/// closure produces. | |
public typealias Element = Transformed | |
/// The type of iterator that produces elements of the sequence. | |
public typealias AsyncIterator = AsyncThrowingMapSequence<Base, Transformed>.Iterator | |
/// The iterator that produces elements of the map sequence. | |
public struct Iterator : AsyncIteratorProtocol { | |
/// Produces the next element in the map sequence. | |
/// | |
/// This iterator calls `next()` on its base iterator; if this call returns | |
/// `nil`, `next()` returns nil. Otherwise, `next()` returns the result of | |
/// calling the transforming closure on the received element. If calling | |
/// the closure throws an error, the sequence ends and `next()` rethrows | |
/// the error. | |
@inlinable public mutating func next() async throws -> Transformed? | |
public typealias Element = Transformed | |
} | |
@inlinable public func makeAsyncIterator() -> AsyncThrowingMapSequence<Base, Transformed>.Iterator | |
} | |
/// An asynchronous sequence, containing the initial, consecutive | |
/// elements of the base sequence that satisfy the given error-throwing | |
/// predicate. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct AsyncThrowingPrefixWhileSequence<Base> where Base : AsyncSequence { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension AsyncThrowingPrefixWhileSequence : AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
/// | |
/// The prefix-while sequence produces whatever type of element its base | |
/// iterator produces. | |
public typealias Element = Base.Element | |
/// The type of iterator that produces elements of the sequence. | |
public typealias AsyncIterator = AsyncThrowingPrefixWhileSequence<Base>.Iterator | |
/// The iterator that produces elements of the prefix-while sequence. | |
public struct Iterator : AsyncIteratorProtocol { | |
/// Produces the next element in the prefix-while sequence. | |
/// | |
/// If the predicate hasn't failed yet, this method gets the next element | |
/// from the base sequence and calls the predicate with it. If this call | |
/// succeeds, this method passes along the element. Otherwise, it returns | |
/// `nil`, ending the sequence. If calling the predicate closure throws an | |
/// error, the sequence ends and `next()` rethrows the error. | |
@inlinable public mutating func next() async throws -> Base.Element? | |
public typealias Element = Base.Element | |
} | |
@inlinable public func makeAsyncIterator() -> AsyncThrowingPrefixWhileSequence<Base>.Iterator | |
} | |
/// A mechanism to interface | |
/// between synchronous and asynchronous code, | |
/// logging correctness violations. | |
/// | |
/// A *continuation* is an opaque representation of program state. | |
/// To create a continuation in asynchronous code, | |
/// call the `withUnsafeContinuation(function:_:)` or | |
/// `withUnsafeThrowingContinuation(function:_:)` function. | |
/// To resume the asynchronous task, | |
/// call the `resume(returning:)`, | |
/// `resume(throwing:)`, | |
/// `resume(with:)`, | |
/// or `resume()` method. | |
/// | |
/// - Important: You must call a resume method exactly once | |
/// on every execution path throughout the program. | |
/// | |
/// Resuming from a continuation more than once is undefined behavior. | |
/// Never resuming leaves the task in a suspended state indefinitely, | |
/// and leaks any associated resources. | |
/// `CheckedContinuation` logs a message | |
/// if either of these invariants is violated. | |
/// | |
/// `CheckedContinuation` performs runtime checks | |
/// for missing or multiple resume operations. | |
/// `UnsafeContinuation` avoids enforcing these invariants at runtime | |
/// because it aims to be a low-overhead mechanism | |
/// for interfacing Swift tasks with | |
/// event loops, delegate methods, callbacks, | |
/// and other non-`async` scheduling mechanisms. | |
/// However, during development, the ability to verify that the | |
/// invariants are being upheld in testing is important. | |
/// Because both types have the same interface, | |
/// you can replace one with the other in most circumstances, | |
/// without making other changes. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct CheckedContinuation<T, E> where E : Error { | |
/// Creates a checked continuation from an unsafe continuation. | |
/// | |
/// Instead of calling this initializer, | |
/// most code calls the `withCheckedContinuation(function:_:)` or | |
/// `withCheckedThrowingContinuation(function:_:)` function instead. | |
/// You only need to initialize | |
/// your own `CheckedContinuation<T, E>` if you already have an | |
/// `UnsafeContinuation` you want to impose checking on. | |
/// | |
/// - Parameters: | |
/// - continuation: An instance of `UnsafeContinuation` | |
/// that hasn't yet been resumed. | |
/// After passing the unsafe continuation to this initializer, | |
/// don't use it outside of this object. | |
/// - function: A string identifying the declaration that is the notional | |
/// source for the continuation, used to identify the continuation in | |
/// runtime diagnostics related to misuse of this continuation. | |
public init(continuation: UnsafeContinuation<T, E>, function: String = #function) | |
/// Resume the task awaiting the continuation by having it return normally | |
/// from its suspension point. | |
/// | |
/// - Parameter value: The value to return from the continuation. | |
/// | |
/// A continuation must be resumed exactly once. If the continuation has | |
/// already been resumed through this object, then the attempt to resume | |
/// the continuation will trap. | |
/// | |
/// After `resume` enqueues the task, control immediately returns to | |
/// the caller. The task continues executing when its executor is | |
/// able to reschedule it. | |
public func resume(returning x: T) | |
/// Resume the task awaiting the continuation by having it throw an error | |
/// from its suspension point. | |
/// | |
/// - Parameter error: The error to throw from the continuation. | |
/// | |
/// A continuation must be resumed exactly once. If the continuation has | |
/// already been resumed through this object, then the attempt to resume | |
/// the continuation will trap. | |
/// | |
/// After `resume` enqueues the task, control immediately returns to | |
/// the caller. The task continues executing when its executor is | |
/// able to reschedule it. | |
public func resume(throwing x: E) | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension CheckedContinuation { | |
/// Resume the task awaiting the continuation by having it either | |
/// return normally or throw an error based on the state of the given | |
/// `Result` value. | |
/// | |
/// - Parameter result: A value to either return or throw from the | |
/// continuation. | |
/// | |
/// A continuation must be resumed exactly once. If the continuation has | |
/// already been resumed through this object, then the attempt to resume | |
/// the continuation will trap. | |
/// | |
/// After `resume` enqueues the task, control immediately returns to | |
/// the caller. The task continues executing when its executor is | |
/// able to reschedule it. | |
public func resume<Er>(with result: Result<T, Er>) where E == Error, Er : Error | |
/// Resume the task awaiting the continuation by having it either | |
/// return normally or throw an error based on the state of the given | |
/// `Result` value. | |
/// | |
/// - Parameter result: A value to either return or throw from the | |
/// continuation. | |
/// | |
/// A continuation must be resumed exactly once. If the continuation has | |
/// already been resumed through this object, then the attempt to resume | |
/// the continuation will trap. | |
/// | |
/// After `resume` enqueues the task, control immediately returns to | |
/// the caller. The task continues executing when its executor is | |
/// able to reschedule it. | |
public func resume(with result: Result<T, E>) | |
/// Resume the task awaiting the continuation by having it return normally | |
/// from its suspension point. | |
/// | |
/// A continuation must be resumed exactly once. If the continuation has | |
/// already been resumed through this object, then the attempt to resume | |
/// the continuation will trap. | |
/// | |
/// After `resume` enqueues the task, control immediately returns to | |
/// the caller. The task continues executing when its executor is | |
/// able to reschedule it. | |
public func resume() where T == Void | |
} | |
/// A singleton actor whose executor is equivalent to | |
/// \c DispatchQueue.main, which is the main dispatch queue. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
@globalActor public actor MainActor { | |
public static let shared: MainActor | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension MainActor { | |
/// Execute the given body closure on the main actor. | |
public static func run<T>(resultType: T.Type = T.self, body: @MainActor @Sendable () throws -> T) async rethrows -> T | |
} | |
/// A unit of scheduleable work. | |
/// | |
/// Unless you're implementing a scheduler, | |
/// you don't generally interact with partial tasks directly. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
@frozen public struct PartialAsyncTask { | |
/// Starts running the task. | |
public func run() | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension PartialAsyncTask : Sendable { | |
} | |
/// A unit of asynchronous work. | |
/// | |
/// All asynchronous functions run as part of some task. | |
/// | |
/// Only code that's running as part of the task can interact with that task, | |
/// by invoking the appropriate context-sensitive static functions which operate | |
/// on the current task. | |
/// | |
/// A task's execution can be seen as a series of periods where the task ran. | |
/// Each such period ends at a suspension point or the | |
/// completion of the task. | |
/// | |
/// These partial periods towards the task's completion are `PartialAsyncTask`. | |
/// Unless you're implementing a scheduler, | |
/// you don't generally interact with partial tasks directly. | |
/// | |
/// Task Cancellation | |
/// ================= | |
/// | |
/// Tasks include a shared mechanism for indicating cancellation, | |
/// but not a shared implementation for how to handle cancellation. | |
/// Depending on the work you're doing in the task, | |
/// the correct way to stop that work varies. | |
/// Likewise, | |
/// it's the responsibility of the code running as part of the task | |
/// to check for cancellation whenever stopping is appropriate. | |
/// In a long-task that includes multiple pieces, | |
/// you might need to check for cancellation at several points, | |
/// and handle cancellation differently at each point. | |
/// If you only need to throw an error to stop the work, | |
/// call the `Task.checkCancellation()` function to check for cancellation. | |
/// Other responses to cancellation include | |
/// returning the work completed so far, returning an empty result, or returning `nil`. | |
/// | |
/// Cancellation is a purely Boolean state; | |
/// there's no way to include additional information | |
/// like the reason for cancellation. | |
/// This reflects the fact that a task can be canceled for many reasons, | |
/// and additional reasons can accrue during the cancellation process. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct Task { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task { | |
/// Returns the task that this code runs on, | |
/// or `nil` when you access this property outside of any task. | |
/// | |
/// If you read this property from the context of an asynchronous function or closure, | |
/// the current task is non-nil. | |
/// In a synchronous context, | |
/// this property's value depends on whether the synchronous operation was | |
/// called from an asynchronous context. | |
/// For example: | |
/// | |
/// func hello() { | |
/// if Task.current == nil { print("Nil") } | |
/// else { print("Not nil") } | |
/// } | |
/// | |
/// func asynchronous() async { hello() } | |
/// | |
/// In the code above, | |
/// because `hello()` is called by an asynchronous function, | |
/// it prints "Not nil". | |
/// | |
@available(*, deprecated, message: "`Task.current` has been deprecated and will be removed, use static functions on Task instead.") | |
public static var current: Task? { get } | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task { | |
/// The current task's priority. | |
/// | |
/// If you access this property outside of any task, | |
/// this queries the system to determine the | |
/// priority at which the current function is running. | |
/// If the system can't provide a priority, | |
/// this property's value is `Priority.default`. | |
/// | |
/// - SeeAlso: `Task.priority` | |
public static var currentPriority: Task.Priority { get } | |
/// The task's priority. | |
/// | |
/// - SeeAlso: `Task.currentPriority` | |
@available(*, deprecated, message: "Storing `Task` instances has been deprecated, and as such instance functions on Task are deprecated and will be removed soon. Use the static 'Task.currentPriority' instead.") | |
public var priority: Task.Priority { get } | |
/// The priority of a task. | |
/// | |
/// The executor determines how priority information affects the way tasks are scheduled. | |
/// The behavior varies depending on the executor currently being used. | |
/// Typically, executors attempt to run tasks with a higher priority | |
/// before tasks with a lower priority. | |
/// However, the semantics of how priority is treated are left up to each | |
/// platform and `Executor` implementation. | |
/// | |
/// Child tasks automatically inherit their parent task's priority. | |
/// | |
/// Detached tasks created by `detach(priority:operation:)` don't inherit task priority | |
/// because they aren't attached to the current task. | |
/// | |
/// In some situations the priority of a task is elevated --- | |
/// that is, the task is treated as it if had a higher priority, | |
/// without actually changing the priority of the task: | |
/// | |
/// - If a task runs on behalf of an actor, | |
/// and a new higher-priority task is enqueued to the actor, | |
/// then the actor's current task is temporarily elevated | |
/// to the priority of the enqueued task. | |
/// This priority elevation allows the new task | |
/// to be processed at (effectively) the priority it was enqueued with. | |
/// - If a task is created with a `Task.Handle` | |
/// and a higher-priority task calls the `await handle.get()` method, | |
/// then the priority of this task increases until the task completes. | |
/// | |
/// In both cases, priority elevation helps you prevent a low-priority task | |
/// blocking the execution of a high priority task, | |
/// which is also known as *priority inversion*. | |
public enum Priority : Int, Comparable { | |
case userInteractive | |
case userInitiated | |
case `default` | |
case utility | |
case background | |
@available(*, deprecated, message: "unspecified priority will be removed; use nil") | |
case unspecified | |
/// Returns a Boolean value indicating whether the value of the first | |
/// argument is less than that of the second argument. | |
/// | |
/// This function is the only requirement of the `Comparable` protocol. The | |
/// remainder of the relational operator functions are implemented by the | |
/// standard library for any type that conforms to `Comparable`. | |
/// | |
/// - Parameters: | |
/// - lhs: A value to compare. | |
/// - rhs: Another value to compare. | |
public static func < (lhs: Task.Priority, rhs: Task.Priority) -> Bool | |
/// Creates a new instance with the specified raw value. | |
/// | |
/// If there is no value of the type that corresponds with the specified raw | |
/// value, this initializer returns `nil`. For example: | |
/// | |
/// enum PaperSize: String { | |
/// case A4, A5, Letter, Legal | |
/// } | |
/// | |
/// print(PaperSize(rawValue: "Legal")) | |
/// // Prints "Optional("PaperSize.Legal")" | |
/// | |
/// print(PaperSize(rawValue: "Tabloid")) | |
/// // Prints "nil" | |
/// | |
/// - Parameter rawValue: The raw value to use for the new instance. | |
public init?(rawValue: Int) | |
/// The raw type that can be used to represent all values of the conforming | |
/// type. | |
/// | |
/// Every distinct value of the conforming type has a corresponding unique | |
/// value of the `RawValue` type, but there may be values of the `RawValue` | |
/// type that don't have a corresponding value of the conforming type. | |
public typealias RawValue = Int | |
/// The corresponding value of the raw type. | |
/// | |
/// A new instance initialized with `rawValue` will be equivalent to this | |
/// instance. For example: | |
/// | |
/// enum PaperSize: String { | |
/// case A4, A5, Letter, Legal | |
/// } | |
/// | |
/// let selectedSize = PaperSize.Letter | |
/// print(selectedSize.rawValue) | |
/// // Prints "Letter" | |
/// | |
/// print(selectedSize == PaperSize(rawValue: selectedSize.rawValue)!) | |
/// // Prints "true" | |
public var rawValue: Int { get } | |
} | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task { | |
/// An affordance to interact with an active task. | |
/// | |
/// You can use a task's handle to wait for its result or cancel the task. | |
/// | |
/// It isn't a programming error to discard a task's handle without awaiting or canceling the task. | |
/// A task runs regardless of whether you still have its handle stored somewhere. | |
/// However, if you discard a task's handle, you give up the ability | |
/// to wait for that task's result or cancel the task. | |
public struct Handle<Success, Failure> where Failure : Error { | |
/// The task that this handle refers to. | |
@available(*, deprecated, message: "Storing `Task` instances has been deprecated and will be removed soon.") | |
public var task: Task { get } | |
/// Wait for the task to complete, returning its result or throw an error. | |
/// | |
/// If the task hasn't completed, its priority increases to the | |
/// priority of the current task. Note that this isn't as effective as | |
/// creating the task with the correct priority. | |
/// | |
/// If the task throws an error, this method propogates that error. | |
/// Tasks that respond to cancellation by throwing `Task.CancellationError` | |
/// have that error propogated here upon cancellation. | |
/// | |
/// - Returns: The task's result. | |
public func get() async throws -> Success | |
/// Wait for the task to complete, returning its result or its error. | |
/// | |
/// If the task hasn't completed, its priority increases to the | |
/// priority of the current task. Note that this isn't as effective as | |
/// creating the task with the correct priority. | |
/// | |
/// If the task throws an error, this method propogates that error. | |
/// Tasks that respond to cancellation by throwing `Task.CancellationError` | |
/// have that error propogated here upon cancellation. | |
/// | |
/// - Returns: If the task succeeded, `.success` | |
/// with the task's result as the associated value; | |
/// otherwise, `.failure` with the error as the associated value. | |
public func getResult() async -> Result<Success, Failure> | |
/// Attempt to cancel the task. | |
/// | |
/// Whether this function has any effect is task-dependent. | |
/// | |
/// For a task to respect cancellation it must cooperatively check for it | |
/// while running. Many tasks check for cancellation before beginning | |
/// their "actual work"; however, this isn't a requirement nor is it guaranteed | |
/// how and when tasks check for cancellation. | |
public func cancel() | |
} | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task : Hashable { | |
/// Hashes the essential components of this value by feeding them into the | |
/// given hasher. | |
/// | |
/// Implement this method to conform to the `Hashable` protocol. The | |
/// components used for hashing must be the same as the components compared | |
/// in your type's `==` operator implementation. Call `hasher.combine(_:)` | |
/// with each of these components. | |
/// | |
/// - Important: Never call `finalize()` on `hasher`. Doing so may become a | |
/// compile-time error in the future. | |
/// | |
/// - Parameter hasher: The hasher to use when combining the components | |
/// of this instance. | |
public func hash(into hasher: inout Hasher) | |
/// The hash value. | |
/// | |
/// Hash values are not guaranteed to be equal across different executions of | |
/// your program. Do not save hash values to use during a future execution. | |
/// | |
/// - Important: `hashValue` is deprecated as a `Hashable` requirement. To | |
/// conform to `Hashable`, implement the `hash(into:)` requirement instead. | |
public var hashValue: Int { get } | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task : Equatable { | |
/// Returns a Boolean value indicating whether two values are equal. | |
/// | |
/// Equality is the inverse of inequality. For any values `a` and `b`, | |
/// `a == b` implies that `a != b` is `false`. | |
/// | |
/// - Parameters: | |
/// - lhs: A value to compare. | |
/// - rhs: Another value to compare. | |
public static func == (lhs: Task, rhs: Task) -> Bool | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task { | |
@available(*, deprecated, message: "`Task.runDetached` was replaced by `detach` and will be removed shortly.") | |
public static func runDetached<T>(priority: Task.Priority = .unspecified, operation: @escaping @Sendable () async throws -> T) -> Task.Handle<T, Error> | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task { | |
/// Suspends the current task | |
/// and waits for at least the given duration before resuming. | |
/// | |
/// This method doesn't guarantee how long the task is suspended. | |
/// Depending on a variety of factors, | |
/// it could be suspended for exactly the given duration, | |
/// or for a longer duration. | |
/// | |
/// Calling this method doesn't block the underlying thread. | |
/// | |
/// - Parameters: | |
/// - duration: The time to sleep, in nanoseconds. | |
public static func sleep(_ duration: UInt64) async | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task { | |
/// Suspends the current task and allows other tasks to execute. | |
/// | |
/// A task can voluntarily suspend itself | |
/// in the middle of a long-running operation | |
/// that doesn't contain any suspension points, | |
/// to let other tasks run for a while | |
/// before execution returns back to this task. | |
/// | |
/// If this task is the highest-priority task in the system, | |
/// the executor immediately resumes execution of the same task. | |
/// As such, | |
/// this method isn't necessarily a way to avoid resource starvation. | |
public static func yield() async | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task { | |
@available(*, deprecated, message: "`Task.unsafeCurrent` was replaced by `withUnsafeCurrentTask { task in ... }`, and will be removed soon.") | |
public static var unsafeCurrent: UnsafeCurrentTask? { get } | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task { | |
/// A Boolean value that indicates whether | |
/// the current task should stop executing. | |
/// | |
/// If there is no current task, the value of this property is `false`. | |
/// | |
/// - SeeAlso: `checkCancellation()` | |
public static var isCancelled: Bool { get } | |
/// A Boolean value that indicates whether the task should stop executing. | |
/// | |
/// - SeeAlso: `checkCancellation()` | |
@available(*, deprecated, message: "Storing `Task` instances has been deprecated and will be removed soon. Use the static 'Task.isCancelled' instead.") | |
public var isCancelled: Bool { get } | |
/// Throws a cancellation error if the current task was canceled. | |
/// | |
/// The error is always an instance of `Task.CancellationError`. | |
/// | |
/// - SeeAlso: `isCancelled()` | |
public static func checkCancellation() throws | |
@available(*, deprecated, message: "`Task.withCancellationHandler` has been replaced by `withTaskCancellationHandler` and will be removed shortly.") | |
public static func withCancellationHandler<T>(handler: @Sendable () -> (), operation: () async throws -> T) async rethrows -> T | |
/// The default error thrown by a canceled task. | |
/// | |
/// The `Task.checkCancellation()` method throws this error | |
/// if the current task has been canceled. | |
/// You can throw this error in your cancellation-checking code, | |
/// or another more specific error if needed. | |
public struct CancellationError : Error { | |
public init() | |
} | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task { | |
@available(*, deprecated, message: "`Task.Group` was replaced by `ThrowingTaskGroup` and `TaskGroup` and will be removed shortly.") | |
public typealias Group<TaskResult> = ThrowingTaskGroup<TaskResult, Error> | |
@available(*, deprecated, message: "`Task.withGroup` was replaced by `withThrowingTaskGroup` and `withTaskGroup` and will be removed shortly.") | |
public static func withGroup<TaskResult, BodyResult>(resultType: TaskResult.Type, returning returnType: BodyResult.Type = BodyResult.self, body: (inout Task.Group<TaskResult>) async throws -> BodyResult) async rethrows -> BodyResult | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task.Priority : Hashable { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task.Priority : RawRepresentable { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task.Handle where Failure == Never { | |
/// Wait for the task to complete and return its result. | |
/// | |
/// If the task hasn't completed, | |
/// its priority increases to that of the current task. | |
/// Note that this might not be as effective as | |
/// creating the task with the correct priority, | |
/// depending on the executor's scheduling details. | |
/// | |
/// The task that this handle refers to might check for cancellation. | |
/// However, because this method is nonthrowing, | |
/// the task needs to handle cancellation using an approach like returning `nil` | |
/// instead of throwing an error. | |
public func get() async -> Success | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task.Handle : Hashable { | |
/// Hashes the essential components of this value by feeding them into the | |
/// given hasher. | |
/// | |
/// Implement this method to conform to the `Hashable` protocol. The | |
/// components used for hashing must be the same as the components compared | |
/// in your type's `==` operator implementation. Call `hasher.combine(_:)` | |
/// with each of these components. | |
/// | |
/// - Important: Never call `finalize()` on `hasher`. Doing so may become a | |
/// compile-time error in the future. | |
/// | |
/// - Parameter hasher: The hasher to use when combining the components | |
/// of this instance. | |
public func hash(into hasher: inout Hasher) | |
/// The hash value. | |
/// | |
/// Hash values are not guaranteed to be equal across different executions of | |
/// your program. Do not save hash values to use during a future execution. | |
/// | |
/// - Important: `hashValue` is deprecated as a `Hashable` requirement. To | |
/// conform to `Hashable`, implement the `hash(into:)` requirement instead. | |
public var hashValue: Int { get } | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task.Handle : Equatable { | |
/// Returns a Boolean value indicating whether two values are equal. | |
/// | |
/// Equality is the inverse of inequality. For any values `a` and `b`, | |
/// `a == b` implies that `a != b` is `false`. | |
/// | |
/// - Parameters: | |
/// - lhs: A value to compare. | |
/// - rhs: Another value to compare. | |
public static func == (lhs: Task.Handle<Success, Failure>, rhs: Task.Handle<Success, Failure>) -> Bool | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension Task.Handle : Sendable { | |
} | |
/// A task group serves as storage for dynamically spawned child tasks. | |
/// | |
/// To create a task group, | |
/// call the `withTaskGroup(of:returning:body:)` method. | |
/// | |
/// A task group must be used only within the task where it was created. | |
/// In most cases, | |
/// the Swift type system prevents a task group from escaping like that | |
/// because adding a child task is a mutating operation, | |
/// and mutation operations can't be performed | |
/// from concurrent execution contexts likes child tasks. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
@frozen public struct TaskGroup<ChildTaskResult> { | |
@available(*, deprecated, message: "`Task.Group.add` has been replaced by `TaskGroup.spawn` or `TaskGroup.spawnUnlessCancelled` and will be removed shortly.") | |
public mutating func add(priority: Task.Priority = .unspecified, operation: @escaping @Sendable () async -> ChildTaskResult) async -> Bool | |
/// Adds a child task to the group. | |
/// | |
/// - Parameters: | |
/// - overridingPriority: The priority of the operation task. | |
/// Omit this parameter or pass `.unspecified` | |
/// to set the child task's priority to the priority of the group. | |
/// - operation: The operation to execute as part of the task group. | |
public mutating func async(priority: Task.Priority? = nil, operation: @escaping @Sendable () async -> ChildTaskResult) | |
/// Adds a child task to the group. | |
/// | |
/// - Parameters: | |
/// - overridingPriority: The priority of the operation task. | |
/// Omit this parameter or pass `.unspecified` | |
/// to set the child task's priority to the priority of the group. | |
/// - operation: The operation to execute as part of the task group. | |
public mutating func spawn(priority: Task.Priority? = nil, operation: @escaping @Sendable () async -> ChildTaskResult) | |
/// Adds a child task to the group, unless the group has been canceled. | |
/// | |
/// - Parameters: | |
/// - overridingPriority: The priority of the operation task. | |
/// Omit this parameter or pass `.unspecified` | |
/// to set the child task's priority to the priority of the group. | |
/// - operation: The operation to execute as part of the task group. | |
/// - Returns: `true` if the operation was added to the group successfully; | |
/// otherwise; `false`. | |
public mutating func asyncUnlessCancelled(priority: Task.Priority? = nil, operation: @escaping @Sendable () async -> ChildTaskResult) -> Bool | |
/// Adds a child task to the group, unless the group has been canceled. | |
/// | |
/// - Parameters: | |
/// - overridingPriority: The priority of the operation task. | |
/// Omit this parameter or pass `.unspecified` | |
/// to set the child task's priority to the priority of the group. | |
/// - operation: The operation to execute as part of the task group. | |
/// - Returns: `true` if the operation was added to the group successfully; | |
/// otherwise; `false`. | |
public mutating func spawnUnlessCancelled(priority: Task.Priority? = nil, operation: @escaping @Sendable () async -> ChildTaskResult) -> Bool | |
/// Wait for the next child task to complete, | |
/// and return the value it returned. | |
/// | |
/// The values returned by successive calls to this method | |
/// appear in the order that the tasks *completed*, | |
/// not in the order that those tasks were added to the task group. | |
/// For example: | |
/// | |
/// group.spawn { 1 } | |
/// group.spawn { 2 } | |
/// | |
/// print(await group.next()) | |
/// // Prints either "2" or "1". | |
/// | |
/// If there aren't any pending tasks in the task group, | |
/// this method returns `nil`, | |
/// which lets you write the following | |
/// to wait for a single task to complete: | |
/// | |
/// if let first = try await group.next() { | |
/// return first | |
/// } | |
/// | |
/// Wait and collect all group child task completions: | |
/// | |
/// while let first = try await group.next() { | |
/// collected += value | |
/// } | |
/// return collected | |
/// | |
/// Awaiting on an empty group | |
/// immediate returns `nil` without suspending. | |
/// | |
/// It's also possible to use `for await` to collect results of a task groups: | |
/// | |
/// for await try value in group { | |
/// collected += value | |
/// } | |
/// | |
/// Don't call this method from outside the task | |
/// where this task group was created. | |
/// In most cases, the Swift type system prevents this mistake; | |
/// for example, because the `add(priority:operation:)` method is mutating, | |
/// that method can't be called from a concurrent execution context like a child task. | |
/// | |
/// - Returns: The value returned by the next child task that completes. | |
public mutating func next() async -> ChildTaskResult? | |
/// A Boolean value that indicates whether the group has any remaining tasks. | |
/// | |
/// At the start of the body of a `withTaskGroup(of:returning:body:)` call, | |
/// the task group is always empty. | |
/// It is guaranteed to be empty when returning from that body | |
/// because a task group waits for all child tasks to complete before returning. | |
/// | |
/// - Returns: `true` if the group has no pending tasks; otherwise `false`. | |
public var isEmpty: Bool { get } | |
/// Cancel all of the remaining tasks in the group. | |
/// | |
/// After canceling a group, adding a new task to it always fails. | |
/// | |
/// Any results, including errors thrown by tasks affected by this | |
/// cancellation, are silently discarded. | |
/// | |
/// This function may be called even from within child (or any other) tasks, | |
/// and causes the group to be canceled. | |
/// | |
/// - SeeAlso: `Task.isCancelled` | |
/// - SeeAlso: `TaskGroup.isCancelled` | |
public func cancelAll() | |
/// A Boolean value that indicates whether the group was canceled. | |
/// | |
/// To cancel a group, call the `TaskGroup.cancelAll()` method. | |
/// | |
/// If the task that's currently running this group is canceled, | |
/// the group is also implicitly canceled, | |
/// which is also reflected in this property's value. | |
public var isCancelled: Bool { get } | |
} | |
/// ==== TaskGroup: AsyncSequence ---------------------------------------------- | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension TaskGroup : AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
public typealias AsyncIterator = TaskGroup<ChildTaskResult>.Iterator | |
/// Creates the asynchronous iterator that produces elements of this | |
/// asynchronous sequence. | |
/// | |
/// - Returns: An instance of the `AsyncIterator` type used to produce | |
/// elements of the asynchronous sequence. | |
public typealias Element = ChildTaskResult | |
public func makeAsyncIterator() -> TaskGroup<ChildTaskResult>.Iterator | |
/// A type that provides an iteration interface | |
/// over the results of tasks added to the group. | |
/// | |
/// The elements returned by this iterator | |
/// appear in the order that the tasks *completed*, | |
/// not in the order that those tasks were added to the task group. | |
/// | |
/// This iterator terminates after all tasks have completed successfully, | |
/// or after any task completes by throwing an error. | |
/// However, it's valid to make a new iterator for the task group, | |
/// which you can use to continue iterating over the group's results. | |
/// For example: | |
/// | |
/// group.spawn { 1 } | |
/// group.spawn { throw SomeError } | |
/// group.spawn { 2 } | |
/// | |
/// do { | |
/// // Assuming the child tasks complete in order, this prints "1" | |
/// // and then throws an error. | |
/// for try await r in group { print(r) } | |
/// } catch { | |
/// // Resolve the error. | |
/// } | |
/// | |
/// // Iterate again. | |
/// for try await r in group { print(r) } | |
/// | |
/// - SeeAlso: `TaskGroup.next()` | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct Iterator : AsyncIteratorProtocol { | |
public typealias Element = ChildTaskResult | |
/// Advances to the result of the next child task, | |
/// or `nil` if there are no remaining child tasks, | |
/// rethrowing an error if the child task threw. | |
/// | |
/// The elements returned from this method | |
/// appear in the order that the tasks *completed*, | |
/// not in the order that those tasks were added to the task group. | |
/// After this method returns `nil`, | |
/// this iterater is guaranteed to never produce more values. | |
/// | |
/// For more information about the iteration order and semantics, | |
/// see `TaskGroup.next()`. | |
public mutating func next() async -> TaskGroup<ChildTaskResult>.Iterator.Element? | |
public mutating func cancel() | |
} | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension TaskGroup : Sendable { | |
} | |
/// Property wrapper that defines a task-local value key. | |
/// | |
/// A task-local value is a value that can be bound and read in the context of a | |
/// `Task`. It is implicitly carried with the task, and is accessible by any | |
/// child tasks the task creates (such as TaskGroup or `async let` created tasks). | |
/// | |
/// ### Task-local declarations | |
/// | |
/// Task locals must be declared as static properties (or global properties, | |
/// once property wrappers support these), like this: | |
/// | |
/// enum TracingExample { | |
/// @TaskLocal | |
/// static let traceID: TraceID? | |
/// } | |
/// | |
/// ### Default values | |
/// Task local values of optional types default to `nil`. It is possible to define | |
/// not-optional task-local values, and an explicit default value must then be | |
/// defined instead. | |
/// | |
/// The default value is returned whenever the task-local is read | |
/// from a context which either: has no task available to read the value from | |
/// (e.g. a synchronous function, called without any asynchronous function in its call stack), | |
/// | |
/// | |
/// ### Reading task-local values | |
/// Reading task local values is simple and looks the same as-if reading a normal | |
/// static property: | |
/// | |
/// guard let traceID = TracingExample.traceID else { | |
/// print("no trace id") | |
/// return | |
/// } | |
/// print(traceID) | |
/// | |
/// It is possible to perform task-local value reads from either asynchronous | |
/// or synchronous functions. Within asynchronous functions, as a "current" task | |
/// is always guaranteed to exist, this will perform the lookup in the task local context. | |
/// | |
/// A lookup made from the context of a synchronous function, that is not called | |
/// from an asynchronous function (!), will immediately return the task-local's | |
/// default value. | |
/// | |
/// ### Binding task-local values | |
/// Task local values cannot be `set` directly and must instead be bound using | |
/// the scoped `$traceID.withValue() { ... }` operation. The value is only bound | |
/// for the duration of that scope, and is available to any child tasks which | |
/// are created within that scope. | |
/// | |
/// Detached tasks do not inherit task-local values, however tasks created using | |
/// the `async {}` operation do inherit task-locals by copying them to the new | |
/// asynchronous task, even though it is an un-structured task. | |
/// | |
/// ### Examples | |
/// | |
/// @TaskLocal | |
/// static var traceID: TraceID? | |
/// | |
/// print("traceID: \(traceID)") // traceID: nil | |
/// | |
/// $traceID.withValue(1234) { // bind the value | |
/// print("traceID: \(traceID)") // traceID: 1234 | |
/// call() // traceID: 1234 | |
/// | |
/// asyncDetached { // detached tasks do not inherit task-local values | |
/// call() // traceID: nil | |
/// } | |
/// | |
/// async { // async tasks do inherit task locals by copying | |
/// call() // traceID: 1234 | |
/// } | |
/// } | |
/// | |
/// | |
/// func call() { | |
/// print("traceID: \(traceID)") // 1234 | |
/// } | |
/// | |
/// This type must be a `class` so it has a stable identity, that is used as key | |
/// value for lookups in the task local storage. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
@propertyWrapper final public class TaskLocal<Value> : CustomStringConvertible { | |
public init(wrappedValue defaultValue: Value) | |
/// Gets the value currently bound to this task-local from the current task. | |
/// | |
/// If no current task is available in the context where this call is made, | |
/// or if the task-local has no value bound, this will return the `defaultValue` | |
/// of the task local. | |
final public func get() -> Value | |
/// Binds the task-local to the specific value for the duration of the operation. | |
/// | |
/// The value is available throughout the execution of the operation closure, | |
/// including any `get` operations performed by child-tasks created during the | |
/// execution of the operation closure. | |
/// | |
/// If the same task-local is bound multiple times, be it in the same task, or | |
/// in specific child tasks, the more specific (i.e. "deeper") binding is | |
/// returned when the value is read. | |
/// | |
/// If the value is a reference type, it will be retained for the duration of | |
/// the operation closure. | |
final public func withValue<R>(_ valueDuringOperation: Value, operation: () async throws -> R, file: String = #file, line: UInt = #line) async rethrows -> R | |
final public var projectedValue: TaskLocal<Value> | |
final public var wrappedValue: Value { get } | |
/// A textual representation of this instance. | |
/// | |
/// Calling this property directly is discouraged. Instead, convert an | |
/// instance of any type to a string by using the `String(describing:)` | |
/// initializer. This initializer works with any type, and uses the custom | |
/// `description` property for types that conform to | |
/// `CustomStringConvertible`: | |
/// | |
/// struct Point: CustomStringConvertible { | |
/// let x: Int, y: Int | |
/// | |
/// var description: String { | |
/// return "(\(x), \(y))" | |
/// } | |
/// } | |
/// | |
/// let p = Point(x: 21, y: 30) | |
/// let s = String(describing: p) | |
/// print(s) | |
/// // Prints "(21, 30)" | |
/// | |
/// The conversion of `p` to a string in the assignment to `s` uses the | |
/// `Point` type's `description` property. | |
final public var description: String { get } | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension TaskLocal : UnsafeSendable { | |
} | |
/// A task group serves as storage for dynamically spawned, | |
/// potentially throwing, child tasks. | |
/// | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
@frozen public struct ThrowingTaskGroup<ChildTaskResult, Failure> where Failure : Error { | |
@available(*, deprecated, message: "`Task.Group.add` has been replaced by `(Throwing)TaskGroup.spawn` or `(Throwing)TaskGroup.spawnUnlessCancelled` and will be removed shortly.") | |
public mutating func add(priority: Task.Priority = .unspecified, operation: @escaping @Sendable () async throws -> ChildTaskResult) async -> Bool | |
/// Adds a child task to the group. | |
/// | |
/// This method doesn't throw an error, even if the child task does. | |
/// Instead, corresponding next call to `TaskGroup.next()` rethrows that error. | |
/// | |
/// - Parameters: | |
/// - overridingPriority: The priority of the operation task. | |
/// Omit this parameter or pass `.unspecified` | |
/// to set the child task's priority to the priority of the group. | |
/// - operation: The operation to execute as part of the task group. | |
public mutating func async(priority: Task.Priority? = nil, operation: @escaping @Sendable () async throws -> ChildTaskResult) | |
/// Adds a child task to the group. | |
/// | |
/// This method doesn't throw an error, even if the child task does. | |
/// Instead, corresponding next call to `TaskGroup.next()` rethrows that error. | |
/// | |
/// - Parameters: | |
/// - overridingPriority: The priority of the operation task. | |
/// Omit this parameter or pass `.unspecified` | |
/// to set the child task's priority to the priority of the group. | |
/// - operation: The operation to execute as part of the task group. | |
public mutating func spawn(priority: Task.Priority? = nil, operation: @escaping @Sendable () async throws -> ChildTaskResult) | |
/// Adds a child task to the group, unless the group has been canceled. | |
/// | |
/// This method doesn't throw an error, even if the child task does. | |
/// Instead, the corresponding call to `TaskGroup.next()` rethrows that error. | |
/// | |
/// - Parameters: | |
/// - overridingPriority: The priority of the operation task. | |
/// Omit this parameter or pass `.unspecified` | |
/// to set the child task's priority to the priority of the group. | |
/// - operation: The operation to execute as part of the task group. | |
/// - Returns: `true` if the operation was added to the group successfully; | |
/// otherwise `false`. | |
public mutating func asyncUnlessCancelled(priority: Task.Priority? = nil, operation: @escaping @Sendable () async throws -> ChildTaskResult) -> Bool | |
/// Adds a child task to the group, unless the group has been canceled. | |
/// | |
/// This method doesn't throw an error, even if the child task does. | |
/// Instead, the corresponding call to `TaskGroup.next()` rethrows that error. | |
/// | |
/// - Parameters: | |
/// - overridingPriority: The priority of the operation task. | |
/// Omit this parameter or pass `.unspecified` | |
/// to set the child task's priority to the priority of the group. | |
/// - operation: The operation to execute as part of the task group. | |
/// - Returns: `true` if the operation was added to the group successfully; | |
/// otherwise `false`. | |
public mutating func spawnUnlessCancelled(priority: Task.Priority? = nil, operation: @escaping @Sendable () async throws -> ChildTaskResult) -> Bool | |
/// Wait for the next child task to complete, | |
/// and return the value it returned or rethrow the error it threw. | |
/// | |
/// The values returned by successive calls to this method | |
/// appear in the order that the tasks *completed*, | |
/// not in the order that those tasks were added to the task group. | |
/// For example: | |
/// | |
/// group.spawn { 1 } | |
/// group.spawn { 2 } | |
/// | |
/// await print(group.next()) | |
/// // Prints either "2" or "1". | |
/// | |
/// If there aren't any pending tasks in the task group, | |
/// this method returns `nil`, | |
/// which lets you write like the following | |
/// to wait for a single task to complete: | |
/// | |
/// if let first = try await group.next() { | |
/// return first | |
/// } | |
/// | |
/// Wait and collect all group child task completions: | |
/// | |
/// while let first = try await group.next() { | |
/// collected += value | |
/// } | |
/// return collected | |
/// | |
/// Awaiting on an empty group | |
/// immediate returns `nil` without suspending. | |
/// | |
/// It's also possible to use `for await` to collect results of a task groups: | |
/// | |
/// for await try value in group { | |
/// collected += value | |
/// } | |
/// | |
/// If the next child task throws an error | |
/// and you propagate that error from this method | |
/// out of the body of a `TaskGroup.withThrowingTaskGroup(of:returning:body:)` call, | |
/// then all remaining child tasks in that group are implicitly canceled. | |
/// | |
/// Don't call this method from outside the task | |
/// where this task group was created. | |
/// In most cases, the Swift type system prevents this mistake; | |
/// for example, because the `add(priority:operation:)` method is mutating, | |
/// that method can't be called from a concurrent execution context like a child task. | |
/// | |
/// - Returns: The value returned by the next child task that completes. | |
/// | |
/// - Throws: The error thrown by the next child task that completes. | |
/// | |
/// - SeeAlso: `nextResult()` | |
public mutating func next() async throws -> ChildTaskResult? | |
/// Wait for the next child task to complete, | |
/// and return a result containing either | |
/// the value that the child task returned or the error that it threw. | |
/// | |
/// The values returned by successive calls to this method | |
/// appear in the order that the tasks *completed*, | |
/// not in the order that those tasks were added to the task group. | |
/// For example: | |
/// | |
/// group.spawn { 1 } | |
/// group.spawn { 2 } | |
/// | |
/// guard let result = await group.nextResult() else { | |
/// return // No task to wait on, which won't happen in this example. | |
/// } | |
/// | |
/// switch result { | |
/// case .success(let value): print(value) | |
/// case .failure(let error): print("Failure: \(error)") | |
/// } | |
/// // Prints either "2" or "1". | |
/// | |
/// If the next child task throws an error | |
/// and you propagate that error from this method | |
/// out of the body of a `ThrowingTaskGroup.withThrowingTaskGroup(of:returning:body:)` call, | |
/// then all remaining child tasks in that group are implicitly canceled. | |
/// | |
/// - Returns: A `Result.success` value | |
/// containing the value that the child task returned, | |
/// or a `Result.failure` value | |
/// containing the error that the child task threw. | |
/// | |
/// - SeeAlso: `next()` | |
public mutating func nextResult() async throws -> Result<ChildTaskResult, Failure>? | |
/// A Boolean value that indicates whether the group has any remaining tasks. | |
/// | |
/// At the start of the body of a `withThrowingTaskGroup(of:returning:body:)` call, | |
/// the task group is always empty. | |
/// It's guaranteed to be empty when returning from that body | |
/// because a task group waits for all child tasks to complete before returning. | |
/// | |
/// - Returns: `true` if the group has no pending tasks; otherwise `false`. | |
public var isEmpty: Bool { get } | |
/// Cancel all of the remaining tasks in the group. | |
/// | |
/// After canceling a group, adding a new task to it always fails. | |
/// | |
/// Any results, including errors thrown by tasks affected by this | |
/// cancellation, are silently discarded. | |
/// | |
/// This function may be called even from within child (or any other) tasks, | |
/// and causes the group to be canceled. | |
/// | |
/// - SeeAlso: `Task.isCancelled` | |
/// - SeeAlso: `TaskGroup.isCancelled` | |
public func cancelAll() | |
/// A Boolean value that indicates whether the group was canceled. | |
/// | |
/// To cancel a group, call the `ThrowingTaskGroup.cancelAll()` method. | |
/// | |
/// If the task that's currently running this group is canceled, | |
/// the group is also implicitly canceled, | |
/// which is also reflected in this property's value. | |
public var isCancelled: Bool { get } | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension ThrowingTaskGroup : AsyncSequence { | |
/// The type of element produced by this asynchronous sequence. | |
public typealias AsyncIterator = ThrowingTaskGroup<ChildTaskResult, Failure>.Iterator | |
/// Creates the asynchronous iterator that produces elements of this | |
/// asynchronous sequence. | |
/// | |
/// - Returns: An instance of the `AsyncIterator` type used to produce | |
/// elements of the asynchronous sequence. | |
public typealias Element = ChildTaskResult | |
public func makeAsyncIterator() -> ThrowingTaskGroup<ChildTaskResult, Failure>.Iterator | |
/// A type that provides an iteration interface | |
/// over the results of tasks added to the group. | |
/// | |
/// The elements returned by this iterator | |
/// appear in the order that the tasks *completed*, | |
/// not in the order that those tasks were added to the task group. | |
/// | |
/// This iterator terminates after all tasks have completed successfully, | |
/// or after any task completes by throwing an error. | |
/// If a task completes by throwing an error, | |
/// no further task results are returned. | |
/// | |
/// - SeeAlso: `ThrowingTaskGroup.next()` | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct Iterator : AsyncIteratorProtocol { | |
public typealias Element = ChildTaskResult | |
/// Advances to the result of the next child task, | |
/// or `nil` if there are no remaining child tasks, | |
/// rethrowing an error if the child task threw. | |
/// | |
/// The elements returned from this method | |
/// appear in the order that the tasks *completed*, | |
/// not in the order that those tasks were added to the task group. | |
/// After this method returns `nil`, | |
/// this iterater is guaranteed to never produce more values. | |
/// | |
/// For more information about the iteration order and semantics, | |
/// see `ThrowingTaskGroup.next()` | |
public mutating func next() async throws -> ThrowingTaskGroup<ChildTaskResult, Failure>.Iterator.Element? | |
public mutating func cancel() | |
} | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension ThrowingTaskGroup : Sendable { | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
@frozen public struct UnownedExecutorRef : Equatable { | |
/// Returns a Boolean value indicating whether two values are equal. | |
/// | |
/// Equality is the inverse of inequality. For any values `a` and `b`, | |
/// `a == b` implies that `a != b` is `false`. | |
/// | |
/// - Parameters: | |
/// - lhs: A value to compare. | |
/// - rhs: Another value to compare. | |
public static func == (a: UnownedExecutorRef, b: UnownedExecutorRef) -> Bool | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension UnownedExecutorRef : Sendable { | |
} | |
/// A mechanism to interface | |
/// between synchronous and asynchronous code, | |
/// without correctness checking. | |
/// | |
/// A *continuation* is an opaque representation of program state. | |
/// To create a continuation in asynchronous code, | |
/// call the `withUnsafeContinuation(_:)` or | |
/// `withUnsafeThrowingContinuation(_:)` function. | |
/// To resume the asynchronous task, | |
/// call the `resume(returning:)`, | |
/// `resume(throwing:)`, | |
/// `resume(with:)`, | |
/// or `resume()` method. | |
/// | |
/// - Important: You must call a resume methods exactly once | |
/// on every execution path throughout the program. | |
/// Resuming from a continuation more than once is undefined behavior. | |
/// Never resuming leaves the task in a suspended state indefinitely, | |
/// and leaks any associated resources. | |
/// | |
/// `CheckedContinuation` performs runtime checks | |
/// for missing or multiple resume operations. | |
/// `UnsafeContinuation` avoids enforcing these invariants at runtime | |
/// because it aims to be a low-overhead mechanism | |
/// for interfacing Swift tasks with | |
/// event loops, delegate methods, callbacks, | |
/// and other non-`async` scheduling mechanisms. | |
/// However, during development, the ability to verify that the | |
/// invariants are being upheld in testing is important. | |
/// Because both types have the same interface, | |
/// you can replace one with the other in most circumstances, | |
/// without making other changes. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
@frozen public struct UnsafeContinuation<T, E> where E : Error { | |
/// Resume the task that's awaiting the continuation | |
/// by returning the given value. | |
/// | |
/// - Parameter value: The value to return from the continuation. | |
/// | |
/// A continuation must be resumed exactly once. | |
/// If the continuation has already resumed, | |
/// then calling this method results in undefined behavior. | |
/// | |
/// After calling this method, | |
/// control immediately returns to the caller. | |
/// The task continues executing | |
/// when its executor schedules it. | |
public func resume(returning value: T) where E == Never | |
/// Resume the task that's awaiting the continuation | |
/// by returning the given value. | |
/// | |
/// - Parameter value: The value to return from the continuation. | |
/// | |
/// A continuation must be resumed exactly once. | |
/// If the continuation has already resumed, | |
/// then calling this method results in undefined behavior. | |
/// | |
/// After calling this method, | |
/// control immediately returns to the caller. | |
/// The task continues executing | |
/// when its executor schedules it. | |
public func resume(returning value: T) | |
/// Resume the task that's awaiting the continuation | |
/// by throwing the given error. | |
/// | |
/// - Parameter error: The error to throw from the continuation. | |
/// | |
/// A continuation must be resumed exactly once. | |
/// If the continuation has already resumed, | |
/// then calling this method results in undefined behavior. | |
/// | |
/// After calling this method, | |
/// control immediately returns to the caller. | |
/// The task continues executing | |
/// when its executor schedules it. | |
public func resume(throwing error: E) | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension UnsafeContinuation { | |
/// Resume the task that's awaiting the continuation | |
/// by returning or throwing the given result value. | |
/// | |
/// - Parameter result: The result. | |
/// If it contains a `.success` value, | |
/// the continuation returns that value; | |
/// otherwise, it throws the `.error` value. | |
/// | |
/// A continuation must be resumed exactly once. | |
/// If the continuation has already resumed, | |
/// then calling this method results in undefined behavior. | |
/// | |
/// After calling this method, | |
/// control immediately returns to the caller. | |
/// The task continues executing | |
/// when its executor schedules it. | |
public func resume<Er>(with result: Result<T, Er>) where E == Error, Er : Error | |
/// Resume the task that's awaiting the continuation | |
/// by returning or throwing the given result value. | |
/// | |
/// - Parameter result: The result. | |
/// If it contains a `.success` value, | |
/// the continuation returns that value; | |
/// otherwise, it throws the `.error` value. | |
/// | |
/// A continuation must be resumed exactly once. | |
/// If the continuation has already resumed, | |
/// then calling this method results in undefined behavior. | |
/// | |
/// After calling this method, | |
/// control immediately returns to the caller. | |
/// The task continues executing | |
/// when its executor schedules it. | |
public func resume(with result: Result<T, E>) | |
/// Resume the task that's awaiting the continuation by returning. | |
/// | |
/// A continuation must be resumed exactly once. | |
/// If the continuation has already resumed, | |
/// then calling this method results in undefined behavior. | |
/// | |
/// After calling this method, | |
/// control immediately returns to the caller. | |
/// The task continues executing | |
/// when its executor schedules it. | |
public func resume() where T == Void | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension UnsafeContinuation : Sendable { | |
} | |
/// An unsafe task handle for the current task. | |
/// | |
/// To get an instance of `UnsafeCurrentTask` for the current task, | |
/// call the `withUnsafeCurrentTask(body:)` method. | |
/// Don't try to store an unsafe task handle | |
/// for use outside that method's closure. | |
/// Storing an unsafe task handle doesn't have an impact on the task's actual life cycle, | |
/// and the behavior of accessing an unsafe task handle | |
/// outside of the `withUnsafeCurrentTask(body:)` method's closure isn't defined. | |
/// Instead, use the `task` property of `UnsafeCurrentTask` | |
/// to access an instance of `Task` that you can store long-term | |
/// and interact with outside of the closure body. | |
/// | |
/// Only APIs on `UnsafeCurrentTask` that are also part of `Task` | |
/// are safe to invoke from another task | |
/// besides the one that this task handle represents. | |
/// Calling other APIs from another task is undefined behavior, | |
/// breaks invariants in other parts of the program running on this task, | |
/// and may lead to crashes or data loss. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct UnsafeCurrentTask { | |
/// The current task, | |
/// represented in a way that's safe to store for later use. | |
/// | |
/// Operations on an instance of `Task` are safe to call from any other task, | |
/// unlike `UnsafeCurrentTask`. | |
@available(*, deprecated, message: "Storing `Task` instances has been deprecated and will be removed soon.") | |
public var task: Task { get } | |
/// A Boolean value that indicates whether the current task was canceled. | |
/// | |
/// After the value of this property is `true`, it remains `true` indefinitely. | |
/// There is no way to uncancel the operation. | |
/// | |
/// - SeeAlso: `checkCancellation()` | |
public var isCancelled: Bool { get } | |
/// The current task's priority. | |
/// | |
/// - SeeAlso: `Task.currentPriority` | |
public var priority: Task.Priority { get } | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension UnsafeCurrentTask : Hashable { | |
/// Hashes the essential components of this value by feeding them into the | |
/// given hasher. | |
/// | |
/// Implement this method to conform to the `Hashable` protocol. The | |
/// components used for hashing must be the same as the components compared | |
/// in your type's `==` operator implementation. Call `hasher.combine(_:)` | |
/// with each of these components. | |
/// | |
/// - Important: Never call `finalize()` on `hasher`. Doing so may become a | |
/// compile-time error in the future. | |
/// | |
/// - Parameter hasher: The hasher to use when combining the components | |
/// of this instance. | |
public func hash(into hasher: inout Hasher) | |
/// The hash value. | |
/// | |
/// Hash values are not guaranteed to be equal across different executions of | |
/// your program. Do not save hash values to use during a future execution. | |
/// | |
/// - Important: `hashValue` is deprecated as a `Hashable` requirement. To | |
/// conform to `Hashable`, implement the `hash(into:)` requirement instead. | |
public var hashValue: Int { get } | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension UnsafeCurrentTask : Equatable { | |
/// Returns a Boolean value indicating whether two values are equal. | |
/// | |
/// Equality is the inverse of inequality. For any values `a` and `b`, | |
/// `a == b` implies that `a != b` is `false`. | |
/// | |
/// - Parameters: | |
/// - lhs: A value to compare. | |
/// - rhs: Another value to compare. | |
public static func == (lhs: UnsafeCurrentTask, rhs: UnsafeCurrentTask) -> Bool | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension UnsafeCurrentTask { | |
/// Allows for executing a synchronous `operation` while binding a task-local value | |
/// in the current task. | |
/// | |
/// This function MUST NOT be invoked by any other task than the current task | |
/// represented by this object. | |
public func withTaskLocal<Value, R>(_ taskLocal: TaskLocal<Value>, boundTo valueDuringOperation: Value, operation: () throws -> R, file: String = #file, line: UInt = #line) rethrows -> R | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
@available(*, deprecated, message: "please use UnsafeContination<..., Error>") | |
public typealias UnsafeThrowingContinuation<T> = UnsafeContinuation<T, Error> | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public struct YieldingContinuation<Element, Failure> where Failure : Error { | |
/// Construct a YieldingContinuation. | |
/// | |
/// This continuation type can be called more than once, unlike the unsafe and | |
/// checked counterparts. Each call to the yielding functions will resume any | |
/// awaiter on the next function. This type is inherently sendable and can | |
/// safely be used and stored in multiple task contexts. | |
public init() | |
/// Construct a YieldingContinuation with specific types including a failure. | |
/// | |
/// This continuation type can be called more than once, unlike the unsafe and | |
/// checked counterparts. Each call to the yielding functions will resume any | |
/// awaiter on the next function. This type is inherently sendable and can | |
/// safely be used and stored in multiple task contexts. | |
public init(yielding: Element.Type, throwing: Failure.Type) | |
/// Resume the task awaiting next by having it return normally from its | |
/// suspension point. | |
/// | |
/// - Parameter value: The value to return from an awaiting call to next. | |
/// | |
/// Unlike other continuations `YieldingContinuation` may resume more than | |
/// once. However if there are no potential awaiting calls to `next` this | |
/// function will return false, indicating that the caller needs to decide how | |
/// the behavior should be handled. | |
public func yield(_ value: Element) -> Bool | |
/// Resume the task awaiting the continuation by having it throw an error | |
/// from its suspension point. | |
/// | |
/// - Parameter error: The error to throw from an awaiting call to next. | |
/// | |
/// Unlike other continuations `YieldingContinuation` may resume more than | |
/// once. However if there are no potential awaiting calls to `next` this | |
/// function will return false, indicating that the caller needs to decide how | |
/// the behavior should be handled. | |
public func yield(throwing error: Failure) -> Bool | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension YieldingContinuation where Failure == Error { | |
/// Await a resume from a call to a yielding function. | |
/// | |
/// - Return: The element that was yielded or a error that was thrown. | |
/// | |
/// When multiple calls are awaiting a produced value from next any call to | |
/// yield will resume all awaiting calls to next with that value. | |
public func next() async throws -> Element | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension YieldingContinuation where Failure == Never { | |
/// Construct a YieldingContinuation with a specific Element type. | |
/// | |
/// This continuation type can be called more than once, unlike the unsafe and | |
/// checked counterparts. Each call to the yielding functions will resume any | |
/// awaiter on the next function. This type is inherently sendable and can | |
/// safely be used and stored in multiple task contexts. | |
public init(yielding: Element.Type) | |
/// Await a resume from a call to a yielding function. | |
/// | |
/// - Return: The element that was yielded. | |
public func next() async -> Element | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension YieldingContinuation { | |
/// Resume the task awaiting the continuation by having it either | |
/// return normally or throw an error based on the state of the given | |
/// `Result` value. | |
/// | |
/// - Parameter result: A value to either return or throw from the | |
/// continuation. | |
/// | |
/// Unlike other continuations `YieldingContinuation` may resume more than | |
/// once. However if there are no potential awaiting calls to `next` this | |
/// function will return false, indicating that the caller needs to decide how | |
/// the behavior should be handled. | |
public func yield<Er>(with result: Result<Element, Er>) -> Bool where Failure == Error, Er : Error | |
/// Resume the task awaiting the continuation by having it either | |
/// return normally or throw an error based on the state of the given | |
/// `Result` value. | |
/// | |
/// - Parameter result: A value to either return or throw from the | |
/// continuation. | |
/// | |
/// Unlike other continuations `YieldingContinuation` may resume more than | |
/// once. However if there are no potential awaiting calls to `next` this | |
/// function will return false, indicating that the caller needs to decide how | |
/// the behavior should be handled. | |
public func yield(with result: Result<Element, Failure>) -> Bool | |
/// Resume the task awaiting the continuation by having it return normally | |
/// from its suspension point. | |
/// | |
/// Unlike other continuations `YieldingContinuation` may resume more than | |
/// once. However if there are no potential awaiting calls to `next` this | |
/// function will return false, indicating that the caller needs to decide how | |
/// the behavior should be handled. | |
public func yield() -> Bool where Element == Void | |
} | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
extension YieldingContinuation : Sendable { | |
} | |
/// Runs the given nonthrowing operation asynchronously | |
/// as part of a new top-level task on behalf of the current actor. | |
/// | |
/// Use this function when creating asynchronous work | |
/// that operates on behalf of the synchronous function that calls it. | |
/// Like `detach(priority:operation:)`, | |
/// this function creates a separate, top-level task. | |
/// Unlike `detach(priority:operation:)`, | |
/// the task created by `async(priority:operation:)` | |
/// inherits the priority and actor context of the caller, | |
/// so the operation is treated more like an asynchronous extension | |
/// to the synchronous operation. | |
/// | |
/// - Parameters: | |
/// - priority: The priority of the task. | |
/// Pass `nil` to use the priority from `Task.currentPriority`. | |
/// - operation: The operation to perform. | |
/// | |
/// - Returns: A handle to the task. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public func async<T>(priority: Task.Priority? = nil, operation: @escaping @Sendable () async -> T) -> Task.Handle<T, Never> | |
/// Runs the given throwing operation asynchronously | |
/// as part of a new top-level task on behalf of the current actor. | |
/// | |
/// Use this function when creating asynchronous work | |
/// that operates on behalf of the synchronous function that calls it. | |
/// Like `detach(priority:operation:)`, | |
/// this function creates a separate, top-level task. | |
/// Unlike `detach(priority:operation:)`, | |
/// the task created by `async(priority:operation:)` | |
/// inherits the priority and actor context of the caller, | |
/// so the operation is treated more like an asynchronous extension | |
/// to the synchronous operation. | |
/// | |
/// - Parameters: | |
/// - priority: The priority of the task. | |
/// Pass `nil` to use the priority from `Task.currentPriority`. | |
/// - operation: The operation to perform. | |
/// | |
/// - Returns: A handle to the task. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public func async<T>(priority: Task.Priority? = nil, operation: @escaping @Sendable () async throws -> T) -> Task.Handle<T, Error> | |
/// Runs the given nonthrowing operation asynchronously | |
/// as part of a new top-level task. | |
/// | |
/// Avoid using a detached task unless it isn't possible | |
/// to model the operation using structured concurrency features like child tasks. | |
/// Child tasks inherit the parent task's priority and task-local storage, | |
/// and canceling a parent task automatically cancels all of its child tasks. | |
/// You need to handle these considerations manually with a detached task. | |
/// | |
/// A detached task runs to completion | |
/// unless it is explicitly canceled by calling the `Task.Handle.cancel()` method. | |
/// Specifically, dropping a detached task's handle | |
/// doesn't cancel that task. | |
/// | |
/// - Parameters: | |
/// - priority: The priority of the task. | |
/// - operation: The operation to perform. | |
/// | |
/// - Returns: A handle to the task. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public func asyncDetached<T>(priority: Task.Priority? = nil, operation: @escaping @Sendable () async -> T) -> Task.Handle<T, Never> | |
/// Runs the given throwing operation asynchronously | |
/// as part of a new top-level task. | |
/// | |
/// If the operation throws an error, this method propogates that error. | |
/// | |
/// Don't use a detached task unless it isn't possible | |
/// to model the operation using structured concurrency features like child tasks. | |
/// Child tasks inherit the parent task's priority and task-local storage, | |
/// and canceling a parent task automatically cancels all of its child tasks. | |
/// You need to handle these considerations manually with a detached task. | |
/// | |
/// A detached task runs to completion | |
/// unless it is explicitly canceled by calling the `Task.Handle.cancel()` method. | |
/// Specifically, dropping a detached task's handle | |
/// doesn't cancel that task. | |
/// | |
/// - Parameters: | |
/// - priority: The priority of the task. | |
/// - operation: The operation to perform. | |
/// | |
/// - Returns: A handle to the task. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public func asyncDetached<T>(priority: Task.Priority? = nil, operation: @escaping @Sendable () async throws -> T) -> Task.Handle<T, Error> | |
/// Runs the given nonthrowing operation asynchronously | |
/// as part of a new top-level task. | |
/// | |
/// Don't use a detached task unless it isn't possible | |
/// to model the operation using structured concurrency features like child tasks. | |
/// Child tasks inherit the parent task's priority and task-local storage, | |
/// and canceling a parent task automatically cancels all of its child tasks. | |
/// You need to handle these considerations manually with a detached task. | |
/// | |
/// You need to keep a reference to the task's handle | |
/// if you need to cancel it by calling the `Task.Handle.cancel()` method. | |
/// Discarding a detached task's handle doesn't implicitly cancel that task, | |
/// it only makes it impossible for you to explicitly cancel the task. | |
/// | |
/// - Parameters: | |
/// - priority: The priority of the task. | |
/// - operation: The operation to perform. | |
/// | |
/// - Returns: A handle to the task. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public func detach<T>(priority: Task.Priority = .unspecified, operation: @escaping @Sendable () async -> T) -> Task.Handle<T, Never> | |
/// Runs the given throwing operation asynchronously | |
/// as part of a new top-level task. | |
/// | |
/// If the operation throws an error, this method propogates that error. | |
/// | |
/// Avoid using a detached task unless it isn't possible | |
/// to model the operation using structured concurrency features like child tasks. | |
/// Child tasks inherit the parent task's priority and task-local storage, | |
/// and canceling a parent task automatically cancels all of its child tasks. | |
/// You need to handle these considerations manually with a detached task. | |
/// | |
/// A detached task runs to completion | |
/// unless it is explicitly canceled by calling the `Task.Handle.cancel()` method. | |
/// Specifically, dropping a detached task's handle | |
/// doesn't cancel that task. | |
/// | |
/// - Parameters: | |
/// - priority: The priority of the task. | |
/// - operation: The operation to perform. | |
/// | |
/// - Returns: A handle to the task. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public func detach<T>(priority: Task.Priority = .unspecified, operation: @escaping @Sendable () async throws -> T) -> Task.Handle<T, Error> | |
public func swift_deletedAsyncMethodError() async | |
/// Suspends the current task, | |
/// then calls the given closure with a checked continuation for the current task. | |
/// | |
/// - Parameters: | |
/// - function: A string identifying the declaration that is the notional | |
/// source for the continuation, used to identify the continuation in | |
/// runtime diagnostics related to misuse of this continuation. | |
/// - body: A closure that takes an `UnsafeContinuation` parameter. | |
/// You must resume the continuation exactly once. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public func withCheckedContinuation<T>(function: String = #function, _ body: (CheckedContinuation<T, Never>) -> Void) async -> T | |
/// Suspends the current task, | |
/// then calls the given closure with a checked throwing continuation for the current task. | |
/// | |
/// - Parameters: | |
/// - function: A string identifying the declaration that is the notional | |
/// source for the continuation, used to identify the continuation in | |
/// runtime diagnostics related to misuse of this continuation. | |
/// - body: A closure that takes an `UnsafeContinuation` parameter. | |
/// You must resume the continuation exactly once. | |
/// | |
/// If `resume(throwing:)` is called on the continuation, | |
/// this function throws that error. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public func withCheckedThrowingContinuation<T>(function: String = #function, _ body: (CheckedContinuation<T, Error>) -> Void) async throws -> T | |
/// Execute an operation with a cancellation handler that's immediately | |
/// invoked if the current task is canceled. | |
/// | |
/// This differs from the operation cooperatively checking for cancellation | |
/// and reacting to it in that the cancellation handler is _always_ and | |
/// _immediately_ invoked when the task is canceled. For example, even if the | |
/// operation is running code that never checks for cancellation, a cancellation | |
/// handler still runs and provides a chance to run some cleanup code. | |
/// | |
/// Doesn't check for cancellation, and always executes the passed `operation`. | |
/// | |
/// This function returns immediately and never suspends. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public func withTaskCancellationHandler<T>(handler: @Sendable () -> (), operation: () async throws -> T) async rethrows -> T | |
/// Starts a new scope in which a dynamic number of tasks can be spawned. | |
/// | |
/// When the group returns, | |
/// it implicitly waits for all spawned tasks to complete. | |
/// The tasks are canceled only if `cancelAll()` was invoked before returning, | |
/// if the group's task was canceled. | |
/// | |
/// After this method returns, the task group is guaranteed to be empty. | |
/// | |
/// To collect the results of tasks that were added to the group, | |
/// you can use the following pattern: | |
/// | |
/// var sum = 0 | |
/// for await result in group { | |
/// sum += result | |
/// } | |
/// | |
/// If you need more control or only a few results, | |
/// you can use a pattern like the following: | |
/// | |
/// guard let first = await group.next() { | |
/// group.cancelAll() | |
/// return 0 | |
/// } | |
/// let second = await group.next() ?? 0 | |
/// group.cancelAll() | |
/// return first + second | |
/// | |
/// Task Group Cancellation | |
/// ======================= | |
/// | |
/// Canceling the task in which the group is running | |
/// also cancels the group and all of its child tasks. | |
/// | |
/// If you call `spawn(priority:operation:)` to create a new task in a canceled group, | |
/// that task is immediately canceled after creation. | |
/// Alternatively, you can call `spawnUnlessCancelled(priority:operation:)`, | |
/// which doesn't spawn the task if the group has already been canceled | |
/// Choosing between these two functions | |
/// lets you control how to react to cancellation within a group: | |
/// some child tasks need to run regardless of cancellation | |
/// and others are better not even being spawned | |
/// knowing they can't produce useful results. | |
/// | |
/// Because the tasks you add to a group with this method are nonthrowing, | |
/// those tasks can't respond to cancellation by throwing `CancellationError`. | |
/// The tasks must handle cancellation in some other way, | |
/// such as returning the work completed so far, returning an empty result, or returning `nil`. | |
/// For tasks that need to handle cancellation by throwing an error, | |
/// use the `withThrowingTaskGroup(of:returning:body:)` method instead. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
@inlinable public func withTaskGroup<ChildTaskResult, GroupResult>(of childTaskResultType: ChildTaskResult.Type, returning returnType: GroupResult.Type = GroupResult.self, body: (inout TaskGroup<ChildTaskResult>) async -> GroupResult) async -> GroupResult | |
/// Starts a new scope in which a dynamic number of throwing tasks can be spawned. | |
/// | |
/// When the group returns, | |
/// it implicitly waits for all spawned tasks to complete. | |
/// The tasks are canceled only if `cancelAll()` was invoked before returning, | |
/// if the group's task was canceled, | |
/// or if the group's body throws an error. | |
/// | |
/// After this method returns, the task group is guaranteed to be empty. | |
/// | |
/// To collect the results of tasks that were added to the group, | |
/// you can use the following pattern: | |
/// | |
/// var sum = 0 | |
/// for await result in group { | |
/// sum += result | |
/// } | |
/// | |
/// If you need more control or only a few results, | |
/// you can use a pattern like the following: | |
/// | |
/// guard let first = await group.next() { | |
/// group.cancelAll() | |
/// return 0 | |
/// } | |
/// let second = await group.next() ?? 0 | |
/// group.cancelAll() | |
/// return first + second | |
/// | |
/// Task Group Cancellation | |
/// ======================= | |
/// | |
/// Canceling the task in which the group is running | |
/// also cancels the group and all of its child tasks. | |
/// | |
/// If you call `spawn(priority:operation:)` to create a new task in a canceled group, | |
/// that task is is immediately canceled after being created. | |
/// Alternatively, you can call `spawnUnlessCancelled(priority:operation:)`, | |
/// which doesn't spawn the task if the group has already been canceled | |
/// Choosing between these two functions | |
/// lets you control how to react to cancellation within a group: | |
/// some child tasks need to run regardless of cancellation | |
/// and others are better not even being spawned | |
/// knowing they can't produce useful results. | |
/// | |
/// Throwing an error in one of the tasks of a task group | |
/// doesn't immediately cancel the other tasks in that group. | |
/// However, | |
/// if you call `next()` in the task group and propogate its error, | |
/// all other tasks are canceled. | |
/// For example, in the code below, | |
/// nothing is canceled and the group doesn't throw an error: | |
/// | |
/// withThrowingTaskGroup { group in | |
/// group.spawn { throw SomeError() } | |
/// } | |
/// | |
/// In contrast, this example throws `SomeError` | |
/// and cancels all of the tasks in the group: | |
/// | |
/// withThrowingTaskGroup { group in | |
/// group.spawn { throw SomeError() } | |
/// try group.next() | |
/// } | |
/// | |
/// An individual task throws its error | |
/// in the corresponding call to `Group.next()`, | |
/// which gives you a chance to handle individual error | |
/// or to let the error be rethrown by the group. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
@inlinable public func withThrowingTaskGroup<ChildTaskResult, GroupResult>(of childTaskResultType: ChildTaskResult.Type, returning returnType: GroupResult.Type = GroupResult.self, body: (inout ThrowingTaskGroup<ChildTaskResult, Error>) async throws -> GroupResult) async rethrows -> GroupResult | |
/// Suspends the current task, | |
/// then calls the given closure with the an unsafe continuation for the current task. | |
/// | |
/// - Parameter fn: A closure that takes an `UnsafeContinuation` parameter. | |
/// You must resume the continuation exactly once. | |
/// | |
/// - Returns: The value passed to the continuation by the closure. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public func withUnsafeContinuation<T>(_ fn: (UnsafeContinuation<T, Never>) -> Void) async -> T | |
/// Calls a closure with an unsafe handle to current task. | |
/// | |
/// If you call this function from the body of an asynchronous function, | |
/// the unsafe task handle passed to the closure is always non-nil | |
/// because an asynchronous function always runs in the context of a task. | |
/// However if you call this function from the body of a synchronous function, | |
/// and that function isn't executing in the context of any task, | |
/// the unsafe task handle is `nil`. | |
/// | |
/// Don't store an unsafe task handle | |
/// for use outside this method's closure. | |
/// Storing an unsafe task handle doesn't have an impact on the task's actual life cycle, | |
/// and the behavior of accessing an unsafe task handle | |
/// outside of the `withUnsafeCurrentTask(body:)` method's closure isn't defined. | |
/// Instead, use the `task` property of `UnsafeCurrentTask` | |
/// to access an instance of `Task` that you can store long-term | |
/// and interact with outside of the closure body. | |
/// | |
/// - Parameters: | |
/// - body: A closure that takes an `UnsafeCurrentTask` parameter. | |
/// If `body` has a return value, | |
/// that value is also used as the return value | |
/// for the `withUnsafeCurrentTask(body:)` function. | |
/// | |
/// - Returns: The return value, if any, of the `body` closure. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public func withUnsafeCurrentTask<T>(body: (UnsafeCurrentTask?) throws -> T) rethrows -> T | |
/// Suspends the current task, | |
/// then calls the given closure with the an unsafe throwing continuation for the current task. | |
/// | |
/// - Parameter fn: A closure that takes an `UnsafeContinuation` parameter. | |
/// You must resume the continuation exactly once. | |
/// | |
/// - Returns: The value passed to the continuation by the closure. | |
/// | |
/// If `resume(throwing:)` is called on the continuation, | |
/// this function throws that error. | |
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) | |
public func withUnsafeThrowingContinuation<T>(_ fn: (UnsafeContinuation<T, Error>) -> Void) async throws -> T | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment