5050#include < map>
5151#include < ostream> // NOLINT
5252#include < sstream>
53+ #include < unordered_set>
5354#include < vector>
5455
5556#include " gtest/gtest-assertion-result.h"
@@ -725,6 +726,11 @@ static bool PatternMatchesString(const std::string& name_str,
725726 return true ;
726727}
727728
729+ static bool IsGlobPattern (const std::string& pattern) {
730+ return std::any_of (pattern.begin (), pattern.end (),
731+ [](const char c) { return c == ' ?' || c == ' *' ; });
732+ }
733+
728734namespace {
729735
730736class UnitTestFilter {
@@ -734,13 +740,19 @@ class UnitTestFilter {
734740 // Constructs a filter from a string of patterns separated by `:`.
735741 explicit UnitTestFilter (const std::string& filter) {
736742 // By design "" filter matches "" string.
737- SplitString (filter, ' :' , &patterns_);
743+ SplitString (filter, ' :' , &glob_patterns_);
744+ const auto exact_match_pattern_begin = std::partition (
745+ glob_patterns_.begin (), glob_patterns_.end (), &IsGlobPattern);
746+ exact_match_patterns_.insert (exact_match_pattern_begin,
747+ glob_patterns_.end ());
748+ glob_patterns_.erase (exact_match_pattern_begin, glob_patterns_.end ());
738749 }
739750
740751 // Returns true if and only if name matches at least one of the patterns in
741752 // the filter.
742753 bool MatchesName (const std::string& name) const {
743- return std::any_of (patterns_.begin (), patterns_.end (),
754+ return exact_match_patterns_.count (name) ||
755+ std::any_of (glob_patterns_.begin (), glob_patterns_.end (),
744756 [&name](const std::string& pattern) {
745757 return PatternMatchesString (
746758 name, pattern.c_str (),
@@ -749,7 +761,8 @@ class UnitTestFilter {
749761 }
750762
751763 private:
752- std::vector<std::string> patterns_;
764+ std::vector<std::string> glob_patterns_;
765+ std::unordered_set<std::string> exact_match_patterns_;
753766};
754767
755768class PositiveAndNegativeUnitTestFilter {
0 commit comments