mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
* Implementations for operators and async functions on AsyncSequence per SE-0298 * Add trailing new lines to AsyncSequence adopter files * Remove extra // from preambles * Transition sequence properties and sequence initializers to internal * Rename Upstream to Base * Rename "Failable" asynchronous sequences to "Throwing" * Make iteration consistent with closure lifetimes and track failure via state * Use for await syntax for async function extensions on AsyncSequence * Work-around rethrows calculations being incorrect for conformance + closure rethrowing * Update testing names to reflect Throwing versus Failable * Incorperate runAsyncAndBlock into the test function for suite calls * Remove @frozen from AsyncSequence operators * Back out reduce family functions for now due to IRGen bug * Additional corrections for throwing cases and fix up potential linux crasher * Add a upstream and throwing tests and correct flatMap's throwing behavior * Unify parameter names to count * Add a more helpful precondition on prefix * Add tests for throwing cases of non closure async functions on AsyncSequence * Correct missing count transition in dropFirst * Correct missing , in assertion * [NFC] add commentary on optimization in dropFirst on dropFirst * Disable collect tests for non macOS platforms for now * Disable all async sequence tests for non macOS platforms for now
166 lines
4.2 KiB
Swift
166 lines
4.2 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2020 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import Swift
|
|
|
|
@rethrows
|
|
public protocol AsyncSequence {
|
|
associatedtype AsyncIterator: AsyncIteratorProtocol where AsyncIterator.Element == Element
|
|
associatedtype Element
|
|
__consuming func makeAsyncIterator() -> AsyncIterator
|
|
}
|
|
|
|
extension AsyncSequence {
|
|
@inlinable
|
|
public func reduce<Result>(
|
|
_ initialResult: Result,
|
|
_ nextPartialResult:
|
|
(_ partialResult: Result, Element) async throws -> Result
|
|
) async rethrows -> Result {
|
|
var accumulator = initialResult
|
|
var iterator = makeAsyncIterator()
|
|
while let element = try await iterator.next() {
|
|
accumulator = try await nextPartialResult(accumulator, element)
|
|
}
|
|
return accumulator
|
|
}
|
|
|
|
@inlinable
|
|
public func reduce<Result>(
|
|
into initialResult: __owned Result,
|
|
_ updateAccumulatingResult:
|
|
(_ partialResult: inout Result, Element) async throws -> Void
|
|
) async rethrows -> Result {
|
|
var accumulator = initialResult
|
|
var iterator = makeAsyncIterator()
|
|
while let element = try await iterator.next() {
|
|
try await updateAccumulatingResult(&accumulator, element)
|
|
}
|
|
return accumulator
|
|
}
|
|
}
|
|
|
|
@inlinable
|
|
@inline(__always)
|
|
func _contains<Source: AsyncSequence>(
|
|
_ self: Source,
|
|
where predicate: (Source.Element) async throws -> Bool
|
|
) async rethrows -> Bool {
|
|
for try await element in self {
|
|
if try await predicate(element) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
extension AsyncSequence {
|
|
@inlinable
|
|
public func contains(
|
|
where predicate: (Element) async throws -> Bool
|
|
) async rethrows -> Bool {
|
|
return try await _contains(self, where: predicate)
|
|
}
|
|
|
|
@inlinable
|
|
public func allSatisfy(
|
|
_ predicate: (Element) async throws -> Bool
|
|
) async rethrows -> Bool {
|
|
return try await !contains { try await !predicate($0) }
|
|
}
|
|
}
|
|
|
|
extension AsyncSequence where Element: Equatable {
|
|
@inlinable
|
|
public func contains(_ search: Element) async rethrows -> Bool {
|
|
for try await element in self {
|
|
if element == search {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
}
|
|
|
|
@inlinable
|
|
@inline(__always)
|
|
func _first<Source: AsyncSequence>(
|
|
_ self: Source,
|
|
where predicate: (Source.Element) async throws -> Bool
|
|
) async rethrows -> Source.Element? {
|
|
for try await element in self {
|
|
if try await predicate(element) {
|
|
return element
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
extension AsyncSequence {
|
|
@inlinable
|
|
public func first(
|
|
where predicate: (Element) async throws -> Bool
|
|
) async rethrows -> Element? {
|
|
return try await _first(self, where: predicate)
|
|
}
|
|
}
|
|
|
|
extension AsyncSequence {
|
|
@inlinable
|
|
@warn_unqualified_access
|
|
public func min(
|
|
by areInIncreasingOrder: (Element, Element) async throws -> Bool
|
|
) async rethrows -> Element? {
|
|
var it = makeAsyncIterator()
|
|
guard var result = try await it.next() else {
|
|
return nil
|
|
}
|
|
while let e = try await it.next() {
|
|
if try await areInIncreasingOrder(e, result) {
|
|
result = e
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
@inlinable
|
|
@warn_unqualified_access
|
|
public func max(
|
|
by areInIncreasingOrder: (Element, Element) async throws -> Bool
|
|
) async rethrows -> Element? {
|
|
var it = makeAsyncIterator()
|
|
guard var result = try await it.next() else {
|
|
return nil
|
|
}
|
|
while let e = try await it.next() {
|
|
if try await areInIncreasingOrder(result, e) {
|
|
result = e
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
}
|
|
|
|
extension AsyncSequence where Element: Comparable {
|
|
@inlinable
|
|
@warn_unqualified_access
|
|
public func min() async rethrows -> Element? {
|
|
return try await self.min(by: <)
|
|
}
|
|
|
|
@inlinable
|
|
@warn_unqualified_access
|
|
public func max() async rethrows -> Element? {
|
|
return try await self.max(by: <)
|
|
}
|
|
}
|