mirror of
https://github.com/apple/swift-foundation.git
synced 2025-05-28 09:47:07 +08:00
252 lines
9.1 KiB
Swift
252 lines
9.1 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2022-2023 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
@available(FoundationPredicate 0.1, *)
|
|
extension PredicateExpressions {
|
|
public struct SequenceContains<
|
|
LHS : PredicateExpression,
|
|
RHS : PredicateExpression
|
|
> : PredicateExpression
|
|
where
|
|
LHS.Output : Sequence,
|
|
LHS.Output.Element : Equatable,
|
|
RHS.Output == LHS.Output.Element
|
|
{
|
|
public typealias Output = Bool
|
|
|
|
public let sequence: LHS
|
|
public let element: RHS
|
|
|
|
public init(sequence: LHS, element: RHS) {
|
|
self.sequence = sequence
|
|
self.element = element
|
|
}
|
|
|
|
public func evaluate(_ bindings: PredicateBindings) throws -> Bool {
|
|
let a = try sequence.evaluate(bindings)
|
|
let b = try element.evaluate(bindings)
|
|
return a.contains(b)
|
|
}
|
|
}
|
|
|
|
public struct SequenceContainsWhere<
|
|
LHS : PredicateExpression,
|
|
RHS : PredicateExpression
|
|
> : PredicateExpression
|
|
where
|
|
LHS.Output : Sequence,
|
|
RHS.Output == Bool
|
|
{
|
|
public typealias Element = LHS.Output.Element
|
|
public typealias Output = Bool
|
|
|
|
public let sequence: LHS
|
|
public let test: RHS
|
|
public let variable: Variable<Element>
|
|
|
|
public init(_ sequence: LHS, builder: (Variable<Element>) -> RHS) {
|
|
self.variable = Variable()
|
|
self.sequence = sequence
|
|
self.test = builder(variable)
|
|
}
|
|
|
|
public func evaluate(_ bindings: PredicateBindings) throws -> Output {
|
|
var mutableBindings = bindings
|
|
return try sequence.evaluate(bindings).contains {
|
|
mutableBindings[variable] = $0
|
|
return try test.evaluate(mutableBindings)
|
|
}
|
|
}
|
|
}
|
|
|
|
public struct SequenceAllSatisfy<
|
|
LHS : PredicateExpression,
|
|
RHS : PredicateExpression
|
|
> : PredicateExpression
|
|
where
|
|
LHS.Output : Sequence,
|
|
RHS.Output == Bool
|
|
{
|
|
public typealias Element = LHS.Output.Element
|
|
public typealias Output = Bool
|
|
|
|
public let sequence: LHS
|
|
public let test: RHS
|
|
public let variable: Variable<Element>
|
|
|
|
public init(_ sequence: LHS, builder: (Variable<Element>) -> RHS) {
|
|
self.variable = Variable()
|
|
self.sequence = sequence
|
|
self.test = builder(variable)
|
|
}
|
|
|
|
public func evaluate(_ bindings: PredicateBindings) throws -> Output {
|
|
var mutableBindings = bindings
|
|
return try sequence.evaluate(bindings).allSatisfy {
|
|
mutableBindings[variable] = $0
|
|
return try test.evaluate(mutableBindings)
|
|
}
|
|
}
|
|
}
|
|
|
|
public struct SequenceStartsWith<
|
|
Base : PredicateExpression,
|
|
Prefix : PredicateExpression
|
|
> : PredicateExpression
|
|
where
|
|
Base.Output : Sequence,
|
|
Prefix.Output : Sequence,
|
|
Base.Output.Element == Prefix.Output.Element,
|
|
Base.Output.Element : Equatable
|
|
{
|
|
public typealias Output = Bool
|
|
|
|
public let base: Base
|
|
public let prefix: Prefix
|
|
|
|
public init(base: Base, prefix: Prefix) {
|
|
self.base = base
|
|
self.prefix = prefix
|
|
}
|
|
|
|
public func evaluate(_ bindings: PredicateBindings) throws -> Bool {
|
|
try base.evaluate(bindings).starts(with: try prefix.evaluate(bindings))
|
|
}
|
|
}
|
|
|
|
@_disfavoredOverload
|
|
public static func build_contains<LHS, RHS>(_ lhs: LHS, _ rhs: RHS) -> SequenceContains<LHS, RHS> {
|
|
SequenceContains(sequence: lhs, element: rhs)
|
|
}
|
|
|
|
public static func build_contains<LHS, RHS>(_ lhs: LHS, where builder: (Variable<LHS.Output.Element>) -> RHS) -> SequenceContainsWhere<LHS, RHS> {
|
|
SequenceContainsWhere(lhs, builder: builder)
|
|
}
|
|
|
|
public static func build_allSatisfy<LHS, RHS>(_ lhs: LHS, _ builder: (Variable<LHS.Output.Element>) -> RHS) -> SequenceAllSatisfy<LHS, RHS> {
|
|
SequenceAllSatisfy(lhs, builder: builder)
|
|
}
|
|
|
|
public static func build_starts<Base, Prefix>(_ base: Base, with prefix: Prefix) -> SequenceStartsWith<Base, Prefix> {
|
|
SequenceStartsWith(base: base, prefix: prefix)
|
|
}
|
|
}
|
|
|
|
@available(FoundationPredicate 0.3, *)
|
|
extension PredicateExpressions.SequenceContains : CustomStringConvertible {
|
|
public var description: String {
|
|
"SequenceContains(sequence: \(sequence), element: \(element))"
|
|
}
|
|
}
|
|
|
|
@available(FoundationPredicate 0.3, *)
|
|
extension PredicateExpressions.SequenceContainsWhere : CustomStringConvertible {
|
|
public var description: String {
|
|
"SequenceContainsWhere(sequence: \(sequence), variable: \(variable), test: \(test))"
|
|
}
|
|
}
|
|
|
|
@available(FoundationPredicate 0.3, *)
|
|
extension PredicateExpressions.SequenceAllSatisfy : CustomStringConvertible {
|
|
public var description: String {
|
|
"SequenceAllSatisfy(sequence: \(sequence), variable: \(variable), test: \(test))"
|
|
}
|
|
}
|
|
|
|
@available(FoundationPredicate 0.1, *)
|
|
extension PredicateExpressions.SequenceContains : StandardPredicateExpression where LHS : StandardPredicateExpression, RHS : StandardPredicateExpression {}
|
|
|
|
@available(FoundationPredicate 0.1, *)
|
|
extension PredicateExpressions.SequenceContainsWhere : StandardPredicateExpression where LHS : StandardPredicateExpression, RHS : StandardPredicateExpression {}
|
|
|
|
@available(FoundationPredicate 0.1, *)
|
|
extension PredicateExpressions.SequenceAllSatisfy : StandardPredicateExpression where LHS : StandardPredicateExpression, RHS : StandardPredicateExpression {}
|
|
|
|
@available(FoundationPredicate 0.1, *)
|
|
extension PredicateExpressions.SequenceStartsWith : StandardPredicateExpression where Base : StandardPredicateExpression, Prefix : StandardPredicateExpression {}
|
|
|
|
@available(FoundationPredicate 0.1, *)
|
|
extension PredicateExpressions.SequenceContains : Codable where LHS : Codable, RHS : Codable {
|
|
public func encode(to encoder: Encoder) throws {
|
|
var container = encoder.unkeyedContainer()
|
|
try container.encode(sequence)
|
|
try container.encode(element)
|
|
}
|
|
|
|
public init(from decoder: Decoder) throws {
|
|
var container = try decoder.unkeyedContainer()
|
|
sequence = try container.decode(LHS.self)
|
|
element = try container.decode(RHS.self)
|
|
}
|
|
}
|
|
|
|
@available(FoundationPredicate 0.1, *)
|
|
extension PredicateExpressions.SequenceContainsWhere : Codable where LHS : Codable, RHS : Codable {
|
|
public func encode(to encoder: Encoder) throws {
|
|
var container = encoder.unkeyedContainer()
|
|
try container.encode(sequence)
|
|
try container.encode(test)
|
|
try container.encode(variable)
|
|
}
|
|
|
|
public init(from decoder: Decoder) throws {
|
|
var container = try decoder.unkeyedContainer()
|
|
sequence = try container.decode(LHS.self)
|
|
test = try container.decode(RHS.self)
|
|
variable = try container.decode(PredicateExpressions.Variable<Element>.self)
|
|
}
|
|
}
|
|
|
|
@available(FoundationPredicate 0.1, *)
|
|
extension PredicateExpressions.SequenceAllSatisfy : Codable where LHS : Codable, RHS : Codable {
|
|
public func encode(to encoder: Encoder) throws {
|
|
var container = encoder.unkeyedContainer()
|
|
try container.encode(sequence)
|
|
try container.encode(test)
|
|
try container.encode(variable)
|
|
}
|
|
|
|
public init(from decoder: Decoder) throws {
|
|
var container = try decoder.unkeyedContainer()
|
|
sequence = try container.decode(LHS.self)
|
|
test = try container.decode(RHS.self)
|
|
variable = try container.decode(PredicateExpressions.Variable<Element>.self)
|
|
}
|
|
}
|
|
|
|
@available(FoundationPredicate 0.1, *)
|
|
extension PredicateExpressions.SequenceStartsWith : Codable where Base : Codable, Prefix : Codable {
|
|
public func encode(to encoder: Encoder) throws {
|
|
var container = encoder.unkeyedContainer()
|
|
try container.encode(base)
|
|
try container.encode(prefix)
|
|
}
|
|
|
|
public init(from decoder: Decoder) throws {
|
|
var container = try decoder.unkeyedContainer()
|
|
self.base = try container.decode(Base.self)
|
|
self.prefix = try container.decode(Prefix.self)
|
|
}
|
|
}
|
|
|
|
@available(FoundationPredicate 0.1, *)
|
|
extension PredicateExpressions.SequenceContains : Sendable where LHS : Sendable, RHS : Sendable {}
|
|
|
|
@available(FoundationPredicate 0.1, *)
|
|
extension PredicateExpressions.SequenceContainsWhere : Sendable where LHS : Sendable, RHS : Sendable {}
|
|
|
|
@available(FoundationPredicate 0.1, *)
|
|
extension PredicateExpressions.SequenceAllSatisfy : Sendable where LHS : Sendable, RHS : Sendable {}
|
|
|
|
@available(FoundationPredicate 0.1, *)
|
|
extension PredicateExpressions.SequenceStartsWith : Sendable where Base : Sendable, Prefix : Sendable {}
|