merging,
This commit is contained in:
		@@ -1718,25 +1718,27 @@ class NotMatcher {
 | 
			
		||||
// that will prevent different instantiations of BothOfMatcher from
 | 
			
		||||
// sharing the same BothOfMatcherImpl<T> class.
 | 
			
		||||
template <typename T>
 | 
			
		||||
class BothOfMatcherImpl
 | 
			
		||||
class AllOfMatcherImpl
 | 
			
		||||
    : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> {
 | 
			
		||||
 public:
 | 
			
		||||
  BothOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2)
 | 
			
		||||
      : matcher1_(matcher1), matcher2_(matcher2) {}
 | 
			
		||||
  explicit AllOfMatcherImpl(std::vector<Matcher<T> > matchers)
 | 
			
		||||
      : matchers_(internal::move(matchers)) {}
 | 
			
		||||
 | 
			
		||||
  virtual void DescribeTo(::std::ostream* os) const {
 | 
			
		||||
    *os << "(";
 | 
			
		||||
    matcher1_.DescribeTo(os);
 | 
			
		||||
    *os << ") and (";
 | 
			
		||||
    matcher2_.DescribeTo(os);
 | 
			
		||||
    for (size_t i = 0; i < matchers_.size(); ++i) {
 | 
			
		||||
      if (i != 0) *os << ") and (";
 | 
			
		||||
      matchers_[i].DescribeTo(os);
 | 
			
		||||
    }
 | 
			
		||||
    *os << ")";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  virtual void DescribeNegationTo(::std::ostream* os) const {
 | 
			
		||||
    *os << "(";
 | 
			
		||||
    matcher1_.DescribeNegationTo(os);
 | 
			
		||||
    *os << ") or (";
 | 
			
		||||
    matcher2_.DescribeNegationTo(os);
 | 
			
		||||
    for (size_t i = 0; i < matchers_.size(); ++i) {
 | 
			
		||||
      if (i != 0) *os << ") or (";
 | 
			
		||||
      matchers_[i].DescribeNegationTo(os);
 | 
			
		||||
    }
 | 
			
		||||
    *os << ")";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -1744,93 +1746,38 @@ class BothOfMatcherImpl
 | 
			
		||||
                               MatchResultListener* listener) const {
 | 
			
		||||
    // If either matcher1_ or matcher2_ doesn't match x, we only need
 | 
			
		||||
    // to explain why one of them fails.
 | 
			
		||||
    StringMatchResultListener listener1;
 | 
			
		||||
    if (!matcher1_.MatchAndExplain(x, &listener1)) {
 | 
			
		||||
      *listener << listener1.str();
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    std::string all_match_result;
 | 
			
		||||
 | 
			
		||||
    StringMatchResultListener listener2;
 | 
			
		||||
    if (!matcher2_.MatchAndExplain(x, &listener2)) {
 | 
			
		||||
      *listener << listener2.str();
 | 
			
		||||
      return false;
 | 
			
		||||
    for (size_t i = 0; i < matchers_.size(); ++i) {
 | 
			
		||||
      StringMatchResultListener slistener;
 | 
			
		||||
      if (matchers_[i].MatchAndExplain(x, &slistener)) {
 | 
			
		||||
        if (all_match_result.empty()) {
 | 
			
		||||
          all_match_result = slistener.str();
 | 
			
		||||
        } else {
 | 
			
		||||
          std::string result = slistener.str();
 | 
			
		||||
          if (!result.empty()) {
 | 
			
		||||
            all_match_result += ", and ";
 | 
			
		||||
            all_match_result += result;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        *listener << slistener.str();
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Otherwise we need to explain why *both* of them match.
 | 
			
		||||
    const std::string s1 = listener1.str();
 | 
			
		||||
    const std::string s2 = listener2.str();
 | 
			
		||||
 | 
			
		||||
    if (s1 == "") {
 | 
			
		||||
      *listener << s2;
 | 
			
		||||
    } else {
 | 
			
		||||
      *listener << s1;
 | 
			
		||||
      if (s2 != "") {
 | 
			
		||||
        *listener << ", and " << s2;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    *listener << all_match_result;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  const Matcher<T> matcher1_;
 | 
			
		||||
  const Matcher<T> matcher2_;
 | 
			
		||||
  const std::vector<Matcher<T> > matchers_;
 | 
			
		||||
 | 
			
		||||
  GTEST_DISALLOW_ASSIGN_(BothOfMatcherImpl);
 | 
			
		||||
  GTEST_DISALLOW_ASSIGN_(AllOfMatcherImpl);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if GTEST_LANG_CXX11
 | 
			
		||||
// MatcherList provides mechanisms for storing a variable number of matchers in
 | 
			
		||||
// a list structure (ListType) and creating a combining matcher from such a
 | 
			
		||||
// list.
 | 
			
		||||
// The template is defined recursively using the following template parameters:
 | 
			
		||||
//   * kSize is the length of the MatcherList.
 | 
			
		||||
//   * Head is the type of the first matcher of the list.
 | 
			
		||||
//   * Tail denotes the types of the remaining matchers of the list.
 | 
			
		||||
template <int kSize, typename Head, typename... Tail>
 | 
			
		||||
struct MatcherList {
 | 
			
		||||
  typedef MatcherList<kSize - 1, Tail...> MatcherListTail;
 | 
			
		||||
  typedef ::std::pair<Head, typename MatcherListTail::ListType> ListType;
 | 
			
		||||
 | 
			
		||||
  // BuildList stores variadic type values in a nested pair structure.
 | 
			
		||||
  // Example:
 | 
			
		||||
  // MatcherList<3, int, string, float>::BuildList(5, "foo", 2.0) will return
 | 
			
		||||
  // the corresponding result of type pair<int, pair<string, float>>.
 | 
			
		||||
  static ListType BuildList(const Head& matcher, const Tail&... tail) {
 | 
			
		||||
    return ListType(matcher, MatcherListTail::BuildList(tail...));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // CreateMatcher<T> creates a Matcher<T> from a given list of matchers (built
 | 
			
		||||
  // by BuildList()). CombiningMatcher<T> is used to combine the matchers of the
 | 
			
		||||
  // list. CombiningMatcher<T> must implement MatcherInterface<T> and have a
 | 
			
		||||
  // constructor taking two Matcher<T>s as input.
 | 
			
		||||
  template <typename T, template <typename /* T */> class CombiningMatcher>
 | 
			
		||||
  static Matcher<T> CreateMatcher(const ListType& matchers) {
 | 
			
		||||
    return Matcher<T>(new CombiningMatcher<T>(
 | 
			
		||||
        SafeMatcherCast<T>(matchers.first),
 | 
			
		||||
        MatcherListTail::template CreateMatcher<T, CombiningMatcher>(
 | 
			
		||||
            matchers.second)));
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// The following defines the base case for the recursive definition of
 | 
			
		||||
// MatcherList.
 | 
			
		||||
template <typename Matcher1, typename Matcher2>
 | 
			
		||||
struct MatcherList<2, Matcher1, Matcher2> {
 | 
			
		||||
  typedef ::std::pair<Matcher1, Matcher2> ListType;
 | 
			
		||||
 | 
			
		||||
  static ListType BuildList(const Matcher1& matcher1,
 | 
			
		||||
                            const Matcher2& matcher2) {
 | 
			
		||||
    return ::std::pair<Matcher1, Matcher2>(matcher1, matcher2);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T, template <typename /* T */> class CombiningMatcher>
 | 
			
		||||
  static Matcher<T> CreateMatcher(const ListType& matchers) {
 | 
			
		||||
    return Matcher<T>(new CombiningMatcher<T>(
 | 
			
		||||
        SafeMatcherCast<T>(matchers.first),
 | 
			
		||||
        SafeMatcherCast<T>(matchers.second)));
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// VariadicMatcher is used for the variadic implementation of
 | 
			
		||||
// AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...).
 | 
			
		||||
// CombiningMatcher<T> is used to recursively combine the provided matchers
 | 
			
		||||
@@ -1839,27 +1786,40 @@ template <template <typename T> class CombiningMatcher, typename... Args>
 | 
			
		||||
class VariadicMatcher {
 | 
			
		||||
 public:
 | 
			
		||||
  VariadicMatcher(const Args&... matchers)  // NOLINT
 | 
			
		||||
      : matchers_(MatcherListType::BuildList(matchers...)) {}
 | 
			
		||||
      : matchers_(matchers...) {
 | 
			
		||||
    static_assert(sizeof...(Args) > 0, "Must have at least one matcher.");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // This template type conversion operator allows an
 | 
			
		||||
  // VariadicMatcher<Matcher1, Matcher2...> object to match any type that
 | 
			
		||||
  // all of the provided matchers (Matcher1, Matcher2, ...) can match.
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  operator Matcher<T>() const {
 | 
			
		||||
    return MatcherListType::template CreateMatcher<T, CombiningMatcher>(
 | 
			
		||||
        matchers_);
 | 
			
		||||
    std::vector<Matcher<T> > values;
 | 
			
		||||
    CreateVariadicMatcher<T>(&values, std::integral_constant<size_t, 0>());
 | 
			
		||||
    return Matcher<T>(new CombiningMatcher<T>(internal::move(values)));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  typedef MatcherList<sizeof...(Args), Args...> MatcherListType;
 | 
			
		||||
  template <typename T, size_t I>
 | 
			
		||||
  void CreateVariadicMatcher(std::vector<Matcher<T> >* values,
 | 
			
		||||
                             std::integral_constant<size_t, I>) const {
 | 
			
		||||
    values->push_back(SafeMatcherCast<T>(std::get<I>(matchers_)));
 | 
			
		||||
    CreateVariadicMatcher<T>(values, std::integral_constant<size_t, I + 1>());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const typename MatcherListType::ListType matchers_;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  void CreateVariadicMatcher(
 | 
			
		||||
      std::vector<Matcher<T> >*,
 | 
			
		||||
      std::integral_constant<size_t, sizeof...(Args)>) const {}
 | 
			
		||||
 | 
			
		||||
  tuple<Args...> matchers_;
 | 
			
		||||
 | 
			
		||||
  GTEST_DISALLOW_ASSIGN_(VariadicMatcher);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename... Args>
 | 
			
		||||
using AllOfMatcher = VariadicMatcher<BothOfMatcherImpl, Args...>;
 | 
			
		||||
using AllOfMatcher = VariadicMatcher<AllOfMatcherImpl, Args...>;
 | 
			
		||||
 | 
			
		||||
#endif  // GTEST_LANG_CXX11
 | 
			
		||||
 | 
			
		||||
@@ -1876,8 +1836,10 @@ class BothOfMatcher {
 | 
			
		||||
  // both Matcher1 and Matcher2 can match.
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  operator Matcher<T>() const {
 | 
			
		||||
    return Matcher<T>(new BothOfMatcherImpl<T>(SafeMatcherCast<T>(matcher1_),
 | 
			
		||||
                                               SafeMatcherCast<T>(matcher2_)));
 | 
			
		||||
    std::vector<Matcher<T> > values;
 | 
			
		||||
    values.push_back(SafeMatcherCast<T>(matcher1_));
 | 
			
		||||
    values.push_back(SafeMatcherCast<T>(matcher2_));
 | 
			
		||||
    return Matcher<T>(new AllOfMatcherImpl<T>(internal::move(values)));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
@@ -1892,70 +1854,69 @@ class BothOfMatcher {
 | 
			
		||||
// that will prevent different instantiations of AnyOfMatcher from
 | 
			
		||||
// sharing the same EitherOfMatcherImpl<T> class.
 | 
			
		||||
template <typename T>
 | 
			
		||||
class EitherOfMatcherImpl
 | 
			
		||||
class AnyOfMatcherImpl
 | 
			
		||||
    : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> {
 | 
			
		||||
 public:
 | 
			
		||||
  EitherOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2)
 | 
			
		||||
      : matcher1_(matcher1), matcher2_(matcher2) {}
 | 
			
		||||
  explicit AnyOfMatcherImpl(std::vector<Matcher<T> > matchers)
 | 
			
		||||
      : matchers_(internal::move(matchers)) {}
 | 
			
		||||
 | 
			
		||||
  virtual void DescribeTo(::std::ostream* os) const {
 | 
			
		||||
    *os << "(";
 | 
			
		||||
    matcher1_.DescribeTo(os);
 | 
			
		||||
    *os << ") or (";
 | 
			
		||||
    matcher2_.DescribeTo(os);
 | 
			
		||||
    for (size_t i = 0; i < matchers_.size(); ++i) {
 | 
			
		||||
      if (i != 0) *os << ") or (";
 | 
			
		||||
      matchers_[i].DescribeTo(os);
 | 
			
		||||
    }
 | 
			
		||||
    *os << ")";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  virtual void DescribeNegationTo(::std::ostream* os) const {
 | 
			
		||||
    *os << "(";
 | 
			
		||||
    matcher1_.DescribeNegationTo(os);
 | 
			
		||||
    *os << ") and (";
 | 
			
		||||
    matcher2_.DescribeNegationTo(os);
 | 
			
		||||
    for (size_t i = 0; i < matchers_.size(); ++i) {
 | 
			
		||||
      if (i != 0) *os << ") and (";
 | 
			
		||||
      matchers_[i].DescribeNegationTo(os);
 | 
			
		||||
    }
 | 
			
		||||
    *os << ")";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x,
 | 
			
		||||
                               MatchResultListener* listener) const {
 | 
			
		||||
    std::string no_match_result;
 | 
			
		||||
 | 
			
		||||
    // If either matcher1_ or matcher2_ matches x, we just need to
 | 
			
		||||
    // explain why *one* of them matches.
 | 
			
		||||
    StringMatchResultListener listener1;
 | 
			
		||||
    if (matcher1_.MatchAndExplain(x, &listener1)) {
 | 
			
		||||
      *listener << listener1.str();
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    StringMatchResultListener listener2;
 | 
			
		||||
    if (matcher2_.MatchAndExplain(x, &listener2)) {
 | 
			
		||||
      *listener << listener2.str();
 | 
			
		||||
      return true;
 | 
			
		||||
    for (size_t i = 0; i < matchers_.size(); ++i) {
 | 
			
		||||
      StringMatchResultListener slistener;
 | 
			
		||||
      if (matchers_[i].MatchAndExplain(x, &slistener)) {
 | 
			
		||||
        *listener << slistener.str();
 | 
			
		||||
        return true;
 | 
			
		||||
      } else {
 | 
			
		||||
        if (no_match_result.empty()) {
 | 
			
		||||
          no_match_result = slistener.str();
 | 
			
		||||
        } else {
 | 
			
		||||
          std::string result = slistener.str();
 | 
			
		||||
          if (!result.empty()) {
 | 
			
		||||
            no_match_result += ", and ";
 | 
			
		||||
            no_match_result += result;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Otherwise we need to explain why *both* of them fail.
 | 
			
		||||
    const std::string s1 = listener1.str();
 | 
			
		||||
    const std::string s2 = listener2.str();
 | 
			
		||||
 | 
			
		||||
    if (s1 == "") {
 | 
			
		||||
      *listener << s2;
 | 
			
		||||
    } else {
 | 
			
		||||
      *listener << s1;
 | 
			
		||||
      if (s2 != "") {
 | 
			
		||||
        *listener << ", and " << s2;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    *listener << no_match_result;
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  const Matcher<T> matcher1_;
 | 
			
		||||
  const Matcher<T> matcher2_;
 | 
			
		||||
  const std::vector<Matcher<T> > matchers_;
 | 
			
		||||
 | 
			
		||||
  GTEST_DISALLOW_ASSIGN_(EitherOfMatcherImpl);
 | 
			
		||||
  GTEST_DISALLOW_ASSIGN_(AnyOfMatcherImpl);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if GTEST_LANG_CXX11
 | 
			
		||||
// AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...).
 | 
			
		||||
template <typename... Args>
 | 
			
		||||
using AnyOfMatcher = VariadicMatcher<EitherOfMatcherImpl, Args...>;
 | 
			
		||||
using AnyOfMatcher = VariadicMatcher<AnyOfMatcherImpl, Args...>;
 | 
			
		||||
 | 
			
		||||
#endif  // GTEST_LANG_CXX11
 | 
			
		||||
 | 
			
		||||
@@ -1973,8 +1934,10 @@ class EitherOfMatcher {
 | 
			
		||||
  // both Matcher1 and Matcher2 can match.
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  operator Matcher<T>() const {
 | 
			
		||||
    return Matcher<T>(new EitherOfMatcherImpl<T>(
 | 
			
		||||
        SafeMatcherCast<T>(matcher1_), SafeMatcherCast<T>(matcher2_)));
 | 
			
		||||
    std::vector<Matcher<T> > values;
 | 
			
		||||
    values.push_back(SafeMatcherCast<T>(matcher1_));
 | 
			
		||||
    values.push_back(SafeMatcherCast<T>(matcher2_));
 | 
			
		||||
    return Matcher<T>(new AnyOfMatcherImpl<T>(internal::move(values)));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user