File indexing completed on 2026-11-05 10:36:04
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 #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
0040 #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
0041
0042 #include "gtest/internal/gtest-port.h"
0043
0044 #ifdef GTEST_OS_LINUX
0045 #include <stdlib.h>
0046 #include <sys/types.h>
0047 #include <sys/wait.h>
0048 #include <unistd.h>
0049 #endif
0050
0051 #if GTEST_HAS_EXCEPTIONS
0052 #include <stdexcept>
0053 #endif
0054
0055 #include <ctype.h>
0056 #include <float.h>
0057 #include <string.h>
0058
0059 #include <cstdint>
0060 #include <functional>
0061 #include <limits>
0062 #include <map>
0063 #include <set>
0064 #include <string>
0065 #include <type_traits>
0066 #include <utility>
0067 #include <vector>
0068
0069 #include "gtest/gtest-message.h"
0070 #include "gtest/internal/gtest-filepath.h"
0071 #include "gtest/internal/gtest-string.h"
0072 #include "gtest/internal/gtest-type-util.h"
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 #define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
0083 #define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo##bar
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 #define GTEST_STRINGIFY_HELPER_(name, ...) #name
0095 #define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, )
0096
0097 namespace proto2 {
0098 class [[nodiscard]] MessageLite;
0099
0100
0101
0102
0103 template <typename T>
0104 T DynamicCastMessage() = delete;
0105 }
0106
0107 namespace testing {
0108
0109
0110
0111 class AssertionResult;
0112 class Message;
0113 class Test;
0114 class TestInfo;
0115 class TestPartResult;
0116 class UnitTest;
0117
0118 template <typename T>
0119 ::std::string PrintToString(const T& value);
0120
0121 namespace internal {
0122
0123 struct TraceInfo;
0124 class [[nodiscard]] TestInfoImpl;
0125 class [[nodiscard]] UnitTestImpl;
0126
0127
0128
0129 GTEST_API_ extern const char kStackTraceMarker[];
0130
0131
0132 class [[nodiscard]] IgnoredValue {
0133 struct Sink {};
0134
0135 public:
0136
0137
0138
0139
0140
0141
0142
0143 template <typename T,
0144 typename std::enable_if<!std::is_convertible<T, Sink>::value,
0145 int>::type = 0>
0146 IgnoredValue(const T& ) {}
0147 };
0148
0149
0150 GTEST_API_ std::string AppendUserMessage(const std::string& gtest_msg,
0151 const Message& user_msg);
0152
0153 #if GTEST_HAS_EXCEPTIONS
0154
0155 GTEST_DISABLE_MSC_WARNINGS_PUSH_(
0156 4275 )
0157
0158
0159
0160
0161
0162
0163
0164 class GTEST_API_ [[nodiscard]] GoogleTestFailureException
0165 : public ::std::runtime_error {
0166 public:
0167 explicit GoogleTestFailureException(const TestPartResult& failure);
0168 };
0169
0170 GTEST_DISABLE_MSC_WARNINGS_POP_()
0171
0172 #endif
0173
0174 namespace edit_distance {
0175
0176
0177
0178
0179
0180 enum EditType { kMatch, kAdd, kRemove, kReplace };
0181 GTEST_API_ std::vector<EditType> CalculateOptimalEdits(
0182 const std::vector<size_t>& left, const std::vector<size_t>& right);
0183
0184
0185 GTEST_API_ std::vector<EditType> CalculateOptimalEdits(
0186 const std::vector<std::string>& left,
0187 const std::vector<std::string>& right);
0188
0189
0190 GTEST_API_ std::string CreateUnifiedDiff(const std::vector<std::string>& left,
0191 const std::vector<std::string>& right,
0192 size_t context = 2);
0193
0194 }
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211 GTEST_API_ AssertionResult EqFailure(const char* expected_expression,
0212 const char* actual_expression,
0213 const std::string& expected_value,
0214 const std::string& actual_value,
0215 bool ignoring_case);
0216
0217
0218 GTEST_API_ std::string GetBoolAssertionFailureMessage(
0219 const AssertionResult& assertion_result, const char* expression_text,
0220 const char* actual_predicate_value, const char* expected_predicate_value);
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 template <typename RawType>
0252 class [[nodiscard]] FloatingPoint {
0253 public:
0254
0255
0256 typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits;
0257
0258
0259
0260
0261 static const size_t kBitCount = 8 * sizeof(RawType);
0262
0263
0264 static const size_t kFractionBitCount =
0265 std::numeric_limits<RawType>::digits - 1;
0266
0267
0268 static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount;
0269
0270
0271 static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1);
0272
0273
0274 static const Bits kFractionBitMask = ~static_cast<Bits>(0) >>
0275 (kExponentBitCount + 1);
0276
0277
0278 static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask);
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292 static const uint32_t kMaxUlps = 4;
0293
0294
0295
0296
0297
0298
0299
0300 explicit FloatingPoint(RawType x) { memcpy(&bits_, &x, sizeof(x)); }
0301
0302
0303
0304
0305
0306
0307 static RawType ReinterpretBits(Bits bits) {
0308 RawType fp;
0309 memcpy(&fp, &bits, sizeof(fp));
0310 return fp;
0311 }
0312
0313
0314 static RawType Infinity() { return ReinterpretBits(kExponentBitMask); }
0315
0316
0317
0318
0319 const Bits& bits() const { return bits_; }
0320
0321
0322 Bits exponent_bits() const { return kExponentBitMask & bits_; }
0323
0324
0325 Bits fraction_bits() const { return kFractionBitMask & bits_; }
0326
0327
0328 Bits sign_bit() const { return kSignBitMask & bits_; }
0329
0330
0331 bool is_nan() const {
0332
0333
0334 return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0);
0335 }
0336
0337
0338
0339
0340
0341
0342
0343 bool AlmostEquals(const FloatingPoint& rhs) const {
0344
0345
0346 if (is_nan() || rhs.is_nan()) return false;
0347
0348 return DistanceBetweenSignAndMagnitudeNumbers(bits_, rhs.bits_) <= kMaxUlps;
0349 }
0350
0351 private:
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367 static Bits SignAndMagnitudeToBiased(Bits sam) {
0368 if (kSignBitMask & sam) {
0369
0370 return ~sam + 1;
0371 } else {
0372
0373 return kSignBitMask | sam;
0374 }
0375 }
0376
0377
0378
0379 static Bits DistanceBetweenSignAndMagnitudeNumbers(Bits sam1, Bits sam2) {
0380 const Bits biased1 = SignAndMagnitudeToBiased(sam1);
0381 const Bits biased2 = SignAndMagnitudeToBiased(sam2);
0382 return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
0383 }
0384
0385 Bits bits_;
0386 };
0387
0388
0389
0390 typedef FloatingPoint<float> Float;
0391 typedef FloatingPoint<double> Double;
0392
0393
0394
0395
0396
0397
0398
0399 typedef const void* TypeId;
0400
0401 template <typename T>
0402 class [[nodiscard]] TypeIdHelper {
0403 public:
0404
0405
0406
0407 static bool dummy_;
0408 };
0409
0410 template <typename T>
0411 bool TypeIdHelper<T>::dummy_ = false;
0412
0413
0414
0415
0416 template <typename T>
0417 TypeId GetTypeId() {
0418
0419
0420
0421
0422 return &(TypeIdHelper<T>::dummy_);
0423 }
0424
0425
0426
0427
0428
0429
0430 GTEST_API_ TypeId GetTestTypeId();
0431
0432
0433
0434 class [[nodiscard]] TestFactoryBase {
0435 public:
0436 virtual ~TestFactoryBase() = default;
0437
0438
0439
0440 virtual Test* CreateTest() = 0;
0441
0442 protected:
0443 TestFactoryBase() {}
0444
0445 private:
0446 TestFactoryBase(const TestFactoryBase&) = delete;
0447 TestFactoryBase& operator=(const TestFactoryBase&) = delete;
0448 };
0449
0450
0451
0452 template <class TestClass>
0453 class [[nodiscard]] TestFactoryImpl : public TestFactoryBase {
0454 public:
0455 Test* CreateTest() override { return new TestClass; }
0456 };
0457
0458 #ifdef GTEST_OS_WINDOWS
0459
0460
0461
0462
0463
0464 GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr,
0465 long hr);
0466 GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr,
0467 long hr);
0468
0469 #endif
0470
0471
0472 using SetUpTestSuiteFunc = void (*)();
0473 using TearDownTestSuiteFunc = void (*)();
0474
0475 struct CodeLocation {
0476 CodeLocation(std::string a_file, int a_line)
0477 : file(std::move(a_file)), line(a_line) {}
0478
0479 std::string file;
0480 int line;
0481 };
0482
0483
0484
0485
0486
0487 using SetUpTearDownSuiteFuncType = void (*)();
0488
0489 inline SetUpTearDownSuiteFuncType GetNotDefaultOrNull(
0490 SetUpTearDownSuiteFuncType a, SetUpTearDownSuiteFuncType def) {
0491 return a == def ? nullptr : a;
0492 }
0493
0494 template <typename T>
0495
0496
0497
0498 struct SuiteApiResolver : T {
0499
0500
0501 using Test =
0502 typename std::conditional<sizeof(T) != 0, ::testing::Test, void>::type;
0503
0504 static SetUpTearDownSuiteFuncType GetSetUpCaseOrSuite(const char* filename,
0505 int line_num) {
0506 #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
0507 SetUpTearDownSuiteFuncType test_case_fp =
0508 GetNotDefaultOrNull(&T::SetUpTestCase, &Test::SetUpTestCase);
0509 SetUpTearDownSuiteFuncType test_suite_fp =
0510 GetNotDefaultOrNull(&T::SetUpTestSuite, &Test::SetUpTestSuite);
0511
0512 GTEST_CHECK_(!test_case_fp || !test_suite_fp)
0513 << "Test can not provide both SetUpTestSuite and SetUpTestCase, please "
0514 "make sure there is only one present at "
0515 << filename << ":" << line_num;
0516
0517 return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
0518 #else
0519 (void)(filename);
0520 (void)(line_num);
0521 return &T::SetUpTestSuite;
0522 #endif
0523 }
0524
0525 static SetUpTearDownSuiteFuncType GetTearDownCaseOrSuite(const char* filename,
0526 int line_num) {
0527 #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
0528 SetUpTearDownSuiteFuncType test_case_fp =
0529 GetNotDefaultOrNull(&T::TearDownTestCase, &Test::TearDownTestCase);
0530 SetUpTearDownSuiteFuncType test_suite_fp =
0531 GetNotDefaultOrNull(&T::TearDownTestSuite, &Test::TearDownTestSuite);
0532
0533 GTEST_CHECK_(!test_case_fp || !test_suite_fp)
0534 << "Test can not provide both TearDownTestSuite and TearDownTestCase,"
0535 " please make sure there is only one present at"
0536 << filename << ":" << line_num;
0537
0538 return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
0539 #else
0540 (void)(filename);
0541 (void)(line_num);
0542 return &T::TearDownTestSuite;
0543 #endif
0544 }
0545 };
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565 GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
0566 std::string test_suite_name, const char* name, const char* type_param,
0567 const char* value_param, CodeLocation code_location,
0568 TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
0569 TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory);
0570
0571
0572
0573
0574 GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr);
0575
0576 GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
0577 )
0578
0579
0580 class GTEST_API_ [[nodiscard]] TypedTestSuitePState {
0581 public:
0582 TypedTestSuitePState() : registered_(false) {}
0583
0584
0585
0586
0587 bool AddTestName(const char* file, int line, const char* case_name,
0588 const char* test_name) {
0589 if (registered_) {
0590 fprintf(stderr,
0591 "%s Test %s must be defined before "
0592 "REGISTER_TYPED_TEST_SUITE_P(%s, ...).\n",
0593 FormatFileLocation(file, line).c_str(), test_name, case_name);
0594 fflush(stderr);
0595 posix::Abort();
0596 }
0597 registered_tests_.emplace(test_name, CodeLocation(file, line));
0598 return true;
0599 }
0600
0601 bool TestExists(const std::string& test_name) const {
0602 return registered_tests_.count(test_name) > 0;
0603 }
0604
0605 const CodeLocation& GetCodeLocation(const std::string& test_name) const {
0606 RegisteredTestsMap::const_iterator it = registered_tests_.find(test_name);
0607 GTEST_CHECK_(it != registered_tests_.end());
0608 return it->second;
0609 }
0610
0611
0612
0613
0614 const char* VerifyRegisteredTestNames(const char* test_suite_name,
0615 const char* file, int line,
0616 const char* registered_tests);
0617
0618 private:
0619 typedef ::std::map<std::string, CodeLocation, std::less<>> RegisteredTestsMap;
0620
0621 bool registered_;
0622 RegisteredTestsMap registered_tests_;
0623 };
0624
0625
0626 #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
0627 using TypedTestCasePState = TypedTestSuitePState;
0628 #endif
0629
0630 GTEST_DISABLE_MSC_WARNINGS_POP_()
0631
0632
0633
0634 inline const char* SkipComma(const char* str) {
0635 const char* comma = strchr(str, ',');
0636 if (comma == nullptr) {
0637 return nullptr;
0638 }
0639 while (IsSpace(*(++comma))) {
0640 }
0641 return comma;
0642 }
0643
0644
0645
0646 inline std::string GetPrefixUntilComma(const char* str) {
0647 const char* comma = strchr(str, ',');
0648 return comma == nullptr ? str : std::string(str, comma);
0649 }
0650
0651
0652
0653 void SplitString(const ::std::string& str, char delimiter,
0654 ::std::vector<::std::string>* dest);
0655
0656
0657
0658 struct DefaultNameGenerator {
0659 template <typename T>
0660 static std::string GetName(int i) {
0661 return StreamableToString(i);
0662 }
0663 };
0664
0665 template <typename Provided = DefaultNameGenerator>
0666 struct NameGeneratorSelector {
0667 typedef Provided type;
0668 };
0669
0670 template <typename NameGenerator>
0671 void GenerateNamesRecursively(internal::None, std::vector<std::string>*, int) {}
0672
0673 template <typename NameGenerator, typename Types>
0674 void GenerateNamesRecursively(Types, std::vector<std::string>* result, int i) {
0675 result->push_back(NameGenerator::template GetName<typename Types::Head>(i));
0676 GenerateNamesRecursively<NameGenerator>(typename Types::Tail(), result,
0677 i + 1);
0678 }
0679
0680 template <typename NameGenerator, typename Types>
0681 std::vector<std::string> GenerateNames() {
0682 std::vector<std::string> result;
0683 GenerateNamesRecursively<NameGenerator>(Types(), &result, 0);
0684 return result;
0685 }
0686
0687
0688
0689
0690
0691
0692
0693
0694 template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>
0695 class [[nodiscard]] TypeParameterizedTest {
0696 public:
0697
0698
0699
0700
0701 static bool Register(const char* prefix, CodeLocation code_location,
0702 const char* case_name, const char* test_names, int index,
0703 const std::vector<std::string>& type_names =
0704 GenerateNames<DefaultNameGenerator, Types>()) {
0705 typedef typename Types::Head Type;
0706 typedef Fixture<Type> FixtureClass;
0707 typedef typename GTEST_BIND_(TestSel, Type) TestClass;
0708
0709
0710
0711 MakeAndRegisterTestInfo(
0712 (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name +
0713 "/" + type_names[static_cast<size_t>(index)]),
0714 StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
0715 GetTypeName<Type>().c_str(),
0716 nullptr,
0717 code_location, GetTypeId<FixtureClass>(),
0718 SuiteApiResolver<TestClass>::GetSetUpCaseOrSuite(
0719 code_location.file.c_str(), code_location.line),
0720 SuiteApiResolver<TestClass>::GetTearDownCaseOrSuite(
0721 code_location.file.c_str(), code_location.line),
0722 new TestFactoryImpl<TestClass>);
0723
0724
0725 return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>::
0726 Register(prefix, std::move(code_location), case_name, test_names,
0727 index + 1, type_names);
0728 }
0729 };
0730
0731
0732 template <GTEST_TEMPLATE_ Fixture, class TestSel>
0733 class [[nodiscard]] TypeParameterizedTest<Fixture, TestSel, internal::None> {
0734 public:
0735 static bool Register(const char* , CodeLocation,
0736 const char* , const char* ,
0737 int ,
0738 const std::vector<std::string>& =
0739 std::vector<std::string>() ) {
0740 return true;
0741 }
0742 };
0743
0744 GTEST_API_ void RegisterTypeParameterizedTestSuite(const char* test_suite_name,
0745 CodeLocation code_location);
0746 GTEST_API_ void RegisterTypeParameterizedTestSuiteInstantiation(
0747 const char* case_name);
0748
0749
0750
0751
0752
0753 template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
0754 class [[nodiscard]] TypeParameterizedTestSuite {
0755 public:
0756 static bool Register(const char* prefix, CodeLocation code_location,
0757 const TypedTestSuitePState* state, const char* case_name,
0758 const char* test_names,
0759 const std::vector<std::string>& type_names =
0760 GenerateNames<DefaultNameGenerator, Types>()) {
0761 RegisterTypeParameterizedTestSuiteInstantiation(case_name);
0762 std::string test_name =
0763 StripTrailingSpaces(GetPrefixUntilComma(test_names));
0764 if (!state->TestExists(test_name)) {
0765 fprintf(stderr, "Failed to get code location for test %s.%s at %s.",
0766 case_name, test_name.c_str(),
0767 FormatFileLocation(code_location.file.c_str(), code_location.line)
0768 .c_str());
0769 fflush(stderr);
0770 posix::Abort();
0771 }
0772 const CodeLocation& test_location = state->GetCodeLocation(test_name);
0773
0774 typedef typename Tests::Head Head;
0775
0776
0777 TypeParameterizedTest<Fixture, Head, Types>::Register(
0778 prefix, test_location, case_name, test_names, 0, type_names);
0779
0780
0781 return TypeParameterizedTestSuite<Fixture, typename Tests::Tail,
0782 Types>::Register(prefix,
0783 std::move(code_location),
0784 state, case_name,
0785 SkipComma(test_names),
0786 type_names);
0787 }
0788 };
0789
0790
0791 template <GTEST_TEMPLATE_ Fixture, typename Types>
0792 class [[nodiscard]] TypeParameterizedTestSuite<Fixture, internal::None, Types> {
0793 public:
0794 static bool Register(const char* , const CodeLocation&,
0795 const TypedTestSuitePState* ,
0796 const char* , const char* ,
0797 const std::vector<std::string>& =
0798 std::vector<std::string>() ) {
0799 return true;
0800 }
0801 };
0802
0803
0804
0805
0806
0807
0808
0809
0810
0811
0812
0813 GTEST_API_ std::string GetCurrentOsStackTraceExceptTop(int skip_count);
0814
0815
0816
0817
0818
0819 GTEST_API_ bool AlwaysTrue();
0820
0821
0822 inline bool AlwaysFalse() { return !AlwaysTrue(); }
0823
0824
0825
0826
0827 struct GTEST_API_ ConstCharPtr {
0828 ConstCharPtr(const char* str) : value(str) {}
0829 operator bool() const { return true; }
0830 const char* value;
0831 };
0832
0833
0834
0835 struct TrueWithString {
0836 TrueWithString() = default;
0837 explicit TrueWithString(const char* str) : value(str) {}
0838 explicit TrueWithString(const std::string& str) : value(str) {}
0839 explicit operator bool() const { return true; }
0840 std::string value;
0841 };
0842
0843
0844
0845
0846
0847
0848 class GTEST_API_ [[nodiscard]] Random {
0849 public:
0850 static const uint32_t kMaxRange = 1u << 31;
0851
0852 explicit Random(uint32_t seed) : state_(seed) {}
0853
0854 void Reseed(uint32_t seed) { state_ = seed; }
0855
0856
0857
0858 uint32_t Generate(uint32_t range);
0859
0860 private:
0861 uint32_t state_;
0862 Random(const Random&) = delete;
0863 Random& operator=(const Random&) = delete;
0864 };
0865
0866
0867 #define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
0868 typename std::remove_const<typename std::remove_reference<T>::type>::type
0869
0870
0871
0872
0873 template <typename T>
0874 class [[nodiscard]] HasDebugStringAndShortDebugString {
0875 private:
0876 template <typename C>
0877 static auto CheckDebugString(C*) -> typename std::is_same<
0878 std::string, decltype(std::declval<const C>().DebugString())>::type;
0879 template <typename>
0880 static std::false_type CheckDebugString(...);
0881
0882 template <typename C>
0883 static auto CheckShortDebugString(C*) -> typename std::is_same<
0884 std::string, decltype(std::declval<const C>().ShortDebugString())>::type;
0885 template <typename>
0886 static std::false_type CheckShortDebugString(...);
0887
0888 using HasDebugStringType = decltype(CheckDebugString<T>(nullptr));
0889 using HasShortDebugStringType = decltype(CheckShortDebugString<T>(nullptr));
0890
0891 public:
0892 static constexpr bool value =
0893 HasDebugStringType::value && HasShortDebugStringType::value;
0894 };
0895
0896
0897
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914
0915
0916
0917
0918
0919
0920 typedef int IsContainer;
0921 template <class C,
0922 class Iterator = decltype(::std::declval<const C&>().begin()),
0923 class = decltype(::std::declval<const C&>().end()),
0924 class = decltype(++::std::declval<Iterator&>()),
0925 class = decltype(*::std::declval<Iterator>()),
0926 class = typename C::const_iterator>
0927 IsContainer IsContainerTest(int ) {
0928 return 0;
0929 }
0930
0931 typedef char IsNotContainer;
0932 template <class C>
0933 IsNotContainer IsContainerTest(long ) {
0934 return '\0';
0935 }
0936
0937
0938
0939
0940
0941 template <typename T>
0942 struct IsHashTable {
0943 private:
0944 template <typename U>
0945 static char test(typename U::hasher*, typename U::reverse_iterator*);
0946 template <typename U>
0947 static int test(typename U::hasher*, ...);
0948 template <typename U>
0949 static char test(...);
0950
0951 public:
0952 static const bool value = sizeof(test<T>(nullptr, nullptr)) == sizeof(int);
0953 };
0954
0955 template <typename T>
0956 const bool IsHashTable<T>::value;
0957
0958 template <typename C,
0959 bool = sizeof(IsContainerTest<C>(0)) == sizeof(IsContainer)>
0960 struct IsRecursiveContainerImpl;
0961
0962 template <typename C>
0963 struct IsRecursiveContainerImpl<C, false> : public std::false_type {};
0964
0965
0966
0967
0968
0969 template <typename C>
0970 struct IsRecursiveContainerImpl<C, true> {
0971 using value_type = decltype(*std::declval<typename C::const_iterator>());
0972 using type =
0973 std::is_same<typename std::remove_const<
0974 typename std::remove_reference<value_type>::type>::type,
0975 C>;
0976 };
0977
0978
0979
0980
0981
0982
0983
0984 template <typename C>
0985 struct IsRecursiveContainer : public IsRecursiveContainerImpl<C>::type {};
0986
0987
0988
0989
0990
0991
0992
0993 template <typename T, typename U>
0994 bool ArrayEq(const T* lhs, size_t size, const U* rhs);
0995
0996
0997 template <typename T, typename U>
0998 inline bool ArrayEq(const T& lhs, const U& rhs) {
0999 return lhs == rhs;
1000 }
1001
1002
1003 template <typename T, typename U, size_t N>
1004 inline bool ArrayEq(const T (&lhs)[N], const U (&rhs)[N]) {
1005 return internal::ArrayEq(lhs, N, rhs);
1006 }
1007
1008
1009
1010
1011 template <typename T, typename U>
1012 bool ArrayEq(const T* lhs, size_t size, const U* rhs) {
1013 for (size_t i = 0; i != size; i++) {
1014 if (!internal::ArrayEq(lhs[i], rhs[i])) return false;
1015 }
1016 return true;
1017 }
1018
1019
1020
1021 template <typename Iter, typename Element>
1022 Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) {
1023 for (Iter it = begin; it != end; ++it) {
1024 if (internal::ArrayEq(*it, elem)) return it;
1025 }
1026 return end;
1027 }
1028
1029
1030
1031
1032
1033 template <typename T, typename U>
1034 void CopyArray(const T* from, size_t size, U* to);
1035
1036
1037 template <typename T, typename U>
1038 inline void CopyArray(const T& from, U* to) {
1039 *to = from;
1040 }
1041
1042
1043 template <typename T, typename U, size_t N>
1044 inline void CopyArray(const T (&from)[N], U (*to)[N]) {
1045 internal::CopyArray(from, N, *to);
1046 }
1047
1048
1049
1050
1051 template <typename T, typename U>
1052 void CopyArray(const T* from, size_t size, U* to) {
1053 for (size_t i = 0; i != size; i++) {
1054 internal::CopyArray(from[i], to + i);
1055 }
1056 }
1057
1058
1059
1060
1061
1062 struct RelationToSourceReference {};
1063 struct RelationToSourceCopy {};
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073 template <typename Element>
1074 class [[nodiscard]] NativeArray {
1075 public:
1076
1077 typedef Element value_type;
1078 typedef Element* iterator;
1079 typedef const Element* const_iterator;
1080
1081
1082 NativeArray(const Element* array, size_t count, RelationToSourceReference) {
1083 InitRef(array, count);
1084 }
1085
1086
1087 NativeArray(const Element* array, size_t count, RelationToSourceCopy) {
1088 InitCopy(array, count);
1089 }
1090
1091
1092 NativeArray(const NativeArray& rhs) {
1093 (this->*rhs.clone_)(rhs.array_, rhs.size_);
1094 }
1095
1096 ~NativeArray() {
1097 if (clone_ != &NativeArray::InitRef) delete[] array_;
1098 }
1099
1100
1101 size_t size() const { return size_; }
1102 const_iterator begin() const { return array_; }
1103 const_iterator end() const { return array_ + size_; }
1104 bool operator==(const NativeArray& rhs) const {
1105 return size() == rhs.size() && ArrayEq(begin(), size(), rhs.begin());
1106 }
1107
1108 private:
1109 static_assert(!std::is_const<Element>::value, "Type must not be const");
1110 static_assert(!std::is_reference<Element>::value,
1111 "Type must not be a reference");
1112
1113
1114 void InitCopy(const Element* array, size_t a_size) {
1115 Element* const copy = new Element[a_size];
1116 CopyArray(array, a_size, copy);
1117 array_ = copy;
1118 size_ = a_size;
1119 clone_ = &NativeArray::InitCopy;
1120 }
1121
1122
1123 void InitRef(const Element* array, size_t a_size) {
1124 array_ = array;
1125 size_ = a_size;
1126 clone_ = &NativeArray::InitRef;
1127 }
1128
1129 const Element* array_;
1130 size_t size_;
1131 void (NativeArray::*clone_)(const Element*, size_t);
1132 };
1133
1134 template <size_t>
1135 struct Ignore {
1136 Ignore(...);
1137 };
1138
1139 template <typename>
1140 struct ElemFromListImpl;
1141 template <size_t... I>
1142 struct ElemFromListImpl<std::index_sequence<I...>> {
1143
1144
1145
1146
1147 template <typename R>
1148 static R Apply(Ignore<0 * I>..., R (*)(), ...);
1149 };
1150
1151 template <size_t N, typename... T>
1152 struct ElemFromList {
1153 using type = decltype(ElemFromListImpl<std::make_index_sequence<N>>::Apply(
1154 static_cast<T (*)()>(nullptr)...));
1155 };
1156
1157 struct FlatTupleConstructTag {};
1158
1159 template <typename... T>
1160 class [[nodiscard]] FlatTuple;
1161
1162 template <typename Derived, size_t I>
1163 struct FlatTupleElemBase;
1164
1165 template <typename... T, size_t I>
1166 struct FlatTupleElemBase<FlatTuple<T...>, I> {
1167 using value_type = typename ElemFromList<I, T...>::type;
1168 FlatTupleElemBase() = default;
1169 template <typename Arg>
1170 explicit FlatTupleElemBase(FlatTupleConstructTag, Arg&& t)
1171 : value(std::forward<Arg>(t)) {}
1172 value_type value;
1173 };
1174
1175 template <typename Derived, typename Idx>
1176 struct FlatTupleBase;
1177
1178 template <size_t... Idx, typename... T>
1179 struct FlatTupleBase<FlatTuple<T...>, std::index_sequence<Idx...>>
1180 : FlatTupleElemBase<FlatTuple<T...>, Idx>... {
1181 using Indices = std::index_sequence<Idx...>;
1182 FlatTupleBase() = default;
1183 template <typename... Args>
1184 explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args)
1185 : FlatTupleElemBase<FlatTuple<T...>, Idx>(FlatTupleConstructTag{},
1186 std::forward<Args>(args))... {}
1187
1188 template <size_t I>
1189 const typename ElemFromList<I, T...>::type& Get() const {
1190 return FlatTupleElemBase<FlatTuple<T...>, I>::value;
1191 }
1192
1193 template <size_t I>
1194 typename ElemFromList<I, T...>::type& Get() {
1195 return FlatTupleElemBase<FlatTuple<T...>, I>::value;
1196 }
1197
1198 template <typename F>
1199 auto Apply(F&& f) -> decltype(std::forward<F>(f)(this->Get<Idx>()...)) {
1200 return std::forward<F>(f)(Get<Idx>()...);
1201 }
1202
1203 template <typename F>
1204 auto Apply(F&& f) const -> decltype(std::forward<F>(f)(this->Get<Idx>()...)) {
1205 return std::forward<F>(f)(Get<Idx>()...);
1206 }
1207 };
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218 template <typename... T>
1219 class [[nodiscard]] FlatTuple
1220 : private FlatTupleBase<FlatTuple<T...>,
1221 std::make_index_sequence<sizeof...(T)>> {
1222 using Indices =
1223 typename FlatTupleBase<FlatTuple<T...>,
1224 std::make_index_sequence<sizeof...(T)>>::Indices;
1225
1226 public:
1227 FlatTuple() = default;
1228 template <typename... Args>
1229 explicit FlatTuple(FlatTupleConstructTag tag, Args&&... args)
1230 : FlatTuple::FlatTupleBase(tag, std::forward<Args>(args)...) {}
1231
1232 using FlatTuple::FlatTupleBase::Apply;
1233 using FlatTuple::FlatTupleBase::Get;
1234 };
1235
1236
1237
1238 [[deprecated(
1239 "INSTANTIATE_TEST_CASE_P is deprecated, please use "
1240 "INSTANTIATE_TEST_SUITE_P")]]
1241 constexpr bool InstantiateTestCase_P_IsDeprecated() {
1242 return true;
1243 }
1244
1245 [[deprecated(
1246 "TYPED_TEST_CASE_P is deprecated, please use "
1247 "TYPED_TEST_SUITE_P")]]
1248 constexpr bool TypedTestCase_P_IsDeprecated() {
1249 return true;
1250 }
1251
1252 [[deprecated(
1253 "TYPED_TEST_CASE is deprecated, please use "
1254 "TYPED_TEST_SUITE")]]
1255 constexpr bool TypedTestCaseIsDeprecated() {
1256 return true;
1257 }
1258
1259 [[deprecated(
1260 "REGISTER_TYPED_TEST_CASE_P is deprecated, please use "
1261 "REGISTER_TYPED_TEST_SUITE_P")]]
1262 constexpr bool RegisterTypedTestCase_P_IsDeprecated() {
1263 return true;
1264 }
1265
1266 [[deprecated(
1267 "INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use "
1268 "INSTANTIATE_TYPED_TEST_SUITE_P")]]
1269 constexpr bool InstantiateTypedTestCase_P_IsDeprecated() {
1270 return true;
1271 }
1272
1273 }
1274 }
1275
1276 namespace std {
1277
1278
1279
1280 #ifdef __clang__
1281 #pragma clang diagnostic push
1282 #pragma clang diagnostic ignored "-Wmismatched-tags"
1283 #endif
1284 template <typename... Ts>
1285 struct tuple_size<testing::internal::FlatTuple<Ts...>>
1286 : std::integral_constant<size_t, sizeof...(Ts)> {};
1287 #ifdef __clang__
1288 #pragma clang diagnostic pop
1289 #endif
1290 }
1291
1292 #define GTEST_MESSAGE_AT_(file, line, message, result_type) \
1293 ::testing::internal::AssertHelper(result_type, file, line, message) = \
1294 ::testing::Message()
1295
1296 #define GTEST_MESSAGE_(message, result_type) \
1297 GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type)
1298
1299 #define GTEST_FATAL_FAILURE_(message) \
1300 return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure)
1301
1302 #define GTEST_NONFATAL_FAILURE_(message) \
1303 GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)
1304
1305 #define GTEST_SUCCESS_(message) \
1306 GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)
1307
1308 #define GTEST_SKIP_(message) \
1309 return GTEST_MESSAGE_(message, ::testing::TestPartResult::kSkip)
1310
1311
1312
1313
1314
1315
1316 #define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
1317 if (::testing::internal::AlwaysTrue()) { \
1318 statement; \
1319 } else \
1320 static_assert(true, "")
1321
1322 #if GTEST_HAS_EXCEPTIONS
1323
1324 namespace testing {
1325 namespace internal {
1326
1327 class [[nodiscard]] NeverThrown {
1328 public:
1329 const char* what() const noexcept {
1330 return "this exception should never be thrown";
1331 }
1332 };
1333
1334 }
1335 }
1336
1337 #if GTEST_HAS_RTTI
1338
1339 #define GTEST_EXCEPTION_TYPE_(e) ::testing::internal::GetTypeName(typeid(e))
1340
1341 #else
1342
1343 #define GTEST_EXCEPTION_TYPE_(e) \
1344 std::string { "an std::exception-derived error" }
1345
1346 #endif
1347
1348 #define GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception) \
1349 catch (typename std::conditional< \
1350 std::is_same<typename std::remove_cv<typename std::remove_reference< \
1351 expected_exception>::type>::type, \
1352 std::exception>::value, \
1353 const ::testing::internal::NeverThrown&, const std::exception&>::type \
1354 e) { \
1355 gtest_msg.value = "Expected: " #statement \
1356 " throws an exception of type " #expected_exception \
1357 ".\n Actual: it throws "; \
1358 gtest_msg.value += GTEST_EXCEPTION_TYPE_(e); \
1359 gtest_msg.value += " with description \""; \
1360 gtest_msg.value += e.what(); \
1361 gtest_msg.value += "\"."; \
1362 goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
1363 }
1364
1365 #else
1366
1367 #define GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception)
1368
1369 #endif
1370
1371 #define GTEST_TEST_THROW_(statement, expected_exception, fail) \
1372 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
1373 if (::testing::internal::TrueWithString gtest_msg{}) { \
1374 bool gtest_caught_expected = false; \
1375 try { \
1376 GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
1377 } catch (expected_exception const&) { \
1378 gtest_caught_expected = true; \
1379 } \
1380 GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception) \
1381 catch (...) { \
1382 gtest_msg.value = "Expected: " #statement \
1383 " throws an exception of type " #expected_exception \
1384 ".\n Actual: it throws a different type."; \
1385 goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
1386 } \
1387 if (!gtest_caught_expected) { \
1388 gtest_msg.value = "Expected: " #statement \
1389 " throws an exception of type " #expected_exception \
1390 ".\n Actual: it throws nothing."; \
1391 goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
1392 } \
1393 } else \
1394 GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) \
1395 : fail(gtest_msg.value.c_str())
1396
1397 #if GTEST_HAS_EXCEPTIONS
1398
1399 #define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() \
1400 catch (std::exception const& e) { \
1401 gtest_msg.value = "it throws "; \
1402 gtest_msg.value += GTEST_EXCEPTION_TYPE_(e); \
1403 gtest_msg.value += " with description \""; \
1404 gtest_msg.value += e.what(); \
1405 gtest_msg.value += "\"."; \
1406 goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
1407 }
1408
1409 #else
1410
1411 #define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_()
1412
1413 #endif
1414
1415 #define GTEST_TEST_NO_THROW_(statement, fail) \
1416 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
1417 if (::testing::internal::TrueWithString gtest_msg{}) { \
1418 try { \
1419 GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
1420 } \
1421 GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() \
1422 catch (...) { \
1423 gtest_msg.value = "it throws."; \
1424 goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
1425 } \
1426 } else \
1427 GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__) \
1428 : fail(("Expected: " #statement " doesn't throw an exception.\n" \
1429 " Actual: " + \
1430 gtest_msg.value) \
1431 .c_str())
1432
1433 #define GTEST_TEST_ANY_THROW_(statement, fail) \
1434 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
1435 if (::testing::internal::AlwaysTrue()) { \
1436 bool gtest_caught_any = false; \
1437 try { \
1438 GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
1439 } catch (...) { \
1440 gtest_caught_any = true; \
1441 } \
1442 if (!gtest_caught_any) { \
1443 goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \
1444 } \
1445 } else \
1446 GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__) \
1447 : fail("Expected: " #statement \
1448 " throws an exception.\n" \
1449 " Actual: it doesn't.")
1450
1451
1452
1453
1454 #define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
1455 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
1456 if (const ::testing::internal::AssertionResultExpectation gtest_are_ = { \
1457 ::testing::AssertionResult(expression), expected}) \
1458 ; \
1459 else \
1460 fail(::testing::internal::GetBoolAssertionFailureMessage( \
1461 gtest_are_.assertion_result, text, #actual, #expected))
1462
1463 #define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
1464 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
1465 if (::testing::internal::AlwaysTrue()) { \
1466 const ::testing::internal::HasNewFatalFailureHelper \
1467 gtest_fatal_failure_checker; \
1468 GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
1469 if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \
1470 goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \
1471 } \
1472 } else \
1473 GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__) \
1474 : fail("Expected: " #statement \
1475 " doesn't generate new fatal " \
1476 "failures in the current thread.\n" \
1477 " Actual: it does.")
1478
1479
1480 #define GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
1481 test_suite_name##_##test_name##_Test
1482
1483
1484 #define GTEST_TEST_(test_suite_name, test_name, parent_class, parent_id) \
1485 static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) > 1, \
1486 "test_suite_name must not be empty"); \
1487 static_assert(sizeof(GTEST_STRINGIFY_(test_name)) > 1, \
1488 "test_name must not be empty"); \
1489 class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
1490 : public parent_class { \
1491 public: \
1492 GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() = default; \
1493 ~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override = default; \
1494 GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
1495 (const GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &) = delete; \
1496 GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \
1497 const GTEST_TEST_CLASS_NAME_(test_suite_name, \
1498 test_name) &) = delete; \
1499 GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
1500 (GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &&) noexcept = delete; \
1501 GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \
1502 GTEST_TEST_CLASS_NAME_(test_suite_name, \
1503 test_name) &&) noexcept = delete; \
1504 \
1505 private: \
1506 void TestBody() override; \
1507 [[maybe_unused]] static ::testing::TestInfo* const test_info_; \
1508 }; \
1509 \
1510 ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \
1511 test_name)::test_info_ = \
1512 ::testing::internal::MakeAndRegisterTestInfo( \
1513 #test_suite_name, #test_name, nullptr, nullptr, \
1514 ::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id), \
1515 ::testing::internal::SuiteApiResolver< \
1516 parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__), \
1517 ::testing::internal::SuiteApiResolver< \
1518 parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__), \
1519 new ::testing::internal::TestFactoryImpl<GTEST_TEST_CLASS_NAME_( \
1520 test_suite_name, test_name)>); \
1521 void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
1522
1523 #endif