diff options
Diffstat (limited to 'include/gmock/gmock-matchers.h')
-rw-r--r-- | include/gmock/gmock-matchers.h | 291 |
1 files changed, 147 insertions, 144 deletions
diff --git a/include/gmock/gmock-matchers.h b/include/gmock/gmock-matchers.h index 5700fb25..bf049d45 100644 --- a/include/gmock/gmock-matchers.h +++ b/include/gmock/gmock-matchers.h @@ -960,10 +960,35 @@ GMOCK_IMPLEMENT_COMPARISON2_MATCHER_(Ne, !=, "not equal to"); #undef GMOCK_IMPLEMENT_COMPARISON2_MATCHER_ -// TODO(vladl@google.com): Move Impl outside of NotMatcher and rename it -// NotMatcherImpl to reduce compilation overhead and the size of the binary. -// This also applies to BothOfMatcher::Impl and EitherOfMatcher::Impl. -// +// Implements the Not(...) matcher for a particular argument type T. +// We do not nest it inside the NotMatcher class template, as that +// will prevent different instantiations of NotMatcher from sharing +// the same NotMatcherImpl<T> class. +template <typename T> +class NotMatcherImpl : public MatcherInterface<T> { + public: + explicit NotMatcherImpl(const Matcher<T>& matcher) + : matcher_(matcher) {} + + virtual bool Matches(T x) const { + return !matcher_.Matches(x); + } + + virtual void DescribeTo(::std::ostream* os) const { + matcher_.DescribeNegationTo(os); + } + + virtual void DescribeNegationTo(::std::ostream* os) const { + matcher_.DescribeTo(os); + } + + virtual void ExplainMatchResultTo(T x, ::std::ostream* os) const { + matcher_.ExplainMatchResultTo(x, os); + } + private: + const Matcher<T> matcher_; +}; + // Implements the Not(m) matcher, which matches a value that doesn't // match matcher m. template <typename InnerMatcher> @@ -975,36 +1000,72 @@ class NotMatcher { // to match any type m can match. template <typename T> operator Matcher<T>() const { - return Matcher<T>(new Impl<T>(matcher_)); + return Matcher<T>(new NotMatcherImpl<T>(SafeMatcherCast<T>(matcher_))); } private: - // Implements the Not(...) matcher for a particular argument type T. - template <typename T> - class Impl : public MatcherInterface<T> { - public: - explicit Impl(InnerMatcher matcher) - : matcher_(SafeMatcherCast<T>(matcher)) {} + InnerMatcher matcher_; +}; - virtual bool Matches(T x) const { - return !matcher_.Matches(x); - } +// Implements the AllOf(m1, m2) matcher for a particular argument type +// T. We do not nest it inside the BothOfMatcher class template, as +// that will prevent different instantiations of BothOfMatcher from +// sharing the same BothOfMatcherImpl<T> class. +template <typename T> +class BothOfMatcherImpl : public MatcherInterface<T> { + public: + BothOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2) + : matcher1_(matcher1), matcher2_(matcher2) {} - virtual void DescribeTo(::std::ostream* os) const { - matcher_.DescribeNegationTo(os); - } + virtual bool Matches(T x) const { + return matcher1_.Matches(x) && matcher2_.Matches(x); + } - virtual void DescribeNegationTo(::std::ostream* os) const { - matcher_.DescribeTo(os); - } + virtual void DescribeTo(::std::ostream* os) const { + *os << "("; + matcher1_.DescribeTo(os); + *os << ") and ("; + matcher2_.DescribeTo(os); + *os << ")"; + } - virtual void ExplainMatchResultTo(T x, ::std::ostream* os) const { - matcher_.ExplainMatchResultTo(x, os); - } - private: - const Matcher<T> matcher_; - }; + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "not "; + DescribeTo(os); + } - InnerMatcher matcher_; + virtual void ExplainMatchResultTo(T x, ::std::ostream* os) const { + if (Matches(x)) { + // When both matcher1_ and matcher2_ match x, we need to + // explain why *both* of them match. + ::std::stringstream ss1; + matcher1_.ExplainMatchResultTo(x, &ss1); + const internal::string s1 = ss1.str(); + + ::std::stringstream ss2; + matcher2_.ExplainMatchResultTo(x, &ss2); + const internal::string s2 = ss2.str(); + + if (s1 == "") { + *os << s2; + } else { + *os << s1; + if (s2 != "") { + *os << "; " << s2; + } + } + } else { + // Otherwise we only need to explain why *one* of them fails + // to match. + if (!matcher1_.Matches(x)) { + matcher1_.ExplainMatchResultTo(x, os); + } else { + matcher2_.ExplainMatchResultTo(x, os); + } + } + } + private: + const Matcher<T> matcher1_; + const Matcher<T> matcher2_; }; // Used for implementing the AllOf(m_1, ..., m_n) matcher, which @@ -1020,72 +1081,73 @@ class BothOfMatcher { // both Matcher1 and Matcher2 can match. template <typename T> operator Matcher<T>() const { - return Matcher<T>(new Impl<T>(matcher1_, matcher2_)); + return Matcher<T>(new BothOfMatcherImpl<T>(SafeMatcherCast<T>(matcher1_), + SafeMatcherCast<T>(matcher2_))); } private: - // Implements the AllOf(m1, m2) matcher for a particular argument - // type T. - template <typename T> - class Impl : public MatcherInterface<T> { - public: - Impl(Matcher1 matcher1, Matcher2 matcher2) - : matcher1_(SafeMatcherCast<T>(matcher1)), - matcher2_(SafeMatcherCast<T>(matcher2)) {} + Matcher1 matcher1_; + Matcher2 matcher2_; +}; - virtual bool Matches(T x) const { - return matcher1_.Matches(x) && matcher2_.Matches(x); - } +// Implements the AnyOf(m1, m2) matcher for a particular argument type +// T. We do not nest it inside the AnyOfMatcher class template, as +// that will prevent different instantiations of AnyOfMatcher from +// sharing the same EitherOfMatcherImpl<T> class. +template <typename T> +class EitherOfMatcherImpl : public MatcherInterface<T> { + public: + EitherOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2) + : matcher1_(matcher1), matcher2_(matcher2) {} - virtual void DescribeTo(::std::ostream* os) const { - *os << "("; - matcher1_.DescribeTo(os); - *os << ") and ("; - matcher2_.DescribeTo(os); - *os << ")"; - } + virtual bool Matches(T x) const { + return matcher1_.Matches(x) || matcher2_.Matches(x); + } - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "not "; - DescribeTo(os); - } + virtual void DescribeTo(::std::ostream* os) const { + *os << "("; + matcher1_.DescribeTo(os); + *os << ") or ("; + matcher2_.DescribeTo(os); + *os << ")"; + } - virtual void ExplainMatchResultTo(T x, ::std::ostream* os) const { - if (Matches(x)) { - // When both matcher1_ and matcher2_ match x, we need to - // explain why *both* of them match. - ::std::stringstream ss1; - matcher1_.ExplainMatchResultTo(x, &ss1); - const internal::string s1 = ss1.str(); - - ::std::stringstream ss2; - matcher2_.ExplainMatchResultTo(x, &ss2); - const internal::string s2 = ss2.str(); - - if (s1 == "") { - *os << s2; - } else { - *os << s1; - if (s2 != "") { - *os << "; " << s2; - } - } + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "not "; + DescribeTo(os); + } + + virtual void ExplainMatchResultTo(T x, ::std::ostream* os) const { + if (Matches(x)) { + // If either matcher1_ or matcher2_ matches x, we just need + // to explain why *one* of them matches. + if (matcher1_.Matches(x)) { + matcher1_.ExplainMatchResultTo(x, os); } else { - // Otherwise we only need to explain why *one* of them fails - // to match. - if (!matcher1_.Matches(x)) { - matcher1_.ExplainMatchResultTo(x, os); - } else { - matcher2_.ExplainMatchResultTo(x, os); + matcher2_.ExplainMatchResultTo(x, os); + } + } else { + // Otherwise we need to explain why *neither* matches. + ::std::stringstream ss1; + matcher1_.ExplainMatchResultTo(x, &ss1); + const internal::string s1 = ss1.str(); + + ::std::stringstream ss2; + matcher2_.ExplainMatchResultTo(x, &ss2); + const internal::string s2 = ss2.str(); + + if (s1 == "") { + *os << s2; + } else { + *os << s1; + if (s2 != "") { + *os << "; " << s2; } } } - private: - const Matcher<T> matcher1_; - const Matcher<T> matcher2_; - }; - - Matcher1 matcher1_; - Matcher2 matcher2_; + } + private: + const Matcher<T> matcher1_; + const Matcher<T> matcher2_; }; // Used for implementing the AnyOf(m_1, ..., m_n) matcher, which @@ -1102,69 +1164,10 @@ class EitherOfMatcher { // both Matcher1 and Matcher2 can match. template <typename T> operator Matcher<T>() const { - return Matcher<T>(new Impl<T>(matcher1_, matcher2_)); + return Matcher<T>(new EitherOfMatcherImpl<T>(SafeMatcherCast<T>(matcher1_), + SafeMatcherCast<T>(matcher2_))); } private: - // Implements the AnyOf(m1, m2) matcher for a particular argument - // type T. - template <typename T> - class Impl : public MatcherInterface<T> { - public: - Impl(Matcher1 matcher1, Matcher2 matcher2) - : matcher1_(SafeMatcherCast<T>(matcher1)), - matcher2_(SafeMatcherCast<T>(matcher2)) {} - - virtual bool Matches(T x) const { - return matcher1_.Matches(x) || matcher2_.Matches(x); - } - - virtual void DescribeTo(::std::ostream* os) const { - *os << "("; - matcher1_.DescribeTo(os); - *os << ") or ("; - matcher2_.DescribeTo(os); - *os << ")"; - } - - virtual void DescribeNegationTo(::std::ostream* os) const { - *os << "not "; - DescribeTo(os); - } - - virtual void ExplainMatchResultTo(T x, ::std::ostream* os) const { - if (Matches(x)) { - // If either matcher1_ or matcher2_ matches x, we just need - // to explain why *one* of them matches. - if (matcher1_.Matches(x)) { - matcher1_.ExplainMatchResultTo(x, os); - } else { - matcher2_.ExplainMatchResultTo(x, os); - } - } else { - // Otherwise we need to explain why *neither* matches. - ::std::stringstream ss1; - matcher1_.ExplainMatchResultTo(x, &ss1); - const internal::string s1 = ss1.str(); - - ::std::stringstream ss2; - matcher2_.ExplainMatchResultTo(x, &ss2); - const internal::string s2 = ss2.str(); - - if (s1 == "") { - *os << s2; - } else { - *os << s1; - if (s2 != "") { - *os << "; " << s2; - } - } - } - } - private: - const Matcher<T> matcher1_; - const Matcher<T> matcher2_; - }; - Matcher1 matcher1_; Matcher2 matcher2_; }; |