| 639 | }; |
| 640 | |
| 641 | Predicate* PredicateFactory::MakeInternedAndOr( |
| 642 | std::vector<Predicate*> simplified_ops, Predicate::Kind pred_kind) { |
| 643 | std::stable_sort( |
| 644 | simplified_ops.begin(), simplified_ops.end(), |
| 645 | [](Predicate* a, Predicate* b) { return a->id() < b->id(); }); |
| 646 | |
| 647 | auto it = interned_and_or_instances_.find({pred_kind, simplified_ops}); |
| 648 | if (it != interned_and_or_instances_.end()) { |
| 649 | return it->second.get(); |
| 650 | } |
| 651 | |
| 652 | simplified_ops.shrink_to_fit(); |
| 653 | // NB! Because we'll use a non-owning reference to simplified_ops in the |
| 654 | // key for interned_and_or_instances_ we need to be careful to std::move() |
| 655 | // it all the way through. |
| 656 | absl::Span<Predicate* const> operands_slice = simplified_ops; |
| 657 | std::unique_ptr<Predicate> new_pred = |
| 658 | pred_kind == Predicate::Kind::kAnd |
| 659 | ? Make<AndPredicate>(std::move(simplified_ops)) |
| 660 | : Make<OrPredicate>(std::move(simplified_ops)); |
| 661 | |
| 662 | Predicate* new_pred_ptr = new_pred.get(); |
| 663 | interned_and_or_instances_.emplace( |
| 664 | SignatureForAndOr(pred_kind, operands_slice), std::move(new_pred)); |
| 665 | return new_pred_ptr; |
| 666 | } |
| 667 | |
| 668 | // Common code to create AndPredicate or OrPredicate instances. |
| 669 | Predicate* PredicateFactory::MakeAndOrImpl( |