summaryrefslogtreecommitdiffstats
path: root/googletest/include/gtest/gtest-matchers.h
diff options
context:
space:
mode:
Diffstat (limited to 'googletest/include/gtest/gtest-matchers.h')
-rw-r--r--googletest/include/gtest/gtest-matchers.h162
1 files changed, 44 insertions, 118 deletions
diff --git a/googletest/include/gtest/gtest-matchers.h b/googletest/include/gtest/gtest-matchers.h
index 9bcf5ac..c10d650 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