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; }