blob: fb46180a28cbdc12b0a444d90d5cf18dbcdb85e6 [file] [log] [blame]
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
// Compound predicates are predicates which act on the results of evaluating other operators. We provide the basic boolean operators: AND, OR, and NOT.
public enum NSCompoundPredicateType : UInt {
case NotPredicateType
case AndPredicateType
case OrPredicateType
}
public class NSCompoundPredicate : NSPredicate {
public init(type: NSCompoundPredicateType, subpredicates: [NSPredicate]) {
if type == .NotPredicateType && subpredicates.count == 0 {
preconditionFailure("Unsupported predicate count of \(subpredicates.count) for \(type)")
}
self.compoundPredicateType = type
self.subpredicates = subpredicates
super.init(value: false)
}
public required init?(coder: NSCoder) { NSUnimplemented() }
public let compoundPredicateType: NSCompoundPredicateType
public let subpredicates: [NSPredicate]
/*** Convenience Methods ***/
public convenience init(andPredicateWithSubpredicates subpredicates: [NSPredicate]) {
self.init(type: .AndPredicateType, subpredicates: subpredicates)
}
public convenience init(orPredicateWithSubpredicates subpredicates: [NSPredicate]) {
self.init(type: .OrPredicateType, subpredicates: subpredicates)
}
public convenience init(notPredicateWithSubpredicate predicate: NSPredicate) {
self.init(type: .NotPredicateType, subpredicates: [predicate])
}
override public func evaluateWithObject(_ object: AnyObject?, substitutionVariables bindings: [String : AnyObject]?) -> Bool {
switch compoundPredicateType {
case .AndPredicateType:
return subpredicates.reduce(true, combine: {
$0 && $1.evaluateWithObject(object, substitutionVariables: bindings)
})
case .OrPredicateType:
return subpredicates.reduce(false, combine: {
$0 || $1.evaluateWithObject(object, substitutionVariables: bindings)
})
case .NotPredicateType:
// safe to get the 0th item here since we trap if there's not at least one on init
return !(subpredicates[0].evaluateWithObject(object, substitutionVariables: bindings))
}
}
}