77 class MatchResultListener {
82 explicit MatchResultListener(::std::ostream* os) : stream_(os) {}
83 virtual ~MatchResultListener() = 0;
89 if (stream_ !=
nullptr) *stream_ <<
x;
94 ::std::ostream* stream() {
return stream_; }
100 bool IsInterested()
const {
return stream_ !=
nullptr; }
103 ::std::ostream*
const stream_;
105 MatchResultListener(
const MatchResultListener&) =
delete;
106 MatchResultListener& operator=(
const MatchResultListener&) =
delete;
109 inline MatchResultListener::~MatchResultListener() {}
115 virtual ~MatcherDescriberInterface() {}
122 virtual void DescribeTo(::std::ostream* os)
const = 0;
130 virtual void DescribeNegationTo(::std::ostream* os)
const {
138 template <
typename T>
139 class MatcherInterface :
public MatcherDescriberInterface {
172 virtual bool MatchAndExplain(T
x, MatchResultListener* listener)
const = 0;
182 template <
typename A,
typename B>
183 bool operator()(
const A&
a,
const B&
b)
const {
188 template <
typename A,
typename B>
189 bool operator()(
const A&
a,
const B&
b)
const {
194 template <
typename A,
typename B>
195 bool operator()(
const A&
a,
const B&
b)
const {
200 template <
typename A,
typename B>
201 bool operator()(
const A&
a,
const B&
b)
const {
206 template <
typename A,
typename B>
207 bool operator()(
const A&
a,
const B&
b)
const {
212 template <
typename A,
typename B>
213 bool operator()(
const A&
a,
const B&
b)
const {
219 class DummyMatchResultListener :
public MatchResultListener {
221 DummyMatchResultListener() : MatchResultListener(nullptr) {}
224 DummyMatchResultListener(
const DummyMatchResultListener&) =
delete;
225 DummyMatchResultListener& operator=(
const DummyMatchResultListener&) =
delete;
231 class StreamMatchResultListener :
public MatchResultListener {
233 explicit StreamMatchResultListener(::std::ostream* os)
234 : MatchResultListener(os) {}
237 StreamMatchResultListener(
const StreamMatchResultListener&) =
delete;
238 StreamMatchResultListener& operator=(
const StreamMatchResultListener&) =
242 struct SharedPayloadBase {
243 std::atomic<int> ref{1};
244 void Ref() { ref.fetch_add(1, std::memory_order_relaxed); }
245 bool Unref() {
return ref.fetch_sub(1, std::memory_order_acq_rel) == 1; }
248 template <
typename T>
249 struct SharedPayload : SharedPayloadBase {
250 explicit SharedPayload(
const T& v) : value(v) {}
251 explicit SharedPayload(T&& v) : value(
std::move(v)) {}
253 static void Destroy(SharedPayloadBase* shared) {
254 delete static_cast<SharedPayload*
>(shared);
263 template <
typename T>
264 class MatcherBase :
private MatcherDescriberInterface {
268 bool MatchAndExplain(
const T&
x, MatchResultListener* listener)
const {
270 return vtable_->match_and_explain(*
this, x, listener);
274 bool Matches(
const T& x)
const {
275 DummyMatchResultListener
dummy;
276 return MatchAndExplain(x, &dummy);
280 void DescribeTo(::std::ostream* os)
const final {
282 vtable_->describe(*
this, os,
false);
286 void DescribeNegationTo(::std::ostream* os)
const final {
288 vtable_->describe(*
this, os,
true);
292 void ExplainMatchResultTo(
const T& x, ::std::ostream* os)
const {
293 StreamMatchResultListener listener(os);
294 MatchAndExplain(x, &listener);
300 const MatcherDescriberInterface* GetDescriber()
const {
301 if (vtable_ ==
nullptr)
return nullptr;
302 return vtable_->get_describer(*
this);
306 MatcherBase() : vtable_(nullptr), buffer_() {}
309 template <
typename U>
310 explicit MatcherBase(
const MatcherInterface<U>* impl)
311 : vtable_(nullptr), buffer_() {
315 template <
typename M,
typename =
typename std::remove_reference<
316 M>::type::is_gtest_matcher>
317 MatcherBase(M&&
m) : vtable_(nullptr), buffer_() {
318 Init(std::forward<M>(
m));
321 MatcherBase(
const MatcherBase& other)
322 : vtable_(other.vtable_), buffer_(other.buffer_) {
323 if (IsShared()) buffer_.shared->Ref();
326 MatcherBase& operator=(
const MatcherBase& other) {
327 if (
this == &other)
return *
this;
329 vtable_ = other.vtable_;
330 buffer_ = other.buffer_;
331 if (IsShared()) buffer_.shared->Ref();
335 MatcherBase(MatcherBase&& other)
336 : vtable_(other.vtable_), buffer_(other.buffer_) {
337 other.vtable_ =
nullptr;
340 MatcherBase& operator=(MatcherBase&& other) {
341 if (
this == &other)
return *
this;
343 vtable_ = other.vtable_;
344 buffer_ = other.buffer_;
345 other.vtable_ =
nullptr;
349 ~MatcherBase()
override { Destroy(); }
353 bool (*match_and_explain)(
const MatcherBase&,
const T&,
354 MatchResultListener*);
355 void (*describe)(
const MatcherBase&, std::ostream*,
bool negation);
358 const MatcherDescriberInterface* (*get_describer)(
const MatcherBase&);
360 void (*shared_destroy)(SharedPayloadBase*);
363 bool IsShared()
const {
364 return vtable_ !=
nullptr && vtable_->shared_destroy !=
nullptr;
368 template <
typename P>
369 static auto MatchAndExplainImpl(
const MatcherBase&
m,
const T& value,
370 MatchResultListener* listener)
371 -> decltype(P::Get(
m).MatchAndExplain(value, listener->stream())) {
372 return P::Get(
m).MatchAndExplain(value, listener->stream());
375 template <
typename P>
376 static auto MatchAndExplainImpl(
const MatcherBase&
m,
const T& value,
377 MatchResultListener* listener)
378 -> decltype(P::Get(
m).MatchAndExplain(value, listener)) {
379 return P::Get(
m).MatchAndExplain(value, listener);
382 template <
typename P>
383 static void DescribeImpl(
const MatcherBase&
m, std::ostream* os,
386 P::Get(m).DescribeNegationTo(os);
388 P::Get(m).DescribeTo(os);
392 template <
typename P>
393 static const MatcherDescriberInterface* GetDescriberImpl(
394 const MatcherBase& m) {
402 std::is_convertible<decltype(&P::Get(m)),
403 const MatcherDescriberInterface*>::value
405 : 0)>(std::make_tuple(&m, &P::Get(m)));
408 template <
typename P>
409 const VTable* GetVTable() {
410 static constexpr VTable kVTable = {&MatchAndExplainImpl<P>,
411 &DescribeImpl<P>, &GetDescriberImpl<P>,
422 SharedPayloadBase* shared;
426 if (IsShared() && buffer_.shared->Unref()) {
427 vtable_->shared_destroy(buffer_.shared);
431 template <
typename M>
432 static constexpr
bool IsInlined() {
433 return sizeof(M) <=
sizeof(Buffer) &&
alignof(M) <=
alignof(Buffer) &&
434 std::is_trivially_copy_constructible<M>::value &&
435 std::is_trivially_destructible<M>::value;
438 template <
typename M,
bool = MatcherBase::IsInlined<M>()>
440 static const M& Get(
const MatcherBase& m) {
444 static_cast<const M*
>(
static_cast<const void*
>(&m.buffer_));
447 static void Init(MatcherBase& m, M impl) {
448 ::new (static_cast<void*>(&m.buffer_)) M(impl);
450 static constexpr auto shared_destroy =
nullptr;
453 template <typename M>
454 struct ValuePolicy<M, false> {
455 using Shared = SharedPayload<M>;
456 static const M& Get(
const MatcherBase& m) {
457 return static_cast<Shared*
>(m.buffer_.shared)->value;
459 template <
typename Arg>
460 static void Init(MatcherBase& m, Arg&& arg) {
461 m.buffer_.shared =
new Shared(std::forward<Arg>(arg));
463 static constexpr
auto shared_destroy = &Shared::Destroy;
466 template <
typename U,
bool B>
467 struct ValuePolicy<const MatcherInterface<U>*, B> {
468 using M =
const MatcherInterface<U>;
469 using Shared = SharedPayload<std::unique_ptr<M>>;
470 static const M& Get(
const MatcherBase& m) {
471 return *
static_cast<Shared*
>(m.buffer_.shared)->value;
473 static void Init(MatcherBase& m, M* impl) {
474 m.buffer_.shared =
new Shared(std::unique_ptr<M>(impl));
477 static constexpr
auto shared_destroy = &Shared::Destroy;
480 template <
typename M>
483 using Policy = ValuePolicy<MM>;
484 vtable_ = GetVTable<Policy>();
485 Policy::Init(*
this, std::forward<M>(m));
488 const VTable* vtable_;
498 template <
typename T>
499 class Matcher :
public internal::MatcherBase<T> {
504 explicit Matcher() {}
507 explicit Matcher(
const MatcherInterface<const T&>* impl)
508 : internal::MatcherBase<T>(impl) {}
510 template <
typename U>
512 const MatcherInterface<U>* impl,
513 typename std::enable_if<!std::is_same<U, const U&>::value>::
type* =
515 : internal::MatcherBase<T>(impl) {}
517 template <
typename M,
typename =
typename std::remove_reference<
518 M>::type::is_gtest_matcher>
519 Matcher(M&& m) : internal::MatcherBase<T>(
std::forward<M>(m)) {}
531 :
public internal::MatcherBase<const std::string&> {
535 explicit Matcher(
const MatcherInterface<const std::string&>* impl)
536 : internal::MatcherBase<const
std::string&>(impl) {}
538 template <
typename M,
typename =
typename std::remove_reference<
539 M>::type::is_gtest_matcher>
541 : internal::MatcherBase<const
std::string&>(
std::forward<M>(m)) {}
545 Matcher(
const std::string& s);
548 Matcher(
const char* s);
553 :
public internal::MatcherBase<std::string> {
557 explicit Matcher(
const MatcherInterface<const std::string&>* impl)
558 : internal::MatcherBase<
std::string>(impl) {}
559 explicit Matcher(
const MatcherInterface<std::string>* impl)
560 : internal::MatcherBase<
std::string>(impl) {}
562 template <
typename M,
typename =
typename std::remove_reference<
563 M>::type::is_gtest_matcher>
565 : internal::MatcherBase<
std::string>(
std::forward<M>(m)) {}
569 Matcher(
const std::string& s);
572 Matcher(
const char* s);
575 #if GTEST_INTERNAL_HAS_STRING_VIEW 580 class GTEST_API_ Matcher<const internal::StringView&>
581 :
public internal::MatcherBase<const internal::StringView&> {
585 explicit Matcher(
const MatcherInterface<const internal::StringView&>* impl)
586 : internal::MatcherBase<const internal::StringView&>(impl) {}
588 template <
typename M,
typename =
typename std::remove_reference<
589 M>::type::is_gtest_matcher>
591 : internal::MatcherBase<const internal::StringView&>(
std::forward<M>(m)) {
596 Matcher(
const std::string& s);
599 Matcher(
const char* s);
602 Matcher(internal::StringView s);
606 class GTEST_API_ Matcher<internal::StringView>
607 :
public internal::MatcherBase<internal::StringView> {
611 explicit Matcher(
const MatcherInterface<const internal::StringView&>* impl)
612 : internal::MatcherBase<internal::StringView>(impl) {}
613 explicit Matcher(
const MatcherInterface<internal::StringView>* impl)
614 : internal::MatcherBase<internal::StringView>(impl) {}
616 template <
typename M,
typename =
typename std::remove_reference<
617 M>::type::is_gtest_matcher>
619 : internal::MatcherBase<internal::StringView>(
std::forward<M>(m)) {}
623 Matcher(
const std::string& s);
626 Matcher(
const char* s);
629 Matcher(internal::StringView s);
631 #endif // GTEST_INTERNAL_HAS_STRING_VIEW 634 template <
typename T>
635 std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
636 matcher.DescribeTo(&os);
652 template <
class Impl>
653 class PolymorphicMatcher {
655 explicit PolymorphicMatcher(
const Impl& an_impl) : impl_(an_impl) {}
659 Impl& mutable_impl() {
return impl_; }
663 const Impl& impl()
const {
return impl_; }
665 template <
typename T>
666 operator Matcher<T>()
const {
667 return Matcher<T>(
new MonomorphicImpl<const T&>(impl_));
671 template <
typename T>
672 class MonomorphicImpl :
public MatcherInterface<T> {
674 explicit MonomorphicImpl(
const Impl& impl) : impl_(impl) {}
676 void DescribeTo(::std::ostream* os)
const override { impl_.DescribeTo(os); }
678 void DescribeNegationTo(::std::ostream* os)
const override {
679 impl_.DescribeNegationTo(os);
682 bool MatchAndExplain(T x, MatchResultListener* listener)
const override {
683 return impl_.MatchAndExplain(x, listener);
699 template <
typename T>
700 inline Matcher<T> MakeMatcher(
const MatcherInterface<T>* impl) {
701 return Matcher<T>(impl);
711 template <
class Impl>
712 inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(
const Impl& impl) {
713 return PolymorphicMatcher<Impl>(impl);
727 template <
typename D,
typename Rhs,
typename Op>
728 class ComparisonBase {
730 explicit ComparisonBase(
const Rhs& rhs) : rhs_(rhs) {}
732 using is_gtest_matcher = void;
734 template <
typename Lhs>
735 bool MatchAndExplain(
const Lhs& lhs, std::ostream*)
const {
736 return Op()(lhs, Unwrap(rhs_));
738 void DescribeTo(std::ostream* os)
const {
739 *os << D::Desc() <<
" ";
742 void DescribeNegationTo(std::ostream* os)
const {
743 *os << D::NegatedDesc() <<
" ";
748 template <
typename T>
749 static const T& Unwrap(
const T& v) {
752 template <
typename T>
753 static const T& Unwrap(std::reference_wrapper<T> v) {
760 template <
typename Rhs>
761 class EqMatcher :
public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> {
763 explicit EqMatcher(
const Rhs& rhs)
764 : ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) {}
765 static const char* Desc() {
return "is equal to"; }
766 static const char* NegatedDesc() {
return "isn't equal to"; }
768 template <
typename Rhs>
769 class NeMatcher :
public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> {
771 explicit NeMatcher(
const Rhs& rhs)
772 : ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) {}
773 static const char* Desc() {
return "isn't equal to"; }
774 static const char* NegatedDesc() {
return "is equal to"; }
776 template <
typename Rhs>
777 class LtMatcher :
public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> {
779 explicit LtMatcher(
const Rhs& rhs)
780 : ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) {}
781 static const char* Desc() {
return "is <"; }
782 static const char* NegatedDesc() {
return "isn't <"; }
784 template <
typename Rhs>
785 class GtMatcher :
public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> {
787 explicit GtMatcher(
const Rhs& rhs)
788 : ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) {}
789 static const char* Desc() {
return "is >"; }
790 static const char* NegatedDesc() {
return "isn't >"; }
792 template <
typename Rhs>
793 class LeMatcher :
public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> {
795 explicit LeMatcher(
const Rhs& rhs)
796 : ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) {}
797 static const char* Desc() {
return "is <="; }
798 static const char* NegatedDesc() {
return "isn't <="; }
800 template <
typename Rhs>
801 class GeMatcher :
public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
803 explicit GeMatcher(
const Rhs& rhs)
804 : ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) {}
805 static const char* Desc() {
return "is >="; }
806 static const char* NegatedDesc() {
return "isn't >="; }
809 template <
typename T,
typename =
typename std::enable_if<
810 std::is_constructible<std::string, T>::value>
::type>
811 using StringLike = T;
816 class MatchesRegexMatcher {
818 MatchesRegexMatcher(
const RE* regex,
bool full_match)
819 : regex_(regex), full_match_(full_match) {}
821 #if GTEST_INTERNAL_HAS_STRING_VIEW 822 bool MatchAndExplain(
const internal::StringView& s,
823 MatchResultListener* listener)
const {
824 return MatchAndExplain(std::string(s), listener);
826 #endif // GTEST_INTERNAL_HAS_STRING_VIEW 833 template <
typename CharType>
834 bool MatchAndExplain(CharType* s, MatchResultListener* listener)
const {
835 return s !=
nullptr && MatchAndExplain(std::string(s), listener);
842 template <
class MatcheeStringType>
843 bool MatchAndExplain(
const MatcheeStringType& s,
844 MatchResultListener* )
const {
845 const std::string s2(s);
846 return full_match_ ? RE::FullMatch(s2, *regex_)
847 : RE::PartialMatch(s2, *regex_);
850 void DescribeTo(::std::ostream* os)
const {
851 *os << (full_match_ ?
"matches" :
"contains") <<
" regular expression ";
852 UniversalPrinter<std::string>::Print(regex_->pattern(), os);
855 void DescribeNegationTo(::std::ostream* os)
const {
856 *os <<
"doesn't " << (full_match_ ?
"match" :
"contain")
857 <<
" regular expression ";
858 UniversalPrinter<std::string>::Print(regex_->pattern(), os);
862 const std::shared_ptr<const RE> regex_;
863 const bool full_match_;
869 inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
870 const internal::RE* regex) {
871 return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex,
true));
873 template <
typename T = std::
string>
874 PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
875 const internal::StringLike<T>& regex) {
876 return MatchesRegex(
new internal::RE(std::string(regex)));
881 inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
882 const internal::RE* regex) {
883 return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex,
false));
885 template <
typename T = std::
string>
886 PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
887 const internal::StringLike<T>& regex) {
888 return ContainsRegex(
new internal::RE(std::string(regex)));
894 template <
typename T>
895 inline internal::EqMatcher<T> Eq(T x) {
896 return internal::EqMatcher<T>(
x);
901 template <
typename T>
902 Matcher<T>::Matcher(T value) {
918 template <
typename Lhs,
typename Rhs>
919 inline Matcher<Lhs> TypedEq(
const Rhs& rhs) {
924 template <
typename Rhs>
925 inline internal::GeMatcher<Rhs> Ge(Rhs x) {
926 return internal::GeMatcher<Rhs>(
x);
930 template <
typename Rhs>
931 inline internal::GtMatcher<Rhs> Gt(Rhs x) {
932 return internal::GtMatcher<Rhs>(
x);
936 template <
typename Rhs>
937 inline internal::LeMatcher<Rhs> Le(Rhs x) {
938 return internal::LeMatcher<Rhs>(
x);
942 template <
typename Rhs>
943 inline internal::LtMatcher<Rhs> Lt(Rhs x) {
944 return internal::LtMatcher<Rhs>(
x);
948 template <
typename Rhs>
949 inline internal::NeMatcher<Rhs> Ne(Rhs x) {
950 return internal::NeMatcher<Rhs>(
x);
std::ostream & operator<<(std::ostream &os, const Message &sb)
#define GTEST_CHECK_(condition)
void UniversalPrint(const T &value, ::std::ostream *os)