| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent c8305f6 commit 69959d0
8 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -129,7 +129,7 @@ namespace testing { | |||
| 129 | 129 | // | |
| 130 | 130 | // Expected: Foo() is even | |
| 131 | 131 | // Actual: it's 5 | |
| 132 | - // | ||
| 132 | + | ||
| 133 | 133 | class GTEST_API_ AssertionResult { | |
| 134 | 134 | public: | |
| 135 | 135 | // Copy constructor. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -71,7 +71,7 @@ class GTEST_API_ FilePath { | |||
| 71 | 71 | public: | |
| 72 | 72 | FilePath() : pathname_("") {} | |
| 73 | 73 | FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {} | |
| 74 | - FilePath(FilePath&& rhs) : pathname_(std::move(rhs.pathname_)) {} | ||
| 74 | + FilePath(FilePath&& rhs) noexcept : pathname_(std::move(rhs.pathname_)) {} | ||
| 75 | 75 | ||
| 76 | 76 | explicit FilePath(std::string pathname) : pathname_(std::move(pathname)) { | |
| 77 | 77 | Normalize(); | |
@@ -81,7 +81,7 @@ class GTEST_API_ FilePath { | |||
| 81 | 81 | Set(rhs); | |
| 82 | 82 | return *this; | |
| 83 | 83 | } | |
| 84 | - FilePath& operator=(FilePath&& rhs) { | ||
| 84 | + FilePath& operator=(FilePath&& rhs) noexcept { | ||
| 85 | 85 | pathname_ = std::move(rhs.pathname_); | |
| 86 | 86 | return *this; | |
| 87 | 87 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1137,40 +1137,6 @@ class NativeArray { | |||
| 1137 | 1137 | void (NativeArray::*clone_)(const Element*, size_t); | |
| 1138 | 1138 | }; | |
| 1139 | 1139 | ||
| 1140 | - // Backport of std::index_sequence. | ||
| 1141 | - template <size_t... Is> | ||
| 1142 | - struct IndexSequence { | ||
| 1143 | - using type = IndexSequence; | ||
| 1144 | - }; | ||
| 1145 | - | ||
| 1146 | - // Double the IndexSequence, and one if plus_one is true. | ||
| 1147 | - template <bool plus_one, typename T, size_t sizeofT> | ||
| 1148 | - struct DoubleSequence; | ||
| 1149 | - template <size_t... I, size_t sizeofT> | ||
| 1150 | - struct DoubleSequence<true, IndexSequence<I...>, sizeofT> { | ||
| 1151 | - using type = IndexSequence<I..., (sizeofT + I)..., 2 * sizeofT>; | ||
| 1152 | - }; | ||
| 1153 | - template <size_t... I, size_t sizeofT> | ||
| 1154 | - struct DoubleSequence<false, IndexSequence<I...>, sizeofT> { | ||
| 1155 | - using type = IndexSequence<I..., (sizeofT + I)...>; | ||
| 1156 | - }; | ||
| 1157 | - | ||
| 1158 | - // Backport of std::make_index_sequence. | ||
| 1159 | - // It uses O(ln(N)) instantiation depth. | ||
| 1160 | - template <size_t N> | ||
| 1161 | - struct MakeIndexSequenceImpl | ||
| 1162 | - : DoubleSequence<N % 2 == 1, typename MakeIndexSequenceImpl<N / 2>::type, | ||
| 1163 | - N / 2>::type {}; | ||
| 1164 | - | ||
| 1165 | - template <> | ||
| 1166 | - struct MakeIndexSequenceImpl<0> : IndexSequence<> {}; | ||
| 1167 | - | ||
| 1168 | - template <size_t N> | ||
| 1169 | - using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::type; | ||
| 1170 | - | ||
| 1171 | - template <typename... T> | ||
| 1172 | - using IndexSequenceFor = typename MakeIndexSequence<sizeof...(T)>::type; | ||
| 1173 | - | ||
| 1174 | 1140 | template <size_t> | |
| 1175 | 1141 | struct Ignore { | |
| 1176 | 1142 | Ignore(...); // NOLINT | |
@@ -1179,7 +1145,7 @@ struct Ignore { | |||
| 1179 | 1145 | template <typename> | |
| 1180 | 1146 | struct ElemFromListImpl; | |
| 1181 | 1147 | template <size_t... I> | |
| 1182 | - struct ElemFromListImpl<IndexSequence<I...>> { | ||
| 1148 | + struct ElemFromListImpl<std::index_sequence<I...>> { | ||
| 1183 | 1149 | // We make Ignore a template to solve a problem with MSVC. | |
| 1184 | 1150 | // A non-template Ignore would work fine with `decltype(Ignore(I))...`, but | |
| 1185 | 1151 | // MSVC doesn't understand how to deal with that pack expansion. | |
@@ -1190,9 +1156,8 @@ struct ElemFromListImpl<IndexSequence<I...>> { | |||
| 1190 | 1156 | ||
| 1191 | 1157 | template <size_t N, typename... T> | |
| 1192 | 1158 | struct ElemFromList { | |
| 1193 | - using type = | ||
| 1194 | - decltype(ElemFromListImpl<typename MakeIndexSequence<N>::type>::Apply( | ||
| 1195 | - static_cast<T (*)()>(nullptr)...)); | ||
| 1159 | + using type = decltype(ElemFromListImpl<std::make_index_sequence<N>>::Apply( | ||
| 1160 | + static_cast<T (*)()>(nullptr)...)); | ||
| 1196 | 1161 | }; | |
| 1197 | 1162 | ||
| 1198 | 1163 | struct FlatTupleConstructTag {}; | |
@@ -1217,9 +1182,9 @@ template <typename Derived, typename Idx> | |||
| 1217 | 1182 | struct FlatTupleBase; | |
| 1218 | 1183 | ||
| 1219 | 1184 | template <size_t... Idx, typename... T> | |
| 1220 | - struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>> | ||
| 1185 | + struct FlatTupleBase<FlatTuple<T...>, std::index_sequence<Idx...>> | ||
| 1221 | 1186 | : FlatTupleElemBase<FlatTuple<T...>, Idx>... { | |
| 1222 | - using Indices = IndexSequence<Idx...>; | ||
| 1187 | + using Indices = std::index_sequence<Idx...>; | ||
| 1223 | 1188 | FlatTupleBase() = default; | |
| 1224 | 1189 | template <typename... Args> | |
| 1225 | 1190 | explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args) | |
@@ -1254,14 +1219,15 @@ struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>> | |||
| 1254 | 1219 | // implementations. | |
| 1255 | 1220 | // FlatTuple and ElemFromList are not recursive and have a fixed depth | |
| 1256 | 1221 | // regardless of T... | |
| 1257 | - // MakeIndexSequence, on the other hand, it is recursive but with an | ||
| 1222 | + // std::make_index_sequence, on the other hand, it is recursive but with an | ||
| 1258 | 1223 | // instantiation depth of O(ln(N)). | |
| 1259 | 1224 | template <typename... T> | |
| 1260 | 1225 | class FlatTuple | |
| 1261 | 1226 | : private FlatTupleBase<FlatTuple<T...>, | |
| 1262 | - typename MakeIndexSequence<sizeof...(T)>::type> { | ||
| 1263 | - using Indices = typename FlatTupleBase< | ||
| 1264 | - FlatTuple<T...>, typename MakeIndexSequence<sizeof...(T)>::type>::Indices; | ||
| 1227 | + std::make_index_sequence<sizeof...(T)>> { | ||
| 1228 | + using Indices = | ||
| 1229 | + typename FlatTupleBase<FlatTuple<T...>, | ||
| 1230 | + std::make_index_sequence<sizeof...(T)>>::Indices; | ||
| 1265 | 1231 | ||
| 1266 | 1232 | public: | |
| 1267 | 1233 | FlatTuple() = default; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -807,12 +807,12 @@ class ValueArray { | |||
| 807 | 807 | ||
| 808 | 808 | template <typename T> | |
| 809 | 809 | operator ParamGenerator<T>() const { // NOLINT | |
| 810 | - return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>())); | ||
| 810 | + return ValuesIn(MakeVector<T>(std::make_index_sequence<sizeof...(Ts)>())); | ||
| 811 | 811 | } | |
| 812 | 812 | ||
| 813 | 813 | private: | |
| 814 | 814 | template <typename T, size_t... I> | |
| 815 | - std::vector<T> MakeVector(IndexSequence<I...>) const { | ||
| 815 | + std::vector<T> MakeVector(std::index_sequence<I...>) const { | ||
| 816 | 816 | return std::vector<T>{static_cast<T>(v_.template Get<I>())...}; | |
| 817 | 817 | } | |
| 818 | 818 | ||
@@ -842,7 +842,7 @@ class CartesianProductGenerator | |||
| 842 | 842 | template <class I> | |
| 843 | 843 | class IteratorImpl; | |
| 844 | 844 | template <size_t... I> | |
| 845 | - class IteratorImpl<IndexSequence<I...>> | ||
| 845 | + class IteratorImpl<std::index_sequence<I...>> | ||
| 846 | 846 | : public ParamIteratorInterface<ParamType> { | |
| 847 | 847 | public: | |
| 848 | 848 | IteratorImpl(const ParamGeneratorInterface<ParamType>* base, | |
@@ -933,7 +933,7 @@ class CartesianProductGenerator | |||
| 933 | 933 | std::shared_ptr<ParamType> current_value_; | |
| 934 | 934 | }; | |
| 935 | 935 | ||
| 936 | - using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>; | ||
| 936 | + using Iterator = IteratorImpl<std::make_index_sequence<sizeof...(T)>>; | ||
| 937 | 937 | ||
| 938 | 938 | std::tuple<ParamGenerator<T>...> generators_; | |
| 939 | 939 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -56,6 +56,8 @@ | |||
| 56 | 56 | #elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE) | |
| 57 | 57 | #define GTEST_OS_WINDOWS_PHONE 1 | |
| 58 | 58 | #define GTEST_OS_WINDOWS_TV_TITLE 1 | |
| 59 | + #elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_GAMES) | ||
| 60 | + #define GTEST_OS_WINDOWS_GAMES 1 | ||
| 59 | 61 | #else | |
| 60 | 62 | // WINAPI_FAMILY defined but no known partition matched. | |
| 61 | 63 | // Default to desktop. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -340,8 +340,8 @@ | |||
| 340 | 340 | ||
| 341 | 341 | #if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS) | |
| 342 | 342 | #define GTEST_INTERNAL_HAS_ABSL_FLAGS // Used only in this file. | |
| 343 | - #include "absl/flags/flag.h" | ||
| 344 | 343 | #include "absl/flags/declare.h" | |
| 344 | + #include "absl/flags/flag.h" | ||
| 345 | 345 | #include "absl/flags/reflection.h" | |
| 346 | 346 | #endif | |
| 347 | 347 | ||
@@ -659,9 +659,9 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; | |||
| 659 | 659 | // platforms except known mobile / embedded ones. Also, if the port doesn't have | |
| 660 | 660 | // a file system, stream redirection is not supported. | |
| 661 | 661 | #if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \ | |
| 662 | - defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_ESP8266) || \ | ||
| 663 | - defined(GTEST_OS_XTENSA) || defined(GTEST_OS_QURT) || \ | ||
| 664 | - !GTEST_HAS_FILE_SYSTEM | ||
| 662 | + defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_WINDOWS_GAMES) || \ | ||
| 663 | + defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) || \ | ||
| 664 | + defined(GTEST_OS_QURT) || !GTEST_HAS_FILE_SYSTEM | ||
| 665 | 665 | #define GTEST_HAS_STREAM_REDIRECTION 0 | |
| 666 | 666 | #else | |
| 667 | 667 | #define GTEST_HAS_STREAM_REDIRECTION 1 | |
@@ -2108,8 +2108,9 @@ GTEST_DISABLE_MSC_DEPRECATED_PUSH_() | |||
| 2108 | 2108 | // defined there. | |
| 2109 | 2109 | #if GTEST_HAS_FILE_SYSTEM | |
| 2110 | 2110 | #if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \ | |
| 2111 | - !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_ESP8266) && \ | ||
| 2112 | - !defined(GTEST_OS_XTENSA) && !defined(GTEST_OS_QURT) | ||
| 2111 | + !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) && \ | ||
| 2112 | + !defined(GTEST_OS_ESP8266) && !defined(GTEST_OS_XTENSA) && \ | ||
| 2113 | + !defined(GTEST_OS_QURT) | ||
| 2113 | 2114 | inline int ChDir(const char* dir) { return chdir(dir); } | |
| 2114 | 2115 | #endif | |
| 2115 | 2116 | inline FILE* FOpen(const char* path, const char* mode) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -587,25 +587,32 @@ class ThreadLocalRegistryImpl { | |||
| 587 | 587 | // thread's ID. | |
| 588 | 588 | typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals; | |
| 589 | 589 | ||
| 590 | - // Holds the thread id and thread handle that we pass from | ||
| 591 | - // StartWatcherThreadFor to WatcherThreadFunc. | ||
| 592 | - typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle; | ||
| 590 | + struct WatcherThreadParams { | ||
| 591 | + DWORD thread_id; | ||
| 592 | + HANDLE handle; | ||
| 593 | + Notification has_initialized; | ||
| 594 | + }; | ||
| 593 | 595 | ||
| 594 | 596 | static void StartWatcherThreadFor(DWORD thread_id) { | |
| 595 | 597 | // The returned handle will be kept in thread_map and closed by | |
| 596 | 598 | // watcher_thread in WatcherThreadFunc. | |
| 597 | 599 | HANDLE thread = | |
| 598 | 600 | ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id); | |
| 599 | 601 | GTEST_CHECK_(thread != nullptr); | |
| 602 | + | ||
| 603 | + WatcherThreadParams* watcher_thread_params = new WatcherThreadParams; | ||
| 604 | + watcher_thread_params->thread_id = thread_id; | ||
| 605 | + watcher_thread_params->handle = thread; | ||
| 606 | + | ||
| 600 | 607 | // We need to pass a valid thread ID pointer into CreateThread for it | |
| 601 | 608 | // to work correctly under Win98. | |
| 602 | 609 | DWORD watcher_thread_id; | |
| 603 | - HANDLE watcher_thread = ::CreateThread( | ||
| 604 | - nullptr, // Default security. | ||
| 605 | - 0, // Default stack size | ||
| 606 | - &ThreadLocalRegistryImpl::WatcherThreadFunc, | ||
| 607 | - reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)), | ||
| 608 | - CREATE_SUSPENDED, &watcher_thread_id); | ||
| 610 | + HANDLE watcher_thread = | ||
| 611 | + ::CreateThread(nullptr, // Default security. | ||
| 612 | + 0, // Default stack size | ||
| 613 | + &ThreadLocalRegistryImpl::WatcherThreadFunc, | ||
| 614 | + reinterpret_cast<LPVOID>(watcher_thread_params), | ||
| 615 | + CREATE_SUSPENDED, &watcher_thread_id); | ||
| 609 | 616 | GTEST_CHECK_(watcher_thread != nullptr) | |
| 610 | 617 | << "CreateThread failed with error " << ::GetLastError() << "."; | |
| 611 | 618 | // Give the watcher thread the same priority as ours to avoid being | |
@@ -614,17 +621,25 @@ class ThreadLocalRegistryImpl { | |||
| 614 | 621 | ::GetThreadPriority(::GetCurrentThread())); | |
| 615 | 622 | ::ResumeThread(watcher_thread); | |
| 616 | 623 | ::CloseHandle(watcher_thread); | |
| 624 | + | ||
| 625 | + // Wait for the watcher thread to start to avoid race conditions. | ||
| 626 | + // One specific race condition that can happen is that we have returned | ||
| 627 | + // from main and have started to tear down, the newly spawned watcher | ||
| 628 | + // thread may access already-freed variables, like global shared_ptrs. | ||
| 629 | + watcher_thread_params->has_initialized.WaitForNotification(); | ||
| 617 | 630 | } | |
| 618 | 631 | ||
| 619 | 632 | // Monitors exit from a given thread and notifies those | |
| 620 | 633 | // ThreadIdToThreadLocals about thread termination. | |
| 621 | 634 | static DWORD WINAPI WatcherThreadFunc(LPVOID param) { | |
| 622 | - const ThreadIdAndHandle* tah = | ||
| 623 | - reinterpret_cast<const ThreadIdAndHandle*>(param); | ||
| 624 | - GTEST_CHECK_(::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); | ||
| 625 | - OnThreadExit(tah->first); | ||
| 626 | - ::CloseHandle(tah->second); | ||
| 627 | - delete tah; | ||
| 635 | + WatcherThreadParams* watcher_thread_params = | ||
| 636 | + reinterpret_cast<WatcherThreadParams*>(param); | ||
| 637 | + watcher_thread_params->has_initialized.Notify(); | ||
| 638 | + GTEST_CHECK_(::WaitForSingleObject(watcher_thread_params->handle, | ||
| 639 | + INFINITE) == WAIT_OBJECT_0); | ||
| 640 | + OnThreadExit(watcher_thread_params->thread_id); | ||
| 641 | + ::CloseHandle(watcher_thread_params->handle); | ||
| 642 | + delete watcher_thread_params; | ||
| 628 | 643 | return 0; | |
| 629 | 644 | } | |
| 630 | 645 | ||
@@ -1033,12 +1048,12 @@ GTestLog::~GTestLog() { | |||
| 1033 | 1048 | } | |
| 1034 | 1049 | } | |
| 1035 | 1050 | ||
| 1051 | + #if GTEST_HAS_STREAM_REDIRECTION | ||
| 1052 | + | ||
| 1036 | 1053 | // Disable Microsoft deprecation warnings for POSIX functions called from | |
| 1037 | 1054 | // this class (creat, dup, dup2, and close) | |
| 1038 | 1055 | GTEST_DISABLE_MSC_DEPRECATED_PUSH_() | |
| 1039 | 1056 | ||
| 1040 | - #if GTEST_HAS_STREAM_REDIRECTION | ||
| 1041 | - | ||
| 1042 | 1057 | namespace { | |
| 1043 | 1058 | ||
| 1044 | 1059 | #if defined(GTEST_OS_LINUX_ANDROID) || defined(GTEST_OS_IOS) | |
@@ -1333,8 +1348,8 @@ bool ParseInt32(const Message& src_text, const char* str, int32_t* value) { | |||
| 1333 | 1348 | ) { | |
| 1334 | 1349 | Message msg; | |
| 1335 | 1350 | msg << "WARNING: " << src_text | |
| 1336 | - << " is expected to be a 32-bit integer, but actually" | ||
| 1337 | - << " has value " << str << ", which overflows.\n"; | ||
| 1351 | + << " is expected to be a 32-bit integer, but actually" << " has value " | ||
| 1352 | + << str << ", which overflows.\n"; | ||
| 1338 | 1353 | printf("%s", msg.GetString().c_str()); | |
| 1339 | 1354 | fflush(stdout); | |
| 1340 | 1355 | return false; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments