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::And(Predicate left, Predicate right) { if (left.isFalse() || right.isFalse()) { return Predicate::False(); } else if (left.isTrue()) { return right; } else if (right.isTrue()) { return left; } else if (left == right) { return left; } else if (left.isAnd() && (left.andLeft() == right || left.andRight() == right)) { return left; } else if (right.isAnd() && (right.andLeft() == left || right.andRight() == left)) { return right; } Predicate predicate(AND); predicate.left_ = std::unique_ptr<Predicate>(new Predicate(std::move(left))); predicate.right_ = std::unique_ptr<Predicate>(new Predicate(std::move(right))); return predicate; }