AllOf, AnyOf, Optional: Avoid generating unnecessary match explanations

Previously, those matchers always invoked the child matchers with an IsInterested MatchResultListener, resulting in unnecessary work formatting match results that would be discarded.

PiperOrigin-RevId: 750704295
Change-Id: I1639a3a15d269459f26b3aebc3a6cbdced6896a3
This commit is contained in:
Abseil Team
2025-04-23 13:29:56 -07:00
committed by Copybara-Service
parent 155b337c93
commit cd430b47a5
2 changed files with 91 additions and 0 deletions
+22
View File
@@ -1312,6 +1312,15 @@ class AllOfMatcherImpl : public MatcherInterface<const T&> {
bool MatchAndExplain(const T& x,
MatchResultListener* listener) const override {
if (!listener->IsInterested()) {
// Fast path to avoid unnecessary formatting.
for (const Matcher<T>& matcher : matchers_) {
if (!matcher.Matches(x)) {
return false;
}
}
return true;
}
// This method uses matcher's explanation when explaining the result.
// However, if matcher doesn't provide one, this method uses matcher's
// description.
@@ -1431,6 +1440,15 @@ class AnyOfMatcherImpl : public MatcherInterface<const T&> {
bool MatchAndExplain(const T& x,
MatchResultListener* listener) const override {
if (!listener->IsInterested()) {
// Fast path to avoid unnecessary formatting of match explanations.
for (const Matcher<T>& matcher : matchers_) {
if (matcher.Matches(x)) {
return true;
}
}
return false;
}
// This method uses matcher's explanation when explaining the result.
// However, if matcher doesn't provide one, this method uses matcher's
// description.
@@ -4118,6 +4136,10 @@ class OptionalMatcher {
return false;
}
const ValueType& value = *optional;
if (!listener->IsInterested()) {
// Fast path to avoid unnecessary generation of match explanation.
return value_matcher_.Matches(value);
}
StringMatchResultListener value_listener;
const bool match = value_matcher_.MatchAndExplain(value, &value_listener);
*listener << "whose value " << PrintToString(value)