Repository: google/googletest
File: googletest/src/gtest.cc (C++)

Code before:
  // the filter.
  bool MatchesName(const std::string& name) const {
    const auto pattern_matches_name = [&name](const std::string& pattern) {
      return PatternMatchesString(name, pattern.c_str(),
                                  pattern.c_str() + pattern.size());
    };
    return std::any_of(patterns_.begin(), patterns_.end(),
                       pattern_matches_name);
  }
};

class PositiveAndNegativeFilter {
  Filter positive_filter_;
  Filter negative_filter_;

  static std::pair<std::string, std::string>
  BreakIntoPositiveAndNegativeFilters(const std::string& filter) {
    const auto dash_pos = filter.find('-');
    if (dash_pos == std::string::npos) {
      return {filter, {}};  // Whole string is a positive filter
    } else {
      return {dash_pos ? filter.substr(0, dash_pos) : kUniversalFilter,
              filter.substr(dash_pos + 1)};
    }
  }
  PositiveAndNegativeFilter(
      const std::pair<std::string, std::string>& positive_and_negative_filters)
      : positive_filter_(positive_and_negative_filters.first),
        negative_filter_(positive_and_negative_filters.second) {}

 public:
  // Constructs a positive and a negative filter from a string. The string
  // contains a positive filter optionally followed by a '-' character and a
  // negative filter. In case only a negative filter is provided the positive
  // filter will be assumed "*".
  // A filter is a list of patterns separated by ':'.
  explicit PositiveAndNegativeFilter(const std::string& filter)
      : PositiveAndNegativeFilter(BreakIntoPositiveAndNegativeFilters(filter)) {
  }

  // Returns true if and only if test name (this is generated by appending test
  // suit name and test name via a '.' character) matches the positive filter
  // and does not match the negative filter.
  bool MatchesTest(const std::string& test_suite_name,
                   const std::string& test_name) const {
    const std::string& full_name = test_suite_name + "." + test_name.c_str();

    return MatchesName(full_name);
  }

  // Returns true if and only if name matches the positive filter and does not

Review comment (performance):
Can we inline everything (including `BreakIntoPositiveAndNegativeFilters`) into a single constructor to improve readability by avoiding some indirection?

I don't think we care that much about the difference in performance between initializer lists vs. `std::move`ing the members in the body of the constructor. We won't be constructing filter instances that often anyway.

Code after:
                       });
  }

 private:
  std::vector<std::string> patterns_;
};

class PositiveAndNegativeUnitTestFilter {
 public:
  // Constructs a positive and a negative filter from a string. The string
  // contains a positive filter optionally followed by a '-' character and a
  // negative filter. In case only a negative filter is provided the positive
  // filter will be assumed "*".
  // A filter is a list of patterns separated by ':'.
  explicit PositiveAndNegativeUnitTestFilter(const std::string& filter) {
    std::vector<std::string> positive_and_negative_filters;

    SplitString(filter, '-', &positive_and_negative_filters);
    const auto& positive_filter = positive_and_negative_filters.front();

    if (positive_and_negative_filters.size() > 1) {
      positive_filter_ = UnitTestFilter{
          positive_filter.empty() ? kUniversalFilter : positive_filter};

      // TODO: Fail on multiple '-' characters
      // For the moment to preserve old behavior we concatenate the rest of the
      // string parts with `-` as separator to generate the negative filter.
      auto negative_filter_string = positive_and_negative_filters[1];
      for (std::size_t i = 2; i < positive_and_negative_filters.size(); i++)
        negative_filter_string =
            negative_filter_string + '-' + positive_and_negative_filters[i];
      negative_filter_ = UnitTestFilter{negative_filter_string};
    } else {
      // In case we don't have a negative filter and positive filter is ""
      // we do not use kUniversalFilter by design as opposed to when we have a
      // negative filter.
      positive_filter_ = UnitTestFilter{positive_filter};
    }
  }

  // Returns true if and only if test name (this is generated by appending test
  // suit name and test name via a '.' character) matches the positive filter
  // and does not match the negative filter.
  bool MatchesTest(const std::string& test_suite_name,
                   const std::string& test_name) const {
    return MatchesName(test_suite_name + "." + test_name);
  }

  // Returns true if and only if name matches the positive filter and does not
  // match the negative filter.
  bool MatchesName(const std::string& name) const {