File indexing completed on 2026-11-05 10:35:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255 #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
0256 #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
0257
0258 #include <algorithm>
0259 #include <cmath>
0260 #include <cstddef>
0261 #include <functional>
0262 #include <initializer_list>
0263 #include <ios>
0264 #include <iterator>
0265 #include <limits>
0266 #include <memory>
0267 #include <ostream> // NOLINT
0268 #include <sstream>
0269 #include <string>
0270 #include <tuple>
0271 #include <type_traits>
0272 #include <utility>
0273 #include <vector>
0274
0275 #include "gmock/internal/gmock-internal-utils.h"
0276 #include "gmock/internal/gmock-pp.h"
0277 #include "gtest/gtest.h"
0278 #include "gtest/internal/gtest-internal.h"
0279
0280
0281 #if defined(_MSC_VER) && _MSC_VER >= 1915
0282 #define GMOCK_MAYBE_5046_ 5046
0283 #else
0284 #define GMOCK_MAYBE_5046_
0285 #endif
0286
0287 #if GTEST_HAS_RTTI
0288 namespace proto2 {
0289 namespace internal {
0290
0291
0292
0293 template <typename T, typename = void>
0294 static constexpr bool kHasDynamicCastMessage = false;
0295 template <typename T>
0296 static constexpr bool kHasDynamicCastMessage<
0297 T, std::void_t<decltype(DynamicCastMessage<T>(
0298 std::declval<const proto2::MessageLite*>()))>> = true;
0299
0300
0301
0302
0303
0304 template <typename T>
0305 const T* DynamicCastMessageForGtest(const proto2::MessageLite* msg) {
0306 if constexpr (kHasDynamicCastMessage<T>) {
0307 return DynamicCastMessage<T>(msg);
0308 } else {
0309 return dynamic_cast<const T*>(msg);
0310 }
0311 }
0312 template <typename T>
0313 T* DynamicCastMessageForGtest(proto2::MessageLite* msg) {
0314 if constexpr (kHasDynamicCastMessage<T>) {
0315 return DynamicCastMessage<T>(msg);
0316 } else {
0317 return dynamic_cast<T*>(msg);
0318 }
0319 }
0320
0321 }
0322 }
0323 #endif
0324
0325 GTEST_DISABLE_MSC_WARNINGS_PUSH_(
0326 4251 GMOCK_MAYBE_5046_
0327
0328 )
0329
0330 namespace testing {
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345 class [[nodiscard]] StringMatchResultListener : public MatchResultListener {
0346 public:
0347 StringMatchResultListener() : MatchResultListener(&ss_) {}
0348
0349
0350 std::string str() const { return ss_.str(); }
0351
0352
0353 void Clear() { ss_.str(""); }
0354
0355 private:
0356 ::std::stringstream ss_;
0357
0358 StringMatchResultListener(const StringMatchResultListener&) = delete;
0359 StringMatchResultListener& operator=(const StringMatchResultListener&) =
0360 delete;
0361 };
0362
0363
0364
0365 namespace internal {
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377 template <typename T, typename M>
0378 class [[nodiscard]] MatcherCastImpl {
0379 public:
0380 static Matcher<T> Cast(const M& polymorphic_matcher_or_value) {
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394 return CastImpl(polymorphic_matcher_or_value,
0395 std::is_convertible<M, Matcher<T>>{},
0396 std::is_convertible<M, T>{});
0397 }
0398
0399 private:
0400 template <bool Ignore>
0401 static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value,
0402 std::true_type ,
0403 std::integral_constant<bool, Ignore>) {
0404
0405
0406
0407
0408
0409
0410
0411
0412 return polymorphic_matcher_or_value;
0413 }
0414
0415
0416
0417
0418 static Matcher<T> CastImpl(const M& value,
0419 std::false_type ,
0420 std::true_type ) {
0421 using NoRefT = std::remove_cv_t<std::remove_reference_t<T>>;
0422 if constexpr (std::is_same_v<M, NoRefT>) {
0423 return Matcher<T>(value);
0424 } else {
0425 return ImplicitCastEqMatcher<NoRefT, std::decay_t<const M&>>(value);
0426 }
0427 }
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437 static Matcher<T> CastImpl(const M& value,
0438 std::false_type ,
0439 std::false_type ) {
0440 return Eq(value);
0441 }
0442 };
0443
0444
0445
0446
0447 template <typename T, typename U>
0448 class [[nodiscard]] MatcherCastImpl<T, Matcher<U>> {
0449 public:
0450 static Matcher<T> Cast(const Matcher<U>& source_matcher) {
0451 return Matcher<T>(new Impl(source_matcher));
0452 }
0453
0454 private:
0455
0456
0457
0458
0459 using ImplArgT =
0460 typename std::conditional<std::is_convertible<const T&, const U&>::value,
0461 const T&, T>::type;
0462
0463 class Impl : public MatcherInterface<ImplArgT> {
0464 public:
0465 explicit Impl(const Matcher<U>& source_matcher)
0466 : source_matcher_(source_matcher) {}
0467
0468
0469 bool MatchAndExplain(ImplArgT x,
0470 MatchResultListener* listener) const override {
0471 using FromType = typename std::remove_cv<typename std::remove_pointer<
0472 typename std::remove_reference<T>::type>::type>::type;
0473 using ToType = typename std::remove_cv<typename std::remove_pointer<
0474 typename std::remove_reference<U>::type>::type>::type;
0475
0476 static_assert(
0477
0478
0479 (std::is_pointer<typename std::remove_reference<T>::type>::value !=
0480 std::is_pointer<typename std::remove_reference<U>::type>::value) ||
0481 std::is_same<FromType, ToType>::value ||
0482 !std::is_base_of<FromType, ToType>::value,
0483 "Can't implicitly convert from <base> to <derived>");
0484
0485
0486
0487 using CastType = typename std::conditional<
0488 std::is_convertible<ImplArgT&, const U&>::value, ImplArgT&, U>::type;
0489
0490 return source_matcher_.MatchAndExplain(static_cast<CastType>(x),
0491 listener);
0492 }
0493
0494 void DescribeTo(::std::ostream* os) const override {
0495 source_matcher_.DescribeTo(os);
0496 }
0497
0498 void DescribeNegationTo(::std::ostream* os) const override {
0499 source_matcher_.DescribeNegationTo(os);
0500 }
0501
0502 private:
0503 const Matcher<U> source_matcher_;
0504 };
0505 };
0506
0507
0508
0509 template <typename T>
0510 class [[nodiscard]] MatcherCastImpl<T, Matcher<T>> {
0511 public:
0512 static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; }
0513 };
0514
0515
0516 template <typename Derived>
0517 class [[nodiscard]] MatcherBaseImpl {
0518 public:
0519 MatcherBaseImpl() = default;
0520
0521 template <typename T>
0522 operator ::testing::Matcher<T>() const {
0523 return ::testing::Matcher<T>(new
0524 typename Derived::template gmock_Impl<T>());
0525 }
0526 };
0527
0528
0529 template <template <typename...> class Derived, typename... Ts>
0530 class [[nodiscard]] MatcherBaseImpl<Derived<Ts...>> {
0531 public:
0532
0533
0534 template <typename E = std::enable_if<sizeof...(Ts) == 1>,
0535 typename E::type* = nullptr>
0536 explicit MatcherBaseImpl(Ts... params)
0537 : params_(std::forward<Ts>(params)...) {}
0538 template <typename E = std::enable_if<sizeof...(Ts) != 1>,
0539 typename = typename E::type>
0540 MatcherBaseImpl(Ts... params)
0541 : params_(std::forward<Ts>(params)...) {}
0542
0543 template <typename F>
0544 operator ::testing::Matcher<F>() const {
0545 return Apply<F>(std::make_index_sequence<sizeof...(Ts)>{});
0546 }
0547
0548 private:
0549 template <typename F, std::size_t... tuple_ids>
0550 ::testing::Matcher<F> Apply(std::index_sequence<tuple_ids...>) const {
0551 return ::testing::Matcher<F>(
0552 new typename Derived<Ts...>::template gmock_Impl<F>(
0553 std::get<tuple_ids>(params_)...));
0554 }
0555
0556 const std::tuple<Ts...> params_;
0557 };
0558
0559 }
0560
0561
0562
0563
0564
0565 template <typename T, typename M>
0566 inline Matcher<T> MatcherCast(const M& matcher) {
0567 return internal::MatcherCastImpl<T, M>::Cast(matcher);
0568 }
0569
0570
0571
0572 template <typename T, typename M>
0573 inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher_or_value) {
0574 return MatcherCast<T>(polymorphic_matcher_or_value);
0575 }
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587 template <typename T, typename U>
0588 inline Matcher<T> SafeMatcherCast(const Matcher<U>& matcher) {
0589
0590 static_assert(std::is_convertible<const T&, const U&>::value,
0591 "T must be implicitly convertible to U (and T must be a "
0592 "non-const reference if U is a non-const reference)");
0593
0594
0595 typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT;
0596 typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU;
0597 constexpr bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther;
0598 constexpr bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther;
0599 static_assert(
0600 kTIsOther || kUIsOther ||
0601 (internal::LosslessArithmeticConvertible<RawT, RawU>::value),
0602 "conversion of arithmetic types must be lossless");
0603 return MatcherCast<T>(matcher);
0604 }
0605
0606
0607 template <typename T>
0608 Matcher<T> A();
0609
0610
0611
0612 namespace internal {
0613
0614
0615 struct Rank0 {};
0616 struct Rank1 : Rank0 {};
0617 using HighestRank = Rank1;
0618
0619
0620 inline void PrintIfNotEmpty(const std::string& explanation,
0621 ::std::ostream* os) {
0622 if (!explanation.empty() && os != nullptr) {
0623 *os << ", " << explanation;
0624 }
0625 }
0626
0627
0628
0629
0630 inline bool IsReadableTypeName(const std::string& type_name) {
0631
0632
0633 return (type_name.length() <= 20 ||
0634 type_name.find_first_of("<(") == std::string::npos);
0635 }
0636
0637
0638
0639
0640
0641
0642 template <typename Value, typename T>
0643 bool MatchPrintAndExplain(Value& value, const Matcher<T>& matcher,
0644 MatchResultListener* listener) {
0645 if (!listener->IsInterested()) {
0646
0647
0648 return matcher.Matches(value);
0649 }
0650
0651 StringMatchResultListener inner_listener;
0652 const bool match = matcher.MatchAndExplain(value, &inner_listener);
0653
0654 UniversalPrint(value, listener->stream());
0655 #if GTEST_HAS_RTTI
0656 const std::string& type_name = GetTypeName<Value>();
0657 if (IsReadableTypeName(type_name))
0658 *listener->stream() << " (of type " << type_name << ")";
0659 #endif
0660 PrintIfNotEmpty(inner_listener.str(), listener->stream());
0661
0662 return match;
0663 }
0664
0665
0666
0667 template <size_t N>
0668 class [[nodiscard]] TuplePrefix {
0669 public:
0670
0671
0672
0673 template <typename MatcherTuple, typename ValueTuple>
0674 static bool Matches(const MatcherTuple& matcher_tuple,
0675 const ValueTuple& value_tuple) {
0676 return TuplePrefix<N - 1>::Matches(matcher_tuple, value_tuple) &&
0677 std::get<N - 1>(matcher_tuple).Matches(std::get<N - 1>(value_tuple));
0678 }
0679
0680
0681
0682
0683
0684 template <typename MatcherTuple, typename ValueTuple>
0685 static void ExplainMatchFailuresTo(const MatcherTuple& matchers,
0686 const ValueTuple& values,
0687 ::std::ostream* os) {
0688
0689 TuplePrefix<N - 1>::ExplainMatchFailuresTo(matchers, values, os);
0690
0691
0692
0693 typename std::tuple_element<N - 1, MatcherTuple>::type matcher =
0694 std::get<N - 1>(matchers);
0695 typedef typename std::tuple_element<N - 1, ValueTuple>::type Value;
0696 const Value& value = std::get<N - 1>(values);
0697 StringMatchResultListener listener;
0698 if (!matcher.MatchAndExplain(value, &listener)) {
0699 *os << " Expected arg #" << N - 1 << ": ";
0700 std::get<N - 1>(matchers).DescribeTo(os);
0701 *os << "\n Actual: ";
0702
0703
0704
0705
0706
0707 internal::UniversalPrint(value, os);
0708 PrintIfNotEmpty(listener.str(), os);
0709 *os << "\n";
0710 }
0711 }
0712 };
0713
0714
0715 template <>
0716 class [[nodiscard]] TuplePrefix<0> {
0717 public:
0718 template <typename MatcherTuple, typename ValueTuple>
0719 static bool Matches(const MatcherTuple& ,
0720 const ValueTuple& ) {
0721 return true;
0722 }
0723
0724 template <typename MatcherTuple, typename ValueTuple>
0725 static void ExplainMatchFailuresTo(const MatcherTuple& ,
0726 const ValueTuple& ,
0727 ::std::ostream* ) {}
0728 };
0729
0730
0731
0732
0733
0734
0735 template <typename MatcherTuple, typename ValueTuple>
0736 bool TupleMatches(const MatcherTuple& matcher_tuple,
0737 const ValueTuple& value_tuple) {
0738
0739
0740 static_assert(std::tuple_size<MatcherTuple>::value ==
0741 std::tuple_size<ValueTuple>::value,
0742 "matcher and value have different numbers of fields");
0743 return TuplePrefix<std::tuple_size<ValueTuple>::value>::Matches(matcher_tuple,
0744 value_tuple);
0745 }
0746
0747
0748
0749 template <typename MatcherTuple, typename ValueTuple>
0750 void ExplainMatchFailureTupleTo(const MatcherTuple& matchers,
0751 const ValueTuple& values, ::std::ostream* os) {
0752 TuplePrefix<std::tuple_size<MatcherTuple>::value>::ExplainMatchFailuresTo(
0753 matchers, values, os);
0754 }
0755
0756
0757
0758
0759
0760 template <typename Tuple, typename Func, typename OutIter>
0761 class [[nodiscard]] TransformTupleValuesHelper {
0762 private:
0763 typedef ::std::tuple_size<Tuple> TupleSize;
0764
0765 public:
0766
0767
0768 static OutIter Run(Func f, const Tuple& t, OutIter out) {
0769 return IterateOverTuple<Tuple, TupleSize::value>()(f, t, out);
0770 }
0771
0772 private:
0773 template <typename Tup, size_t kRemainingSize>
0774 struct IterateOverTuple {
0775 OutIter operator()(Func f, const Tup& t, OutIter out) const {
0776 *out++ = f(::std::get<TupleSize::value - kRemainingSize>(t));
0777 return IterateOverTuple<Tup, kRemainingSize - 1>()(f, t, out);
0778 }
0779 };
0780 template <typename Tup>
0781 struct IterateOverTuple<Tup, 0> {
0782 OutIter operator()(Func , const Tup& , OutIter out) const {
0783 return out;
0784 }
0785 };
0786 };
0787
0788
0789
0790
0791 template <typename Tuple, typename Func, typename OutIter>
0792 OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) {
0793 return TransformTupleValuesHelper<Tuple, Func, OutIter>::Run(f, t, out);
0794 }
0795
0796
0797
0798
0799
0800 class [[nodiscard]] AnythingMatcher {
0801 public:
0802 using is_gtest_matcher = void;
0803
0804 template <typename T>
0805 bool MatchAndExplain(const T& , std::ostream* ) const {
0806 return true;
0807 }
0808 void DescribeTo(std::ostream* os) const { *os << "is anything"; }
0809 void DescribeNegationTo(::std::ostream* os) const {
0810
0811
0812
0813 *os << "never matches";
0814 }
0815 };
0816
0817
0818
0819 class [[nodiscard]] IsNullMatcher {
0820 public:
0821 template <typename Pointer>
0822 bool MatchAndExplain(const Pointer& p,
0823 MatchResultListener* ) const {
0824 if constexpr (std::is_function_v<Pointer>) {
0825 return false;
0826 } else {
0827 return p == nullptr;
0828 }
0829 }
0830
0831 void DescribeTo(::std::ostream* os) const { *os << "is NULL"; }
0832 void DescribeNegationTo(::std::ostream* os) const { *os << "isn't NULL"; }
0833 };
0834
0835
0836
0837 class [[nodiscard]] NotNullMatcher {
0838 public:
0839 template <typename Pointer>
0840 bool MatchAndExplain(const Pointer& p,
0841 MatchResultListener* ) const {
0842 if constexpr (std::is_function_v<Pointer>) {
0843 return true;
0844 } else {
0845 return p != nullptr;
0846 }
0847 }
0848
0849 void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; }
0850 void DescribeNegationTo(::std::ostream* os) const { *os << "is NULL"; }
0851 };
0852
0853
0854
0855
0856
0857
0858
0859
0860
0861
0862
0863
0864
0865
0866 template <typename T>
0867 class [[nodiscard]] RefMatcher;
0868
0869 template <typename T>
0870 class [[nodiscard]] RefMatcher<T&> {
0871
0872
0873
0874
0875
0876 public:
0877
0878
0879
0880 explicit RefMatcher(T& x) : object_(x) {}
0881
0882 template <typename Super>
0883 operator Matcher<Super&>() const {
0884
0885
0886
0887
0888
0889 return MakeMatcher(new Impl<Super>(object_));
0890 }
0891
0892 private:
0893 template <typename Super>
0894 class Impl : public MatcherInterface<Super&> {
0895 public:
0896 explicit Impl(Super& x) : object_(x) {}
0897
0898
0899
0900 bool MatchAndExplain(Super& x,
0901 MatchResultListener* listener) const override {
0902 *listener << "which is located @" << static_cast<const void*>(&x);
0903 return &x == &object_;
0904 }
0905
0906 void DescribeTo(::std::ostream* os) const override {
0907 *os << "references the variable ";
0908 UniversalPrinter<Super&>::Print(object_, os);
0909 }
0910
0911 void DescribeNegationTo(::std::ostream* os) const override {
0912 *os << "does not reference the variable ";
0913 UniversalPrinter<Super&>::Print(object_, os);
0914 }
0915
0916 private:
0917 const Super& object_;
0918 };
0919
0920 T& object_;
0921 };
0922
0923
0924 inline bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) {
0925 return String::CaseInsensitiveCStringEquals(lhs, rhs);
0926 }
0927
0928 inline bool CaseInsensitiveCStringEquals(const wchar_t* lhs,
0929 const wchar_t* rhs) {
0930 return String::CaseInsensitiveWideCStringEquals(lhs, rhs);
0931 }
0932
0933
0934
0935 template <typename StringType>
0936 bool CaseInsensitiveStringEquals(const StringType& s1, const StringType& s2) {
0937
0938 if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) {
0939 return false;
0940 }
0941
0942
0943 const typename StringType::value_type nul = 0;
0944 const size_t i1 = s1.find(nul), i2 = s2.find(nul);
0945
0946
0947 if (i1 == StringType::npos || i2 == StringType::npos) {
0948 return i1 == i2;
0949 }
0950
0951
0952 return CaseInsensitiveStringEquals(s1.substr(i1 + 1), s2.substr(i2 + 1));
0953 }
0954
0955
0956
0957
0958 template <typename StringType>
0959 class [[nodiscard]] StrEqualityMatcher {
0960 public:
0961 StrEqualityMatcher(StringType str, bool expect_eq, bool case_sensitive)
0962 : string_(std::move(str)),
0963 expect_eq_(expect_eq),
0964 case_sensitive_(case_sensitive) {}
0965
0966 bool MatchAndExplain(const internal::StringView& s,
0967 MatchResultListener* listener) const {
0968
0969
0970 const StringType& str = std::string(s);
0971 return MatchAndExplain(str, listener);
0972 }
0973
0974
0975
0976
0977
0978
0979 template <typename CharType>
0980 bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
0981 if (s == nullptr) {
0982 return !expect_eq_;
0983 }
0984 return MatchAndExplain(StringType(s), listener);
0985 }
0986
0987
0988
0989
0990
0991 template <typename MatcheeStringType>
0992 bool MatchAndExplain(const MatcheeStringType& s,
0993 MatchResultListener* ) const {
0994 const StringType s2(s);
0995 const bool eq = case_sensitive_ ? s2 == string_
0996 : CaseInsensitiveStringEquals(s2, string_);
0997 return expect_eq_ == eq;
0998 }
0999
1000 void DescribeTo(::std::ostream* os) const {
1001 DescribeToHelper(expect_eq_, os);
1002 }
1003
1004 void DescribeNegationTo(::std::ostream* os) const {
1005 DescribeToHelper(!expect_eq_, os);
1006 }
1007
1008 private:
1009 void DescribeToHelper(bool expect_eq, ::std::ostream* os) const {
1010 *os << (expect_eq ? "is " : "isn't ");
1011 *os << "equal to ";
1012 if (!case_sensitive_) {
1013 *os << "(ignoring case) ";
1014 }
1015 UniversalPrint(string_, os);
1016 }
1017
1018 const StringType string_;
1019 const bool expect_eq_;
1020 const bool case_sensitive_;
1021 };
1022
1023
1024
1025
1026 template <typename StringType>
1027 class [[nodiscard]] HasSubstrMatcher {
1028 public:
1029 explicit HasSubstrMatcher(const StringType& substring)
1030 : substring_(substring) {}
1031
1032 bool MatchAndExplain(const internal::StringView& s,
1033 MatchResultListener* listener) const {
1034
1035
1036 const StringType& str = std::string(s);
1037 return MatchAndExplain(str, listener);
1038 }
1039
1040
1041
1042
1043
1044
1045 template <typename CharType>
1046 bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
1047 return s != nullptr && MatchAndExplain(StringType(s), listener);
1048 }
1049
1050
1051
1052
1053
1054 template <typename MatcheeStringType>
1055 bool MatchAndExplain(const MatcheeStringType& s,
1056 MatchResultListener* ) const {
1057 return StringType(s).find(substring_) != StringType::npos;
1058 }
1059
1060
1061 void DescribeTo(::std::ostream* os) const {
1062 *os << "has substring ";
1063 UniversalPrint(substring_, os);
1064 }
1065
1066 void DescribeNegationTo(::std::ostream* os) const {
1067 *os << "has no substring ";
1068 UniversalPrint(substring_, os);
1069 }
1070
1071 private:
1072 const StringType substring_;
1073 };
1074
1075
1076
1077
1078 template <typename StringType>
1079 class [[nodiscard]] StartsWithMatcher {
1080 public:
1081 explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) {}
1082
1083 bool MatchAndExplain(const internal::StringView& s,
1084 MatchResultListener* listener) const {
1085
1086
1087 const StringType& str = std::string(s);
1088 return MatchAndExplain(str, listener);
1089 }
1090
1091
1092
1093
1094
1095
1096 template <typename CharType>
1097 bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
1098 return s != nullptr && MatchAndExplain(StringType(s), listener);
1099 }
1100
1101
1102
1103
1104
1105 template <typename MatcheeStringType>
1106 bool MatchAndExplain(const MatcheeStringType& s,
1107 MatchResultListener* ) const {
1108 const StringType s2(s);
1109 return s2.length() >= prefix_.length() &&
1110 s2.substr(0, prefix_.length()) == prefix_;
1111 }
1112
1113 void DescribeTo(::std::ostream* os) const {
1114 *os << "starts with ";
1115 UniversalPrint(prefix_, os);
1116 }
1117
1118 void DescribeNegationTo(::std::ostream* os) const {
1119 *os << "doesn't start with ";
1120 UniversalPrint(prefix_, os);
1121 }
1122
1123 private:
1124 const StringType prefix_;
1125 };
1126
1127
1128
1129
1130 template <typename StringType>
1131 class [[nodiscard]] EndsWithMatcher {
1132 public:
1133 explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {}
1134
1135 bool MatchAndExplain(const internal::StringView& s,
1136 MatchResultListener* listener) const {
1137
1138
1139 const StringType& str = std::string(s);
1140 return MatchAndExplain(str, listener);
1141 }
1142
1143
1144
1145
1146
1147
1148 template <typename CharType>
1149 bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
1150 return s != nullptr && MatchAndExplain(StringType(s), listener);
1151 }
1152
1153
1154
1155
1156
1157 template <typename MatcheeStringType>
1158 bool MatchAndExplain(const MatcheeStringType& s,
1159 MatchResultListener* ) const {
1160 const StringType s2(s);
1161 return s2.length() >= suffix_.length() &&
1162 s2.substr(s2.length() - suffix_.length()) == suffix_;
1163 }
1164
1165 void DescribeTo(::std::ostream* os) const {
1166 *os << "ends with ";
1167 UniversalPrint(suffix_, os);
1168 }
1169
1170 void DescribeNegationTo(::std::ostream* os) const {
1171 *os << "doesn't end with ";
1172 UniversalPrint(suffix_, os);
1173 }
1174
1175 private:
1176 const StringType suffix_;
1177 };
1178
1179
1180
1181 class [[nodiscard]] WhenBase64UnescapedMatcher {
1182 public:
1183 using is_gtest_matcher = void;
1184
1185 explicit WhenBase64UnescapedMatcher(
1186 const Matcher<const std::string&>& internal_matcher)
1187 : internal_matcher_(internal_matcher) {}
1188
1189
1190 template <typename MatcheeStringType>
1191 bool MatchAndExplain(const MatcheeStringType& s,
1192 MatchResultListener* listener) const {
1193 const std::string s2(s);
1194 std::string unescaped;
1195 if (!internal::Base64Unescape(s2, &unescaped)) {
1196 if (listener != nullptr) {
1197 *listener << "is not a valid base64 escaped string";
1198 }
1199 return false;
1200 }
1201 return MatchPrintAndExplain(unescaped, internal_matcher_, listener);
1202 }
1203
1204 void DescribeTo(::std::ostream* os) const {
1205 *os << "matches after Base64Unescape ";
1206 internal_matcher_.DescribeTo(os);
1207 }
1208
1209 void DescribeNegationTo(::std::ostream* os) const {
1210 *os << "does not match after Base64Unescape ";
1211 internal_matcher_.DescribeTo(os);
1212 }
1213
1214 private:
1215 const Matcher<const std::string&> internal_matcher_;
1216 };
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226 template <typename D, typename Op>
1227 class [[nodiscard]] PairMatchBase {
1228 public:
1229 template <typename T1, typename T2>
1230 operator Matcher<::std::tuple<T1, T2>>() const {
1231 return Matcher<::std::tuple<T1, T2>>(new Impl<const ::std::tuple<T1, T2>&>);
1232 }
1233 template <typename T1, typename T2>
1234 operator Matcher<const ::std::tuple<T1, T2>&>() const {
1235 return MakeMatcher(new Impl<const ::std::tuple<T1, T2>&>);
1236 }
1237
1238 private:
1239 static ::std::ostream& GetDesc(::std::ostream& os) {
1240 return os << D::Desc();
1241 }
1242
1243 template <typename Tuple>
1244 class Impl : public MatcherInterface<Tuple> {
1245 public:
1246 bool MatchAndExplain(Tuple args,
1247 MatchResultListener* ) const override {
1248 return Op()(::std::get<0>(args), ::std::get<1>(args));
1249 }
1250 void DescribeTo(::std::ostream* os) const override {
1251 *os << "are " << GetDesc;
1252 }
1253 void DescribeNegationTo(::std::ostream* os) const override {
1254 *os << "aren't " << GetDesc;
1255 }
1256 };
1257 };
1258
1259 class [[nodiscard]] Eq2Matcher
1260 : public PairMatchBase<Eq2Matcher, std::equal_to<>> {
1261 public:
1262 static const char* Desc() { return "an equal pair"; }
1263 };
1264 class [[nodiscard]] Ne2Matcher
1265 : public PairMatchBase<Ne2Matcher, std::not_equal_to<>> {
1266 public:
1267 static const char* Desc() { return "an unequal pair"; }
1268 };
1269 class [[nodiscard]] Lt2Matcher : public PairMatchBase<Lt2Matcher, std::less<>> {
1270 public:
1271 static const char* Desc() { return "a pair where the first < the second"; }
1272 };
1273 class [[nodiscard]] Gt2Matcher
1274 : public PairMatchBase<Gt2Matcher, std::greater<>> {
1275 public:
1276 static const char* Desc() { return "a pair where the first > the second"; }
1277 };
1278 class [[nodiscard]] Le2Matcher
1279 : public PairMatchBase<Le2Matcher, std::less_equal<>> {
1280 public:
1281 static const char* Desc() { return "a pair where the first <= the second"; }
1282 };
1283 class [[nodiscard]] Ge2Matcher
1284 : public PairMatchBase<Ge2Matcher, std::greater_equal<>> {
1285 public:
1286 static const char* Desc() { return "a pair where the first >= the second"; }
1287 };
1288
1289
1290
1291
1292
1293 template <typename T>
1294 class [[nodiscard]] NotMatcherImpl : public MatcherInterface<const T&> {
1295 public:
1296 explicit NotMatcherImpl(const Matcher<T>& matcher) : matcher_(matcher) {}
1297
1298 bool MatchAndExplain(const T& x,
1299 MatchResultListener* listener) const override {
1300 return !matcher_.MatchAndExplain(x, listener);
1301 }
1302
1303 void DescribeTo(::std::ostream* os) const override {
1304 matcher_.DescribeNegationTo(os);
1305 }
1306
1307 void DescribeNegationTo(::std::ostream* os) const override {
1308 matcher_.DescribeTo(os);
1309 }
1310
1311 private:
1312 const Matcher<T> matcher_;
1313 };
1314
1315
1316
1317 template <typename InnerMatcher>
1318 class [[nodiscard]] NotMatcher {
1319 public:
1320 explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {}
1321
1322
1323
1324 template <typename T>
1325 operator Matcher<T>() const {
1326 return Matcher<T>(new NotMatcherImpl<T>(SafeMatcherCast<T>(matcher_)));
1327 }
1328
1329 private:
1330 InnerMatcher matcher_;
1331 };
1332
1333
1334
1335
1336
1337 template <typename T>
1338 class [[nodiscard]] AllOfMatcherImpl : public MatcherInterface<const T&> {
1339 public:
1340 explicit AllOfMatcherImpl(std::vector<Matcher<T>> matchers)
1341 : matchers_(std::move(matchers)) {}
1342
1343 void DescribeTo(::std::ostream* os) const override {
1344 *os << "(";
1345 for (size_t i = 0; i < matchers_.size(); ++i) {
1346 if (i != 0) *os << ") and (";
1347 matchers_[i].DescribeTo(os);
1348 }
1349 *os << ")";
1350 }
1351
1352 void DescribeNegationTo(::std::ostream* os) const override {
1353 *os << "(";
1354 for (size_t i = 0; i < matchers_.size(); ++i) {
1355 if (i != 0) *os << ") or (";
1356 matchers_[i].DescribeNegationTo(os);
1357 }
1358 *os << ")";
1359 }
1360
1361 bool MatchAndExplain(const T& x,
1362 MatchResultListener* listener) const override {
1363 if (!listener->IsInterested()) {
1364
1365 for (const Matcher<T>& matcher : matchers_) {
1366 if (!matcher.Matches(x)) {
1367 return false;
1368 }
1369 }
1370 return true;
1371 }
1372
1373
1374
1375 std::string all_match_result;
1376 bool success = true;
1377 for (const Matcher<T>& matcher : matchers_) {
1378 StringMatchResultListener slistener;
1379
1380 if (!matcher.MatchAndExplain(x, &slistener)) {
1381 const std::string explanation = slistener.str();
1382 if (!success) {
1383
1384 *listener << ", and ";
1385 }
1386 if (!explanation.empty()) {
1387 *listener << explanation;
1388 } else {
1389 *listener << "which doesn't match (" << Describe(matcher) << ")";
1390 }
1391 success = false;
1392 continue;
1393 }
1394
1395 std::string explanation = slistener.str();
1396 if (explanation.empty()) {
1397 explanation = Describe(matcher);
1398 }
1399 if (all_match_result.empty()) {
1400 all_match_result = explanation;
1401 } else {
1402 if (!explanation.empty()) {
1403 all_match_result += ", and ";
1404 all_match_result += explanation;
1405 }
1406 }
1407 }
1408
1409 if (success) {
1410 *listener << all_match_result;
1411 }
1412 return success;
1413 }
1414
1415 private:
1416
1417 std::string Describe(const Matcher<T>& matcher) const {
1418 StringMatchResultListener listener;
1419 matcher.DescribeTo(listener.stream());
1420 return listener.str();
1421 }
1422 const std::vector<Matcher<T>> matchers_;
1423 };
1424
1425
1426
1427
1428
1429 template <template <typename T> class CombiningMatcher, typename... Args>
1430 class [[nodiscard]] VariadicMatcher {
1431 public:
1432 VariadicMatcher(const Args&... matchers)
1433 : matchers_(matchers...) {
1434 static_assert(sizeof...(Args) > 0, "Must have at least one matcher.");
1435 }
1436
1437 VariadicMatcher(const VariadicMatcher&) = default;
1438 VariadicMatcher& operator=(const VariadicMatcher&) = delete;
1439
1440
1441
1442
1443 template <typename T>
1444 operator Matcher<T>() const {
1445 std::vector<Matcher<T>> values;
1446 CreateVariadicMatcher<T>(&values, std::integral_constant<size_t, 0>());
1447 return Matcher<T>(new CombiningMatcher<T>(std::move(values)));
1448 }
1449
1450 private:
1451 template <typename T, size_t I>
1452 void CreateVariadicMatcher(std::vector<Matcher<T>>* values,
1453 std::integral_constant<size_t, I>) const {
1454 values->push_back(SafeMatcherCast<T>(std::get<I>(matchers_)));
1455 CreateVariadicMatcher<T>(values, std::integral_constant<size_t, I + 1>());
1456 }
1457
1458 template <typename T>
1459 void CreateVariadicMatcher(
1460 std::vector<Matcher<T>>*,
1461 std::integral_constant<size_t, sizeof...(Args)>) const {}
1462
1463 std::tuple<Args...> matchers_;
1464 };
1465
1466 template <typename... Args>
1467 using AllOfMatcher = VariadicMatcher<AllOfMatcherImpl, Args...>;
1468
1469
1470
1471
1472
1473 template <typename T>
1474 class [[nodiscard]] AnyOfMatcherImpl : public MatcherInterface<const T&> {
1475 public:
1476 explicit AnyOfMatcherImpl(std::vector<Matcher<T>> matchers)
1477 : matchers_(std::move(matchers)) {}
1478
1479 void DescribeTo(::std::ostream* os) const override {
1480 *os << "(";
1481 for (size_t i = 0; i < matchers_.size(); ++i) {
1482 if (i != 0) *os << ") or (";
1483 matchers_[i].DescribeTo(os);
1484 }
1485 *os << ")";
1486 }
1487
1488 void DescribeNegationTo(::std::ostream* os) const override {
1489 *os << "(";
1490 for (size_t i = 0; i < matchers_.size(); ++i) {
1491 if (i != 0) *os << ") and (";
1492 matchers_[i].DescribeNegationTo(os);
1493 }
1494 *os << ")";
1495 }
1496
1497 bool MatchAndExplain(const T& x,
1498 MatchResultListener* listener) const override {
1499 if (!listener->IsInterested()) {
1500
1501 for (const Matcher<T>& matcher : matchers_) {
1502 if (matcher.Matches(x)) {
1503 return true;
1504 }
1505 }
1506 return false;
1507 }
1508
1509
1510
1511 std::string no_match_result;
1512 for (const Matcher<T>& matcher : matchers_) {
1513 StringMatchResultListener slistener;
1514
1515 if (matcher.MatchAndExplain(x, &slistener)) {
1516 const std::string explanation = slistener.str();
1517 if (!explanation.empty()) {
1518 *listener << explanation;
1519 } else {
1520 *listener << "which matches (" << Describe(matcher) << ")";
1521 }
1522 return true;
1523 }
1524
1525 std::string explanation = slistener.str();
1526 if (explanation.empty()) {
1527 explanation = DescribeNegation(matcher);
1528 }
1529 if (no_match_result.empty()) {
1530 no_match_result = explanation;
1531 } else {
1532 if (!explanation.empty()) {
1533 no_match_result += ", and ";
1534 no_match_result += explanation;
1535 }
1536 }
1537 }
1538
1539 *listener << no_match_result;
1540 return false;
1541 }
1542
1543 private:
1544
1545 std::string Describe(const Matcher<T>& matcher) const {
1546 StringMatchResultListener listener;
1547 matcher.DescribeTo(listener.stream());
1548 return listener.str();
1549 }
1550
1551 std::string DescribeNegation(const Matcher<T>& matcher) const {
1552 StringMatchResultListener listener;
1553 matcher.DescribeNegationTo(listener.stream());
1554 return listener.str();
1555 }
1556
1557 const std::vector<Matcher<T>> matchers_;
1558 };
1559
1560
1561 template <typename... Args>
1562 using AnyOfMatcher = VariadicMatcher<AnyOfMatcherImpl, Args...>;
1563
1564
1565 template <typename MatcherTrue, typename MatcherFalse>
1566 class [[nodiscard]] ConditionalMatcher {
1567 public:
1568 ConditionalMatcher(bool condition, MatcherTrue matcher_true,
1569 MatcherFalse matcher_false)
1570 : condition_(condition),
1571 matcher_true_(std::move(matcher_true)),
1572 matcher_false_(std::move(matcher_false)) {}
1573
1574 template <typename T>
1575 operator Matcher<T>() const {
1576 return condition_ ? SafeMatcherCast<T>(matcher_true_)
1577 : SafeMatcherCast<T>(matcher_false_);
1578 }
1579
1580 private:
1581 bool condition_;
1582 MatcherTrue matcher_true_;
1583 MatcherFalse matcher_false_;
1584 };
1585
1586
1587 template <template <class> class MatcherImpl, typename T>
1588 class [[nodiscard]] SomeOfArrayMatcher {
1589 public:
1590
1591
1592 template <typename Iter>
1593 SomeOfArrayMatcher(Iter first, Iter last) : matchers_(first, last) {}
1594
1595 template <typename U>
1596 operator Matcher<U>() const {
1597 using RawU = typename std::decay<U>::type;
1598 std::vector<Matcher<RawU>> matchers;
1599 matchers.reserve(matchers_.size());
1600 for (const auto& matcher : matchers_) {
1601 matchers.push_back(MatcherCast<RawU>(matcher));
1602 }
1603 return Matcher<U>(new MatcherImpl<RawU>(std::move(matchers)));
1604 }
1605
1606 private:
1607 const std::vector<std::remove_const_t<T>> matchers_;
1608 };
1609
1610 template <typename T>
1611 using AllOfArrayMatcher = SomeOfArrayMatcher<AllOfMatcherImpl, T>;
1612
1613 template <typename T>
1614 using AnyOfArrayMatcher = SomeOfArrayMatcher<AnyOfMatcherImpl, T>;
1615
1616
1617
1618 template <typename Predicate>
1619 class [[nodiscard]] TrulyMatcher {
1620 public:
1621 explicit TrulyMatcher(Predicate pred) : predicate_(pred) {}
1622
1623
1624
1625
1626
1627 template <typename T>
1628 bool MatchAndExplain(T& x,
1629 MatchResultListener* listener) const {
1630
1631
1632
1633
1634
1635
1636 if (predicate_(x)) return true;
1637 *listener << "didn't satisfy the given predicate";
1638 return false;
1639 }
1640
1641 void DescribeTo(::std::ostream* os) const {
1642 *os << "satisfies the given predicate";
1643 }
1644
1645 void DescribeNegationTo(::std::ostream* os) const {
1646 *os << "doesn't satisfy the given predicate";
1647 }
1648
1649 private:
1650 Predicate predicate_;
1651 };
1652
1653
1654
1655 template <typename M>
1656 class [[nodiscard]] MatcherAsPredicate {
1657 public:
1658 explicit MatcherAsPredicate(M matcher) : matcher_(matcher) {}
1659
1660
1661
1662
1663
1664
1665
1666 template <typename T>
1667 bool operator()(const T& x) const {
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682 return MatcherCast<const T&>(matcher_).Matches(x);
1683 }
1684
1685 private:
1686 M matcher_;
1687 };
1688
1689
1690
1691 template <typename M>
1692 class [[nodiscard]] PredicateFormatterFromMatcher {
1693 public:
1694 explicit PredicateFormatterFromMatcher(M m) : matcher_(std::move(m)) {}
1695
1696
1697
1698
1699 template <typename T>
1700 AssertionResult operator()(const char* value_text, const T& x) const {
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712 const Matcher<const T&> matcher = SafeMatcherCast<const T&>(matcher_);
1713
1714
1715
1716 if (matcher.Matches(x)) {
1717 return AssertionSuccess();
1718 }
1719
1720 ::std::stringstream ss;
1721 ss << "Value of: " << value_text << "\n"
1722 << "Expected: ";
1723 matcher.DescribeTo(&ss);
1724
1725
1726 StringMatchResultListener listener;
1727 if (MatchPrintAndExplain(x, matcher, &listener)) {
1728 ss << "\n The matcher failed on the initial attempt; but passed when "
1729 "rerun to generate the explanation.";
1730 }
1731 ss << "\n Actual: " << listener.str();
1732 return AssertionFailure() << ss.str();
1733 }
1734
1735 private:
1736 const M matcher_;
1737 };
1738
1739
1740
1741
1742
1743 template <typename M>
1744 inline PredicateFormatterFromMatcher<M> MakePredicateFormatterFromMatcher(
1745 M matcher) {
1746 return PredicateFormatterFromMatcher<M>(std::move(matcher));
1747 }
1748
1749
1750
1751 class [[nodiscard]] IsNanMatcher {
1752 public:
1753 template <typename FloatType>
1754 bool MatchAndExplain(const FloatType& f,
1755 MatchResultListener* ) const {
1756 return (::std::isnan)(f);
1757 }
1758
1759 void DescribeTo(::std::ostream* os) const { *os << "is NaN"; }
1760 void DescribeNegationTo(::std::ostream* os) const { *os << "isn't NaN"; }
1761 };
1762
1763
1764
1765
1766
1767 template <typename FloatType>
1768 class [[nodiscard]] FloatingEqMatcher {
1769 public:
1770
1771
1772
1773
1774
1775
1776 FloatingEqMatcher(FloatType expected, bool nan_eq_nan)
1777 : expected_(expected), nan_eq_nan_(nan_eq_nan), max_abs_error_(-1) {}
1778
1779
1780
1781
1782 FloatingEqMatcher(FloatType expected, bool nan_eq_nan,
1783 FloatType max_abs_error)
1784 : expected_(expected),
1785 nan_eq_nan_(nan_eq_nan),
1786 max_abs_error_(max_abs_error) {
1787 GTEST_CHECK_(max_abs_error >= 0)
1788 << ", where max_abs_error is" << max_abs_error;
1789 }
1790
1791
1792 template <typename T>
1793 class Impl : public MatcherInterface<T> {
1794 public:
1795 Impl(FloatType expected, bool nan_eq_nan, FloatType max_abs_error)
1796 : expected_(expected),
1797 nan_eq_nan_(nan_eq_nan),
1798 max_abs_error_(max_abs_error) {}
1799
1800 bool MatchAndExplain(T value,
1801 MatchResultListener* listener) const override {
1802 const FloatingPoint<FloatType> actual(value), expected(expected_);
1803
1804
1805 if (actual.is_nan() || expected.is_nan()) {
1806 if (actual.is_nan() && expected.is_nan()) {
1807 return nan_eq_nan_;
1808 }
1809
1810 return false;
1811 }
1812 if (HasMaxAbsError()) {
1813
1814
1815
1816
1817 if (value == expected_) {
1818 return true;
1819 }
1820
1821 const FloatType diff = value - expected_;
1822 if (::std::fabs(diff) <= max_abs_error_) {
1823 return true;
1824 }
1825
1826 if (listener->IsInterested()) {
1827 *listener << "which is " << diff << " from " << expected_;
1828 }
1829 return false;
1830 } else {
1831 return actual.AlmostEquals(expected);
1832 }
1833 }
1834
1835 void DescribeTo(::std::ostream* os) const override {
1836
1837
1838
1839 const ::std::streamsize old_precision =
1840 os->precision(::std::numeric_limits<FloatType>::digits10 + 2);
1841 if (FloatingPoint<FloatType>(expected_).is_nan()) {
1842 if (nan_eq_nan_) {
1843 *os << "is NaN";
1844 } else {
1845 *os << "never matches";
1846 }
1847 } else {
1848 *os << "is approximately " << expected_;
1849 if (HasMaxAbsError()) {
1850 *os << " (absolute error <= " << max_abs_error_ << ")";
1851 }
1852 }
1853 os->precision(old_precision);
1854 }
1855
1856 void DescribeNegationTo(::std::ostream* os) const override {
1857
1858 const ::std::streamsize old_precision =
1859 os->precision(::std::numeric_limits<FloatType>::digits10 + 2);
1860 if (FloatingPoint<FloatType>(expected_).is_nan()) {
1861 if (nan_eq_nan_) {
1862 *os << "isn't NaN";
1863 } else {
1864 *os << "is anything";
1865 }
1866 } else {
1867 *os << "isn't approximately " << expected_;
1868 if (HasMaxAbsError()) {
1869 *os << " (absolute error > " << max_abs_error_ << ")";
1870 }
1871 }
1872
1873 os->precision(old_precision);
1874 }
1875
1876 private:
1877 bool HasMaxAbsError() const { return max_abs_error_ >= 0; }
1878
1879 const FloatType expected_;
1880 const bool nan_eq_nan_;
1881
1882 const FloatType max_abs_error_;
1883 };
1884
1885
1886
1887
1888 operator Matcher<FloatType>() const {
1889 return MakeMatcher(
1890 new Impl<FloatType>(expected_, nan_eq_nan_, max_abs_error_));
1891 }
1892
1893 operator Matcher<const FloatType&>() const {
1894 return MakeMatcher(
1895 new Impl<const FloatType&>(expected_, nan_eq_nan_, max_abs_error_));
1896 }
1897
1898 operator Matcher<FloatType&>() const {
1899 return MakeMatcher(
1900 new Impl<FloatType&>(expected_, nan_eq_nan_, max_abs_error_));
1901 }
1902
1903 private:
1904 const FloatType expected_;
1905 const bool nan_eq_nan_;
1906
1907 const FloatType max_abs_error_;
1908 };
1909
1910
1911
1912
1913
1914
1915 template <typename FloatType>
1916 class [[nodiscard]] FloatingEq2Matcher {
1917 public:
1918 FloatingEq2Matcher() { Init(-1, false); }
1919
1920 explicit FloatingEq2Matcher(bool nan_eq_nan) { Init(-1, nan_eq_nan); }
1921
1922 explicit FloatingEq2Matcher(FloatType max_abs_error) {
1923 Init(max_abs_error, false);
1924 }
1925
1926 FloatingEq2Matcher(FloatType max_abs_error, bool nan_eq_nan) {
1927 Init(max_abs_error, nan_eq_nan);
1928 }
1929
1930 template <typename T1, typename T2>
1931 operator Matcher<::std::tuple<T1, T2>>() const {
1932 return MakeMatcher(
1933 new Impl<::std::tuple<T1, T2>>(max_abs_error_, nan_eq_nan_));
1934 }
1935 template <typename T1, typename T2>
1936 operator Matcher<const ::std::tuple<T1, T2>&>() const {
1937 return MakeMatcher(
1938 new Impl<const ::std::tuple<T1, T2>&>(max_abs_error_, nan_eq_nan_));
1939 }
1940
1941 private:
1942 static ::std::ostream& GetDesc(::std::ostream& os) {
1943 return os << "an almost-equal pair";
1944 }
1945
1946 template <typename Tuple>
1947 class Impl : public MatcherInterface<Tuple> {
1948 public:
1949 Impl(FloatType max_abs_error, bool nan_eq_nan)
1950 : max_abs_error_(max_abs_error), nan_eq_nan_(nan_eq_nan) {}
1951
1952 bool MatchAndExplain(Tuple args,
1953 MatchResultListener* listener) const override {
1954 if (max_abs_error_ == -1) {
1955 FloatingEqMatcher<FloatType> fm(::std::get<0>(args), nan_eq_nan_);
1956 return static_cast<Matcher<FloatType>>(fm).MatchAndExplain(
1957 ::std::get<1>(args), listener);
1958 } else {
1959 FloatingEqMatcher<FloatType> fm(::std::get<0>(args), nan_eq_nan_,
1960 max_abs_error_);
1961 return static_cast<Matcher<FloatType>>(fm).MatchAndExplain(
1962 ::std::get<1>(args), listener);
1963 }
1964 }
1965 void DescribeTo(::std::ostream* os) const override {
1966 *os << "are " << GetDesc;
1967 }
1968 void DescribeNegationTo(::std::ostream* os) const override {
1969 *os << "aren't " << GetDesc;
1970 }
1971
1972 private:
1973 FloatType max_abs_error_;
1974 const bool nan_eq_nan_;
1975 };
1976
1977 void Init(FloatType max_abs_error_val, bool nan_eq_nan_val) {
1978 max_abs_error_ = max_abs_error_val;
1979 nan_eq_nan_ = nan_eq_nan_val;
1980 }
1981 FloatType max_abs_error_;
1982 bool nan_eq_nan_;
1983 };
1984
1985
1986
1987 template <typename InnerMatcher>
1988 class [[nodiscard]] PointeeMatcher {
1989 public:
1990 explicit PointeeMatcher(const InnerMatcher& matcher) : matcher_(matcher) {}
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000 template <typename Pointer>
2001 operator Matcher<Pointer>() const {
2002 return Matcher<Pointer>(new Impl<const Pointer&>(matcher_));
2003 }
2004
2005 private:
2006
2007 template <typename Pointer>
2008 class Impl : public MatcherInterface<Pointer> {
2009 public:
2010 using Pointee =
2011 typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_(
2012 Pointer)>::element_type;
2013
2014 explicit Impl(const InnerMatcher& matcher)
2015 : matcher_(MatcherCast<const Pointee&>(matcher)) {}
2016
2017 void DescribeTo(::std::ostream* os) const override {
2018 *os << "points to a value that ";
2019 matcher_.DescribeTo(os);
2020 }
2021
2022 void DescribeNegationTo(::std::ostream* os) const override {
2023 *os << "does not point to a value that ";
2024 matcher_.DescribeTo(os);
2025 }
2026
2027 bool MatchAndExplain(Pointer pointer,
2028 MatchResultListener* listener) const override {
2029 if (GetRawPointer(pointer) == nullptr) return false;
2030
2031 *listener << "which points to ";
2032 return MatchPrintAndExplain(*pointer, matcher_, listener);
2033 }
2034
2035 private:
2036 const Matcher<const Pointee&> matcher_;
2037 };
2038
2039 const InnerMatcher matcher_;
2040 };
2041
2042
2043
2044
2045
2046 template <typename InnerMatcher>
2047 class [[nodiscard]] PointerMatcher {
2048 public:
2049 explicit PointerMatcher(const InnerMatcher& matcher) : matcher_(matcher) {}
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059 template <typename PointerType>
2060 operator Matcher<PointerType>() const {
2061 return Matcher<PointerType>(new Impl<const PointerType&>(matcher_));
2062 }
2063
2064 private:
2065
2066 template <typename PointerType>
2067 class Impl : public MatcherInterface<PointerType> {
2068 public:
2069 using Pointer =
2070 const typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_(
2071 PointerType)>::element_type*;
2072
2073 explicit Impl(const InnerMatcher& matcher)
2074 : matcher_(MatcherCast<Pointer>(matcher)) {}
2075
2076 void DescribeTo(::std::ostream* os) const override {
2077 *os << "is a pointer that ";
2078 matcher_.DescribeTo(os);
2079 }
2080
2081 void DescribeNegationTo(::std::ostream* os) const override {
2082 *os << "is not a pointer that ";
2083 matcher_.DescribeTo(os);
2084 }
2085
2086 bool MatchAndExplain(PointerType pointer,
2087 MatchResultListener* listener) const override {
2088 *listener << "which is a pointer that ";
2089 Pointer p = GetRawPointer(pointer);
2090 return MatchPrintAndExplain(p, matcher_, listener);
2091 }
2092
2093 private:
2094 Matcher<Pointer> matcher_;
2095 };
2096
2097 const InnerMatcher matcher_;
2098 };
2099
2100 #if GTEST_HAS_RTTI
2101
2102
2103
2104
2105
2106
2107 template <typename To>
2108 class [[nodiscard]] WhenDynamicCastToMatcherBase {
2109 public:
2110 explicit WhenDynamicCastToMatcherBase(const Matcher<To>& matcher)
2111 : matcher_(matcher) {}
2112
2113 void DescribeTo(::std::ostream* os) const {
2114 GetCastTypeDescription(os);
2115 matcher_.DescribeTo(os);
2116 }
2117
2118 void DescribeNegationTo(::std::ostream* os) const {
2119 GetCastTypeDescription(os);
2120 matcher_.DescribeNegationTo(os);
2121 }
2122
2123 protected:
2124 const Matcher<To> matcher_;
2125
2126 static std::string GetToName() { return GetTypeName<To>(); }
2127
2128 template <typename From>
2129 static auto DoDynamicCast(From& from) {
2130 using ToType =
2131 std::remove_const_t<std::remove_reference_t<std::remove_pointer_t<To>>>;
2132
2133 if constexpr (std::is_base_of_v<proto2::MessageLite, ToType>) {
2134 if constexpr (std::is_pointer_v<To>) {
2135 return proto2::internal::DynamicCastMessageForGtest<ToType>(from);
2136 } else {
2137
2138 return proto2::internal::DynamicCastMessageForGtest<ToType>(&from);
2139 }
2140 } else if constexpr (std::is_pointer_v<To>) {
2141 return dynamic_cast<To>(from);
2142 } else {
2143
2144 return dynamic_cast<std::remove_reference_t<To>*>(&from);
2145 }
2146 }
2147
2148 private:
2149 static void GetCastTypeDescription(::std::ostream* os) {
2150 *os << "when dynamic_cast to " << GetToName() << ", ";
2151 }
2152 };
2153
2154
2155
2156 template <typename To>
2157 class [[nodiscard]] WhenDynamicCastToMatcher
2158 : public WhenDynamicCastToMatcherBase<To> {
2159 public:
2160 explicit WhenDynamicCastToMatcher(const Matcher<To>& matcher)
2161 : WhenDynamicCastToMatcherBase<To>(matcher) {}
2162
2163 template <typename From>
2164 bool MatchAndExplain(From from, MatchResultListener* listener) const {
2165 To to = this->DoDynamicCast(from);
2166 return MatchPrintAndExplain(to, this->matcher_, listener);
2167 }
2168 };
2169
2170
2171
2172 template <typename To>
2173 class [[nodiscard]]
2174 WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> {
2175 public:
2176 explicit WhenDynamicCastToMatcher(const Matcher<To&>& matcher)
2177 : WhenDynamicCastToMatcherBase<To&>(matcher) {}
2178
2179 template <typename From>
2180 bool MatchAndExplain(From& from, MatchResultListener* listener) const {
2181 To* to = this->DoDynamicCast(from);
2182 if (to == nullptr) {
2183 *listener << "which cannot be dynamic_cast to " << this->GetToName();
2184 return false;
2185 }
2186 return MatchPrintAndExplain(*to, this->matcher_, listener);
2187 }
2188 };
2189 #endif
2190
2191
2192
2193 template <typename Class, typename FieldType>
2194 class [[nodiscard]] FieldMatcher {
2195 public:
2196 FieldMatcher(FieldType Class::* field,
2197 const Matcher<const FieldType&>& matcher)
2198 : field_(field), matcher_(matcher), whose_field_("whose given field ") {}
2199
2200 FieldMatcher(const std::string& field_name, FieldType Class::* field,
2201 const Matcher<const FieldType&>& matcher)
2202 : field_(field),
2203 matcher_(matcher),
2204 whose_field_("whose field `" + field_name + "` ") {}
2205
2206 void DescribeTo(::std::ostream* os) const {
2207 *os << "is an object " << whose_field_;
2208 matcher_.DescribeTo(os);
2209 }
2210
2211 void DescribeNegationTo(::std::ostream* os) const {
2212 *os << "is an object " << whose_field_;
2213 matcher_.DescribeNegationTo(os);
2214 }
2215
2216 template <typename T>
2217 bool MatchAndExplain(const T& value, MatchResultListener* listener) const {
2218
2219
2220 return MatchAndExplainImpl(
2221 typename std::is_pointer<typename std::remove_const<T>::type>::type(),
2222 value, listener);
2223 }
2224
2225 private:
2226 bool MatchAndExplainImpl(std::false_type ,
2227 const Class& obj,
2228 MatchResultListener* listener) const {
2229 *listener << whose_field_ << "is ";
2230 return MatchPrintAndExplain(obj.*field_, matcher_, listener);
2231 }
2232
2233 bool MatchAndExplainImpl(std::true_type , const Class* p,
2234 MatchResultListener* listener) const {
2235 if (p == nullptr) return false;
2236
2237 *listener << "which points to an object ";
2238
2239
2240
2241 return MatchAndExplainImpl(std::false_type(), *p, listener);
2242 }
2243
2244 const FieldType Class::* field_;
2245 const Matcher<const FieldType&> matcher_;
2246
2247
2248
2249 const std::string whose_field_;
2250 };
2251
2252
2253
2254
2255
2256
2257 template <typename Class, typename PropertyType, typename Property>
2258 class [[nodiscard]] PropertyMatcher {
2259 public:
2260 typedef const PropertyType& RefToConstProperty;
2261
2262 PropertyMatcher(Property property, const Matcher<RefToConstProperty>& matcher)
2263 : property_(property),
2264 matcher_(matcher),
2265 whose_property_("whose given property ") {}
2266
2267 PropertyMatcher(const std::string& property_name, Property property,
2268 const Matcher<RefToConstProperty>& matcher)
2269 : property_(property),
2270 matcher_(matcher),
2271 whose_property_("whose property `" + property_name + "` ") {}
2272
2273 void DescribeTo(::std::ostream* os) const {
2274 *os << "is an object " << whose_property_;
2275 matcher_.DescribeTo(os);
2276 }
2277
2278 void DescribeNegationTo(::std::ostream* os) const {
2279 *os << "is an object " << whose_property_;
2280 matcher_.DescribeNegationTo(os);
2281 }
2282
2283 template <typename T>
2284 bool MatchAndExplain(const T& value, MatchResultListener* listener) const {
2285 return MatchAndExplainImpl(
2286 typename std::is_pointer<typename std::remove_const<T>::type>::type(),
2287 value, listener);
2288 }
2289
2290 private:
2291 bool MatchAndExplainImpl(std::false_type ,
2292 const Class& obj,
2293 MatchResultListener* listener) const {
2294 *listener << whose_property_ << "is ";
2295
2296
2297 RefToConstProperty result = (obj.*property_)();
2298 return MatchPrintAndExplain(result, matcher_, listener);
2299 }
2300
2301 bool MatchAndExplainImpl(std::true_type , const Class* p,
2302 MatchResultListener* listener) const {
2303 if (p == nullptr) return false;
2304
2305 *listener << "which points to an object ";
2306
2307
2308
2309 return MatchAndExplainImpl(std::false_type(), *p, listener);
2310 }
2311
2312 Property property_;
2313 const Matcher<RefToConstProperty> matcher_;
2314
2315
2316
2317 const std::string whose_property_;
2318 };
2319
2320
2321
2322 template <typename Functor>
2323 struct CallableTraits {
2324 typedef Functor StorageType;
2325
2326 static void CheckIsValid(Functor ) {}
2327
2328 template <typename T>
2329 static auto Invoke(Functor f, const T& arg) -> decltype(f(arg)) {
2330 return f(arg);
2331 }
2332 };
2333
2334
2335 template <typename ArgType, typename ResType>
2336 struct CallableTraits<ResType (*)(ArgType)> {
2337 typedef ResType ResultType;
2338 typedef ResType (*StorageType)(ArgType);
2339
2340 static void CheckIsValid(ResType (*f)(ArgType)) {
2341 GTEST_CHECK_(f != nullptr)
2342 << "NULL function pointer is passed into ResultOf().";
2343 }
2344 template <typename T>
2345 static ResType Invoke(ResType (*f)(ArgType), T arg) {
2346 return (*f)(arg);
2347 }
2348 };
2349
2350
2351
2352 template <typename Callable, typename InnerMatcher>
2353 class [[nodiscard]] ResultOfMatcher {
2354 public:
2355 ResultOfMatcher(Callable callable, InnerMatcher matcher)
2356 : ResultOfMatcher("", std::move(callable),
2357 std::move(matcher)) {}
2358
2359 ResultOfMatcher(const std::string& result_description, Callable callable,
2360 InnerMatcher matcher)
2361 : result_description_(result_description),
2362 callable_(std::move(callable)),
2363 matcher_(std::move(matcher)) {
2364 CallableTraits<Callable>::CheckIsValid(callable_);
2365 }
2366
2367 template <typename T>
2368 operator Matcher<T>() const {
2369 return Matcher<T>(
2370 new Impl<const T&>(result_description_, callable_, matcher_));
2371 }
2372
2373 private:
2374 typedef typename CallableTraits<Callable>::StorageType CallableStorageType;
2375
2376 template <typename T>
2377 class Impl : public MatcherInterface<T> {
2378 using ResultType = decltype(CallableTraits<Callable>::template Invoke<T>(
2379 std::declval<CallableStorageType>(), std::declval<T>()));
2380 using InnerType = std::conditional_t<
2381 std::is_lvalue_reference<ResultType>::value,
2382 const typename std::remove_reference<ResultType>::type&, ResultType>;
2383
2384 public:
2385 template <typename M>
2386 Impl(const std::string& result_description,
2387 const CallableStorageType& callable, const M& matcher)
2388 : result_description_(result_description),
2389 callable_(callable),
2390 matcher_(MatcherCast<InnerType>(matcher)) {}
2391
2392 void DescribeTo(::std::ostream* os) const override {
2393 if (result_description_.empty()) {
2394 *os << "is mapped by the given callable to a value that ";
2395 } else {
2396 *os << "whose " << result_description_ << " ";
2397 }
2398 matcher_.DescribeTo(os);
2399 }
2400
2401 void DescribeNegationTo(::std::ostream* os) const override {
2402 if (result_description_.empty()) {
2403 *os << "is mapped by the given callable to a value that ";
2404 } else {
2405 *os << "whose " << result_description_ << " ";
2406 }
2407 matcher_.DescribeNegationTo(os);
2408 }
2409
2410 bool MatchAndExplain(T obj, MatchResultListener* listener) const override {
2411 if (result_description_.empty()) {
2412 *listener << "which is mapped by the given callable to ";
2413 } else {
2414 *listener << "whose " << result_description_ << " is ";
2415 }
2416
2417
2418
2419
2420 InnerType result =
2421 CallableTraits<Callable>::template Invoke<T>(callable_, obj);
2422 return MatchPrintAndExplain(result, matcher_, listener);
2423 }
2424
2425 private:
2426 const std::string result_description_;
2427
2428
2429
2430
2431
2432 mutable CallableStorageType callable_;
2433 const Matcher<InnerType> matcher_;
2434 };
2435
2436 const std::string result_description_;
2437 const CallableStorageType callable_;
2438 const InnerMatcher matcher_;
2439 };
2440
2441
2442 template <typename SizeMatcher>
2443 class [[nodiscard]] SizeIsMatcher {
2444 public:
2445 explicit SizeIsMatcher(const SizeMatcher& size_matcher)
2446 : size_matcher_(size_matcher) {}
2447
2448 template <typename Container>
2449 operator Matcher<Container>() const {
2450 return Matcher<Container>(new Impl<const Container&>(size_matcher_));
2451 }
2452
2453 template <typename Container>
2454 class Impl : public MatcherInterface<Container> {
2455 public:
2456 using SizeType = decltype(std::declval<Container>().size());
2457 explicit Impl(const SizeMatcher& size_matcher)
2458 : size_matcher_(MatcherCast<SizeType>(size_matcher)) {}
2459
2460 void DescribeTo(::std::ostream* os) const override {
2461 *os << "has a size that ";
2462 size_matcher_.DescribeTo(os);
2463 }
2464 void DescribeNegationTo(::std::ostream* os) const override {
2465 *os << "has a size that ";
2466 size_matcher_.DescribeNegationTo(os);
2467 }
2468
2469 bool MatchAndExplain(Container container,
2470 MatchResultListener* listener) const override {
2471 SizeType size = container.size();
2472 StringMatchResultListener size_listener;
2473 const bool result = size_matcher_.MatchAndExplain(size, &size_listener);
2474 *listener << "whose size " << size
2475 << (result ? " matches" : " doesn't match");
2476 PrintIfNotEmpty(size_listener.str(), listener->stream());
2477 return result;
2478 }
2479
2480 private:
2481 const Matcher<SizeType> size_matcher_;
2482 };
2483
2484 private:
2485 const SizeMatcher size_matcher_;
2486 };
2487
2488
2489
2490 template <typename DistanceMatcher>
2491 class [[nodiscard]] BeginEndDistanceIsMatcher {
2492 public:
2493 explicit BeginEndDistanceIsMatcher(const DistanceMatcher& distance_matcher)
2494 : distance_matcher_(distance_matcher) {}
2495
2496 template <typename Container>
2497 operator Matcher<Container>() const {
2498 return Matcher<Container>(new Impl<const Container&>(distance_matcher_));
2499 }
2500
2501 template <typename Container>
2502 class Impl : public MatcherInterface<Container> {
2503 public:
2504 typedef internal::StlContainerView<GTEST_REMOVE_REFERENCE_AND_CONST_(
2505 Container)>
2506 ContainerView;
2507 typedef typename std::iterator_traits<
2508 typename ContainerView::type::const_iterator>::difference_type
2509 DistanceType;
2510 explicit Impl(const DistanceMatcher& distance_matcher)
2511 : distance_matcher_(MatcherCast<DistanceType>(distance_matcher)) {}
2512
2513 void DescribeTo(::std::ostream* os) const override {
2514 *os << "distance between begin() and end() ";
2515 distance_matcher_.DescribeTo(os);
2516 }
2517 void DescribeNegationTo(::std::ostream* os) const override {
2518 *os << "distance between begin() and end() ";
2519 distance_matcher_.DescribeNegationTo(os);
2520 }
2521
2522 bool MatchAndExplain(Container container,
2523 MatchResultListener* listener) const override {
2524 using std::begin;
2525 using std::end;
2526 DistanceType distance = std::distance(begin(container), end(container));
2527 StringMatchResultListener distance_listener;
2528 const bool result =
2529 distance_matcher_.MatchAndExplain(distance, &distance_listener);
2530 *listener << "whose distance between begin() and end() " << distance
2531 << (result ? " matches" : " doesn't match");
2532 PrintIfNotEmpty(distance_listener.str(), listener->stream());
2533 return result;
2534 }
2535
2536 private:
2537 const Matcher<DistanceType> distance_matcher_;
2538 };
2539
2540 private:
2541 const DistanceMatcher distance_matcher_;
2542 };
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554 template <typename Container>
2555 class [[nodiscard]] ContainerEqMatcher {
2556 public:
2557 typedef internal::StlContainerView<Container> View;
2558 typedef typename View::type StlContainer;
2559 typedef typename View::const_reference StlContainerReference;
2560
2561 static_assert(!std::is_const<Container>::value,
2562 "Container type must not be const");
2563 static_assert(!std::is_reference<Container>::value,
2564 "Container type must not be a reference");
2565
2566
2567
2568 explicit ContainerEqMatcher(const Container& expected)
2569 : expected_(View::Copy(expected)) {}
2570
2571 void DescribeTo(::std::ostream* os) const {
2572 *os << "equals ";
2573 UniversalPrint(expected_, os);
2574 }
2575 void DescribeNegationTo(::std::ostream* os) const {
2576 *os << "does not equal ";
2577 UniversalPrint(expected_, os);
2578 }
2579
2580 template <typename LhsContainer>
2581 bool MatchAndExplain(const LhsContainer& lhs,
2582 MatchResultListener* listener) const {
2583 typedef internal::StlContainerView<
2584 typename std::remove_const<LhsContainer>::type>
2585 LhsView;
2586 StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
2587 if (lhs_stl_container == expected_) return true;
2588
2589 ::std::ostream* const os = listener->stream();
2590 if (os != nullptr) {
2591
2592 bool printed_header = false;
2593 for (auto it = lhs_stl_container.begin(); it != lhs_stl_container.end();
2594 ++it) {
2595 if (internal::ArrayAwareFind(expected_.begin(), expected_.end(), *it) ==
2596 expected_.end()) {
2597 if (printed_header) {
2598 *os << ", ";
2599 } else {
2600 *os << "which has these unexpected elements: ";
2601 printed_header = true;
2602 }
2603 UniversalPrint(*it, os);
2604 }
2605 }
2606
2607
2608 bool printed_header2 = false;
2609 for (auto it = expected_.begin(); it != expected_.end(); ++it) {
2610 if (internal::ArrayAwareFind(lhs_stl_container.begin(),
2611 lhs_stl_container.end(),
2612 *it) == lhs_stl_container.end()) {
2613 if (printed_header2) {
2614 *os << ", ";
2615 } else {
2616 *os << (printed_header ? ",\nand" : "which")
2617 << " doesn't have these expected elements: ";
2618 printed_header2 = true;
2619 }
2620 UniversalPrint(*it, os);
2621 }
2622 }
2623 }
2624
2625 return false;
2626 }
2627
2628 private:
2629 const StlContainer expected_;
2630 };
2631
2632
2633 struct LessComparator {
2634 template <typename T, typename U>
2635 bool operator()(const T& lhs, const U& rhs) const {
2636 return lhs < rhs;
2637 }
2638 };
2639
2640
2641 template <typename Comparator, typename ContainerMatcher>
2642 class [[nodiscard]] WhenSortedByMatcher {
2643 public:
2644 WhenSortedByMatcher(const Comparator& comparator,
2645 const ContainerMatcher& matcher)
2646 : comparator_(comparator), matcher_(matcher) {}
2647
2648 template <typename LhsContainer>
2649 operator Matcher<LhsContainer>() const {
2650 return MakeMatcher(new Impl<LhsContainer>(comparator_, matcher_));
2651 }
2652
2653 template <typename LhsContainer>
2654 class Impl : public MatcherInterface<LhsContainer> {
2655 public:
2656 typedef internal::StlContainerView<GTEST_REMOVE_REFERENCE_AND_CONST_(
2657 LhsContainer)>
2658 LhsView;
2659 typedef typename LhsView::type LhsStlContainer;
2660 typedef typename LhsView::const_reference LhsStlContainerReference;
2661
2662
2663 typedef typename RemoveConstFromKey<
2664 typename internal::RangeTraits<LhsStlContainer>::value_type>::type
2665 LhsValue;
2666
2667 Impl(const Comparator& comparator, const ContainerMatcher& matcher)
2668 : comparator_(comparator), matcher_(matcher) {}
2669
2670 void DescribeTo(::std::ostream* os) const override {
2671 *os << "(when sorted) ";
2672 matcher_.DescribeTo(os);
2673 }
2674
2675 void DescribeNegationTo(::std::ostream* os) const override {
2676 *os << "(when sorted) ";
2677 matcher_.DescribeNegationTo(os);
2678 }
2679
2680 bool MatchAndExplain(LhsContainer lhs,
2681 MatchResultListener* listener) const override {
2682 LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
2683 ::std::vector<LhsValue> sorted_container(lhs_stl_container.begin(),
2684 lhs_stl_container.end());
2685 ::std::sort(sorted_container.begin(), sorted_container.end(),
2686 comparator_);
2687
2688 if (!listener->IsInterested()) {
2689
2690
2691 return matcher_.Matches(sorted_container);
2692 }
2693
2694 *listener << "which is ";
2695 UniversalPrint(sorted_container, listener->stream());
2696 *listener << " when sorted";
2697
2698 StringMatchResultListener inner_listener;
2699 const bool match =
2700 matcher_.MatchAndExplain(sorted_container, &inner_listener);
2701 PrintIfNotEmpty(inner_listener.str(), listener->stream());
2702 return match;
2703 }
2704
2705 private:
2706 const Comparator comparator_;
2707 const Matcher<const ::std::vector<LhsValue>&> matcher_;
2708
2709 Impl(const Impl&) = delete;
2710 Impl& operator=(const Impl&) = delete;
2711 };
2712
2713 private:
2714 const Comparator comparator_;
2715 const ContainerMatcher matcher_;
2716 };
2717
2718
2719
2720
2721
2722 template <typename TupleMatcher, typename RhsContainer>
2723 class [[nodiscard]] PointwiseMatcher {
2724 static_assert(
2725 !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>::value,
2726 "use UnorderedPointwise with hash tables");
2727
2728 public:
2729 typedef internal::StlContainerView<RhsContainer> RhsView;
2730 typedef typename RhsView::type RhsStlContainer;
2731 typedef typename internal::RangeTraits<RhsStlContainer>::value_type RhsValue;
2732
2733 static_assert(!std::is_const<RhsContainer>::value,
2734 "RhsContainer type must not be const");
2735 static_assert(!std::is_reference<RhsContainer>::value,
2736 "RhsContainer type must not be a reference");
2737
2738
2739
2740 PointwiseMatcher(const TupleMatcher& tuple_matcher, const RhsContainer& rhs)
2741 : tuple_matcher_(tuple_matcher), rhs_(RhsView::Copy(rhs)) {}
2742
2743 template <typename LhsContainer>
2744 operator Matcher<LhsContainer>() const {
2745 static_assert(
2746 !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)>::value,
2747 "use UnorderedPointwise with hash tables");
2748
2749 return Matcher<LhsContainer>(
2750 new Impl<const LhsContainer&>(tuple_matcher_, rhs_));
2751 }
2752
2753 template <typename LhsContainer>
2754 class Impl : public MatcherInterface<LhsContainer> {
2755 public:
2756 typedef internal::StlContainerView<GTEST_REMOVE_REFERENCE_AND_CONST_(
2757 LhsContainer)>
2758 LhsView;
2759 typedef typename LhsView::type LhsStlContainer;
2760 typedef typename LhsView::const_reference LhsStlContainerReference;
2761 typedef
2762 typename internal::RangeTraits<LhsStlContainer>::value_type LhsValue;
2763
2764
2765
2766
2767 typedef ::std::tuple<const LhsValue&, const RhsValue&> InnerMatcherArg;
2768
2769 Impl(const TupleMatcher& tuple_matcher, const RhsStlContainer& rhs)
2770
2771 : mono_tuple_matcher_(SafeMatcherCast<InnerMatcherArg>(tuple_matcher)),
2772 rhs_(rhs) {}
2773
2774 void DescribeTo(::std::ostream* os) const override {
2775 *os << "contains " << rhs_.size()
2776 << " values, where each value and its corresponding value in ";
2777 UniversalPrinter<RhsStlContainer>::Print(rhs_, os);
2778 *os << " ";
2779 mono_tuple_matcher_.DescribeTo(os);
2780 }
2781 void DescribeNegationTo(::std::ostream* os) const override {
2782 *os << "doesn't contain exactly " << rhs_.size()
2783 << " values, or contains a value x at some index i"
2784 << " where x and the i-th value of ";
2785 UniversalPrint(rhs_, os);
2786 *os << " ";
2787 mono_tuple_matcher_.DescribeNegationTo(os);
2788 }
2789
2790 bool MatchAndExplain(LhsContainer lhs,
2791 MatchResultListener* listener) const override {
2792 LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
2793 const size_t actual_size = lhs_stl_container.size();
2794 if (actual_size != rhs_.size()) {
2795 *listener << "which contains " << actual_size << " values";
2796 return false;
2797 }
2798
2799 auto left = lhs_stl_container.begin();
2800 auto right = rhs_.begin();
2801 for (size_t i = 0; i != actual_size; ++i, ++left, ++right) {
2802 if (listener->IsInterested()) {
2803 StringMatchResultListener inner_listener;
2804
2805
2806
2807 if (!mono_tuple_matcher_.MatchAndExplain(
2808 InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),
2809 ImplicitCast_<const RhsValue&>(*right)),
2810 &inner_listener)) {
2811 *listener << "where the value pair (";
2812 UniversalPrint(*left, listener->stream());
2813 *listener << ", ";
2814 UniversalPrint(*right, listener->stream());
2815 *listener << ") at index #" << i << " don't match";
2816 PrintIfNotEmpty(inner_listener.str(), listener->stream());
2817 return false;
2818 }
2819 } else {
2820 if (!mono_tuple_matcher_.Matches(
2821 InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),
2822 ImplicitCast_<const RhsValue&>(*right))))
2823 return false;
2824 }
2825 }
2826
2827 return true;
2828 }
2829
2830 private:
2831 const Matcher<InnerMatcherArg> mono_tuple_matcher_;
2832 const RhsStlContainer rhs_;
2833 };
2834
2835 private:
2836 const TupleMatcher tuple_matcher_;
2837 const RhsStlContainer rhs_;
2838 };
2839
2840
2841 template <typename Container>
2842 class [[nodiscard]] QuantifierMatcherImpl : public MatcherInterface<Container> {
2843 public:
2844 typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
2845 typedef StlContainerView<RawContainer> View;
2846 typedef typename View::type StlContainer;
2847 typedef typename View::const_reference StlContainerReference;
2848 typedef typename internal::RangeTraits<StlContainer>::value_type Element;
2849
2850 template <typename InnerMatcher>
2851 explicit QuantifierMatcherImpl(InnerMatcher inner_matcher)
2852 : inner_matcher_(
2853 testing::SafeMatcherCast<const Element&>(inner_matcher)) {}
2854
2855
2856
2857
2858 bool MatchAndExplainImpl(bool all_elements_should_match, Container container,
2859 MatchResultListener* listener) const {
2860 StlContainerReference stl_container = View::ConstReference(container);
2861 size_t i = 0;
2862 for (auto it = stl_container.begin(); it != stl_container.end();
2863 ++it, ++i) {
2864 StringMatchResultListener inner_listener;
2865 const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener);
2866
2867 if (matches != all_elements_should_match) {
2868 *listener << "whose element #" << i
2869 << (matches ? " matches" : " doesn't match");
2870 PrintIfNotEmpty(inner_listener.str(), listener->stream());
2871 return !all_elements_should_match;
2872 }
2873 }
2874 return all_elements_should_match;
2875 }
2876
2877 bool MatchAndExplainImpl(const Matcher<size_t>& count_matcher,
2878 Container container,
2879 MatchResultListener* listener) const {
2880 StlContainerReference stl_container = View::ConstReference(container);
2881 size_t i = 0;
2882 std::vector<size_t> match_elements;
2883 for (auto it = stl_container.begin(); it != stl_container.end();
2884 ++it, ++i) {
2885 StringMatchResultListener inner_listener;
2886 const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener);
2887 if (matches) {
2888 match_elements.push_back(i);
2889 }
2890 }
2891 if (listener->IsInterested()) {
2892 if (match_elements.empty()) {
2893 *listener << "has no element that matches";
2894 } else if (match_elements.size() == 1) {
2895 *listener << "whose element #" << match_elements[0] << " matches";
2896 } else {
2897 *listener << "whose elements (";
2898 std::string sep = "";
2899 for (size_t e : match_elements) {
2900 *listener << sep << e;
2901 sep = ", ";
2902 }
2903 *listener << ") match";
2904 }
2905 }
2906 StringMatchResultListener count_listener;
2907 if (count_matcher.MatchAndExplain(match_elements.size(), &count_listener)) {
2908 *listener << " and whose match quantity of " << match_elements.size()
2909 << " matches";
2910 PrintIfNotEmpty(count_listener.str(), listener->stream());
2911 return true;
2912 } else {
2913 if (match_elements.empty()) {
2914 *listener << " and";
2915 } else {
2916 *listener << " but";
2917 }
2918 *listener << " whose match quantity of " << match_elements.size()
2919 << " does not match";
2920 PrintIfNotEmpty(count_listener.str(), listener->stream());
2921 return false;
2922 }
2923 }
2924
2925 protected:
2926 const Matcher<const Element&> inner_matcher_;
2927 };
2928
2929
2930
2931 template <typename Container>
2932 class [[nodiscard]] ContainsMatcherImpl
2933 : public QuantifierMatcherImpl<Container> {
2934 public:
2935 template <typename InnerMatcher>
2936 explicit ContainsMatcherImpl(InnerMatcher inner_matcher)
2937 : QuantifierMatcherImpl<Container>(inner_matcher) {}
2938
2939
2940 void DescribeTo(::std::ostream* os) const override {
2941 *os << "contains at least one element that ";
2942 this->inner_matcher_.DescribeTo(os);
2943 }
2944
2945 void DescribeNegationTo(::std::ostream* os) const override {
2946 *os << "doesn't contain any element that ";
2947 this->inner_matcher_.DescribeTo(os);
2948 }
2949
2950 bool MatchAndExplain(Container container,
2951 MatchResultListener* listener) const override {
2952 return this->MatchAndExplainImpl(false, container, listener);
2953 }
2954 };
2955
2956
2957
2958
2959
2960
2961
2962
2963 template <typename V, typename T, typename Distance, typename GetDistance>
2964 class [[nodiscard]] DistanceFromMatcherImpl : public MatcherInterface<V> {
2965 public:
2966
2967
2968
2969
2970
2971 DistanceFromMatcherImpl(T target, GetDistance get_distance,
2972 Matcher<const Distance&> distance_matcher)
2973 : target_(std::move(target)),
2974 get_distance_(std::move(get_distance)),
2975 distance_matcher_(std::move(distance_matcher)) {}
2976
2977
2978 void DescribeTo(::std::ostream* os) const override {
2979 distance_matcher_.DescribeTo(os);
2980 *os << " away from " << PrintToString(target_);
2981 }
2982
2983 void DescribeNegationTo(::std::ostream* os) const override {
2984 distance_matcher_.DescribeNegationTo(os);
2985 *os << " away from " << PrintToString(target_);
2986 }
2987
2988 bool MatchAndExplain(V value, MatchResultListener* listener) const override {
2989 const auto distance = get_distance_(value, target_);
2990 const bool match = distance_matcher_.Matches(distance);
2991 if (!match && listener->IsInterested()) {
2992 *listener << "which is " << PrintToString(distance) << " away from "
2993 << PrintToString(target_);
2994 }
2995 return match;
2996 }
2997
2998 private:
2999 const T target_;
3000 const GetDistance get_distance_;
3001 const Matcher<const Distance&> distance_matcher_;
3002 };
3003
3004
3005
3006 template <typename Container>
3007 class [[nodiscard]] EachMatcherImpl : public QuantifierMatcherImpl<Container> {
3008 public:
3009 template <typename InnerMatcher>
3010 explicit EachMatcherImpl(InnerMatcher inner_matcher)
3011 : QuantifierMatcherImpl<Container>(inner_matcher) {}
3012
3013
3014 void DescribeTo(::std::ostream* os) const override {
3015 *os << "only contains elements that ";
3016 this->inner_matcher_.DescribeTo(os);
3017 }
3018
3019 void DescribeNegationTo(::std::ostream* os) const override {
3020 *os << "contains some element that ";
3021 this->inner_matcher_.DescribeNegationTo(os);
3022 }
3023
3024 bool MatchAndExplain(Container container,
3025 MatchResultListener* listener) const override {
3026 return this->MatchAndExplainImpl(true, container, listener);
3027 }
3028 };
3029
3030
3031
3032 template <typename Container>
3033 class [[nodiscard]] ContainsTimesMatcherImpl
3034 : public QuantifierMatcherImpl<Container> {
3035 public:
3036 template <typename InnerMatcher>
3037 explicit ContainsTimesMatcherImpl(InnerMatcher inner_matcher,
3038 Matcher<size_t> count_matcher)
3039 : QuantifierMatcherImpl<Container>(inner_matcher),
3040 count_matcher_(std::move(count_matcher)) {}
3041
3042 void DescribeTo(::std::ostream* os) const override {
3043 *os << "quantity of elements that match ";
3044 this->inner_matcher_.DescribeTo(os);
3045 *os << " ";
3046 count_matcher_.DescribeTo(os);
3047 }
3048
3049 void DescribeNegationTo(::std::ostream* os) const override {
3050 *os << "quantity of elements that match ";
3051 this->inner_matcher_.DescribeTo(os);
3052 *os << " ";
3053 count_matcher_.DescribeNegationTo(os);
3054 }
3055
3056 bool MatchAndExplain(Container container,
3057 MatchResultListener* listener) const override {
3058 return this->MatchAndExplainImpl(count_matcher_, container, listener);
3059 }
3060
3061 private:
3062 const Matcher<size_t> count_matcher_;
3063 };
3064
3065
3066 template <typename M>
3067 class [[nodiscard]] ContainsTimesMatcher {
3068 public:
3069 explicit ContainsTimesMatcher(M m, Matcher<size_t> count_matcher)
3070 : inner_matcher_(m), count_matcher_(std::move(count_matcher)) {}
3071
3072 template <typename Container>
3073 operator Matcher<Container>() const {
3074 return Matcher<Container>(new ContainsTimesMatcherImpl<const Container&>(
3075 inner_matcher_, count_matcher_));
3076 }
3077
3078 private:
3079 const M inner_matcher_;
3080 const Matcher<size_t> count_matcher_;
3081 };
3082
3083
3084 template <typename M>
3085 class [[nodiscard]] ContainsMatcher {
3086 public:
3087 explicit ContainsMatcher(M m) : inner_matcher_(m) {}
3088
3089 template <typename Container>
3090 operator Matcher<Container>() const {
3091 return Matcher<Container>(
3092 new ContainsMatcherImpl<const Container&>(inner_matcher_));
3093 }
3094
3095 ContainsTimesMatcher<M> Times(Matcher<size_t> count_matcher) const {
3096 return ContainsTimesMatcher<M>(inner_matcher_, std::move(count_matcher));
3097 }
3098
3099 private:
3100 const M inner_matcher_;
3101 };
3102
3103
3104 template <typename M>
3105 class [[nodiscard]] EachMatcher {
3106 public:
3107 explicit EachMatcher(M m) : inner_matcher_(m) {}
3108
3109 template <typename Container>
3110 operator Matcher<Container>() const {
3111 return Matcher<Container>(
3112 new EachMatcherImpl<const Container&>(inner_matcher_));
3113 }
3114
3115 private:
3116 const M inner_matcher_;
3117 };
3118
3119 namespace pair_getters {
3120 using std::get;
3121 template <typename T>
3122 auto First(T& x, Rank0) -> decltype(get<0>(x)) {
3123 return get<0>(x);
3124 }
3125 template <typename T>
3126 auto First(T& x, Rank1) -> decltype((x.first)) {
3127 return x.first;
3128 }
3129
3130 template <typename T>
3131 auto Second(T& x, Rank0) -> decltype(get<1>(x)) {
3132 return get<1>(x);
3133 }
3134 template <typename T>
3135 auto Second(T& x, Rank1) -> decltype((x.second)) {
3136 return x.second;
3137 }
3138 }
3139
3140
3141 struct DefaultGetDistance {
3142 template <typename T, typename U>
3143 auto operator()(const T& lhs, const U& rhs) const {
3144 using std::abs;
3145
3146 return abs(lhs - rhs);
3147 }
3148 };
3149
3150
3151
3152
3153
3154
3155
3156 template <typename T, typename GetDistance, typename DistanceMatcher>
3157 class [[nodiscard]] DistanceFromMatcher {
3158 public:
3159
3160
3161
3162
3163
3164 DistanceFromMatcher(T target, GetDistance get_distance,
3165 DistanceMatcher distance_matcher)
3166 : target_(std::move(target)),
3167 get_distance_(std::move(get_distance)),
3168 distance_matcher_(std::move(distance_matcher)) {}
3169
3170 DistanceFromMatcher(const DistanceFromMatcher& other) = default;
3171
3172
3173 template <typename V>
3174 operator Matcher<V>() const {
3175 using Distance = decltype(get_distance_(std::declval<V>(), target_));
3176 return Matcher<V>(new DistanceFromMatcherImpl<V, T, Distance, GetDistance>(
3177 target_, get_distance_, distance_matcher_));
3178 }
3179
3180 private:
3181 const T target_;
3182 const GetDistance get_distance_;
3183 const DistanceMatcher distance_matcher_;
3184 };
3185
3186
3187
3188
3189
3190 template <typename PairType>
3191 class [[nodiscard]] KeyMatcherImpl : public MatcherInterface<PairType> {
3192 public:
3193 typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType;
3194 typedef typename RawPairType::first_type KeyType;
3195
3196 template <typename InnerMatcher>
3197 explicit KeyMatcherImpl(InnerMatcher inner_matcher)
3198 : inner_matcher_(
3199 testing::SafeMatcherCast<const KeyType&>(inner_matcher)) {}
3200
3201
3202
3203 bool MatchAndExplain(PairType key_value,
3204 MatchResultListener* listener) const override {
3205 StringMatchResultListener inner_listener;
3206 const bool match = inner_matcher_.MatchAndExplain(
3207 pair_getters::First(key_value, Rank1()), &inner_listener);
3208 const std::string explanation = inner_listener.str();
3209 if (!explanation.empty()) {
3210 *listener << "whose first field is a value " << explanation;
3211 }
3212 return match;
3213 }
3214
3215
3216 void DescribeTo(::std::ostream* os) const override {
3217 *os << "has a key that ";
3218 inner_matcher_.DescribeTo(os);
3219 }
3220
3221
3222 void DescribeNegationTo(::std::ostream* os) const override {
3223 *os << "doesn't have a key that ";
3224 inner_matcher_.DescribeTo(os);
3225 }
3226
3227 private:
3228 const Matcher<const KeyType&> inner_matcher_;
3229 };
3230
3231
3232 template <typename M>
3233 class [[nodiscard]] KeyMatcher {
3234 public:
3235 explicit KeyMatcher(M m) : matcher_for_key_(m) {}
3236
3237 template <typename PairType>
3238 operator Matcher<PairType>() const {
3239 return Matcher<PairType>(
3240 new KeyMatcherImpl<const PairType&>(matcher_for_key_));
3241 }
3242
3243 private:
3244 const M matcher_for_key_;
3245 };
3246
3247
3248 template <typename InnerMatcher>
3249 class [[nodiscard]] AddressMatcher {
3250 public:
3251 explicit AddressMatcher(InnerMatcher m) : matcher_(m) {}
3252
3253 template <typename Type>
3254 operator Matcher<Type>() const {
3255 return Matcher<Type>(new Impl<const Type&>(matcher_));
3256 }
3257
3258 private:
3259
3260 template <typename Type>
3261 class Impl : public MatcherInterface<Type> {
3262 public:
3263 using Address = const GTEST_REMOVE_REFERENCE_AND_CONST_(Type) *;
3264 explicit Impl(const InnerMatcher& matcher)
3265 : matcher_(MatcherCast<Address>(matcher)) {}
3266
3267 void DescribeTo(::std::ostream* os) const override {
3268 *os << "has address that ";
3269 matcher_.DescribeTo(os);
3270 }
3271
3272 void DescribeNegationTo(::std::ostream* os) const override {
3273 *os << "does not have address that ";
3274 matcher_.DescribeTo(os);
3275 }
3276
3277 bool MatchAndExplain(Type object,
3278 MatchResultListener* listener) const override {
3279 *listener << "which has address ";
3280 Address address = std::addressof(object);
3281 return MatchPrintAndExplain(address, matcher_, listener);
3282 }
3283
3284 private:
3285 const Matcher<Address> matcher_;
3286 };
3287 const InnerMatcher matcher_;
3288 };
3289
3290
3291
3292 template <typename PairType>
3293 class [[nodiscard]] PairMatcherImpl : public MatcherInterface<PairType> {
3294 public:
3295 typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType;
3296 typedef typename RawPairType::first_type FirstType;
3297 typedef typename RawPairType::second_type SecondType;
3298
3299 template <typename FirstMatcher, typename SecondMatcher>
3300 PairMatcherImpl(FirstMatcher first_matcher, SecondMatcher second_matcher)
3301 : first_matcher_(
3302 testing::SafeMatcherCast<const FirstType&>(first_matcher)),
3303 second_matcher_(
3304 testing::SafeMatcherCast<const SecondType&>(second_matcher)) {}
3305
3306
3307 void DescribeTo(::std::ostream* os) const override {
3308 *os << "has a first field that ";
3309 first_matcher_.DescribeTo(os);
3310 *os << ", and has a second field that ";
3311 second_matcher_.DescribeTo(os);
3312 }
3313
3314
3315 void DescribeNegationTo(::std::ostream* os) const override {
3316 *os << "has a first field that ";
3317 first_matcher_.DescribeNegationTo(os);
3318 *os << ", or has a second field that ";
3319 second_matcher_.DescribeNegationTo(os);
3320 }
3321
3322
3323
3324 bool MatchAndExplain(PairType a_pair,
3325 MatchResultListener* listener) const override {
3326 if (!listener->IsInterested()) {
3327
3328
3329 return first_matcher_.Matches(pair_getters::First(a_pair, Rank1())) &&
3330 second_matcher_.Matches(pair_getters::Second(a_pair, Rank1()));
3331 }
3332 StringMatchResultListener first_inner_listener;
3333 if (!first_matcher_.MatchAndExplain(pair_getters::First(a_pair, Rank1()),
3334 &first_inner_listener)) {
3335 *listener << "whose first field does not match";
3336 PrintIfNotEmpty(first_inner_listener.str(), listener->stream());
3337 return false;
3338 }
3339 StringMatchResultListener second_inner_listener;
3340 if (!second_matcher_.MatchAndExplain(pair_getters::Second(a_pair, Rank1()),
3341 &second_inner_listener)) {
3342 *listener << "whose second field does not match";
3343 PrintIfNotEmpty(second_inner_listener.str(), listener->stream());
3344 return false;
3345 }
3346 ExplainSuccess(first_inner_listener.str(), second_inner_listener.str(),
3347 listener);
3348 return true;
3349 }
3350
3351 private:
3352 void ExplainSuccess(const std::string& first_explanation,
3353 const std::string& second_explanation,
3354 MatchResultListener* listener) const {
3355 *listener << "whose both fields match";
3356 if (!first_explanation.empty()) {
3357 *listener << ", where the first field is a value " << first_explanation;
3358 }
3359 if (!second_explanation.empty()) {
3360 *listener << ", ";
3361 if (!first_explanation.empty()) {
3362 *listener << "and ";
3363 } else {
3364 *listener << "where ";
3365 }
3366 *listener << "the second field is a value " << second_explanation;
3367 }
3368 }
3369
3370 const Matcher<const FirstType&> first_matcher_;
3371 const Matcher<const SecondType&> second_matcher_;
3372 };
3373
3374
3375 template <typename FirstMatcher, typename SecondMatcher>
3376 class [[nodiscard]] PairMatcher {
3377 public:
3378 PairMatcher(FirstMatcher first_matcher, SecondMatcher second_matcher)
3379 : first_matcher_(first_matcher), second_matcher_(second_matcher) {}
3380
3381 template <typename PairType>
3382 operator Matcher<PairType>() const {
3383 return Matcher<PairType>(
3384 new PairMatcherImpl<const PairType&>(first_matcher_, second_matcher_));
3385 }
3386
3387 private:
3388 const FirstMatcher first_matcher_;
3389 const SecondMatcher second_matcher_;
3390 };
3391
3392 template <typename T, size_t... I>
3393 auto UnpackStructImpl(const T& t, std::index_sequence<I...>, int)
3394 -> decltype(std::tie(get<I>(t)...)) {
3395 static_assert(std::tuple_size<T>::value == sizeof...(I),
3396 "Number of arguments doesn't match the number of fields.");
3397 return std::tie(get<I>(t)...);
3398 }
3399
3400 #if defined(__cpp_structured_bindings) && __cpp_structured_bindings >= 201606
3401 template <typename T>
3402 auto UnpackStructImpl(const T& t, std::make_index_sequence<1>, char) {
3403 const auto& [a] = t;
3404 return std::tie(a);
3405 }
3406 template <typename T>
3407 auto UnpackStructImpl(const T& t, std::make_index_sequence<2>, char) {
3408 const auto& [a, b] = t;
3409 return std::tie(a, b);
3410 }
3411 template <typename T>
3412 auto UnpackStructImpl(const T& t, std::make_index_sequence<3>, char) {
3413 const auto& [a, b, c] = t;
3414 return std::tie(a, b, c);
3415 }
3416 template <typename T>
3417 auto UnpackStructImpl(const T& t, std::make_index_sequence<4>, char) {
3418 const auto& [a, b, c, d] = t;
3419 return std::tie(a, b, c, d);
3420 }
3421 template <typename T>
3422 auto UnpackStructImpl(const T& t, std::make_index_sequence<5>, char) {
3423 const auto& [a, b, c, d, e] = t;
3424 return std::tie(a, b, c, d, e);
3425 }
3426 template <typename T>
3427 auto UnpackStructImpl(const T& t, std::make_index_sequence<6>, char) {
3428 const auto& [a, b, c, d, e, f] = t;
3429 return std::tie(a, b, c, d, e, f);
3430 }
3431 template <typename T>
3432 auto UnpackStructImpl(const T& t, std::make_index_sequence<7>, char) {
3433 const auto& [a, b, c, d, e, f, g] = t;
3434 return std::tie(a, b, c, d, e, f, g);
3435 }
3436 template <typename T>
3437 auto UnpackStructImpl(const T& t, std::make_index_sequence<8>, char) {
3438 const auto& [a, b, c, d, e, f, g, h] = t;
3439 return std::tie(a, b, c, d, e, f, g, h);
3440 }
3441 template <typename T>
3442 auto UnpackStructImpl(const T& t, std::make_index_sequence<9>, char) {
3443 const auto& [a, b, c, d, e, f, g, h, i] = t;
3444 return std::tie(a, b, c, d, e, f, g, h, i);
3445 }
3446 template <typename T>
3447 auto UnpackStructImpl(const T& t, std::make_index_sequence<10>, char) {
3448 const auto& [a, b, c, d, e, f, g, h, i, j] = t;
3449 return std::tie(a, b, c, d, e, f, g, h, i, j);
3450 }
3451 template <typename T>
3452 auto UnpackStructImpl(const T& t, std::make_index_sequence<11>, char) {
3453 const auto& [a, b, c, d, e, f, g, h, i, j, k] = t;
3454 return std::tie(a, b, c, d, e, f, g, h, i, j, k);
3455 }
3456 template <typename T>
3457 auto UnpackStructImpl(const T& t, std::make_index_sequence<12>, char) {
3458 const auto& [a, b, c, d, e, f, g, h, i, j, k, l] = t;
3459 return std::tie(a, b, c, d, e, f, g, h, i, j, k, l);
3460 }
3461 template <typename T>
3462 auto UnpackStructImpl(const T& t, std::make_index_sequence<13>, char) {
3463 const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m] = t;
3464 return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m);
3465 }
3466 template <typename T>
3467 auto UnpackStructImpl(const T& t, std::make_index_sequence<14>, char) {
3468 const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n] = t;
3469 return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
3470 }
3471 template <typename T>
3472 auto UnpackStructImpl(const T& t, std::make_index_sequence<15>, char) {
3473 const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o] = t;
3474 return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);
3475 }
3476 template <typename T>
3477 auto UnpackStructImpl(const T& t, std::make_index_sequence<16>, char) {
3478 const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = t;
3479 return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p);
3480 }
3481 template <typename T>
3482 auto UnpackStructImpl(const T& t, std::make_index_sequence<17>, char) {
3483 const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q] = t;
3484 return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q);
3485 }
3486 template <typename T>
3487 auto UnpackStructImpl(const T& t, std::make_index_sequence<18>, char) {
3488 const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r] = t;
3489 return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r);
3490 }
3491 template <typename T>
3492 auto UnpackStructImpl(const T& t, std::make_index_sequence<19>, char) {
3493 const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s] = t;
3494 return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s);
3495 }
3496 template <typename T>
3497 auto UnpackStructImpl(const T& u, std::make_index_sequence<20>, char) {
3498 const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t] = u;
3499 return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t);
3500 }
3501 template <typename T>
3502 auto UnpackStructImpl(const T& in, std::make_index_sequence<21>, char) {
3503 const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u] =
3504 in;
3505 return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t,
3506 u);
3507 }
3508
3509 template <typename T>
3510 auto UnpackStructImpl(const T& in, std::make_index_sequence<22>, char) {
3511 const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
3512 v] = in;
3513 return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
3514 v);
3515 }
3516
3517 template <typename T>
3518 auto UnpackStructImpl(const T& in, std::make_index_sequence<23>, char) {
3519 const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v,
3520 w] = in;
3521 return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
3522 v, w);
3523 }
3524 template <typename T>
3525 auto UnpackStructImpl(const T& in, std::make_index_sequence<24>, char) {
3526 const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v,
3527 w, x] = in;
3528 return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
3529 v, w, x);
3530 }
3531 template <typename T>
3532 auto UnpackStructImpl(const T& in, std::make_index_sequence<25>, char) {
3533 const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v,
3534 w, x, y] = in;
3535 return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
3536 v, w, x, y);
3537 }
3538 template <typename T>
3539 auto UnpackStructImpl(const T& in, std::make_index_sequence<26>, char) {
3540 const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v,
3541 w, x, y, z] = in;
3542 return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u,
3543 v, w, x, y, z);
3544 }
3545 #endif
3546
3547 template <size_t I, typename T>
3548 auto UnpackStruct(const T& t)
3549 -> decltype((UnpackStructImpl)(t, std::make_index_sequence<I>{}, 0)) {
3550 return (UnpackStructImpl)(t, std::make_index_sequence<I>{}, 0);
3551 }
3552
3553
3554
3555
3556 template <typename T, size_t N>
3557 void VariadicExpand(const T (&)[N]) {}
3558
3559 template <typename Struct, typename StructSize>
3560 class [[nodiscard]] FieldsAreMatcherImpl;
3561
3562 template <typename Struct, size_t... I>
3563 class [[nodiscard]] FieldsAreMatcherImpl<Struct, std::index_sequence<I...>>
3564 : public MatcherInterface<Struct> {
3565 using UnpackedType =
3566 decltype(UnpackStruct<sizeof...(I)>(std::declval<const Struct&>()));
3567 using MatchersType = std::tuple<
3568 Matcher<const typename std::tuple_element<I, UnpackedType>::type&>...>;
3569
3570 public:
3571 template <typename Inner>
3572 explicit FieldsAreMatcherImpl(const Inner& matchers)
3573 : matchers_(testing::SafeMatcherCast<
3574 const typename std::tuple_element<I, UnpackedType>::type&>(
3575 std::get<I>(matchers))...) {}
3576
3577 void DescribeTo(::std::ostream* os) const override {
3578 const char* separator = "";
3579 VariadicExpand(
3580 {(*os << separator << "has field #" << I << " that ",
3581 std::get<I>(matchers_).DescribeTo(os), separator = ", and ")...});
3582 }
3583
3584 void DescribeNegationTo(::std::ostream* os) const override {
3585 const char* separator = "";
3586 VariadicExpand({(*os << separator << "has field #" << I << " that ",
3587 std::get<I>(matchers_).DescribeNegationTo(os),
3588 separator = ", or ")...});
3589 }
3590
3591 bool MatchAndExplain(Struct t, MatchResultListener* listener) const override {
3592 return MatchInternal((UnpackStruct<sizeof...(I)>)(t), listener);
3593 }
3594
3595 private:
3596 bool MatchInternal(UnpackedType tuple, MatchResultListener* listener) const {
3597 if (!listener->IsInterested()) {
3598
3599
3600 bool good = true;
3601 VariadicExpand({good = good && std::get<I>(matchers_).Matches(
3602 std::get<I>(tuple))...});
3603 return good;
3604 }
3605
3606 size_t failed_pos = ~size_t{};
3607
3608 std::vector<StringMatchResultListener> inner_listener(sizeof...(I));
3609
3610 VariadicExpand(
3611 {failed_pos == ~size_t{} && !std::get<I>(matchers_).MatchAndExplain(
3612 std::get<I>(tuple), &inner_listener[I])
3613 ? failed_pos = I
3614 : 0 ...});
3615 if (failed_pos != ~size_t{}) {
3616 *listener << "whose field #" << failed_pos << " does not match";
3617 PrintIfNotEmpty(inner_listener[failed_pos].str(), listener->stream());
3618 return false;
3619 }
3620
3621 *listener << "whose all elements match";
3622 const char* separator = ", where";
3623 for (size_t index = 0; index < sizeof...(I); ++index) {
3624 const std::string str = inner_listener[index].str();
3625 if (!str.empty()) {
3626 *listener << separator << " field #" << index << " is a value " << str;
3627 separator = ", and";
3628 }
3629 }
3630
3631 return true;
3632 }
3633
3634 MatchersType matchers_;
3635 };
3636
3637 template <typename... Inner>
3638 class [[nodiscard]] FieldsAreMatcher {
3639 public:
3640 explicit FieldsAreMatcher(Inner... inner) : matchers_(std::move(inner)...) {}
3641
3642 template <typename Struct>
3643 operator Matcher<Struct>() const {
3644 return Matcher<Struct>(
3645 new FieldsAreMatcherImpl<const Struct&,
3646 std::index_sequence_for<Inner...>>(matchers_));
3647 }
3648
3649 private:
3650 std::tuple<Inner...> matchers_;
3651 };
3652
3653
3654 template <typename Container>
3655 class [[nodiscard]] ElementsAreMatcherImpl
3656 : public MatcherInterface<Container> {
3657 public:
3658 typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
3659 typedef internal::StlContainerView<RawContainer> View;
3660 typedef typename View::type StlContainer;
3661 typedef typename View::const_reference StlContainerReference;
3662 typedef typename internal::RangeTraits<StlContainer>::value_type Element;
3663
3664
3665
3666 template <typename InputIter>
3667 ElementsAreMatcherImpl(InputIter first, InputIter last) {
3668 while (first != last) {
3669 matchers_.push_back(MatcherCast<const Element&>(*first++));
3670 }
3671 }
3672
3673
3674 void DescribeTo(::std::ostream* os) const override {
3675 if (count() == 0) {
3676 *os << "is empty";
3677 } else if (count() == 1) {
3678 *os << "has 1 element that ";
3679 matchers_[0].DescribeTo(os);
3680 } else {
3681 *os << "has " << Elements(count()) << " where\n";
3682 for (size_t i = 0; i != count(); ++i) {
3683 *os << "element #" << i << " ";
3684 matchers_[i].DescribeTo(os);
3685 if (i + 1 < count()) {
3686 *os << ",\n";
3687 }
3688 }
3689 }
3690 }
3691
3692
3693 void DescribeNegationTo(::std::ostream* os) const override {
3694 if (count() == 0) {
3695 *os << "isn't empty";
3696 return;
3697 }
3698
3699 *os << "doesn't have " << Elements(count()) << ", or\n";
3700 for (size_t i = 0; i != count(); ++i) {
3701 *os << "element #" << i << " ";
3702 matchers_[i].DescribeNegationTo(os);
3703 if (i + 1 < count()) {
3704 *os << ", or\n";
3705 }
3706 }
3707 }
3708
3709 bool MatchAndExplain(Container container,
3710 MatchResultListener* listener) const override {
3711
3712
3713
3714 const bool listener_interested = listener->IsInterested();
3715
3716
3717 ::std::vector<std::string> explanations(count());
3718 StlContainerReference stl_container = View::ConstReference(container);
3719 auto it = stl_container.begin();
3720 size_t exam_pos = 0;
3721 bool unmatched_found = false;
3722
3723
3724
3725
3726 for (; it != stl_container.end() && exam_pos != count(); ++it, ++exam_pos) {
3727 bool match;
3728 if (listener_interested) {
3729 StringMatchResultListener s;
3730 match = matchers_[exam_pos].MatchAndExplain(*it, &s);
3731 explanations[exam_pos] = s.str();
3732 } else {
3733 match = matchers_[exam_pos].Matches(*it);
3734 }
3735
3736 if (!match) {
3737 unmatched_found = true;
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750 break;
3751 }
3752 }
3753
3754
3755
3756
3757
3758 size_t actual_count = exam_pos;
3759 for (; it != stl_container.end(); ++it) {
3760 ++actual_count;
3761 }
3762
3763 if (actual_count != count()) {
3764
3765
3766
3767
3768 if (listener_interested && (actual_count != 0)) {
3769 *listener << "which has " << Elements(actual_count);
3770 }
3771 return false;
3772 }
3773
3774 if (unmatched_found) {
3775
3776 if (listener_interested) {
3777
3778 auto unmatched_it = stl_container.begin();
3779
3780
3781
3782
3783 for (size_t i = 0; i != exam_pos; ++i) {
3784 ++unmatched_it;
3785 }
3786
3787
3788
3789
3790
3791
3792 *listener << "whose element #" << exam_pos << " ("
3793 << PrintToString(*unmatched_it) << ") ";
3794 matchers_[exam_pos].DescribeNegationTo(listener->stream());
3795 PrintIfNotEmpty(explanations[exam_pos], listener->stream());
3796 }
3797 return false;
3798 }
3799
3800
3801
3802 if (listener_interested) {
3803 bool reason_printed = false;
3804 for (size_t i = 0; i != count(); ++i) {
3805 const std::string& s = explanations[i];
3806 if (!s.empty()) {
3807 if (reason_printed) {
3808 *listener << ",\nand ";
3809 }
3810 *listener << "whose element #" << i << " matches, " << s;
3811 reason_printed = true;
3812 }
3813 }
3814 }
3815 return true;
3816 }
3817
3818 private:
3819 static Message Elements(size_t count) {
3820 return Message() << count << (count == 1 ? " element" : " elements");
3821 }
3822
3823 size_t count() const { return matchers_.size(); }
3824
3825 ::std::vector<Matcher<const Element&>> matchers_;
3826 };
3827
3828
3829
3830
3831
3832 class GTEST_API_ [[nodiscard]] MatchMatrix {
3833 public:
3834 MatchMatrix(size_t num_elements, size_t num_matchers)
3835 : num_elements_(num_elements),
3836 num_matchers_(num_matchers),
3837 matched_(num_elements_ * num_matchers_, 0) {}
3838
3839 size_t LhsSize() const { return num_elements_; }
3840 size_t RhsSize() const { return num_matchers_; }
3841 bool HasEdge(size_t ilhs, size_t irhs) const {
3842 return matched_[SpaceIndex(ilhs, irhs)] == 1;
3843 }
3844 void SetEdge(size_t ilhs, size_t irhs, bool b) {
3845 matched_[SpaceIndex(ilhs, irhs)] = b ? 1 : 0;
3846 }
3847
3848
3849
3850
3851 bool NextGraph();
3852
3853 void Randomize();
3854
3855 std::string DebugString() const;
3856
3857 private:
3858 size_t SpaceIndex(size_t ilhs, size_t irhs) const {
3859 return ilhs * num_matchers_ + irhs;
3860 }
3861
3862 size_t num_elements_;
3863 size_t num_matchers_;
3864
3865
3866
3867
3868 ::std::vector<char> matched_;
3869 };
3870
3871 typedef ::std::pair<size_t, size_t> ElementMatcherPair;
3872 typedef ::std::vector<ElementMatcherPair> ElementMatcherPairs;
3873
3874
3875
3876 GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g);
3877
3878 struct UnorderedMatcherRequire {
3879 enum Flags {
3880 Superset = 1 << 0,
3881 Subset = 1 << 1,
3882 ExactMatch = Superset | Subset,
3883 };
3884 };
3885
3886
3887
3888
3889 class GTEST_API_ [[nodiscard]] UnorderedElementsAreMatcherImplBase {
3890 protected:
3891 explicit UnorderedElementsAreMatcherImplBase(
3892 UnorderedMatcherRequire::Flags matcher_flags)
3893 : match_flags_(matcher_flags) {}
3894
3895
3896
3897
3898 typedef ::std::vector<const MatcherDescriberInterface*> MatcherDescriberVec;
3899
3900
3901 void DescribeToImpl(::std::ostream* os) const;
3902
3903
3904 void DescribeNegationToImpl(::std::ostream* os) const;
3905
3906 bool VerifyMatchMatrix(const ::std::vector<std::string>& element_printouts,
3907 const MatchMatrix& matrix,
3908 MatchResultListener* listener) const;
3909
3910 bool FindPairing(const MatchMatrix& matrix,
3911 MatchResultListener* listener) const;
3912
3913 MatcherDescriberVec& matcher_describers() { return matcher_describers_; }
3914
3915 static Message Elements(size_t n) {
3916 return Message() << n << " element" << (n == 1 ? "" : "s");
3917 }
3918
3919 UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; }
3920
3921 private:
3922 UnorderedMatcherRequire::Flags match_flags_;
3923 MatcherDescriberVec matcher_describers_;
3924 };
3925
3926
3927
3928 template <typename Container>
3929 class [[nodiscard]] UnorderedElementsAreMatcherImpl
3930 : public MatcherInterface<Container>,
3931 public UnorderedElementsAreMatcherImplBase {
3932 public:
3933 typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
3934 typedef internal::StlContainerView<RawContainer> View;
3935 typedef typename View::type StlContainer;
3936 typedef typename View::const_reference StlContainerReference;
3937 typedef typename internal::RangeTraits<StlContainer>::value_type Element;
3938
3939 template <typename InputIter>
3940 UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags,
3941 InputIter first, InputIter last)
3942 : UnorderedElementsAreMatcherImplBase(matcher_flags) {
3943 for (; first != last; ++first) {
3944 matchers_.push_back(MatcherCast<const Element&>(*first));
3945 }
3946 for (const auto& m : matchers_) {
3947 matcher_describers().push_back(m.GetDescriber());
3948 }
3949 }
3950
3951
3952 void DescribeTo(::std::ostream* os) const override {
3953 return UnorderedElementsAreMatcherImplBase::DescribeToImpl(os);
3954 }
3955
3956
3957 void DescribeNegationTo(::std::ostream* os) const override {
3958 return UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(os);
3959 }
3960
3961 bool MatchAndExplain(Container container,
3962 MatchResultListener* listener) const override {
3963 StlContainerReference stl_container = View::ConstReference(container);
3964 ::std::vector<std::string> element_printouts;
3965 MatchMatrix matrix =
3966 AnalyzeElements(stl_container.begin(), stl_container.end(),
3967 &element_printouts, listener);
3968
3969 return VerifyMatchMatrix(element_printouts, matrix, listener) &&
3970 FindPairing(matrix, listener);
3971 }
3972
3973 private:
3974 template <typename ElementIter>
3975 MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,
3976 ::std::vector<std::string>* element_printouts,
3977 MatchResultListener* listener) const {
3978 element_printouts->clear();
3979 ::std::vector<char> did_match;
3980 size_t num_elements = 0;
3981 DummyMatchResultListener dummy;
3982 for (; elem_first != elem_last; ++num_elements, ++elem_first) {
3983 if (listener->IsInterested()) {
3984 element_printouts->push_back(PrintToString(*elem_first));
3985 }
3986 for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) {
3987 did_match.push_back(
3988 matchers_[irhs].MatchAndExplain(*elem_first, &dummy));
3989 }
3990 }
3991
3992 MatchMatrix matrix(num_elements, matchers_.size());
3993 ::std::vector<char>::const_iterator did_match_iter = did_match.begin();
3994 for (size_t ilhs = 0; ilhs != num_elements; ++ilhs) {
3995 for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) {
3996 matrix.SetEdge(ilhs, irhs, *did_match_iter++ != 0);
3997 }
3998 }
3999 return matrix;
4000 }
4001
4002 ::std::vector<Matcher<const Element&>> matchers_;
4003 };
4004
4005
4006 template <typename Container>
4007 class [[nodiscard]] ContainsSubsequenceMatcherImpl
4008 : public MatcherInterface<Container> {
4009 public:
4010 typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
4011 typedef internal::StlContainerView<RawContainer> View;
4012 typedef typename View::type StlContainer;
4013 typedef typename View::const_reference StlContainerReference;
4014 typedef typename internal::RangeTraits<StlContainer>::value_type Element;
4015
4016
4017
4018 template <typename InputIter>
4019 ContainsSubsequenceMatcherImpl(InputIter first, InputIter last) {
4020 std::copy(first, last, std::back_inserter(matchers_));
4021 }
4022
4023
4024 void DescribeTo(::std::ostream* os) const override {
4025 if (matchers_.size() == 0) {
4026 *os << "contains an empty sequence";
4027 return;
4028 }
4029 *os << "contains in order a subsequence of elements that matches: ";
4030 for (size_t i = 0; i != matchers_.size(); ++i) {
4031 if (i > 0) {
4032 *os << ", then ";
4033 }
4034 matchers_[i].DescribeTo(os);
4035 }
4036 }
4037
4038
4039 void DescribeNegationTo(::std::ostream* os) const override {
4040 if (matchers_.size() == 0) {
4041 *os << "does not contain an empty sequence";
4042 return;
4043 }
4044 *os << "does not contain in order a subsequence of elements that matches ";
4045 for (size_t i = 0; i != matchers_.size(); ++i) {
4046 if (i > 0) {
4047 *os << ", then ";
4048 }
4049 matchers_[i].DescribeTo(os);
4050 }
4051 }
4052
4053 bool MatchAndExplain(Container container,
4054 MatchResultListener* listener) const override {
4055 StlContainerReference stl_container = View::ConstReference(container);
4056
4057 size_t num_matches = 0;
4058
4059 size_t num_elements_examined = 0;
4060 std::vector<size_t> match_indices;
4061 for (const auto& element : stl_container) {
4062 if (num_matches == matchers_.size()) {
4063 break;
4064 }
4065 StringMatchResultListener inner_listener;
4066 if (matchers_[num_matches].MatchAndExplain(element, &inner_listener)) {
4067 ++num_matches;
4068 match_indices.push_back(num_elements_examined);
4069 }
4070
4071 ++num_elements_examined;
4072 }
4073
4074 if (num_matches < matchers_.size()) {
4075
4076
4077
4078
4079
4080
4081 if (listener->IsInterested()) {
4082 for (size_t i = 0; i < match_indices.size(); ++i) {
4083 *listener << "found match for matcher #" << i
4084 << " with element at position #" << match_indices[i]
4085 << ", ";
4086 }
4087
4088 if (num_matches > 0) {
4089 *listener << "but ";
4090 }
4091
4092 *listener << "could not find a match for matcher #" << num_matches
4093 << " (";
4094 matchers_[num_matches].DescribeTo(listener->stream());
4095 *listener << ")";
4096
4097 if (num_matches > 0) {
4098 *listener << " after the last match at position #"
4099 << match_indices[num_matches - 1];
4100 }
4101 }
4102
4103 return false;
4104 }
4105
4106 return true;
4107 }
4108
4109 private:
4110 ::std::vector<Matcher<const Element&>> matchers_;
4111 };
4112
4113
4114
4115 template <typename Target>
4116 struct CastAndAppendTransform {
4117 template <typename Arg>
4118 Matcher<Target> operator()(const Arg& a) const {
4119 return MatcherCast<Target>(a);
4120 }
4121 };
4122
4123
4124 template <typename MatcherTuple>
4125 class [[nodiscard]] ContainsSubsequenceMatcher {
4126 public:
4127 explicit ContainsSubsequenceMatcher(const MatcherTuple& args)
4128 : matchers_(args) {}
4129
4130 template <typename Container>
4131
4132 operator Matcher<Container>() const {
4133 typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
4134 typedef typename internal::StlContainerView<RawContainer>::type View;
4135 typedef typename internal::RangeTraits<View>::value_type Element;
4136 typedef ::std::vector<Matcher<const Element&>> MatcherVec;
4137 MatcherVec matchers;
4138 matchers.reserve(::std::tuple_size<MatcherTuple>::value);
4139 TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
4140 ::std::back_inserter(matchers));
4141 return Matcher<Container>(
4142 new ContainsSubsequenceMatcherImpl<const Container&>(matchers.begin(),
4143 matchers.end()));
4144 }
4145
4146 private:
4147 const MatcherTuple matchers_;
4148 };
4149
4150
4151 template <typename MatcherTuple>
4152 class [[nodiscard]] UnorderedElementsAreMatcher {
4153 public:
4154 explicit UnorderedElementsAreMatcher(const MatcherTuple& args)
4155 : matchers_(args) {}
4156
4157 template <typename Container>
4158 operator Matcher<Container>() const {
4159 typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
4160 typedef typename internal::RangeTraits<RawContainer>::value_type Element;
4161 typedef ::std::vector<Matcher<const Element&>> MatcherVec;
4162 MatcherVec matchers;
4163 matchers.reserve(::std::tuple_size<MatcherTuple>::value);
4164 TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
4165 ::std::back_inserter(matchers));
4166 return Matcher<Container>(
4167 new UnorderedElementsAreMatcherImpl<const Container&>(
4168 UnorderedMatcherRequire::ExactMatch, matchers.begin(),
4169 matchers.end()));
4170 }
4171
4172 private:
4173 const MatcherTuple matchers_;
4174 };
4175
4176
4177 template <typename MatcherTuple>
4178 class [[nodiscard]] ElementsAreMatcher {
4179 public:
4180 explicit ElementsAreMatcher(const MatcherTuple& args) : matchers_(args) {}
4181
4182 template <typename Container>
4183 operator Matcher<Container>() const {
4184 static_assert(
4185 !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value ||
4186 ::std::tuple_size<MatcherTuple>::value < 2,
4187 "use UnorderedElementsAre with hash tables");
4188
4189 typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
4190 typedef typename internal::StlContainerView<RawContainer>::type View;
4191 typedef typename internal::RangeTraits<View>::value_type Element;
4192 typedef ::std::vector<Matcher<const Element&>> MatcherVec;
4193 MatcherVec matchers;
4194 matchers.reserve(::std::tuple_size<MatcherTuple>::value);
4195 TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
4196 ::std::back_inserter(matchers));
4197 return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>(
4198 matchers.begin(), matchers.end()));
4199 }
4200
4201 private:
4202 const MatcherTuple matchers_;
4203 };
4204
4205
4206 template <typename T>
4207 class [[nodiscard]] UnorderedElementsAreArrayMatcher {
4208 public:
4209 template <typename Iter>
4210 UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags,
4211 Iter first, Iter last)
4212 : match_flags_(match_flags), matchers_(first, last) {}
4213
4214 template <typename Container>
4215 operator Matcher<Container>() const {
4216 return Matcher<Container>(
4217 new UnorderedElementsAreMatcherImpl<const Container&>(
4218 match_flags_, matchers_.begin(), matchers_.end()));
4219 }
4220
4221 private:
4222 UnorderedMatcherRequire::Flags match_flags_;
4223 std::vector<std::remove_const_t<T>> matchers_;
4224 };
4225
4226
4227 template <typename T>
4228 class [[nodiscard]] ElementsAreArrayMatcher {
4229 public:
4230 template <typename Iter>
4231 ElementsAreArrayMatcher(Iter first, Iter last) : matchers_(first, last) {}
4232
4233 template <typename Container>
4234 operator Matcher<Container>() const {
4235 static_assert(
4236 !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value,
4237 "use UnorderedElementsAreArray with hash tables");
4238
4239 return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>(
4240 matchers_.begin(), matchers_.end()));
4241 }
4242
4243 private:
4244 const std::vector<std::remove_const_t<T>> matchers_;
4245 };
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256 template <typename Tuple2Matcher, typename Second>
4257 class [[nodiscard]] BoundSecondMatcher {
4258 public:
4259 BoundSecondMatcher(const Tuple2Matcher& tm, const Second& second)
4260 : tuple2_matcher_(tm), second_value_(second) {}
4261
4262 BoundSecondMatcher(const BoundSecondMatcher& other) = default;
4263
4264 template <typename T>
4265 operator Matcher<T>() const {
4266 return MakeMatcher(new Impl<T>(tuple2_matcher_, second_value_));
4267 }
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277 void operator=(const BoundSecondMatcher& ) {
4278 GTEST_LOG_(FATAL) << "BoundSecondMatcher should never be assigned.";
4279 }
4280
4281 private:
4282 template <typename T>
4283 class Impl : public MatcherInterface<T> {
4284 public:
4285 typedef ::std::tuple<T, Second> ArgTuple;
4286
4287 Impl(const Tuple2Matcher& tm, const Second& second)
4288 : mono_tuple2_matcher_(SafeMatcherCast<const ArgTuple&>(tm)),
4289 second_value_(second) {}
4290
4291 void DescribeTo(::std::ostream* os) const override {
4292 *os << "and ";
4293 UniversalPrint(second_value_, os);
4294 *os << " ";
4295 mono_tuple2_matcher_.DescribeTo(os);
4296 }
4297
4298 bool MatchAndExplain(T x, MatchResultListener* listener) const override {
4299 return mono_tuple2_matcher_.MatchAndExplain(ArgTuple(x, second_value_),
4300 listener);
4301 }
4302
4303 private:
4304 const Matcher<const ArgTuple&> mono_tuple2_matcher_;
4305 const Second second_value_;
4306 };
4307
4308 const Tuple2Matcher tuple2_matcher_;
4309 const Second second_value_;
4310 };
4311
4312
4313
4314
4315
4316 template <typename Tuple2Matcher, typename Second>
4317 BoundSecondMatcher<Tuple2Matcher, Second> MatcherBindSecond(
4318 const Tuple2Matcher& tm, const Second& second) {
4319 return BoundSecondMatcher<Tuple2Matcher, Second>(tm, second);
4320 }
4321
4322
4323
4324
4325
4326
4327 GTEST_API_ std::string FormatMatcherDescription(
4328 bool negation, const char* matcher_name,
4329 const std::vector<const char*>& param_names, const Strings& param_values);
4330
4331
4332
4333 template <typename Optional>
4334 auto IsOptionalEngaged(const Optional& optional, Rank1)
4335 -> decltype(!!optional) {
4336
4337
4338 return !static_cast<bool>(!optional);
4339 }
4340 template <typename Optional>
4341 auto IsOptionalEngaged(const Optional& optional, Rank0)
4342 -> decltype(!optional.has_value()) {
4343 return optional.has_value();
4344 }
4345
4346
4347 template <typename ValueMatcher>
4348 class [[nodiscard]] OptionalMatcher {
4349 public:
4350 explicit OptionalMatcher(const ValueMatcher& value_matcher)
4351 : value_matcher_(value_matcher) {}
4352
4353 template <typename Optional>
4354 operator Matcher<Optional>() const {
4355 return Matcher<Optional>(new Impl<const Optional&>(value_matcher_));
4356 }
4357
4358 template <typename Optional>
4359 class Impl : public MatcherInterface<Optional> {
4360 public:
4361 typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Optional) OptionalView;
4362 typedef typename OptionalView::value_type ValueType;
4363 explicit Impl(const ValueMatcher& value_matcher)
4364 : value_matcher_(MatcherCast<ValueType>(value_matcher)) {}
4365
4366 void DescribeTo(::std::ostream* os) const override {
4367 *os << "value ";
4368 value_matcher_.DescribeTo(os);
4369 }
4370
4371 void DescribeNegationTo(::std::ostream* os) const override {
4372 *os << "value ";
4373 value_matcher_.DescribeNegationTo(os);
4374 }
4375
4376 bool MatchAndExplain(Optional optional,
4377 MatchResultListener* listener) const override {
4378 if (!IsOptionalEngaged(optional, HighestRank())) {
4379 *listener << "which is not engaged";
4380 return false;
4381 }
4382 const ValueType& value = *optional;
4383 if (!listener->IsInterested()) {
4384
4385 return value_matcher_.Matches(value);
4386 }
4387 StringMatchResultListener value_listener;
4388 const bool match = value_matcher_.MatchAndExplain(value, &value_listener);
4389 *listener << "whose value " << PrintToString(value)
4390 << (match ? " matches" : " doesn't match");
4391 PrintIfNotEmpty(value_listener.str(), listener->stream());
4392 return match;
4393 }
4394
4395 private:
4396 const Matcher<ValueType> value_matcher_;
4397 };
4398
4399 private:
4400 const ValueMatcher value_matcher_;
4401 };
4402
4403 namespace variant_matcher {
4404
4405 template <typename T>
4406 void holds_alternative() {}
4407 template <typename T>
4408 void get() {}
4409
4410
4411 template <typename T>
4412 class [[nodiscard]] VariantMatcher {
4413 public:
4414 explicit VariantMatcher(::testing::Matcher<const T&> matcher)
4415 : matcher_(std::move(matcher)) {}
4416
4417 template <typename Variant>
4418 bool MatchAndExplain(const Variant& value,
4419 ::testing::MatchResultListener* listener) const {
4420 using std::get;
4421 if (!listener->IsInterested()) {
4422 return holds_alternative<T>(value) && matcher_.Matches(get<T>(value));
4423 }
4424
4425 if (!holds_alternative<T>(value)) {
4426 *listener << "whose value is not of type '" << GetTypeName() << "'";
4427 return false;
4428 }
4429
4430 const T& elem = get<T>(value);
4431 StringMatchResultListener elem_listener;
4432 const bool match = matcher_.MatchAndExplain(elem, &elem_listener);
4433 *listener << "whose value " << PrintToString(elem)
4434 << (match ? " matches" : " doesn't match");
4435 PrintIfNotEmpty(elem_listener.str(), listener->stream());
4436 return match;
4437 }
4438
4439 void DescribeTo(std::ostream* os) const {
4440 *os << "is a variant<> with value of type '" << GetTypeName()
4441 << "' and the value ";
4442 matcher_.DescribeTo(os);
4443 }
4444
4445 void DescribeNegationTo(std::ostream* os) const {
4446 *os << "is a variant<> with value of type other than '" << GetTypeName()
4447 << "' or the value ";
4448 matcher_.DescribeNegationTo(os);
4449 }
4450
4451 private:
4452 static std::string GetTypeName() {
4453 #if GTEST_HAS_RTTI
4454 GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(
4455 return internal::GetTypeName<T>());
4456 #endif
4457 return "the element type";
4458 }
4459
4460 const ::testing::Matcher<const T&> matcher_;
4461 };
4462
4463 }
4464
4465 namespace any_cast_matcher {
4466
4467
4468 template <typename T>
4469 void any_cast() {}
4470
4471
4472 template <typename T>
4473 class [[nodiscard]] AnyCastMatcher {
4474 public:
4475 explicit AnyCastMatcher(const ::testing::Matcher<const T&>& matcher)
4476 : matcher_(matcher) {}
4477
4478 template <typename AnyType>
4479 bool MatchAndExplain(const AnyType& value,
4480 ::testing::MatchResultListener* listener) const {
4481 if (!listener->IsInterested()) {
4482 const T* ptr = any_cast<T>(&value);
4483 return ptr != nullptr && matcher_.Matches(*ptr);
4484 }
4485
4486 const T* elem = any_cast<T>(&value);
4487 if (elem == nullptr) {
4488 *listener << "whose value is not of type '" << GetTypeName() << "'";
4489 return false;
4490 }
4491
4492 StringMatchResultListener elem_listener;
4493 const bool match = matcher_.MatchAndExplain(*elem, &elem_listener);
4494 *listener << "whose value " << PrintToString(*elem)
4495 << (match ? " matches" : " doesn't match");
4496 PrintIfNotEmpty(elem_listener.str(), listener->stream());
4497 return match;
4498 }
4499
4500 void DescribeTo(std::ostream* os) const {
4501 *os << "is an 'any' type with value of type '" << GetTypeName()
4502 << "' and the value ";
4503 matcher_.DescribeTo(os);
4504 }
4505
4506 void DescribeNegationTo(std::ostream* os) const {
4507 *os << "is an 'any' type with value of type other than '" << GetTypeName()
4508 << "' or the value ";
4509 matcher_.DescribeNegationTo(os);
4510 }
4511
4512 private:
4513 static std::string GetTypeName() {
4514 #if GTEST_HAS_RTTI
4515 GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(
4516 return internal::GetTypeName<T>());
4517 #endif
4518 return "the element type";
4519 }
4520
4521 const ::testing::Matcher<const T&> matcher_;
4522 };
4523
4524 }
4525
4526
4527 template <class ArgsTuple, size_t... k>
4528 class [[nodiscard]] ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
4529 public:
4530 using RawArgsTuple = typename std::decay<ArgsTuple>::type;
4531 using SelectedArgs =
4532 std::tuple<typename std::tuple_element<k, RawArgsTuple>::type...>;
4533 using MonomorphicInnerMatcher = Matcher<const SelectedArgs&>;
4534
4535 template <typename InnerMatcher>
4536 explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
4537 : inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
4538
4539 bool MatchAndExplain(ArgsTuple args,
4540 MatchResultListener* listener) const override {
4541
4542 (void)args;
4543 const SelectedArgs& selected_args =
4544 std::forward_as_tuple(std::get<k>(args)...);
4545 if (!listener->IsInterested()) return inner_matcher_.Matches(selected_args);
4546
4547 PrintIndices(listener->stream());
4548 *listener << "are " << PrintToString(selected_args);
4549
4550 StringMatchResultListener inner_listener;
4551 const bool match =
4552 inner_matcher_.MatchAndExplain(selected_args, &inner_listener);
4553 PrintIfNotEmpty(inner_listener.str(), listener->stream());
4554 return match;
4555 }
4556
4557 void DescribeTo(::std::ostream* os) const override {
4558 *os << "are a tuple ";
4559 PrintIndices(os);
4560 inner_matcher_.DescribeTo(os);
4561 }
4562
4563 void DescribeNegationTo(::std::ostream* os) const override {
4564 *os << "are a tuple ";
4565 PrintIndices(os);
4566 inner_matcher_.DescribeNegationTo(os);
4567 }
4568
4569 private:
4570
4571 static void PrintIndices(::std::ostream* os) {
4572 *os << "whose fields (";
4573 const char* sep = "";
4574
4575 (void)sep;
4576
4577
4578
4579
4580 const char* dummy[] = {
4581 "", (static_cast<void>(*os << sep << "#" << k), sep = ", ")...};
4582 (void)dummy;
4583 *os << ") ";
4584 }
4585
4586 MonomorphicInnerMatcher inner_matcher_;
4587 };
4588
4589 template <class InnerMatcher, size_t... k>
4590 class [[nodiscard]] ArgsMatcher {
4591 public:
4592 explicit ArgsMatcher(InnerMatcher inner_matcher)
4593 : inner_matcher_(std::move(inner_matcher)) {}
4594
4595 template <typename ArgsTuple>
4596 operator Matcher<ArgsTuple>() const {
4597 return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, k...>(inner_matcher_));
4598 }
4599
4600 private:
4601 InnerMatcher inner_matcher_;
4602 };
4603
4604 }
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621 template <typename Iter>
4622 inline internal::ElementsAreArrayMatcher<
4623 typename ::std::iterator_traits<Iter>::value_type>
4624 ElementsAreArray(Iter first, Iter last) {
4625 typedef typename ::std::iterator_traits<Iter>::value_type T;
4626 return internal::ElementsAreArrayMatcher<T>(first, last);
4627 }
4628
4629 template <typename T>
4630 inline auto ElementsAreArray(const T* pointer, size_t count)
4631 -> decltype(ElementsAreArray(pointer, pointer + count)) {
4632 return ElementsAreArray(pointer, pointer + count);
4633 }
4634
4635 template <typename T, size_t N>
4636 inline auto ElementsAreArray(const T (&array)[N])
4637 -> decltype(ElementsAreArray(array, N)) {
4638 return ElementsAreArray(array, N);
4639 }
4640
4641 template <typename Container>
4642 inline auto ElementsAreArray(const Container& container)
4643 -> decltype(ElementsAreArray(container.begin(), container.end())) {
4644 return ElementsAreArray(container.begin(), container.end());
4645 }
4646
4647 template <typename T>
4648 inline auto ElementsAreArray(::std::initializer_list<T> xs)
4649 -> decltype(ElementsAreArray(xs.begin(), xs.end())) {
4650 return ElementsAreArray(xs.begin(), xs.end());
4651 }
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666 template <typename Iter>
4667 inline internal::UnorderedElementsAreArrayMatcher<
4668 typename ::std::iterator_traits<Iter>::value_type>
4669 UnorderedElementsAreArray(Iter first, Iter last) {
4670 typedef typename ::std::iterator_traits<Iter>::value_type T;
4671 return internal::UnorderedElementsAreArrayMatcher<T>(
4672 internal::UnorderedMatcherRequire::ExactMatch, first, last);
4673 }
4674
4675 template <typename T>
4676 inline internal::UnorderedElementsAreArrayMatcher<T> UnorderedElementsAreArray(
4677 const T* pointer, size_t count) {
4678 return UnorderedElementsAreArray(pointer, pointer + count);
4679 }
4680
4681 template <typename T, size_t N>
4682 inline internal::UnorderedElementsAreArrayMatcher<T> UnorderedElementsAreArray(
4683 const T (&array)[N]) {
4684 return UnorderedElementsAreArray(array, N);
4685 }
4686
4687 template <typename Container>
4688 inline internal::UnorderedElementsAreArrayMatcher<
4689 typename Container::value_type>
4690 UnorderedElementsAreArray(const Container& container) {
4691 return UnorderedElementsAreArray(container.begin(), container.end());
4692 }
4693
4694 template <typename T>
4695 inline internal::UnorderedElementsAreArrayMatcher<T> UnorderedElementsAreArray(
4696 ::std::initializer_list<T> xs) {
4697 return UnorderedElementsAreArray(xs.begin(), xs.end());
4698 }
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709 const internal::AnythingMatcher _ = {};
4710
4711 template <typename T>
4712 inline Matcher<T> A() {
4713 return _;
4714 }
4715
4716
4717 template <typename T>
4718 inline Matcher<T> An() {
4719 return _;
4720 }
4721
4722
4723 inline PolymorphicMatcher<internal::IsNullMatcher> IsNull() {
4724 return MakePolymorphicMatcher(internal::IsNullMatcher());
4725 }
4726
4727
4728
4729
4730 inline PolymorphicMatcher<internal::NotNullMatcher> NotNull() {
4731 return MakePolymorphicMatcher(internal::NotNullMatcher());
4732 }
4733
4734
4735
4736 template <typename T>
4737 inline internal::RefMatcher<T&> Ref(T& x) {
4738 return internal::RefMatcher<T&>(x);
4739 }
4740
4741
4742 inline PolymorphicMatcher<internal::IsNanMatcher> IsNan() {
4743 return MakePolymorphicMatcher(internal::IsNanMatcher());
4744 }
4745
4746
4747
4748 inline internal::FloatingEqMatcher<double> DoubleEq(double rhs) {
4749 return internal::FloatingEqMatcher<double>(rhs, false);
4750 }
4751
4752
4753
4754 inline internal::FloatingEqMatcher<double> NanSensitiveDoubleEq(double rhs) {
4755 return internal::FloatingEqMatcher<double>(rhs, true);
4756 }
4757
4758
4759
4760
4761 inline internal::FloatingEqMatcher<double> DoubleNear(double rhs,
4762 double max_abs_error) {
4763 return internal::FloatingEqMatcher<double>(rhs, false, max_abs_error);
4764 }
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786 template <typename T, typename GetDistance, typename DistanceMatcher>
4787 inline internal::DistanceFromMatcher<T, GetDistance, DistanceMatcher>
4788 DistanceFrom(T target, GetDistance get_distance,
4789 DistanceMatcher distance_matcher) {
4790 return internal::DistanceFromMatcher<T, GetDistance, DistanceMatcher>(
4791 std::move(target), std::move(get_distance), std::move(distance_matcher));
4792 }
4793
4794 template <typename T, typename DistanceMatcher>
4795 inline internal::DistanceFromMatcher<T, internal::DefaultGetDistance,
4796 DistanceMatcher>
4797 DistanceFrom(T target, DistanceMatcher distance_matcher) {
4798 return DistanceFrom(std::move(target), internal::DefaultGetDistance(),
4799 std::move(distance_matcher));
4800 }
4801
4802
4803
4804
4805 inline internal::FloatingEqMatcher<double> NanSensitiveDoubleNear(
4806 double rhs, double max_abs_error) {
4807 return internal::FloatingEqMatcher<double>(rhs, true, max_abs_error);
4808 }
4809
4810
4811
4812 inline internal::FloatingEqMatcher<float> FloatEq(float rhs) {
4813 return internal::FloatingEqMatcher<float>(rhs, false);
4814 }
4815
4816
4817
4818 inline internal::FloatingEqMatcher<float> NanSensitiveFloatEq(float rhs) {
4819 return internal::FloatingEqMatcher<float>(rhs, true);
4820 }
4821
4822
4823
4824
4825 inline internal::FloatingEqMatcher<float> FloatNear(float rhs,
4826 float max_abs_error) {
4827 return internal::FloatingEqMatcher<float>(rhs, false, max_abs_error);
4828 }
4829
4830
4831
4832
4833 inline internal::FloatingEqMatcher<float> NanSensitiveFloatNear(
4834 float rhs, float max_abs_error) {
4835 return internal::FloatingEqMatcher<float>(rhs, true, max_abs_error);
4836 }
4837
4838
4839
4840 template <typename InnerMatcher>
4841 inline internal::PointeeMatcher<InnerMatcher> Pointee(
4842 const InnerMatcher& inner_matcher) {
4843 return internal::PointeeMatcher<InnerMatcher>(inner_matcher);
4844 }
4845
4846 #if GTEST_HAS_RTTI
4847
4848
4849
4850
4851
4852
4853 template <typename To>
4854 inline PolymorphicMatcher<internal::WhenDynamicCastToMatcher<To>>
4855 WhenDynamicCastTo(const Matcher<To>& inner_matcher) {
4856 return MakePolymorphicMatcher(
4857 internal::WhenDynamicCastToMatcher<To>(inner_matcher));
4858 }
4859 #endif
4860
4861
4862
4863
4864
4865 template <typename Class, typename FieldType, typename FieldMatcher>
4866 inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(
4867 FieldType Class::* field, const FieldMatcher& matcher) {
4868 return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(
4869 field, MatcherCast<const FieldType&>(matcher)));
4870
4871
4872
4873
4874 }
4875
4876
4877
4878 template <typename Class, typename FieldType, typename FieldMatcher>
4879 inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field(
4880 const std::string& field_name, FieldType Class::* field,
4881 const FieldMatcher& matcher) {
4882 return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(
4883 field_name, field, MatcherCast<const FieldType&>(matcher)));
4884 }
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894 template <typename Class, typename PropertyType, typename PropertyMatcher>
4895 inline PolymorphicMatcher<internal::PropertyMatcher<
4896 Class, PropertyType, PropertyType (Class::*)() const>>
4897 Property(PropertyType (Class::*property)() const,
4898 const PropertyMatcher& matcher) {
4899 return MakePolymorphicMatcher(
4900 internal::PropertyMatcher<Class, PropertyType,
4901 PropertyType (Class::*)() const>(
4902 property, MatcherCast<const PropertyType&>(matcher)));
4903
4904
4905
4906
4907 }
4908
4909
4910
4911 template <typename Class, typename PropertyType, typename PropertyMatcher>
4912 inline PolymorphicMatcher<internal::PropertyMatcher<
4913 Class, PropertyType, PropertyType (Class::*)() const>>
4914 Property(const std::string& property_name,
4915 PropertyType (Class::*property)() const,
4916 const PropertyMatcher& matcher) {
4917 return MakePolymorphicMatcher(
4918 internal::PropertyMatcher<Class, PropertyType,
4919 PropertyType (Class::*)() const>(
4920 property_name, property, MatcherCast<const PropertyType&>(matcher)));
4921 }
4922
4923
4924 template <typename Class, typename PropertyType, typename PropertyMatcher>
4925 inline PolymorphicMatcher<internal::PropertyMatcher<
4926 Class, PropertyType, PropertyType (Class::*)() const&>>
4927 Property(PropertyType (Class::*property)() const&,
4928 const PropertyMatcher& matcher) {
4929 return MakePolymorphicMatcher(
4930 internal::PropertyMatcher<Class, PropertyType,
4931 PropertyType (Class::*)() const&>(
4932 property, MatcherCast<const PropertyType&>(matcher)));
4933 }
4934
4935
4936 template <typename Class, typename PropertyType, typename PropertyMatcher>
4937 inline PolymorphicMatcher<internal::PropertyMatcher<
4938 Class, PropertyType, PropertyType (Class::*)() const&>>
4939 Property(const std::string& property_name,
4940 PropertyType (Class::*property)() const&,
4941 const PropertyMatcher& matcher) {
4942 return MakePolymorphicMatcher(
4943 internal::PropertyMatcher<Class, PropertyType,
4944 PropertyType (Class::*)() const&>(
4945 property_name, property, MatcherCast<const PropertyType&>(matcher)));
4946 }
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956 template <typename Callable, typename InnerMatcher>
4957 internal::ResultOfMatcher<Callable, InnerMatcher> ResultOf(
4958 Callable callable, InnerMatcher matcher) {
4959 return internal::ResultOfMatcher<Callable, InnerMatcher>(std::move(callable),
4960 std::move(matcher));
4961 }
4962
4963
4964
4965 template <typename Callable, typename InnerMatcher>
4966 internal::ResultOfMatcher<Callable, InnerMatcher> ResultOf(
4967 const std::string& result_description, Callable callable,
4968 InnerMatcher matcher) {
4969 return internal::ResultOfMatcher<Callable, InnerMatcher>(
4970 result_description, std::move(callable), std::move(matcher));
4971 }
4972
4973
4974
4975
4976 template <typename T = std::string>
4977 PolymorphicMatcher<internal::StrEqualityMatcher<internal::StringType<T>>> StrEq(
4978 const T& str) {
4979 return MakePolymorphicMatcher(
4980 internal::StrEqualityMatcher<internal::StringType<T>>(
4981 internal::StringType<T>(str), true, true));
4982 }
4983
4984
4985 template <typename T = std::string>
4986 PolymorphicMatcher<internal::StrEqualityMatcher<internal::StringType<T>>> StrNe(
4987 const T& str) {
4988 return MakePolymorphicMatcher(
4989 internal::StrEqualityMatcher<internal::StringType<T>>(
4990 internal::StringType<T>(str), false, true));
4991 }
4992
4993
4994 template <typename T = std::string>
4995 PolymorphicMatcher<internal::StrEqualityMatcher<internal::StringType<T>>>
4996 StrCaseEq(const T& str) {
4997 return MakePolymorphicMatcher(
4998 internal::StrEqualityMatcher<internal::StringType<T>>(
4999 internal::StringType<T>(str), true, false));
5000 }
5001
5002
5003 template <typename T = std::string>
5004 PolymorphicMatcher<internal::StrEqualityMatcher<internal::StringType<T>>>
5005 StrCaseNe(const T& str) {
5006 return MakePolymorphicMatcher(
5007 internal::StrEqualityMatcher<internal::StringType<T>>(
5008 internal::StringType<T>(str), false, false));
5009 }
5010
5011
5012
5013 template <typename T = std::string>
5014 PolymorphicMatcher<internal::HasSubstrMatcher<internal::StringType<T>>>
5015 HasSubstr(const T& substring) {
5016 return MakePolymorphicMatcher(
5017 internal::HasSubstrMatcher<internal::StringType<T>>(
5018 internal::StringType<T>(substring)));
5019 }
5020
5021
5022 template <typename T = std::string>
5023 PolymorphicMatcher<internal::StartsWithMatcher<internal::StringType<T>>>
5024 StartsWith(const T& prefix) {
5025 return MakePolymorphicMatcher(
5026 internal::StartsWithMatcher<internal::StringType<T>>(
5027 internal::StringType<T>(prefix)));
5028 }
5029
5030
5031 template <typename T = std::string>
5032 PolymorphicMatcher<internal::EndsWithMatcher<internal::StringType<T>>> EndsWith(
5033 const T& suffix) {
5034 return MakePolymorphicMatcher(
5035 internal::EndsWithMatcher<internal::StringType<T>>(
5036 internal::StringType<T>(suffix)));
5037 }
5038
5039
5040
5041 inline internal::Eq2Matcher Eq() { return internal::Eq2Matcher(); }
5042
5043
5044
5045 inline internal::Ge2Matcher Ge() { return internal::Ge2Matcher(); }
5046
5047
5048
5049 inline internal::Gt2Matcher Gt() { return internal::Gt2Matcher(); }
5050
5051
5052
5053 inline internal::Le2Matcher Le() { return internal::Le2Matcher(); }
5054
5055
5056
5057 inline internal::Lt2Matcher Lt() { return internal::Lt2Matcher(); }
5058
5059
5060
5061 inline internal::Ne2Matcher Ne() { return internal::Ne2Matcher(); }
5062
5063
5064
5065 inline internal::FloatingEq2Matcher<float> FloatEq() {
5066 return internal::FloatingEq2Matcher<float>();
5067 }
5068
5069
5070
5071 inline internal::FloatingEq2Matcher<double> DoubleEq() {
5072 return internal::FloatingEq2Matcher<double>();
5073 }
5074
5075
5076
5077 inline internal::FloatingEq2Matcher<float> NanSensitiveFloatEq() {
5078 return internal::FloatingEq2Matcher<float>(true);
5079 }
5080
5081
5082
5083 inline internal::FloatingEq2Matcher<double> NanSensitiveDoubleEq() {
5084 return internal::FloatingEq2Matcher<double>(true);
5085 }
5086
5087
5088
5089 inline internal::FloatingEq2Matcher<float> FloatNear(float max_abs_error) {
5090 return internal::FloatingEq2Matcher<float>(max_abs_error);
5091 }
5092
5093
5094
5095 inline internal::FloatingEq2Matcher<double> DoubleNear(double max_abs_error) {
5096 return internal::FloatingEq2Matcher<double>(max_abs_error);
5097 }
5098
5099
5100
5101
5102 inline internal::FloatingEq2Matcher<float> NanSensitiveFloatNear(
5103 float max_abs_error) {
5104 return internal::FloatingEq2Matcher<float>(max_abs_error, true);
5105 }
5106
5107
5108
5109
5110 inline internal::FloatingEq2Matcher<double> NanSensitiveDoubleNear(
5111 double max_abs_error) {
5112 return internal::FloatingEq2Matcher<double>(max_abs_error, true);
5113 }
5114
5115
5116
5117 template <typename InnerMatcher>
5118 inline internal::NotMatcher<InnerMatcher> Not(InnerMatcher m) {
5119 return internal::NotMatcher<InnerMatcher>(m);
5120 }
5121
5122
5123
5124
5125 template <typename Predicate>
5126 inline PolymorphicMatcher<internal::TrulyMatcher<Predicate>> Truly(
5127 Predicate pred) {
5128 return MakePolymorphicMatcher(internal::TrulyMatcher<Predicate>(pred));
5129 }
5130
5131
5132
5133
5134
5135
5136
5137 template <typename SizeMatcher>
5138 inline internal::SizeIsMatcher<SizeMatcher> SizeIs(
5139 const SizeMatcher& size_matcher) {
5140 return internal::SizeIsMatcher<SizeMatcher>(size_matcher);
5141 }
5142
5143
5144
5145
5146
5147
5148 template <typename DistanceMatcher>
5149 inline internal::BeginEndDistanceIsMatcher<DistanceMatcher> BeginEndDistanceIs(
5150 const DistanceMatcher& distance_matcher) {
5151 return internal::BeginEndDistanceIsMatcher<DistanceMatcher>(distance_matcher);
5152 }
5153
5154
5155
5156
5157
5158 template <typename Container>
5159 inline PolymorphicMatcher<
5160 internal::ContainerEqMatcher<typename std::remove_const<Container>::type>>
5161 ContainerEq(const Container& rhs) {
5162 return MakePolymorphicMatcher(internal::ContainerEqMatcher<Container>(rhs));
5163 }
5164
5165
5166
5167 template <typename Comparator, typename ContainerMatcher>
5168 inline internal::WhenSortedByMatcher<Comparator, ContainerMatcher> WhenSortedBy(
5169 const Comparator& comparator, const ContainerMatcher& container_matcher) {
5170 return internal::WhenSortedByMatcher<Comparator, ContainerMatcher>(
5171 comparator, container_matcher);
5172 }
5173
5174
5175
5176 template <typename ContainerMatcher>
5177 inline internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher>
5178 WhenSorted(const ContainerMatcher& container_matcher) {
5179 return internal::WhenSortedByMatcher<internal::LessComparator,
5180 ContainerMatcher>(
5181 internal::LessComparator(), container_matcher);
5182 }
5183
5184
5185
5186
5187
5188
5189
5190 template <typename TupleMatcher, typename Container>
5191 inline internal::PointwiseMatcher<TupleMatcher,
5192 typename std::remove_const<Container>::type>
5193 Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) {
5194 return internal::PointwiseMatcher<TupleMatcher, Container>(tuple_matcher,
5195 rhs);
5196 }
5197
5198
5199 template <typename TupleMatcher, typename T>
5200 inline internal::PointwiseMatcher<TupleMatcher,
5201 std::vector<std::remove_const_t<T>>>
5202 Pointwise(const TupleMatcher& tuple_matcher, std::initializer_list<T> rhs) {
5203 return Pointwise(tuple_matcher, std::vector<std::remove_const_t<T>>(rhs));
5204 }
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217 template <typename Tuple2Matcher, typename RhsContainer>
5218 inline internal::UnorderedElementsAreArrayMatcher<
5219 typename internal::BoundSecondMatcher<
5220 Tuple2Matcher,
5221 typename internal::StlContainerView<
5222 typename std::remove_const<RhsContainer>::type>::type::value_type>>
5223 UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
5224 const RhsContainer& rhs_container) {
5225
5226
5227 typedef typename internal::StlContainerView<RhsContainer> RhsView;
5228 typedef typename RhsView::type RhsStlContainer;
5229 typedef typename internal::RangeTraits<RhsStlContainer>::value_type Second;
5230 const RhsStlContainer& rhs_stl_container =
5231 RhsView::ConstReference(rhs_container);
5232
5233
5234 ::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second>> matchers;
5235 for (auto it = rhs_stl_container.begin(); it != rhs_stl_container.end();
5236 ++it) {
5237 matchers.push_back(internal::MatcherBindSecond(tuple2_matcher, *it));
5238 }
5239
5240
5241 return UnorderedElementsAreArray(matchers);
5242 }
5243
5244
5245 template <typename Tuple2Matcher, typename T>
5246 inline internal::UnorderedElementsAreArrayMatcher<
5247 typename internal::BoundSecondMatcher<Tuple2Matcher, T>>
5248 UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
5249 std::initializer_list<T> rhs) {
5250 return UnorderedPointwise(tuple2_matcher, std::vector<T>(rhs));
5251 }
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284 template <typename M>
5285 inline internal::ContainsMatcher<M> Contains(M matcher) {
5286 return internal::ContainsMatcher<M>(matcher);
5287 }
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316 template <typename Iter>
5317 inline internal::UnorderedElementsAreArrayMatcher<
5318 typename ::std::iterator_traits<Iter>::value_type>
5319 IsSupersetOf(Iter first, Iter last) {
5320 typedef typename ::std::iterator_traits<Iter>::value_type T;
5321 return internal::UnorderedElementsAreArrayMatcher<T>(
5322 internal::UnorderedMatcherRequire::Superset, first, last);
5323 }
5324
5325 template <typename T>
5326 inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
5327 const T* pointer, size_t count) {
5328 return IsSupersetOf(pointer, pointer + count);
5329 }
5330
5331 template <typename T, size_t N>
5332 inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
5333 const T (&array)[N]) {
5334 return IsSupersetOf(array, N);
5335 }
5336
5337 template <typename Container>
5338 inline internal::UnorderedElementsAreArrayMatcher<
5339 typename Container::value_type>
5340 IsSupersetOf(const Container& container) {
5341 return IsSupersetOf(container.begin(), container.end());
5342 }
5343
5344 template <typename T>
5345 inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
5346 ::std::initializer_list<T> xs) {
5347 return IsSupersetOf(xs.begin(), xs.end());
5348 }
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373 template <typename Iter>
5374 inline internal::UnorderedElementsAreArrayMatcher<
5375 typename ::std::iterator_traits<Iter>::value_type>
5376 IsSubsetOf(Iter first, Iter last) {
5377 typedef typename ::std::iterator_traits<Iter>::value_type T;
5378 return internal::UnorderedElementsAreArrayMatcher<T>(
5379 internal::UnorderedMatcherRequire::Subset, first, last);
5380 }
5381
5382 template <typename T>
5383 inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
5384 const T* pointer, size_t count) {
5385 return IsSubsetOf(pointer, pointer + count);
5386 }
5387
5388 template <typename T, size_t N>
5389 inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
5390 const T (&array)[N]) {
5391 return IsSubsetOf(array, N);
5392 }
5393
5394 template <typename Container>
5395 inline internal::UnorderedElementsAreArrayMatcher<
5396 typename Container::value_type>
5397 IsSubsetOf(const Container& container) {
5398 return IsSubsetOf(container.begin(), container.end());
5399 }
5400
5401 template <typename T>
5402 inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
5403 ::std::initializer_list<T> xs) {
5404 return IsSubsetOf(xs.begin(), xs.end());
5405 }
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434 template <typename M>
5435 inline internal::EachMatcher<M> Each(M matcher) {
5436 return internal::EachMatcher<M>(matcher);
5437 }
5438
5439
5440
5441
5442 template <typename M>
5443 inline internal::KeyMatcher<M> Key(M inner_matcher) {
5444 return internal::KeyMatcher<M>(inner_matcher);
5445 }
5446
5447
5448
5449
5450
5451
5452 template <typename FirstMatcher, typename SecondMatcher>
5453 inline internal::PairMatcher<FirstMatcher, SecondMatcher> Pair(
5454 FirstMatcher first_matcher, SecondMatcher second_matcher) {
5455 return internal::PairMatcher<FirstMatcher, SecondMatcher>(first_matcher,
5456 second_matcher);
5457 }
5458
5459 namespace no_adl {
5460
5461
5462
5463
5464
5465 template <typename MatcherTrue, typename MatcherFalse>
5466 internal::ConditionalMatcher<MatcherTrue, MatcherFalse> Conditional(
5467 bool condition, MatcherTrue matcher_true, MatcherFalse matcher_false) {
5468 return internal::ConditionalMatcher<MatcherTrue, MatcherFalse>(
5469 condition, std::move(matcher_true), std::move(matcher_false));
5470 }
5471
5472
5473
5474
5475
5476 template <typename... M>
5477 internal::FieldsAreMatcher<typename std::decay<M>::type...> FieldsAre(
5478 M&&... matchers) {
5479 return internal::FieldsAreMatcher<typename std::decay<M>::type...>(
5480 std::forward<M>(matchers)...);
5481 }
5482
5483
5484
5485 template <typename InnerMatcher>
5486 inline internal::PointerMatcher<InnerMatcher> Pointer(
5487 const InnerMatcher& inner_matcher) {
5488 return internal::PointerMatcher<InnerMatcher>(inner_matcher);
5489 }
5490
5491
5492
5493 template <typename InnerMatcher>
5494 inline internal::AddressMatcher<InnerMatcher> Address(
5495 const InnerMatcher& inner_matcher) {
5496 return internal::AddressMatcher<InnerMatcher>(inner_matcher);
5497 }
5498
5499
5500
5501 template <typename MatcherType>
5502 internal::WhenBase64UnescapedMatcher WhenBase64Unescaped(
5503 const MatcherType& internal_matcher) {
5504 return internal::WhenBase64UnescapedMatcher(internal_matcher);
5505 }
5506 }
5507
5508
5509
5510 template <typename M>
5511 inline internal::MatcherAsPredicate<M> Matches(M matcher) {
5512 return internal::MatcherAsPredicate<M>(matcher);
5513 }
5514
5515
5516 template <typename T, typename M>
5517 inline bool Value(const T& value, M matcher) {
5518 return testing::Matches(matcher)(value);
5519 }
5520
5521
5522
5523 template <typename T, typename M>
5524 inline bool ExplainMatchResult(M matcher, const T& value,
5525 MatchResultListener* listener) {
5526 return SafeMatcherCast<const T&>(matcher).MatchAndExplain(value, listener);
5527 }
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540 template <typename T, typename M>
5541 std::string DescribeMatcher(const M& matcher, bool negation = false) {
5542 ::std::stringstream ss;
5543 Matcher<T> monomorphic_matcher = SafeMatcherCast<T>(matcher);
5544 if (negation) {
5545 monomorphic_matcher.DescribeNegationTo(&ss);
5546 } else {
5547 monomorphic_matcher.DescribeTo(&ss);
5548 }
5549 return ss.str();
5550 }
5551
5552 template <typename... Args>
5553 internal::ElementsAreMatcher<
5554 std::tuple<typename std::decay<const Args&>::type...>>
5555 ElementsAre(const Args&... matchers) {
5556 return internal::ElementsAreMatcher<
5557 std::tuple<typename std::decay<const Args&>::type...>>(
5558 std::make_tuple(matchers...));
5559 }
5560
5561 template <typename... Args>
5562 internal::UnorderedElementsAreMatcher<
5563 std::tuple<typename std::decay<const Args&>::type...>>
5564 UnorderedElementsAre(const Args&... matchers) {
5565 return internal::UnorderedElementsAreMatcher<
5566 std::tuple<typename std::decay<const Args&>::type...>>(
5567 std::make_tuple(matchers...));
5568 }
5569
5570
5571
5572
5573 template <typename... Args>
5574 internal::ContainsSubsequenceMatcher<
5575 ::std::tuple<typename ::std::decay<const Args&>::type...>>
5576 ContainsSubsequence(const Args&... matchers) {
5577 return internal::ContainsSubsequenceMatcher<
5578 ::std::tuple<typename ::std::decay<const Args&>::type...>>(
5579 ::std::make_tuple(matchers...));
5580 }
5581
5582
5583 template <typename... Args>
5584 internal::AllOfMatcher<typename std::decay<const Args&>::type...> AllOf(
5585 const Args&... matchers) {
5586 return internal::AllOfMatcher<typename std::decay<const Args&>::type...>(
5587 matchers...);
5588 }
5589
5590 template <typename... Args>
5591 internal::AnyOfMatcher<typename std::decay<const Args&>::type...> AnyOf(
5592 const Args&... matchers) {
5593 return internal::AnyOfMatcher<typename std::decay<const Args&>::type...>(
5594 matchers...);
5595 }
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619 template <typename Iter>
5620 inline internal::AnyOfArrayMatcher<
5621 typename ::std::iterator_traits<Iter>::value_type>
5622 AnyOfArray(Iter first, Iter last) {
5623 return internal::AnyOfArrayMatcher<
5624 typename ::std::iterator_traits<Iter>::value_type>(first, last);
5625 }
5626
5627 template <typename Iter>
5628 inline internal::AllOfArrayMatcher<
5629 typename ::std::iterator_traits<Iter>::value_type>
5630 AllOfArray(Iter first, Iter last) {
5631 return internal::AllOfArrayMatcher<
5632 typename ::std::iterator_traits<Iter>::value_type>(first, last);
5633 }
5634
5635 template <typename T>
5636 inline internal::AnyOfArrayMatcher<T> AnyOfArray(const T* ptr, size_t count) {
5637 return AnyOfArray(ptr, ptr + count);
5638 }
5639
5640 template <typename T>
5641 inline internal::AllOfArrayMatcher<T> AllOfArray(const T* ptr, size_t count) {
5642 return AllOfArray(ptr, ptr + count);
5643 }
5644
5645 template <typename T, size_t N>
5646 inline internal::AnyOfArrayMatcher<T> AnyOfArray(const T (&array)[N]) {
5647 return AnyOfArray(array, N);
5648 }
5649
5650 template <typename T, size_t N>
5651 inline internal::AllOfArrayMatcher<T> AllOfArray(const T (&array)[N]) {
5652 return AllOfArray(array, N);
5653 }
5654
5655 template <typename Container>
5656 inline internal::AnyOfArrayMatcher<typename Container::value_type> AnyOfArray(
5657 const Container& container) {
5658 return AnyOfArray(container.begin(), container.end());
5659 }
5660
5661 template <typename Container>
5662 inline internal::AllOfArrayMatcher<typename Container::value_type> AllOfArray(
5663 const Container& container) {
5664 return AllOfArray(container.begin(), container.end());
5665 }
5666
5667 template <typename T>
5668 inline internal::AnyOfArrayMatcher<T> AnyOfArray(
5669 ::std::initializer_list<T> xs) {
5670 return AnyOfArray(xs.begin(), xs.end());
5671 }
5672
5673 template <typename T>
5674 inline internal::AllOfArrayMatcher<T> AllOfArray(
5675 ::std::initializer_list<T> xs) {
5676 return AllOfArray(xs.begin(), xs.end());
5677 }
5678
5679
5680
5681
5682 template <size_t... k, typename InnerMatcher>
5683 internal::ArgsMatcher<typename std::decay<InnerMatcher>::type, k...> Args(
5684 InnerMatcher&& matcher) {
5685 return internal::ArgsMatcher<typename std::decay<InnerMatcher>::type, k...>(
5686 std::forward<InnerMatcher>(matcher));
5687 }
5688
5689
5690
5691
5692
5693
5694
5695
5696 template <typename InnerMatcher>
5697 inline InnerMatcher AllArgs(const InnerMatcher& matcher) {
5698 return matcher;
5699 }
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710 template <typename ValueMatcher>
5711 inline internal::OptionalMatcher<ValueMatcher> Optional(
5712 const ValueMatcher& value_matcher) {
5713 return internal::OptionalMatcher<ValueMatcher>(value_matcher);
5714 }
5715
5716
5717 template <typename T>
5718 PolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T>> AnyWith(
5719 const Matcher<const T&>& matcher) {
5720 return MakePolymorphicMatcher(
5721 internal::any_cast_matcher::AnyCastMatcher<T>(matcher));
5722 }
5723
5724
5725
5726
5727
5728 template <typename T>
5729 PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T>> VariantWith(
5730 const Matcher<const T&>& matcher) {
5731 return MakePolymorphicMatcher(
5732 internal::variant_matcher::VariantMatcher<T>(matcher));
5733 }
5734
5735 #if GTEST_HAS_EXCEPTIONS
5736
5737
5738
5739 namespace internal {
5740
5741 class [[nodiscard]] WithWhatMatcherImpl {
5742 public:
5743 WithWhatMatcherImpl(Matcher<std::string> matcher)
5744 : matcher_(std::move(matcher)) {}
5745
5746 void DescribeTo(std::ostream* os) const {
5747 *os << "contains .what() that ";
5748 matcher_.DescribeTo(os);
5749 }
5750
5751 void DescribeNegationTo(std::ostream* os) const {
5752 *os << "contains .what() that does not ";
5753 matcher_.DescribeTo(os);
5754 }
5755
5756 template <typename Err>
5757 bool MatchAndExplain(const Err& err, MatchResultListener* listener) const {
5758 *listener << "which contains .what() (of value = " << err.what()
5759 << ") that ";
5760 return matcher_.MatchAndExplain(err.what(), listener);
5761 }
5762
5763 private:
5764 const Matcher<std::string> matcher_;
5765 };
5766
5767 inline PolymorphicMatcher<WithWhatMatcherImpl> WithWhat(
5768 Matcher<std::string> m) {
5769 return MakePolymorphicMatcher(WithWhatMatcherImpl(std::move(m)));
5770 }
5771
5772 template <typename Err>
5773 class [[nodiscard]] ExceptionMatcherImpl {
5774 class NeverThrown {
5775 public:
5776 const char* what() const noexcept {
5777 return "this exception should never be thrown";
5778 }
5779 };
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802 using DefaultExceptionType = typename std::conditional<
5803 std::is_same<typename std::remove_cv<
5804 typename std::remove_reference<Err>::type>::type,
5805 std::exception>::value,
5806 const NeverThrown&, const std::exception&>::type;
5807
5808 public:
5809 ExceptionMatcherImpl(Matcher<const Err&> matcher)
5810 : matcher_(std::move(matcher)) {}
5811
5812 void DescribeTo(std::ostream* os) const {
5813 *os << "throws an exception which is a " << GetTypeName<Err>();
5814 *os << " which ";
5815 matcher_.DescribeTo(os);
5816 }
5817
5818 void DescribeNegationTo(std::ostream* os) const {
5819 *os << "throws an exception which is not a " << GetTypeName<Err>();
5820 *os << " which ";
5821 matcher_.DescribeNegationTo(os);
5822 }
5823
5824 template <typename T>
5825 bool MatchAndExplain(T&& x, MatchResultListener* listener) const {
5826 try {
5827 (void)(std::forward<T>(x)());
5828 } catch (const Err& err) {
5829 *listener << "throws an exception which is a " << GetTypeName<Err>();
5830 *listener << " ";
5831 return matcher_.MatchAndExplain(err, listener);
5832 } catch (DefaultExceptionType err) {
5833 #if GTEST_HAS_RTTI
5834 *listener << "throws an exception of type " << GetTypeName(typeid(err));
5835 *listener << " ";
5836 #else
5837 *listener << "throws an std::exception-derived type ";
5838 #endif
5839 *listener << "with description \"" << err.what() << "\"";
5840 return false;
5841 } catch (...) {
5842 *listener << "throws an exception of an unknown type";
5843 return false;
5844 }
5845
5846 *listener << "does not throw any exception";
5847 return false;
5848 }
5849
5850 private:
5851 const Matcher<const Err&> matcher_;
5852 };
5853
5854 }
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878 template <typename Err>
5879 PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> Throws() {
5880 return MakePolymorphicMatcher(
5881 internal::ExceptionMatcherImpl<Err>(A<const Err&>()));
5882 }
5883
5884 template <typename Err, typename ExceptionMatcher>
5885 PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> Throws(
5886 const ExceptionMatcher& exception_matcher) {
5887
5888
5889
5890 return MakePolymorphicMatcher(internal::ExceptionMatcherImpl<Err>(
5891 SafeMatcherCast<const Err&>(exception_matcher)));
5892 }
5893
5894 template <typename Err, typename MessageMatcher>
5895 PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
5896 MessageMatcher&& message_matcher) {
5897 static_assert(std::is_base_of<std::exception, Err>::value,
5898 "expected an std::exception-derived type");
5899 return Throws<Err>(internal::WithWhat(
5900 MatcherCast<std::string>(std::forward<MessageMatcher>(message_matcher))));
5901 }
5902
5903 #endif
5904
5905
5906
5907
5908
5909 #define ASSERT_THAT(value, matcher) \
5910 ASSERT_PRED_FORMAT1( \
5911 ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
5912 #define EXPECT_THAT(value, matcher) \
5913 EXPECT_PRED_FORMAT1( \
5914 ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
5915
5916
5917 #define MATCHER(name, description) \
5918 class name##Matcher \
5919 : public ::testing::internal::MatcherBaseImpl<name##Matcher> { \
5920 public: \
5921 template <typename arg_type> \
5922 class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> { \
5923 public: \
5924 gmock_Impl() {} \
5925 bool MatchAndExplain( \
5926 const arg_type& arg, \
5927 ::testing::MatchResultListener* result_listener) const override; \
5928 void DescribeTo(::std::ostream* gmock_os) const override { \
5929 *gmock_os << FormatDescription(false); \
5930 } \
5931 void DescribeNegationTo(::std::ostream* gmock_os) const override { \
5932 *gmock_os << FormatDescription(true); \
5933 } \
5934 \
5935 private: \
5936 ::std::string FormatDescription(bool negation) const { \
5937 \
5938 ::std::string gmock_description = (description); \
5939 if (!gmock_description.empty()) { \
5940 return gmock_description; \
5941 } \
5942 return ::testing::internal::FormatMatcherDescription(negation, #name, \
5943 {}, {}); \
5944 } \
5945 }; \
5946 }; \
5947 inline name##Matcher GMOCK_INTERNAL_WARNING_PUSH() \
5948 GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-function") \
5949 GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-member-function") \
5950 name GMOCK_INTERNAL_WARNING_POP()() { \
5951 return {}; \
5952 } \
5953 template <typename arg_type> \
5954 bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain( \
5955 const arg_type& arg, \
5956 [[maybe_unused]] ::testing::MatchResultListener* result_listener) const
5957
5958 #define MATCHER_P(name, p0, description) \
5959 GMOCK_INTERNAL_MATCHER(name, name##MatcherP, description, (#p0), (p0))
5960 #define MATCHER_P2(name, p0, p1, description) \
5961 GMOCK_INTERNAL_MATCHER(name, name##MatcherP2, description, (#p0, #p1), \
5962 (p0, p1))
5963 #define MATCHER_P3(name, p0, p1, p2, description) \
5964 GMOCK_INTERNAL_MATCHER(name, name##MatcherP3, description, (#p0, #p1, #p2), \
5965 (p0, p1, p2))
5966 #define MATCHER_P4(name, p0, p1, p2, p3, description) \
5967 GMOCK_INTERNAL_MATCHER(name, name##MatcherP4, description, \
5968 (#p0, #p1, #p2, #p3), (p0, p1, p2, p3))
5969 #define MATCHER_P5(name, p0, p1, p2, p3, p4, description) \
5970 GMOCK_INTERNAL_MATCHER(name, name##MatcherP5, description, \
5971 (#p0, #p1, #p2, #p3, #p4), (p0, p1, p2, p3, p4))
5972 #define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description) \
5973 GMOCK_INTERNAL_MATCHER(name, name##MatcherP6, description, \
5974 (#p0, #p1, #p2, #p3, #p4, #p5), \
5975 (p0, p1, p2, p3, p4, p5))
5976 #define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description) \
5977 GMOCK_INTERNAL_MATCHER(name, name##MatcherP7, description, \
5978 (#p0, #p1, #p2, #p3, #p4, #p5, #p6), \
5979 (p0, p1, p2, p3, p4, p5, p6))
5980 #define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description) \
5981 GMOCK_INTERNAL_MATCHER(name, name##MatcherP8, description, \
5982 (#p0, #p1, #p2, #p3, #p4, #p5, #p6, #p7), \
5983 (p0, p1, p2, p3, p4, p5, p6, p7))
5984 #define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description) \
5985 GMOCK_INTERNAL_MATCHER(name, name##MatcherP9, description, \
5986 (#p0, #p1, #p2, #p3, #p4, #p5, #p6, #p7, #p8), \
5987 (p0, p1, p2, p3, p4, p5, p6, p7, p8))
5988 #define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description) \
5989 GMOCK_INTERNAL_MATCHER(name, name##MatcherP10, description, \
5990 (#p0, #p1, #p2, #p3, #p4, #p5, #p6, #p7, #p8, #p9), \
5991 (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9))
5992
5993 #define GMOCK_INTERNAL_MATCHER(name, full_name, description, arg_names, args) \
5994 template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \
5995 class full_name : public ::testing::internal::MatcherBaseImpl< \
5996 full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>> { \
5997 public: \
5998 using full_name::MatcherBaseImpl::MatcherBaseImpl; \
5999 template <typename arg_type> \
6000 class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> { \
6001 public: \
6002 explicit gmock_Impl(GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args)) \
6003 : GMOCK_INTERNAL_MATCHER_FORWARD_ARGS(args) {} \
6004 bool MatchAndExplain( \
6005 const arg_type& arg, \
6006 ::testing::MatchResultListener* result_listener) const override; \
6007 void DescribeTo(::std::ostream* gmock_os) const override { \
6008 *gmock_os << FormatDescription(false); \
6009 } \
6010 void DescribeNegationTo(::std::ostream* gmock_os) const override { \
6011 *gmock_os << FormatDescription(true); \
6012 } \
6013 GMOCK_INTERNAL_MATCHER_MEMBERS(args) \
6014 \
6015 private: \
6016 ::std::string FormatDescription(bool negation) const { \
6017 ::std::string gmock_description; \
6018 gmock_description = (description); \
6019 if (!gmock_description.empty()) { \
6020 return gmock_description; \
6021 } \
6022 return ::testing::internal::FormatMatcherDescription( \
6023 negation, #name, {GMOCK_PP_REMOVE_PARENS(arg_names)}, \
6024 ::testing::internal::UniversalTersePrintTupleFieldsToStrings( \
6025 ::std::tuple<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>( \
6026 GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args)))); \
6027 } \
6028 }; \
6029 }; \
6030 template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \
6031 inline full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)> name( \
6032 GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args)) { \
6033 return full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>( \
6034 GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args)); \
6035 } \
6036 template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \
6037 template <typename arg_type> \
6038 bool full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>:: \
6039 gmock_Impl<arg_type>::MatchAndExplain( \
6040 const arg_type& arg, \
6041 [[maybe_unused]] ::testing::MatchResultListener* result_listener) \
6042 const
6043
6044 #define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args) \
6045 GMOCK_PP_TAIL( \
6046 GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAM, , args))
6047 #define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAM(i_unused, data_unused, arg) \
6048 , typename arg##_type
6049
6050 #define GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args) \
6051 GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_TYPE_PARAM, , args))
6052 #define GMOCK_INTERNAL_MATCHER_TYPE_PARAM(i_unused, data_unused, arg) \
6053 , arg##_type
6054
6055 #define GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args) \
6056 GMOCK_PP_TAIL(dummy_first GMOCK_PP_FOR_EACH( \
6057 GMOCK_INTERNAL_MATCHER_FUNCTION_ARG, , args))
6058 #define GMOCK_INTERNAL_MATCHER_FUNCTION_ARG(i, data_unused, arg) \
6059 , arg##_type gmock_p##i
6060
6061 #define GMOCK_INTERNAL_MATCHER_FORWARD_ARGS(args) \
6062 GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_FORWARD_ARG, , args))
6063 #define GMOCK_INTERNAL_MATCHER_FORWARD_ARG(i, data_unused, arg) \
6064 , arg(::std::forward<arg##_type>(gmock_p##i))
6065
6066 #define GMOCK_INTERNAL_MATCHER_MEMBERS(args) \
6067 GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_MEMBER, , args)
6068 #define GMOCK_INTERNAL_MATCHER_MEMBER(i_unused, data_unused, arg) \
6069 const arg##_type arg;
6070
6071 #define GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args) \
6072 GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_MEMBER_USAGE, , args))
6073 #define GMOCK_INTERNAL_MATCHER_MEMBER_USAGE(i_unused, data_unused, arg) , arg
6074
6075 #define GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args) \
6076 GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_ARG_USAGE, , args))
6077 #define GMOCK_INTERNAL_MATCHER_ARG_USAGE(i, data_unused, arg) \
6078 , ::std::forward<arg##_type>(gmock_p##i)
6079
6080
6081 using namespace no_adl;
6082
6083 }
6084
6085 GTEST_DISABLE_MSC_WARNINGS_POP_()
6086
6087
6088
6089
6090 #include "gmock/internal/custom/gmock-matchers.h"
6091
6092 #endif