bool Predicate::operator==(const Predicate& other) const { if (kind() != other.kind()) { return false; } switch (kind()) { case TRUE: case FALSE: case SELFCONST: { return true; } case AND: { return andLeft() == other.andLeft() && andRight() == other.andRight(); } case OR: { return orLeft() == other.orLeft() && orRight() == other.orRight(); } case SATISFIES: { return satisfiesType() == other.satisfiesType() && satisfiesRequirement() == other.satisfiesRequirement(); } case VARIABLE: { return variableTemplateVar() == other.variableTemplateVar(); } } locic_unreachable("Unknown predicate kind."); }
Predicate Predicate::Or(Predicate left, Predicate right) { if (left.isTrue() || right.isTrue()) { return Predicate::True(); } else if (left.isFalse()) { return right; } else if (right.isFalse()) { return left; } else if (left == right) { return left; } else if (left.isOr() && (left.orLeft() == right || left.orRight() == right)) { return left; } else if (right.isOr() && (right.orLeft() == left || right.orRight() == left)) { return right; } Predicate predicate(OR); predicate.left_ = std::unique_ptr<Predicate>(new Predicate(std::move(left))); predicate.right_ = std::unique_ptr<Predicate>(new Predicate(std::move(right))); return predicate; }