39 #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
40 #define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
47 #include <type_traits>
54 #if defined(_MSC_VER) && _MSC_VER >= 1915
55 #define GTEST_MAYBE_5046_ 5046
57 #define GTEST_MAYBE_5046_
78 class MatchResultListener {
83 explicit MatchResultListener(::std::ostream* os) : stream_(os) {}
84 virtual ~MatchResultListener() = 0;
90 if (stream_ !=
nullptr) *stream_ <<
x;
95 ::std::ostream* stream() {
return stream_; }
101 bool IsInterested()
const {
return stream_ !=
nullptr; }
104 ::std::ostream*
const stream_;
106 MatchResultListener(
const MatchResultListener&) =
delete;
107 MatchResultListener& operator=(
const MatchResultListener&) =
delete;
110 inline MatchResultListener::~MatchResultListener() =
default;
116 virtual ~MatcherDescriberInterface() =
default;
123 virtual void DescribeTo(::std::ostream* os)
const = 0;
131 virtual void DescribeNegationTo(::std::ostream* os)
const {
139 template <
typename T>
140 class MatcherInterface :
public MatcherDescriberInterface {
173 virtual bool MatchAndExplain(
T x, MatchResultListener* listener)
const = 0;
183 class DummyMatchResultListener :
public MatchResultListener {
185 DummyMatchResultListener() : MatchResultListener(
nullptr) {}
188 DummyMatchResultListener(
const DummyMatchResultListener&) =
delete;
189 DummyMatchResultListener& operator=(
const DummyMatchResultListener&) =
delete;
195 class StreamMatchResultListener :
public MatchResultListener {
197 explicit StreamMatchResultListener(::std::ostream* os)
198 : MatchResultListener(os) {}
201 StreamMatchResultListener(
const StreamMatchResultListener&) =
delete;
202 StreamMatchResultListener& operator=(
const StreamMatchResultListener&) =
206 struct SharedPayloadBase {
207 std::atomic<int> ref{1};
208 void Ref() { ref.fetch_add(1, std::memory_order_relaxed); }
209 bool Unref() {
return ref.fetch_sub(1, std::memory_order_acq_rel) == 1; }
212 template <
typename T>
213 struct SharedPayload : SharedPayloadBase {
214 explicit SharedPayload(
const T& v) :
value(v) {}
215 explicit SharedPayload(
T&& v) :
value(std::move(v)) {}
217 static void Destroy(SharedPayloadBase* shared) {
218 delete static_cast<SharedPayload*
>(shared);
227 template <
typename T>
228 class MatcherBase :
private MatcherDescriberInterface {
232 bool MatchAndExplain(
const T&
x, MatchResultListener* listener)
const {
234 return vtable_->match_and_explain(*
this, x, listener);
238 bool Matches(
const T& x)
const {
239 DummyMatchResultListener dummy;
240 return MatchAndExplain(x, &dummy);
244 void DescribeTo(::std::ostream* os)
const final {
246 vtable_->describe(*
this, os,
false);
250 void DescribeNegationTo(::std::ostream* os)
const final {
252 vtable_->describe(*
this, os,
true);
256 void ExplainMatchResultTo(
const T& x, ::std::ostream* os)
const {
257 StreamMatchResultListener listener(os);
258 MatchAndExplain(x, &listener);
264 const MatcherDescriberInterface* GetDescriber()
const {
265 if (vtable_ ==
nullptr)
return nullptr;
266 return vtable_->get_describer(*
this);
270 MatcherBase() : vtable_(
nullptr), buffer_() {}
273 template <
typename U>
274 explicit MatcherBase(
const MatcherInterface<U>* impl)
275 : vtable_(
nullptr), buffer_() {
279 template <
typename M,
typename =
typename std::remove_reference<
280 M>::type::is_gtest_matcher>
281 MatcherBase(M&& m) : vtable_(
nullptr), buffer_() {
282 Init(std::forward<M>(m));
285 MatcherBase(
const MatcherBase& other)
286 : vtable_(other.vtable_), buffer_(other.buffer_) {
287 if (IsShared()) buffer_.shared->Ref();
290 MatcherBase& operator=(
const MatcherBase& other) {
291 if (
this == &other)
return *
this;
293 vtable_ = other.vtable_;
294 buffer_ = other.buffer_;
295 if (IsShared()) buffer_.shared->Ref();
299 MatcherBase(MatcherBase&& other)
300 : vtable_(other.vtable_), buffer_(other.buffer_) {
301 other.vtable_ =
nullptr;
304 MatcherBase& operator=(MatcherBase&& other) {
305 if (
this == &other)
return *
this;
307 vtable_ = other.vtable_;
308 buffer_ = other.buffer_;
309 other.vtable_ =
nullptr;
313 ~MatcherBase()
override { Destroy(); }
317 bool (*match_and_explain)(
const MatcherBase&,
const T&,
318 MatchResultListener*);
319 void (*describe)(
const MatcherBase&, std::ostream*,
bool negation);
322 const MatcherDescriberInterface* (*get_describer)(
const MatcherBase&);
324 void (*shared_destroy)(SharedPayloadBase*);
327 bool IsShared()
const {
328 return vtable_ !=
nullptr && vtable_->shared_destroy !=
nullptr;
332 template <
typename P>
333 static auto MatchAndExplainImpl(
const MatcherBase& m,
const T&
value,
334 MatchResultListener* listener)
335 -> decltype(P::Get(m).MatchAndExplain(value, listener->stream())) {
336 return P::Get(m).MatchAndExplain(value, listener->stream());
339 template <
typename P>
340 static auto MatchAndExplainImpl(
const MatcherBase& m,
const T& value,
341 MatchResultListener* listener)
342 -> decltype(P::Get(m).MatchAndExplain(value, listener)) {
343 return P::Get(m).MatchAndExplain(value, listener);
346 template <
typename P>
347 static void DescribeImpl(
const MatcherBase& m, std::ostream* os,
350 P::Get(m).DescribeNegationTo(os);
352 P::Get(m).DescribeTo(os);
356 template <
typename P>
357 static const MatcherDescriberInterface* GetDescriberImpl(
358 const MatcherBase& m) {
366 std::is_convertible<decltype(&P::Get(m)),
367 const MatcherDescriberInterface*>
::value
369 : 0)>(std::make_tuple(&m, &P::Get(m)));
372 template <
typename P>
373 const VTable* GetVTable() {
374 static constexpr VTable kVTable = {&MatchAndExplainImpl<P>,
375 &DescribeImpl<P>, &GetDescriberImpl<P>,
386 SharedPayloadBase* shared;
390 if (IsShared() && buffer_.shared->Unref()) {
391 vtable_->shared_destroy(buffer_.shared);
395 template <
typename M>
396 static constexpr
bool IsInlined() {
397 return sizeof(M) <=
sizeof(Buffer) &&
alignof(M) <=
alignof(Buffer) &&
402 template <
typename M,
bool = MatcherBase::IsInlined<M>()>
404 static const M& Get(
const MatcherBase& m) {
408 static_cast<const M*
>(
static_cast<const void*
>(&m.buffer_));
411 static void Init(MatcherBase& m, M impl) {
412 ::new (static_cast<void*>(&m.buffer_)) M(impl);
414 static constexpr
auto shared_destroy =
nullptr;
417 template <
typename M>
418 struct ValuePolicy<M, false> {
419 using Shared = SharedPayload<M>;
420 static const M& Get(
const MatcherBase& m) {
421 return static_cast<Shared*
>(m.buffer_.shared)->value;
423 template <
typename Arg>
424 static void Init(MatcherBase& m, Arg&& arg) {
425 m.buffer_.shared =
new Shared(std::forward<Arg>(arg));
427 static constexpr
auto shared_destroy = &Shared::Destroy;
430 template <
typename U,
bool B>
431 struct ValuePolicy<const MatcherInterface<U>*,
B> {
432 using M =
const MatcherInterface<U>;
433 using Shared = SharedPayload<std::unique_ptr<M>>;
434 static const M& Get(
const MatcherBase& m) {
435 return *
static_cast<Shared*
>(m.buffer_.shared)->value;
437 static void Init(MatcherBase& m, M* impl) {
438 m.buffer_.shared =
new Shared(std::unique_ptr<M>(impl));
441 static constexpr
auto shared_destroy = &Shared::Destroy;
444 template <
typename M>
446 using MM =
typename std::decay<M>::type;
447 using Policy = ValuePolicy<MM>;
448 vtable_ = GetVTable<Policy>();
449 Policy::Init(*
this, std::forward<M>(m));
452 const VTable* vtable_;
462 template <
typename T>
463 class Matcher :
public internal::MatcherBase<T> {
468 explicit Matcher() {}
471 explicit Matcher(
const MatcherInterface<const T&>* impl)
472 : internal::MatcherBase<T>(impl) {}
474 template <
typename U>
476 const MatcherInterface<U>* impl,
479 : internal::MatcherBase<T>(impl) {}
481 template <
typename M,
typename =
typename std::remove_reference<
482 M>::type::is_gtest_matcher>
483 Matcher(M&& m) : internal::MatcherBase<T>(std::forward<M>(m)) {}
495 :
public internal::MatcherBase<const std::string&> {
499 explicit Matcher(
const MatcherInterface<const std::string&>* impl)
500 : internal::MatcherBase<const std::string&>(impl) {}
502 template <
typename M,
typename =
typename std::remove_reference<
503 M>::type::is_gtest_matcher>
505 : internal::MatcherBase<const std::string&>(std::forward<M>(m)) {}
509 Matcher(
const std::string& s);
512 Matcher(
const char* s);
517 :
public internal::MatcherBase<std::string> {
521 explicit Matcher(
const MatcherInterface<const std::string&>* impl)
522 : internal::MatcherBase<std::string>(impl) {}
523 explicit Matcher(
const MatcherInterface<std::string>* impl)
524 : internal::MatcherBase<std::string>(impl) {}
526 template <
typename M,
typename =
typename std::remove_reference<
527 M>::type::is_gtest_matcher>
529 : internal::MatcherBase<std::string>(std::forward<M>(m)) {}
533 Matcher(
const std::string& s);
536 Matcher(
const char* s);
539 #if GTEST_INTERNAL_HAS_STRING_VIEW
544 class GTEST_API_ Matcher<const internal::StringView&>
545 :
public internal::MatcherBase<const internal::StringView&> {
549 explicit Matcher(
const MatcherInterface<const internal::StringView&>* impl)
550 : internal::MatcherBase<const internal::StringView&>(impl) {}
552 template <
typename M,
typename =
typename std::remove_reference<
553 M>::type::is_gtest_matcher>
555 : internal::MatcherBase<const internal::StringView&>(std::forward<M>(m)) {
560 Matcher(
const std::string& s);
563 Matcher(
const char* s);
566 Matcher(internal::StringView s);
570 class GTEST_API_ Matcher<internal::StringView>
571 :
public internal::MatcherBase<internal::StringView> {
575 explicit Matcher(
const MatcherInterface<const internal::StringView&>* impl)
576 : internal::MatcherBase<internal::StringView>(impl) {}
577 explicit Matcher(
const MatcherInterface<internal::StringView>* impl)
578 : internal::MatcherBase<internal::StringView>(impl) {}
580 template <
typename M,
typename =
typename std::remove_reference<
581 M>::type::is_gtest_matcher>
583 : internal::MatcherBase<internal::StringView>(std::forward<M>(m)) {}
587 Matcher(
const std::string& s);
590 Matcher(
const char* s);
593 Matcher(internal::StringView s);
595 #endif // GTEST_INTERNAL_HAS_STRING_VIEW
598 template <
typename T>
599 std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
600 matcher.DescribeTo(&os);
616 template <
class Impl>
617 class PolymorphicMatcher {
619 explicit PolymorphicMatcher(
const Impl& an_impl) : impl_(an_impl) {}
623 Impl& mutable_impl() {
return impl_; }
627 const Impl& impl()
const {
return impl_; }
629 template <
typename T>
630 operator Matcher<T>()
const {
631 return Matcher<T>(
new MonomorphicImpl<const T&>(impl_));
635 template <
typename T>
636 class MonomorphicImpl :
public MatcherInterface<T> {
638 explicit MonomorphicImpl(
const Impl& impl) : impl_(impl) {}
640 void DescribeTo(::std::ostream* os)
const override { impl_.DescribeTo(os); }
642 void DescribeNegationTo(::std::ostream* os)
const override {
643 impl_.DescribeNegationTo(os);
646 bool MatchAndExplain(
T x, MatchResultListener* listener)
const override {
647 return impl_.MatchAndExplain(x, listener);
663 template <
typename T>
664 inline Matcher<T> MakeMatcher(
const MatcherInterface<T>* impl) {
665 return Matcher<T>(impl);
675 template <
class Impl>
676 inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(
const Impl& impl) {
677 return PolymorphicMatcher<Impl>(impl);
691 template <
typename D,
typename Rhs,
typename Op>
692 class ComparisonBase {
694 explicit ComparisonBase(
const Rhs& rhs) : rhs_(rhs) {}
696 using is_gtest_matcher =
void;
698 template <
typename Lhs>
699 bool MatchAndExplain(
const Lhs& lhs, std::ostream*)
const {
700 return Op()(lhs, Unwrap(rhs_));
702 void DescribeTo(std::ostream* os)
const {
703 *os << D::Desc() <<
" ";
706 void DescribeNegationTo(std::ostream* os)
const {
707 *os << D::NegatedDesc() <<
" ";
712 template <
typename T>
713 static const T& Unwrap(
const T& v) {
716 template <
typename T>
717 static const T& Unwrap(std::reference_wrapper<T> v) {
724 template <
typename Rhs>
725 class EqMatcher :
public ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>> {
727 explicit EqMatcher(
const Rhs& rhs)
728 : ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>>(rhs) {}
729 static const char* Desc() {
return "is equal to"; }
730 static const char* NegatedDesc() {
return "isn't equal to"; }
732 template <
typename Rhs>
734 :
public ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>> {
736 explicit NeMatcher(
const Rhs& rhs)
737 : ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>>(rhs) {}
738 static const char* Desc() {
return "isn't equal to"; }
739 static const char* NegatedDesc() {
return "is equal to"; }
741 template <
typename Rhs>
742 class LtMatcher :
public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {
744 explicit LtMatcher(
const Rhs& rhs)
745 : ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>>(rhs) {}
746 static const char* Desc() {
return "is <"; }
747 static const char* NegatedDesc() {
return "isn't <"; }
749 template <
typename Rhs>
750 class GtMatcher :
public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {
752 explicit GtMatcher(
const Rhs& rhs)
753 : ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>>(rhs) {}
754 static const char* Desc() {
return "is >"; }
755 static const char* NegatedDesc() {
return "isn't >"; }
757 template <
typename Rhs>
759 :
public ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>> {
761 explicit LeMatcher(
const Rhs& rhs)
762 : ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>>(rhs) {}
763 static const char* Desc() {
return "is <="; }
764 static const char* NegatedDesc() {
return "isn't <="; }
766 template <
typename Rhs>
768 :
public ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>> {
770 explicit GeMatcher(
const Rhs& rhs)
771 : ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>>(rhs) {}
772 static const char* Desc() {
return "is >="; }
773 static const char* NegatedDesc() {
return "isn't >="; }
776 template <
typename T,
typename =
typename std::enable_if<
778 using StringLike =
T;
783 class MatchesRegexMatcher {
785 MatchesRegexMatcher(
const RE* regex,
bool full_match)
786 : regex_(regex), full_match_(full_match) {}
788 #if GTEST_INTERNAL_HAS_STRING_VIEW
789 bool MatchAndExplain(
const internal::StringView& s,
790 MatchResultListener* listener)
const {
791 return MatchAndExplain(std::string(s), listener);
793 #endif // GTEST_INTERNAL_HAS_STRING_VIEW
800 template <
typename CharType>
801 bool MatchAndExplain(CharType* s, MatchResultListener* listener)
const {
802 return s !=
nullptr && MatchAndExplain(std::string(s), listener);
809 template <
class MatcheeStringType>
810 bool MatchAndExplain(
const MatcheeStringType& s,
811 MatchResultListener* )
const {
812 const std::string s2(s);
813 return full_match_ ? RE::FullMatch(s2, *regex_)
814 : RE::PartialMatch(s2, *regex_);
817 void DescribeTo(::std::ostream* os)
const {
818 *os << (full_match_ ?
"matches" :
"contains") <<
" regular expression ";
822 void DescribeNegationTo(::std::ostream* os)
const {
823 *os <<
"doesn't " << (full_match_ ?
"match" :
"contain")
824 <<
" regular expression ";
829 const std::shared_ptr<const RE> regex_;
830 const bool full_match_;
836 inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
837 const internal::RE* regex) {
838 return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex,
true));
840 template <
typename T = std::
string>
841 PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
842 const internal::StringLike<T>& regex) {
843 return MatchesRegex(
new internal::RE(std::string(regex)));
848 inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
849 const internal::RE* regex) {
850 return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex,
false));
852 template <
typename T = std::
string>
853 PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
854 const internal::StringLike<T>& regex) {
855 return ContainsRegex(
new internal::RE(std::string(regex)));
861 template <
typename T>
862 inline internal::EqMatcher<T> Eq(
T x) {
863 return internal::EqMatcher<T>(
x);
868 template <
typename T>
869 Matcher<T>::Matcher(
T value) {
885 template <
typename Lhs,
typename Rhs>
886 inline Matcher<Lhs> TypedEq(
const Rhs& rhs) {
891 template <
typename Rhs>
892 inline internal::GeMatcher<Rhs> Ge(Rhs x) {
893 return internal::GeMatcher<Rhs>(
x);
897 template <
typename Rhs>
898 inline internal::GtMatcher<Rhs> Gt(Rhs x) {
899 return internal::GtMatcher<Rhs>(
x);
903 template <
typename Rhs>
904 inline internal::LeMatcher<Rhs> Le(Rhs x) {
905 return internal::LeMatcher<Rhs>(
x);
909 template <
typename Rhs>
910 inline internal::LtMatcher<Rhs> Lt(Rhs x) {
911 return internal::LtMatcher<Rhs>(
x);
915 template <
typename Rhs>
916 inline internal::NeMatcher<Rhs> Ne(Rhs x) {
917 return internal::NeMatcher<Rhs>(
x);
923 #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
GTEST_DISABLE_MSC_WARNINGS_POP_() TEST(LinkTest
std::string Print(const T &value)
#define GTEST_MAYBE_5046_
std::ostream & operator<<(std::ostream &os, const Expr< T > &xx)
#define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings)
#define GTEST_CHECK_(condition)
void UniversalPrint(const T &value,::std::ostream *os)