diff options
Diffstat (limited to 'googletest/include/gtest/gtest-matchers.h')
-rw-r--r-- | googletest/include/gtest/gtest-matchers.h | 162 |
1 files changed, 44 insertions, 118 deletions
diff --git a/googletest/include/gtest/gtest-matchers.h b/googletest/include/gtest/gtest-matchers.h index 9bcf5ac2..c10d650b 100644 --- a/googletest/include/gtest/gtest-matchers.h +++ b/googletest/include/gtest/gtest-matchers.h @@ -42,14 +42,22 @@ #include <memory> #include <ostream> #include <string> +#include <type_traits> #include "gtest/gtest-printers.h" #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-port.h" +// MSVC warning C5046 is new as of VS2017 version 15.8. +#if defined(_MSC_VER) && _MSC_VER >= 1915 +#define GTEST_MAYBE_5046_ 5046 +#else +#define GTEST_MAYBE_5046_ +#endif + GTEST_DISABLE_MSC_WARNINGS_PUSH_( - 4251 5046 /* class A needs to have dll-interface to be used by clients of - class B */ + 4251 GTEST_MAYBE_5046_ /* class A needs to have dll-interface to be used by + clients of class B */ /* Symbol involving type with internal linkage not defined */) namespace testing { @@ -69,10 +77,6 @@ namespace testing { // MatchResultListener is an abstract class. Its << operator can be // used by a matcher to explain why a value matches or doesn't match. // -// FIXME: add method -// bool InterestedInWhy(bool result) const; -// to indicate whether the listener is interested in why the match -// result is 'result'. class MatchResultListener { public: // Creates a listener object with the given underlying ostream. The @@ -92,7 +96,7 @@ class MatchResultListener { // Returns the underlying ostream. ::std::ostream* stream() { return stream_; } - // Returns true iff the listener is interested in an explanation of + // Returns true if the listener is interested in an explanation of // the match result. A matcher's MatchAndExplain() method can use // this information to avoid generating the explanation when no one // intends to hear it. @@ -137,7 +141,7 @@ class MatcherDescriberInterface { template <typename T> class MatcherInterface : public MatcherDescriberInterface { public: - // Returns true iff the matcher matches x; also explains the match + // Returns true if the matcher matches x; also explains the match // result to 'listener' if necessary (see the next paragraph), in // the form of a non-restrictive relative clause ("which ...", // "whose ...", etc) that describes x. For example, the @@ -254,15 +258,14 @@ class StreamMatchResultListener : public MatchResultListener { template <typename T> class MatcherBase { public: - // Returns true iff the matcher matches x; also explains the match + // Returns true if the matcher matches x; also explains the match // result to 'listener'. - bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x, - MatchResultListener* listener) const { + bool MatchAndExplain(const T& x, MatchResultListener* listener) const { return impl_->MatchAndExplain(x, listener); } - // Returns true iff this matcher matches x. - bool Matches(GTEST_REFERENCE_TO_CONST_(T) x) const { + // Returns true if this matcher matches x. + bool Matches(const T& x) const { DummyMatchResultListener dummy; return MatchAndExplain(x, &dummy); } @@ -276,8 +279,7 @@ class MatcherBase { } // Explains why x matches, or doesn't match, the matcher. - void ExplainMatchResultTo(GTEST_REFERENCE_TO_CONST_(T) x, - ::std::ostream* os) const { + void ExplainMatchResultTo(const T& x, ::std::ostream* os) const { StreamMatchResultListener listener(os); MatchAndExplain(x, &listener); } @@ -293,22 +295,24 @@ class MatcherBase { MatcherBase() {} // Constructs a matcher from its implementation. - explicit MatcherBase( - const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)>* impl) - : impl_(impl) {} + explicit MatcherBase(const MatcherInterface<const T&>* impl) : impl_(impl) {} template <typename U> explicit MatcherBase( const MatcherInterface<U>* impl, - typename internal::EnableIf< - !internal::IsSame<U, GTEST_REFERENCE_TO_CONST_(U)>::value>::type* = + typename std::enable_if<!std::is_same<U, const U&>::value>::type* = nullptr) : impl_(new internal::MatcherInterfaceAdapter<U>(impl)) {} + MatcherBase(const MatcherBase&) = default; + MatcherBase& operator=(const MatcherBase&) = default; + MatcherBase(MatcherBase&&) = default; + MatcherBase& operator=(MatcherBase&&) = default; + virtual ~MatcherBase() {} private: - std::shared_ptr<const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)>> impl_; + std::shared_ptr<const MatcherInterface<const T&>> impl_; }; } // namespace internal @@ -326,14 +330,13 @@ class Matcher : public internal::MatcherBase<T> { explicit Matcher() {} // NOLINT // Constructs a matcher from its implementation. - explicit Matcher(const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)>* impl) + explicit Matcher(const MatcherInterface<const T&>* impl) : internal::MatcherBase<T>(impl) {} template <typename U> explicit Matcher( const MatcherInterface<U>* impl, - typename internal::EnableIf< - !internal::IsSame<U, GTEST_REFERENCE_TO_CONST_(U)>::value>::type* = + typename std::enable_if<!std::is_same<U, const U&>::value>::type* = nullptr) : internal::MatcherBase<T>(impl) {} @@ -358,12 +361,6 @@ class GTEST_API_ Matcher<const std::string&> // str is a std::string object. Matcher(const std::string& s); // NOLINT -#if GTEST_HAS_GLOBAL_STRING - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a ::string object. - Matcher(const ::string& s); // NOLINT -#endif // GTEST_HAS_GLOBAL_STRING - // Allows the user to write "foo" instead of Eq("foo") sometimes. Matcher(const char* s); // NOLINT }; @@ -383,65 +380,10 @@ class GTEST_API_ Matcher<std::string> // str is a string object. Matcher(const std::string& s); // NOLINT -#if GTEST_HAS_GLOBAL_STRING - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a ::string object. - Matcher(const ::string& s); // NOLINT -#endif // GTEST_HAS_GLOBAL_STRING - // Allows the user to write "foo" instead of Eq("foo") sometimes. Matcher(const char* s); // NOLINT }; -#if GTEST_HAS_GLOBAL_STRING -// The following two specializations allow the user to write str -// instead of Eq(str) and "foo" instead of Eq("foo") when a ::string -// matcher is expected. -template <> -class GTEST_API_ Matcher<const ::string&> - : public internal::MatcherBase<const ::string&> { - public: - Matcher() {} - - explicit Matcher(const MatcherInterface<const ::string&>* impl) - : internal::MatcherBase<const ::string&>(impl) {} - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a std::string object. - Matcher(const std::string& s); // NOLINT - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a ::string object. - Matcher(const ::string& s); // NOLINT - - // Allows the user to write "foo" instead of Eq("foo") sometimes. - Matcher(const char* s); // NOLINT -}; - -template <> -class GTEST_API_ Matcher< ::string> - : public internal::MatcherBase< ::string> { - public: - Matcher() {} - - explicit Matcher(const MatcherInterface<const ::string&>* impl) - : internal::MatcherBase< ::string>(impl) {} - explicit Matcher(const MatcherInterface< ::string>* impl) - : internal::MatcherBase< ::string>(impl) {} - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a std::string object. - Matcher(const std::string& s); // NOLINT - - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a ::string object. - Matcher(const ::string& s); // NOLINT - - // Allows the user to write "foo" instead of Eq("foo") sometimes. - Matcher(const char* s); // NOLINT -}; -#endif // GTEST_HAS_GLOBAL_STRING - #if GTEST_HAS_ABSL // The following two specializations allow the user to write str // instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view @@ -459,12 +401,6 @@ class GTEST_API_ Matcher<const absl::string_view&> // str is a std::string object. Matcher(const std::string& s); // NOLINT -#if GTEST_HAS_GLOBAL_STRING - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a ::string object. - Matcher(const ::string& s); // NOLINT -#endif // GTEST_HAS_GLOBAL_STRING - // Allows the user to write "foo" instead of Eq("foo") sometimes. Matcher(const char* s); // NOLINT @@ -487,12 +423,6 @@ class GTEST_API_ Matcher<absl::string_view> // str is a std::string object. Matcher(const std::string& s); // NOLINT -#if GTEST_HAS_GLOBAL_STRING - // Allows the user to write str instead of Eq(str) sometimes, where - // str is a ::string object. - Matcher(const ::string& s); // NOLINT -#endif // GTEST_HAS_GLOBAL_STRING - // Allows the user to write "foo" instead of Eq("foo") sometimes. Matcher(const char* s); // NOLINT @@ -535,7 +465,7 @@ class PolymorphicMatcher { template <typename T> operator Matcher<T>() const { - return Matcher<T>(new MonomorphicImpl<GTEST_REFERENCE_TO_CONST_(T)>(impl_)); + return Matcher<T>(new MonomorphicImpl<const T&>(impl_)); } private: @@ -556,22 +486,17 @@ class PolymorphicMatcher { private: const Impl impl_; - - GTEST_DISALLOW_ASSIGN_(MonomorphicImpl); }; Impl impl_; - - GTEST_DISALLOW_ASSIGN_(PolymorphicMatcher); }; -// Creates a matcher from its implementation. This is easier to use -// than the Matcher<T> constructor as it doesn't require you to -// explicitly write the template argument, e.g. +// Creates a matcher from its implementation. +// DEPRECATED: Especially in the generic code, prefer: +// Matcher<T>(new MyMatcherImpl<const T&>(...)); // -// MakeMatcher(foo); -// vs -// Matcher<const string&>(foo); +// MakeMatcher may create a Matcher that accepts its argument by value, which +// leads to unnecessary copies & lack of support for non-copyable types. template <typename T> inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) { return Matcher<T>(impl); @@ -606,33 +531,36 @@ class ComparisonBase { explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {} template <typename Lhs> operator Matcher<Lhs>() const { - return MakeMatcher(new Impl<Lhs>(rhs_)); + return Matcher<Lhs>(new Impl<const Lhs&>(rhs_)); } private: - template <typename Lhs> + template <typename T> + static const T& Unwrap(const T& v) { return v; } + template <typename T> + static const T& Unwrap(std::reference_wrapper<T> v) { return v; } + + template <typename Lhs, typename = Rhs> class Impl : public MatcherInterface<Lhs> { public: explicit Impl(const Rhs& rhs) : rhs_(rhs) {} bool MatchAndExplain(Lhs lhs, MatchResultListener* /* listener */) const override { - return Op()(lhs, rhs_); + return Op()(lhs, Unwrap(rhs_)); } void DescribeTo(::std::ostream* os) const override { *os << D::Desc() << " "; - UniversalPrint(rhs_, os); + UniversalPrint(Unwrap(rhs_), os); } void DescribeNegationTo(::std::ostream* os) const override { *os << D::NegatedDesc() << " "; - UniversalPrint(rhs_, os); + UniversalPrint(Unwrap(rhs_), os); } private: Rhs rhs_; - GTEST_DISALLOW_ASSIGN_(Impl); }; Rhs rhs_; - GTEST_DISALLOW_ASSIGN_(ComparisonBase); }; template <typename Rhs> @@ -695,7 +623,7 @@ class MatchesRegexMatcher { #if GTEST_HAS_ABSL bool MatchAndExplain(const absl::string_view& s, MatchResultListener* listener) const { - return MatchAndExplain(string(s), listener); + return MatchAndExplain(std::string(s), listener); } #endif // GTEST_HAS_ABSL @@ -735,8 +663,6 @@ class MatchesRegexMatcher { private: const std::shared_ptr<const RE> regex_; const bool full_match_; - - GTEST_DISALLOW_ASSIGN_(MatchesRegexMatcher); }; } // namespace internal |