Skip to content

Instantly share code, notes, and snippets.

@muukii
Created June 9, 2021 03:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save muukii/c14f2cf93083768a51745c684716a378 to your computer and use it in GitHub Desktop.
Save muukii/c14f2cf93083768a51745c684716a378 to your computer and use it in GitHub Desktop.
Concurrency module interface
/// 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