35 #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
36 #define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
42 #include <type_traits>
44 #include "gtest/gtest-printers.h"
45 #include "gtest/internal/gtest-internal.h"
46 #include "gtest/internal/gtest-port.h"
49 #if defined(_MSC_VER) && _MSC_VER >= 1915
50 #define GTEST_MAYBE_5046_ 5046
52 #define GTEST_MAYBE_5046_
73 class MatchResultListener {
78 explicit MatchResultListener(::std::ostream* os) : stream_(os) {}
79 virtual ~MatchResultListener() = 0;
85 if (stream_ !=
nullptr) *stream_ << x;
90 ::std::ostream* stream() {
return stream_; }
96 bool IsInterested()
const {
return stream_ !=
nullptr; }
99 ::std::ostream*
const stream_;
104 inline MatchResultListener::~MatchResultListener() {
109 class MatcherDescriberInterface {
111 virtual ~MatcherDescriberInterface() {}
118 virtual void DescribeTo(::std::ostream* os)
const = 0;
126 virtual void DescribeNegationTo(::std::ostream* os)
const {
134 template <
typename T>
135 class MatcherInterface :
public MatcherDescriberInterface {
168 virtual bool MatchAndExplain(T x, MatchResultListener* listener)
const = 0;
178 template <
typename A,
typename B>
179 bool operator()(
const A& a,
const B& b)
const {
return a == b; }
182 template <
typename A,
typename B>
183 bool operator()(
const A& a,
const B& b)
const {
return a != b; }
186 template <
typename A,
typename B>
187 bool operator()(
const A& a,
const B& b)
const {
return a < b; }
190 template <
typename A,
typename B>
191 bool operator()(
const A& a,
const B& b)
const {
return a > b; }
194 template <
typename A,
typename B>
195 bool operator()(
const A& a,
const B& b)
const {
return a <= b; }
198 template <
typename A,
typename B>
199 bool operator()(
const A& a,
const B& b)
const {
return a >= b; }
203 class DummyMatchResultListener :
public MatchResultListener {
205 DummyMatchResultListener() : MatchResultListener(
nullptr) {}
214 class StreamMatchResultListener :
public MatchResultListener {
216 explicit StreamMatchResultListener(::std::ostream* os)
217 : MatchResultListener(os) {}
223 struct SharedPayloadBase {
224 std::atomic<int> ref{1};
225 void Ref() { ref.fetch_add(1, std::memory_order_relaxed); }
226 bool Unref() {
return ref.fetch_sub(1, std::memory_order_acq_rel) == 1; }
229 template <
typename T>
230 struct SharedPayload : SharedPayloadBase {
231 explicit SharedPayload(
const T& v) : value(v) {}
232 explicit SharedPayload(T&& v) : value(std::move(v)) {}
234 static void Destroy(SharedPayloadBase* shared) {
235 delete static_cast<SharedPayload*
>(shared);
244 template <
typename T>
245 class MatcherBase :
private MatcherDescriberInterface {
249 bool MatchAndExplain(
const T& x, MatchResultListener* listener)
const {
251 return vtable_->match_and_explain(*
this, x, listener);
255 bool Matches(
const T& x)
const {
256 DummyMatchResultListener dummy;
257 return MatchAndExplain(x, &dummy);
261 void DescribeTo(::std::ostream* os)
const final {
263 vtable_->describe(*
this, os,
false);
267 void DescribeNegationTo(::std::ostream* os)
const final {
269 vtable_->describe(*
this, os,
true);
273 void ExplainMatchResultTo(
const T& x, ::std::ostream* os)
const {
274 StreamMatchResultListener listener(os);
275 MatchAndExplain(x, &listener);
281 const MatcherDescriberInterface* GetDescriber()
const {
282 if (vtable_ ==
nullptr)
return nullptr;
283 return vtable_->get_describer(*
this);
287 MatcherBase() : vtable_(
nullptr) {}
290 template <
typename U>
291 explicit MatcherBase(
const MatcherInterface<U>* impl) {
295 template <
typename M,
typename =
typename std::remove_reference<
296 M>::type::is_gtest_matcher>
298 Init(std::forward<M>(m));
301 MatcherBase(
const MatcherBase& other)
302 : vtable_(other.vtable_), buffer_(other.buffer_) {
303 if (IsShared()) buffer_.shared->Ref();
306 MatcherBase& operator=(
const MatcherBase& other) {
307 if (
this == &other)
return *
this;
309 vtable_ = other.vtable_;
310 buffer_ = other.buffer_;
311 if (IsShared()) buffer_.shared->Ref();
315 MatcherBase(MatcherBase&& other)
316 : vtable_(other.vtable_), buffer_(other.buffer_) {
317 other.vtable_ =
nullptr;
320 MatcherBase& operator=(MatcherBase&& other) {
321 if (
this == &other)
return *
this;
323 vtable_ = other.vtable_;
324 buffer_ = other.buffer_;
325 other.vtable_ =
nullptr;
329 ~MatcherBase()
override { Destroy(); }
333 bool (*match_and_explain)(
const MatcherBase&,
const T&,
334 MatchResultListener*);
335 void (*describe)(
const MatcherBase&, std::ostream*,
bool negation);
338 const MatcherDescriberInterface* (*get_describer)(
const MatcherBase&);
340 void (*shared_destroy)(SharedPayloadBase*);
343 bool IsShared()
const {
344 return vtable_ !=
nullptr && vtable_->shared_destroy !=
nullptr;
348 template <
typename P>
349 static auto MatchAndExplainImpl(
const MatcherBase& m,
const T& value,
350 MatchResultListener* listener)
351 -> decltype(P::Get(m).MatchAndExplain(value, listener->stream())) {
352 return P::Get(m).MatchAndExplain(value, listener->stream());
355 template <
typename P>
356 static auto MatchAndExplainImpl(
const MatcherBase& m,
const T& value,
357 MatchResultListener* listener)
358 -> decltype(P::Get(m).MatchAndExplain(value, listener)) {
359 return P::Get(m).MatchAndExplain(value, listener);
362 template <
typename P>
363 static void DescribeImpl(
const MatcherBase& m, std::ostream* os,
366 P::Get(m).DescribeNegationTo(os);
368 P::Get(m).DescribeTo(os);
372 template <
typename P>
373 static const MatcherDescriberInterface* GetDescriberImpl(
374 const MatcherBase& m) {
382 std::is_convertible<decltype(&P::Get(m)),
383 const MatcherDescriberInterface*>::value
385 : 0)>(std::make_tuple(&m, &P::Get(m)));
388 template <
typename P>
389 const VTable* GetVTable() {
390 static constexpr VTable kVTable = {&MatchAndExplainImpl<P>,
391 &DescribeImpl<P>, &GetDescriberImpl<P>,
402 SharedPayloadBase* shared;
406 if (IsShared() && buffer_.shared->Unref()) {
407 vtable_->shared_destroy(buffer_.shared);
411 template <
typename M>
412 static constexpr
bool IsInlined() {
413 return sizeof(M) <=
sizeof(Buffer) &&
alignof(M) <=
alignof(Buffer) &&
414 std::is_trivially_copy_constructible<M>::value &&
415 std::is_trivially_destructible<M>::value;
418 template <typename M, bool = MatcherBase::IsInlined<M>()>
420 static const M& Get(
const MatcherBase& m) {
423 const M *ptr =
static_cast<const M*
>(
424 static_cast<const void*
>(&m.buffer_));
427 static void Init(MatcherBase& m, M impl) {
428 ::new (
static_cast<void*
>(&m.buffer_)) M(impl);
430 static constexpr
auto shared_destroy =
nullptr;
433 template <
typename M>
434 struct ValuePolicy<M, false> {
435 using Shared = SharedPayload<M>;
436 static const M& Get(
const MatcherBase& m) {
437 return static_cast<Shared*
>(m.buffer_.shared)->value;
439 template <
typename Arg>
440 static void Init(MatcherBase& m, Arg&& arg) {
441 m.buffer_.shared =
new Shared(std::forward<Arg>(arg));
443 static constexpr
auto shared_destroy = &Shared::Destroy;
446 template <
typename U,
bool B>
447 struct ValuePolicy<const MatcherInterface<U>*, B> {
448 using M =
const MatcherInterface<U>;
449 using Shared = SharedPayload<std::unique_ptr<M>>;
450 static const M& Get(
const MatcherBase& m) {
451 return *
static_cast<Shared*
>(m.buffer_.shared)->value;
453 static void Init(MatcherBase& m, M* impl) {
454 m.buffer_.shared =
new Shared(std::unique_ptr<M>(impl));
457 static constexpr
auto shared_destroy = &Shared::Destroy;
460 template <
typename M>
462 using MM =
typename std::decay<M>::type;
463 using Policy = ValuePolicy<MM>;
464 vtable_ = GetVTable<Policy>();
465 Policy::Init(*
this, std::forward<M>(m));
468 const VTable* vtable_;
478 template <
typename T>
479 class Matcher :
public internal::MatcherBase<T> {
484 explicit Matcher() {}
487 explicit Matcher(
const MatcherInterface<const T&>* impl)
488 : internal::MatcherBase<T>(impl) {}
490 template <
typename U>
492 const MatcherInterface<U>* impl,
493 typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
495 : internal::MatcherBase<T>(impl) {}
497 template <
typename M,
typename =
typename std::remove_reference<
498 M>::type::is_gtest_matcher>
499 Matcher(M&& m) : internal::MatcherBase<T>(std::forward<M>(m)) {}
511 :
public internal::MatcherBase<const std::string&> {
515 explicit Matcher(
const MatcherInterface<const std::string&>* impl)
516 : internal::MatcherBase<const std::string&>(impl) {}
518 template <
typename M,
typename =
typename std::remove_reference<
519 M>::type::is_gtest_matcher>
521 : internal::MatcherBase<const std::string&>(std::forward<M>(m)) {}
525 Matcher(
const std::string& s);
528 Matcher(
const char* s);
533 :
public internal::MatcherBase<std::string> {
537 explicit Matcher(
const MatcherInterface<const std::string&>* impl)
538 : internal::MatcherBase<std::string>(impl) {}
539 explicit Matcher(
const MatcherInterface<std::string>* impl)
540 : internal::MatcherBase<std::string>(impl) {}
542 template <
typename M,
typename =
typename std::remove_reference<
543 M>::type::is_gtest_matcher>
545 : internal::MatcherBase<std::string>(std::forward<M>(m)) {}
549 Matcher(
const std::string& s);
552 Matcher(
const char* s);
555 #if GTEST_INTERNAL_HAS_STRING_VIEW
560 class GTEST_API_ Matcher<const internal::StringView&>
561 :
public internal::MatcherBase<const internal::StringView&> {
565 explicit Matcher(
const MatcherInterface<const internal::StringView&>* impl)
566 : internal::MatcherBase<const internal::StringView&>(impl) {}
568 template <
typename M,
typename =
typename std::remove_reference<
569 M>::type::is_gtest_matcher>
571 : internal::MatcherBase<const internal::StringView&>(std::forward<M>(m)) {
576 Matcher(
const std::string& s);
579 Matcher(
const char* s);
582 Matcher(internal::StringView s);
586 class GTEST_API_ Matcher<internal::StringView>
587 :
public internal::MatcherBase<internal::StringView> {
591 explicit Matcher(
const MatcherInterface<const internal::StringView&>* impl)
592 : internal::MatcherBase<internal::StringView>(impl) {}
593 explicit Matcher(
const MatcherInterface<internal::StringView>* impl)
594 : internal::MatcherBase<internal::StringView>(impl) {}
596 template <
typename M,
typename =
typename std::remove_reference<
597 M>::type::is_gtest_matcher>
599 : internal::MatcherBase<internal::StringView>(std::forward<M>(m)) {}
603 Matcher(
const std::string& s);
606 Matcher(
const char* s);
609 Matcher(internal::StringView s);
614 template <
typename T>
615 std::ostream&
operator<<(std::ostream& os,
const Matcher<T>& matcher) {
616 matcher.DescribeTo(&os);
632 template <
class Impl>
633 class PolymorphicMatcher {
635 explicit PolymorphicMatcher(
const Impl& an_impl) : impl_(an_impl) {}
639 Impl& mutable_impl() {
return impl_; }
643 const Impl& impl()
const {
return impl_; }
645 template <
typename T>
646 operator Matcher<T>()
const {
647 return Matcher<T>(
new MonomorphicImpl<const T&>(impl_));
651 template <
typename T>
652 class MonomorphicImpl :
public MatcherInterface<T> {
654 explicit MonomorphicImpl(
const Impl& impl) : impl_(impl) {}
656 void DescribeTo(::std::ostream* os)
const override { impl_.DescribeTo(os); }
658 void DescribeNegationTo(::std::ostream* os)
const override {
659 impl_.DescribeNegationTo(os);
662 bool MatchAndExplain(T x, MatchResultListener* listener)
const override {
663 return impl_.MatchAndExplain(x, listener);
679 template <
typename T>
680 inline Matcher<T> MakeMatcher(
const MatcherInterface<T>* impl) {
681 return Matcher<T>(impl);
691 template <
class Impl>
692 inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(
const Impl& impl) {
693 return PolymorphicMatcher<Impl>(impl);
707 template <
typename D,
typename Rhs,
typename Op>
708 class ComparisonBase {
710 explicit ComparisonBase(
const Rhs& rhs) : rhs_(rhs) {}
712 using is_gtest_matcher = void;
714 template <
typename Lhs>
715 bool MatchAndExplain(
const Lhs& lhs, std::ostream*)
const {
716 return Op()(lhs, Unwrap(rhs_));
718 void DescribeTo(std::ostream* os)
const {
719 *os << D::Desc() <<
" ";
722 void DescribeNegationTo(std::ostream* os)
const {
723 *os << D::NegatedDesc() <<
" ";
728 template <
typename T>
729 static const T& Unwrap(
const T& v) {
732 template <
typename T>
733 static const T& Unwrap(std::reference_wrapper<T> v) {
740 template <
typename Rhs>
741 class EqMatcher :
public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> {
743 explicit EqMatcher(
const Rhs& rhs)
744 : ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) { }
745 static const char* Desc() {
return "is equal to"; }
746 static const char* NegatedDesc() {
return "isn't equal to"; }
748 template <
typename Rhs>
749 class NeMatcher :
public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> {
751 explicit NeMatcher(
const Rhs& rhs)
752 : ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) { }
753 static const char* Desc() {
return "isn't equal to"; }
754 static const char* NegatedDesc() {
return "is equal to"; }
756 template <
typename Rhs>
757 class LtMatcher :
public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> {
759 explicit LtMatcher(
const Rhs& rhs)
760 : ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) { }
761 static const char* Desc() {
return "is <"; }
762 static const char* NegatedDesc() {
return "isn't <"; }
764 template <
typename Rhs>
765 class GtMatcher :
public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> {
767 explicit GtMatcher(
const Rhs& rhs)
768 : ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) { }
769 static const char* Desc() {
return "is >"; }
770 static const char* NegatedDesc() {
return "isn't >"; }
772 template <
typename Rhs>
773 class LeMatcher :
public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> {
775 explicit LeMatcher(
const Rhs& rhs)
776 : ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) { }
777 static const char* Desc() {
return "is <="; }
778 static const char* NegatedDesc() {
return "isn't <="; }
780 template <
typename Rhs>
781 class GeMatcher :
public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
783 explicit GeMatcher(
const Rhs& rhs)
784 : ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) { }
785 static const char* Desc() {
return "is >="; }
786 static const char* NegatedDesc() {
return "isn't >="; }
789 template <
typename T,
typename =
typename std::enable_if<
790 std::is_constructible<std::string, T>::value>::type>
791 using StringLike = T;
796 class MatchesRegexMatcher {
798 MatchesRegexMatcher(
const RE* regex,
bool full_match)
799 : regex_(regex), full_match_(full_match) {}
801 #if GTEST_INTERNAL_HAS_STRING_VIEW
802 bool MatchAndExplain(
const internal::StringView& s,
803 MatchResultListener* listener)
const {
804 return MatchAndExplain(std::string(s), listener);
813 template <
typename CharType>
814 bool MatchAndExplain(CharType* s, MatchResultListener* listener)
const {
815 return s !=
nullptr && MatchAndExplain(std::string(s), listener);
822 template <
class MatcheeStringType>
823 bool MatchAndExplain(
const MatcheeStringType& s,
824 MatchResultListener* )
const {
825 const std::string& s2(s);
830 void DescribeTo(::std::ostream* os)
const {
831 *os << (full_match_ ?
"matches" :
"contains") <<
" regular expression ";
835 void DescribeNegationTo(::std::ostream* os)
const {
836 *os <<
"doesn't " << (full_match_ ?
"match" :
"contain")
837 <<
" regular expression ";
842 const std::shared_ptr<const RE> regex_;
843 const bool full_match_;
849 inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
850 const internal::RE* regex) {
851 return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex,
true));
853 template <
typename T = std::
string>
854 PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
855 const internal::StringLike<T>& regex) {
856 return MatchesRegex(
new internal::RE(std::string(regex)));
861 inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
862 const internal::RE* regex) {
863 return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex,
false));
865 template <
typename T = std::
string>
866 PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
867 const internal::StringLike<T>& regex) {
868 return ContainsRegex(
new internal::RE(std::string(regex)));
874 template <
typename T>
875 inline internal::EqMatcher<T> Eq(T x) {
return internal::EqMatcher<T>(x); }
879 template <
typename T>
880 Matcher<T>::Matcher(T value) { *
this = Eq(value); }
894 template <
typename Lhs,
typename Rhs>
895 inline Matcher<Lhs> TypedEq(
const Rhs& rhs) {
return Eq(rhs); }
898 template <
typename Rhs>
899 inline internal::GeMatcher<Rhs> Ge(Rhs x) {
900 return internal::GeMatcher<Rhs>(x);
904 template <
typename Rhs>
905 inline internal::GtMatcher<Rhs> Gt(Rhs x) {
906 return internal::GtMatcher<Rhs>(x);
910 template <
typename Rhs>
911 inline internal::LeMatcher<Rhs> Le(Rhs x) {
912 return internal::LeMatcher<Rhs>(x);
916 template <
typename Rhs>
917 inline internal::LtMatcher<Rhs> Lt(Rhs x) {
918 return internal::LtMatcher<Rhs>(x);
922 template <
typename Rhs>
923 inline internal::NeMatcher<Rhs> Ne(Rhs x) {
924 return internal::NeMatcher<Rhs>(x);
static bool PartialMatch(const ::std::string &str, const RE &re)
Definition: cmake-build-debug/googletest-src/googletest/include/gtest/internal/gtest-port.h:911
static bool FullMatch(const ::std::string &str, const RE &re)
Definition: cmake-build-debug/googletest-src/googletest/include/gtest/internal/gtest-port.h:908
static void Print(const T &value, ::std::ostream *os)
Definition: cmake-build-debug/googletest-src/googletest/include/gtest/gtest-printers.h:665
#define GTEST_API_
Definition: cmake-build-debug/googletest-src/googletest/include/gtest/internal/gtest-port.h:775
#define GTEST_DISABLE_MSC_WARNINGS_POP_()
Definition: cmake-build-debug/googletest-src/googletest/include/gtest/internal/gtest-port.h:324
#define GTEST_CHECK_(condition)
Definition: cmake-build-debug/googletest-src/googletest/include/gtest/internal/gtest-port.h:1004
#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)
Definition: cmake-build-debug/googletest-src/googletest/include/gtest/internal/gtest-port.h:693
#define GTEST_MAYBE_5046_
Definition: cmake-build-release/googletest-src/googletest/include/gtest/gtest-matchers.h:52
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 GTEST_MAYBE_5046_) namespace testing
Definition: cmake-build-release/googletest-src/googletest/include/gtest/gtest-matchers.h:55
void UniversalPrint(const T &value, ::std::ostream *os)
Definition: cmake-build-debug/googletest-src/googletest/include/gtest/gtest-printers.h:902
Definition: cmake-build-debug/googletest-src/googlemock/include/gmock/gmock-actions.h:154
std::ostream & operator<<(std::ostream &os, const Message &sb)
Definition: cmake-build-debug/googletest-src/googletest/include/gtest/gtest-message.h:199