diff options
| author | zhanyong.wan <zhanyong.wan@8415998a-534a-0410-bf83-d39667b30386> | 2009-05-13 23:38:40 +0000 | 
|---|---|---|
| committer | zhanyong.wan <zhanyong.wan@8415998a-534a-0410-bf83-d39667b30386> | 2009-05-13 23:38:40 +0000 | 
| commit | c6a412397bc98f120d5e79d4a64e3972854b5af3 (patch) | |
| tree | f36e9c70faf270aa9f4516110345e01778088e87 /include | |
| parent | 18490653e80d484b4650d8799184fd1e021efc7b (diff) | |
| download | googletest-c6a412397bc98f120d5e79d4a64e3972854b5af3.tar.gz googletest-c6a412397bc98f120d5e79d4a64e3972854b5af3.tar.bz2 googletest-c6a412397bc98f120d5e79d4a64e3972854b5af3.zip  | |
Adds more tests for using SetArgumentPointee with protobufs; works around a compiler bug on Symbian that gmock-printers.h triggers; reduces template code bloat in gmock-matchers.h; avoids RTTI when it's disabled.
Diffstat (limited to 'include')
| -rw-r--r-- | include/gmock/gmock-matchers.h | 291 | ||||
| -rw-r--r-- | include/gmock/gmock-printers.h | 64 | ||||
| -rw-r--r-- | include/gmock/internal/gmock-port.h | 2 | 
3 files changed, 189 insertions, 168 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_;  }; diff --git a/include/gmock/gmock-printers.h b/include/gmock/gmock-printers.h index bbe44c38..6997a6c1 100644 --- a/include/gmock/gmock-printers.h +++ b/include/gmock/gmock-printers.h @@ -211,7 +211,9 @@ class UniversalPrinter;  // Used to print an STL-style container when the user doesn't define  // a PrintTo() for it.  template <typename C> -void DefaultPrintTo(IsContainer, const C& container, ::std::ostream* os) { +void DefaultPrintTo(IsContainer /* dummy */, +                    false_type /* is not a pointer */, +                    const C& container, ::std::ostream* os) {    const size_t kMaxCount = 32;  // The maximum number of elements to print.    *os << '{';    size_t count = 0; @@ -234,9 +236,31 @@ void DefaultPrintTo(IsContainer, const C& container, ::std::ostream* os) {    *os << '}';  } -// Used to print a value when the user doesn't define PrintTo() for it. +// Used to print a pointer that is neither a char pointer nor a member +// pointer, when the user doesn't define PrintTo() for it.  (A member +// variable pointer or member function pointer doesn't really point to +// a location in the address space.  Their representation is +// implementation-defined.  Therefore they will be printed as raw +// bytes.)  template <typename T> -void DefaultPrintTo(IsNotContainer, const T& value, ::std::ostream* os) { +void DefaultPrintTo(IsNotContainer /* dummy */, +                    true_type /* is a pointer */, +                    T* p, ::std::ostream* os) { +  if (p == NULL) { +    *os << "NULL"; +  } else { +    // We cannot use implicit_cast or static_cast here, as they don't +    // work when p is a function pointer. +    *os << reinterpret_cast<const void*>(p); +  } +} + +// Used to print a non-container, non-pointer value when the user +// doesn't define PrintTo() for it. +template <typename T> +void DefaultPrintTo(IsNotContainer /* dummy */, +                    false_type /* is not a pointer */, +                    const T& value, ::std::ostream* os) {    ::testing_internal::DefaultPrintNonContainerTo(value, os);  } @@ -253,10 +277,11 @@ void DefaultPrintTo(IsNotContainer, const T& value, ::std::ostream* os) {  // wants).  template <typename T>  void PrintTo(const T& value, ::std::ostream* os) { -  // DefaultPrintTo() is overloaded.  The type of its first argument -  // determines which version will be picked.  If T is an STL-style -  // container, the version for container will be called.  Otherwise -  // the generic version will be called. +  // DefaultPrintTo() is overloaded.  The type of its first two +  // arguments determine which version will be picked.  If T is an +  // STL-style container, the version for container will be called; if +  // T is a pointer, the pointer version will be called; otherwise the +  // generic version will be called.    //    // Note that we check for container types here, prior to we check    // for protocol message types in our operator<<.  The rationale is: @@ -267,7 +292,14 @@ void PrintTo(const T& value, ::std::ostream* os) {    // incompatible with Google Mock's format for the container    // elements; therefore we check for container types here to ensure    // that our format is used. -  DefaultPrintTo(IsContainerTest<T>(0), value, os); +  // +  // The second argument of DefaultPrintTo() is needed to bypass a bug +  // in Symbian's C++ compiler that prevents it from picking the right +  // overload between: +  // +  //   PrintTo(const T& x, ...); +  //   PrintTo(T* x, ...); +  DefaultPrintTo(IsContainerTest<T>(0), is_pointer<T>(), value, os);  }  // The following list of PrintTo() overloads tells @@ -323,22 +355,6 @@ inline void PrintTo(wchar_t* s, ::std::ostream* os) {  }  #endif -// Overload for pointers that are neither char pointers nor member -// pointers.  (A member variable pointer or member function pointer -// doesn't really points to a location in the address space.  Their -// representation is implementation-defined.  Therefore they will be -// printed as raw bytes.) -template <typename T> -void PrintTo(T* p, ::std::ostream* os) { -  if (p == NULL) { -    *os << "NULL"; -  } else { -    // We cannot use implicit_cast or static_cast here, as they don't -    // work when p is a function pointer. -    *os << reinterpret_cast<const void*>(p); -  } -} -  // Overload for C arrays.  Multi-dimensional arrays are printed  // properly. diff --git a/include/gmock/internal/gmock-port.h b/include/gmock/internal/gmock-port.h index d242c8e4..75be9edd 100644 --- a/include/gmock/internal/gmock-port.h +++ b/include/gmock/internal/gmock-port.h @@ -162,7 +162,9 @@ inline To down_cast(From* f) {  // so we only accept pointers      implicit_cast<From*, To>(0);    } +#if GTEST_HAS_RTTI    assert(f == NULL || dynamic_cast<To>(f) != NULL);  // RTTI: debug mode only! +#endif    return static_cast<To>(f);  }  | 
