diff --git a/3rdparty/googletest/CONTRIBUTING.md b/3rdparty/googletest/CONTRIBUTING.md index 8bed14b266..ab5a47bf55 100644 --- a/3rdparty/googletest/CONTRIBUTING.md +++ b/3rdparty/googletest/CONTRIBUTING.md @@ -47,11 +47,11 @@ PR is acceptable as an alternative. ## The Google Test and Google Mock Communities The Google Test community exists primarily through the -[discussion group](http://groups.google.com/group/googletestframework) and the +[discussion group](https://groups.google.com/group/googletestframework) and the GitHub repository. Likewise, the Google Mock community exists primarily through -their own [discussion group](http://groups.google.com/group/googlemock). You are -definitely encouraged to contribute to the discussion and you can also help us -to keep the effectiveness of the group high by following and promoting the +their own [discussion group](https://groups.google.com/group/googlemock). You +are definitely encouraged to contribute to the discussion and you can also help +us to keep the effectiveness of the group high by following and promoting the guidelines listed here. ### Please Be Friendly diff --git a/3rdparty/googletest/README.md b/3rdparty/googletest/README.md index 151b3263b6..598cf31242 100644 --- a/3rdparty/googletest/README.md +++ b/3rdparty/googletest/README.md @@ -2,27 +2,18 @@ ### Announcements -#### Live at Head - -GoogleTest now follows the -[Abseil Live at Head philosophy](https://abseil.io/about/philosophy#upgrade-support). -We recommend -[updating to the latest commit in the `main` branch as often as possible](https://github.com/abseil/abseil-cpp/blob/master/FAQ.md#what-is-live-at-head-and-how-do-i-do-it). -We do publish occasional semantic versions, tagged with -`v${major}.${minor}.${patch}` (e.g. `v1.16.0`). - #### Documentation Updates Our documentation is now live on GitHub Pages at https://google.github.io/googletest/. We recommend browsing the documentation on GitHub Pages rather than directly in the repository. -#### Release 1.16.0 +#### Release 1.17.0 -[Release 1.16.0](https://github.com/google/googletest/releases/tag/v1.16.0) is +[Release 1.17.0](https://github.com/google/googletest/releases/tag/v1.17.0) is now available. -The 1.16.x branch requires at least C++14. +The 1.17.x branch [requires at least C++17]((https://opensource.google/documentation/policies/cplusplus-support#c_language_standard). #### Continuous Integration diff --git a/3rdparty/googletest/googlemock/include/gmock/gmock-actions.h b/3rdparty/googletest/googlemock/include/gmock/gmock-actions.h index aa47079948..5fe50e3d8e 100644 --- a/3rdparty/googletest/googlemock/include/gmock/gmock-actions.h +++ b/3rdparty/googletest/googlemock/include/gmock/gmock-actions.h @@ -835,6 +835,10 @@ class Action { Result operator()(const InArgs&...) const { return function_impl(); } + template + Result operator()(const InArgs&...) { + return function_impl(); + } FunctionImpl function_impl; }; @@ -1451,6 +1455,30 @@ struct WithArgsAction { return OA{std::move(inner_action)}; } + // As above, but in the case where we want to create a OnceAction from a const + // WithArgsAction. This is fine as long as the inner action doesn't need to + // move any of its state to create a OnceAction. + template < + typename R, typename... Args, + typename std::enable_if< + std::is_convertible>...)>>::value, + int>::type = 0> + operator OnceAction() const& { // NOLINT + struct OA { + OnceAction> inner_action; + + R operator()(Args&&... args) && { + return std::move(inner_action) + .Call(std::get( + std::forward_as_tuple(std::forward(args)...))...); + } + }; + + return OA{inner_action}; + } + template < typename R, typename... Args, typename std::enable_if< @@ -1703,9 +1731,8 @@ template struct ReturnArgAction { template ::type> - auto operator()(Args&&... args) const - -> decltype(std::get( - std::forward_as_tuple(std::forward(args)...))) { + auto operator()(Args&&... args) const -> decltype(std::get( + std::forward_as_tuple(std::forward(args)...))) { return std::get(std::forward_as_tuple(std::forward(args)...)); } }; @@ -1720,6 +1747,16 @@ struct SaveArgAction { } }; +template +struct SaveArgByMoveAction { + Ptr pointer; + + template + void operator()(Args&&... args) const { + *pointer = std::move(std::get(std::tie(args...))); + } +}; + template struct SaveArgPointeeAction { Ptr pointer; @@ -2070,6 +2107,13 @@ internal::SaveArgAction SaveArg(Ptr pointer) { return {pointer}; } +// Action SaveArgByMove(pointer) moves the k-th (0-based) argument of the +// mock function into *pointer. +template +internal::SaveArgByMoveAction SaveArgByMove(Ptr pointer) { + return {pointer}; +} + // Action SaveArgPointee(pointer) saves the value pointed to // by the k-th (0-based) argument of the mock function to *pointer. template @@ -2213,9 +2257,9 @@ template } #define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \ - , GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const arg##i##_type& arg##i -#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \ - GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const args_type& args GMOCK_PP_REPEAT( \ + , [[maybe_unused]] const arg##i##_type& arg##i +#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \ + [[maybe_unused]] const args_type& args GMOCK_PP_REPEAT( \ GMOCK_INTERNAL_ARG_UNUSED, , 10) #define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i @@ -2280,8 +2324,8 @@ template std::shared_ptr impl_; \ }; \ template \ - inline full_name name( \ - GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) GTEST_MUST_USE_RESULT_; \ + [[nodiscard]] inline full_name name( \ + GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)); \ template \ inline full_name name( \ GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) { \ @@ -2316,7 +2360,7 @@ template return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \ }; \ }; \ - inline name##Action name() GTEST_MUST_USE_RESULT_; \ + [[nodiscard]] inline name##Action name(); \ inline name##Action name() { return name##Action(); } \ template \ diff --git a/3rdparty/googletest/googlemock/include/gmock/gmock-matchers.h b/3rdparty/googletest/googlemock/include/gmock/gmock-matchers.h index e979544c72..aa3a5eb16f 100644 --- a/3rdparty/googletest/googlemock/include/gmock/gmock-matchers.h +++ b/3rdparty/googletest/googlemock/include/gmock/gmock-matchers.h @@ -257,6 +257,7 @@ #include #include +#include #include #include #include @@ -1311,6 +1312,15 @@ class AllOfMatcherImpl : public MatcherInterface { bool MatchAndExplain(const T& x, MatchResultListener* listener) const override { + if (!listener->IsInterested()) { + // Fast path to avoid unnecessary formatting. + for (const Matcher& matcher : matchers_) { + if (!matcher.Matches(x)) { + return false; + } + } + return true; + } // This method uses matcher's explanation when explaining the result. // However, if matcher doesn't provide one, this method uses matcher's // description. @@ -1430,6 +1440,15 @@ class AnyOfMatcherImpl : public MatcherInterface { bool MatchAndExplain(const T& x, MatchResultListener* listener) const override { + if (!listener->IsInterested()) { + // Fast path to avoid unnecessary formatting of match explanations. + for (const Matcher& matcher : matchers_) { + if (matcher.Matches(x)) { + return true; + } + } + return false; + } // This method uses matcher's explanation when explaining the result. // However, if matcher doesn't provide one, this method uses matcher's // description. @@ -2097,11 +2116,11 @@ class WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase { template class FieldMatcher { public: - FieldMatcher(FieldType Class::*field, + FieldMatcher(FieldType Class::* field, const Matcher& matcher) : field_(field), matcher_(matcher), whose_field_("whose given field ") {} - FieldMatcher(const std::string& field_name, FieldType Class::*field, + FieldMatcher(const std::string& field_name, FieldType Class::* field, const Matcher& matcher) : field_(field), matcher_(matcher), @@ -2145,7 +2164,7 @@ class FieldMatcher { return MatchAndExplainImpl(std::false_type(), *p, listener); } - const FieldType Class::*field_; + const FieldType Class::* field_; const Matcher matcher_; // Contains either "whose given field " if the name of the field is unknown @@ -2855,6 +2874,54 @@ class ContainsMatcherImpl : public QuantifierMatcherImpl { } }; +// Implements DistanceFrom(target, get_distance, distance_matcher) for the given +// argument types: +// * V is the type of the value to be matched. +// * T is the type of the target value. +// * Distance is the type of the distance between V and T. +// * GetDistance is the type of the functor for computing the distance between +// V and T. +template +class DistanceFromMatcherImpl : public MatcherInterface { + public: + // Arguments: + // * target: the target value. + // * get_distance: the functor for computing the distance between the value + // being matched and target. + // * distance_matcher: the matcher for checking the distance. + DistanceFromMatcherImpl(T target, GetDistance get_distance, + Matcher distance_matcher) + : target_(std::move(target)), + get_distance_(std::move(get_distance)), + distance_matcher_(std::move(distance_matcher)) {} + + // Describes what this matcher does. + void DescribeTo(::std::ostream* os) const override { + distance_matcher_.DescribeTo(os); + *os << " away from " << PrintToString(target_); + } + + void DescribeNegationTo(::std::ostream* os) const override { + distance_matcher_.DescribeNegationTo(os); + *os << " away from " << PrintToString(target_); + } + + bool MatchAndExplain(V value, MatchResultListener* listener) const override { + const auto distance = get_distance_(value, target_); + const bool match = distance_matcher_.Matches(distance); + if (!match && listener->IsInterested()) { + *listener << "which is " << PrintToString(distance) << " away from " + << PrintToString(target_); + } + return match; + } + + private: + const T target_; + const GetDistance get_distance_; + const Matcher distance_matcher_; +}; + // Implements Each(element_matcher) for the given argument type Container. // Symmetric to ContainsMatcherImpl. template @@ -2990,6 +3057,52 @@ auto Second(T& x, Rank1) -> decltype((x.second)) { // NOLINT } } // namespace pair_getters +// Default functor for computing the distance between two values. +struct DefaultGetDistance { + template + auto operator()(const T& lhs, const U& rhs) const { + using std::abs; + // Allow finding abs() in the type's namespace via ADL. + return abs(lhs - rhs); + } +}; + +// Implements polymorphic DistanceFrom(target, get_distance, distance_matcher) +// matcher. Template arguments: +// * T is the type of the target value. +// * GetDistance is the type of the functor for computing the distance between +// the value being matched and the target. +// * DistanceMatcher is the type of the matcher for checking the distance. +template +class DistanceFromMatcher { + public: + // Arguments: + // * target: the target value. + // * get_distance: the functor for computing the distance between the value + // being matched and target. + // * distance_matcher: the matcher for checking the distance. + DistanceFromMatcher(T target, GetDistance get_distance, + DistanceMatcher distance_matcher) + : target_(std::move(target)), + get_distance_(std::move(get_distance)), + distance_matcher_(std::move(distance_matcher)) {} + + DistanceFromMatcher(const DistanceFromMatcher& other) = default; + + // Implicitly converts to a monomorphic matcher of the given type. + template + operator Matcher() const { // NOLINT + using Distance = decltype(get_distance_(std::declval(), target_)); + return Matcher(new DistanceFromMatcherImpl( + target_, get_distance_, distance_matcher_)); + } + + private: + const T target_; + const GetDistance get_distance_; + const DistanceMatcher distance_matcher_; +}; + // Implements Key(inner_matcher) for the given argument pair type. // Key(inner_matcher) matches an std::pair whose 'first' field matches // inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an @@ -3197,8 +3310,8 @@ class PairMatcher { }; template -auto UnpackStructImpl(const T& t, std::index_sequence, - int) -> decltype(std::tie(get(t)...)) { +auto UnpackStructImpl(const T& t, std::index_sequence, int) + -> decltype(std::tie(get(t)...)) { static_assert(std::tuple_size::value == sizeof...(I), "Number of arguments doesn't match the number of fields."); return std::tie(get(t)...); @@ -3305,6 +3418,21 @@ auto UnpackStructImpl(const T& u, std::make_index_sequence<20>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t] = u; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t); } +template +auto UnpackStructImpl(const T& in, std::make_index_sequence<21>, char) { + const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u] = + in; + return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, + u); +} + +template +auto UnpackStructImpl(const T& in, std::make_index_sequence<22>, char) { + const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, + v] = in; + return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, + v); +} #endif // defined(__cpp_structured_bindings) template @@ -3480,7 +3608,7 @@ class ElementsAreMatcherImpl : public MatcherInterface { StlContainerReference stl_container = View::ConstReference(container); auto it = stl_container.begin(); size_t exam_pos = 0; - bool mismatch_found = false; // Have we found a mismatched element yet? + bool unmatched_found = false; // Go through the elements and matchers in pairs, until we reach // the end of either the elements or the matchers, or until we find a @@ -3496,11 +3624,23 @@ class ElementsAreMatcherImpl : public MatcherInterface { } if (!match) { - mismatch_found = true; + unmatched_found = true; + // We cannot store the iterator for the unmatched element to be used + // later, as some users use ElementsAre() with a "container" whose + // iterator is not copy-constructible or copy-assignable. + // + // We cannot store a pointer to the element either, as some container's + // iterators return a temporary. + // + // We cannot store the element itself either, as the element may not be + // copyable. + // + // Therefore, we just remember the index of the unmatched element, + // and use it later to print the unmatched element. break; } } - // If mismatch_found is true, 'exam_pos' is the index of the mismatch. + // If unmatched_found is true, exam_pos is the index of the mismatch. // Find how many elements the actual container has. We avoid // calling size() s.t. this code works for stream-like "containers" @@ -3521,10 +3661,27 @@ class ElementsAreMatcherImpl : public MatcherInterface { return false; } - if (mismatch_found) { + if (unmatched_found) { // The element count matches, but the exam_pos-th element doesn't match. if (listener_interested) { - *listener << "whose element #" << exam_pos << " doesn't match"; + // Find the unmatched element. + auto unmatched_it = stl_container.begin(); + // We cannot call std::advance() on the iterator, as some users use + // ElementsAre() with a "container" whose iterator is incompatible with + // std::advance() (e.g. it may not have the difference_type member + // type). + for (size_t i = 0; i != exam_pos; ++i) { + ++unmatched_it; + } + + // If the array is long or the elements' print-out is large, it may be + // hard for the user to find the mismatched element and its + // corresponding matcher description. Therefore we print the index, the + // value of the mismatched element, and the corresponding matcher + // description to ease debugging. + *listener << "whose element #" << exam_pos << " (" + << PrintToString(*unmatched_it) << ") "; + matchers_[exam_pos].DescribeNegationTo(listener->stream()); PrintIfNotEmpty(explanations[exam_pos], listener->stream()); } return false; @@ -3930,15 +4087,15 @@ GTEST_API_ std::string FormatMatcherDescription( // Overloads to support `OptionalMatcher` being used with a type that either // supports implicit conversion to bool or a `has_value()` method. template -auto IsOptionalEngaged(const Optional& optional, - Rank1) -> decltype(!!optional) { +auto IsOptionalEngaged(const Optional& optional, Rank1) + -> decltype(!!optional) { // The use of double-negation here is to preserve historical behavior where // the matcher used `operator!` rather than directly using `operator bool`. return !static_cast(!optional); } template -auto IsOptionalEngaged(const Optional& optional, - Rank0) -> decltype(!optional.has_value()) { +auto IsOptionalEngaged(const Optional& optional, Rank0) + -> decltype(!optional.has_value()) { return optional.has_value(); } @@ -3979,6 +4136,10 @@ class OptionalMatcher { return false; } const ValueType& value = *optional; + if (!listener->IsInterested()) { + // Fast path to avoid unnecessary generation of match explanation. + return value_matcher_.Matches(value); + } StringMatchResultListener value_listener; const bool match = value_matcher_.MatchAndExplain(value, &value_listener); *listener << "whose value " << PrintToString(value) @@ -4365,6 +4526,42 @@ inline internal::FloatingEqMatcher DoubleNear(double rhs, return internal::FloatingEqMatcher(rhs, false, max_abs_error); } +// The DistanceFrom(target, get_distance, m) and DistanceFrom(target, m) +// matchers work on arbitrary types that have the "distance" concept. What they +// do: +// +// 1. compute the distance between the value and the target using +// get_distance(value, target) if get_distance is provided; otherwise compute +// the distance as abs(value - target). +// 2. match the distance against the user-provided matcher m; if the match +// succeeds, the DistanceFrom() match succeeds. +// +// Examples: +// +// // 0.5's distance from 0.6 should be <= 0.2. +// EXPECT_THAT(0.5, DistanceFrom(0.6, Le(0.2))); +// +// Vector2D v1(3.0, 4.0), v2(3.2, 6.0); +// // v1's distance from v2, as computed by EuclideanDistance(v1, v2), +// // should be >= 1.0. +// EXPECT_THAT(v1, DistanceFrom(v2, EuclideanDistance, Ge(1.0))); + +template +inline internal::DistanceFromMatcher +DistanceFrom(T target, GetDistance get_distance, + DistanceMatcher distance_matcher) { + return internal::DistanceFromMatcher( + std::move(target), std::move(get_distance), std::move(distance_matcher)); +} + +template +inline internal::DistanceFromMatcher +DistanceFrom(T target, DistanceMatcher distance_matcher) { + return DistanceFrom(std::move(target), internal::DefaultGetDistance(), + std::move(distance_matcher)); +} + // Creates a matcher that matches any double argument approximately equal to // rhs, up to the specified max absolute error bound, including NaN values when // rhs is NaN. The max absolute error bound must be non-negative. @@ -4430,7 +4627,7 @@ WhenDynamicCastTo(const Matcher& inner_matcher) { // matches a Foo object x if and only if x.number >= 5. template inline PolymorphicMatcher> Field( - FieldType Class::*field, const FieldMatcher& matcher) { + FieldType Class::* field, const FieldMatcher& matcher) { return MakePolymorphicMatcher(internal::FieldMatcher( field, MatcherCast(matcher))); // The call to MatcherCast() is required for supporting inner @@ -4443,7 +4640,7 @@ inline PolymorphicMatcher> Field( // messages. template inline PolymorphicMatcher> Field( - const std::string& field_name, FieldType Class::*field, + const std::string& field_name, FieldType Class::* field, const FieldMatcher& matcher) { return MakePolymorphicMatcher(internal::FieldMatcher( field_name, field, MatcherCast(matcher))); @@ -4453,6 +4650,10 @@ inline PolymorphicMatcher> Field( // matches 'matcher'. For example, // Property(&Foo::str, StartsWith("hi")) // matches a Foo object x if and only if x.str() starts with "hi". +// +// Warning: Don't use `Property()` against member functions that you do not +// own, because taking addresses of functions is fragile and generally not part +// of the contract of the function. template inline PolymorphicMatcher> @@ -5551,8 +5752,7 @@ PolymorphicMatcher> ThrowsMessage( template \ bool name##Matcher::gmock_Impl::MatchAndExplain( \ const arg_type& arg, \ - GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED ::testing::MatchResultListener* \ - result_listener) const + [[maybe_unused]] ::testing::MatchResultListener* result_listener) const #define MATCHER_P(name, p0, description) \ GMOCK_INTERNAL_MATCHER(name, name##MatcherP, description, (#p0), (p0)) @@ -5637,8 +5837,8 @@ PolymorphicMatcher> ThrowsMessage( bool full_name:: \ gmock_Impl::MatchAndExplain( \ const arg_type& arg, \ - GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED ::testing:: \ - MatchResultListener* result_listener) const + [[maybe_unused]] ::testing::MatchResultListener* result_listener) \ + const #define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args) \ GMOCK_PP_TAIL( \ diff --git a/3rdparty/googletest/googlemock/include/gmock/gmock-more-actions.h b/3rdparty/googletest/googlemock/include/gmock/gmock-more-actions.h index 55294dbdbd..eacfdcd9e7 100644 --- a/3rdparty/googletest/googlemock/include/gmock/gmock-more-actions.h +++ b/3rdparty/googletest/googlemock/include/gmock/gmock-more-actions.h @@ -521,9 +521,8 @@ GMOCK_INTERNAL_DECL_##value_params) \ GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \ = default; \ - , \ - : impl_(std::make_shared( \ - GMOCK_INTERNAL_LIST_##value_params)){}) \ + , : impl_(std::make_shared( \ + GMOCK_INTERNAL_LIST_##value_params)){}) \ GMOCK_ACTION_CLASS_(name, value_params)(const GMOCK_ACTION_CLASS_( \ name, value_params) &) noexcept GMOCK_INTERNAL_DEFN_COPY_ \ ##value_params \ @@ -551,10 +550,10 @@ }; \ template \ - GMOCK_ACTION_CLASS_( \ + [[nodiscard]] GMOCK_ACTION_CLASS_( \ name, value_params) \ - name(GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_; \ + name(GMOCK_INTERNAL_DECL_##value_params); \ template \ inline GMOCK_ACTION_CLASS_( \ diff --git a/3rdparty/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h b/3rdparty/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h index b7685f5730..8fc1ddc7ab 100644 --- a/3rdparty/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h +++ b/3rdparty/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h @@ -467,11 +467,6 @@ struct Function { using MakeResultIgnoredValue = IgnoredValue(Args...); }; -#ifdef GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL -template -constexpr size_t Function::ArgumentCount; -#endif - // Workaround for MSVC error C2039: 'type': is not a member of 'std' // when std::tuple_element is used. // See: https://github.com/google/googletest/issues/3931 diff --git a/3rdparty/googletest/googletest/README.md b/3rdparty/googletest/googletest/README.md index 5de23c5ed2..a760759eb0 100644 --- a/3rdparty/googletest/googletest/README.md +++ b/3rdparty/googletest/googletest/README.md @@ -25,7 +25,7 @@ When building GoogleTest as a standalone project, the typical workflow starts with ``` -git clone https://github.com/google/googletest.git -b v1.16.0 +git clone https://github.com/google/googletest.git -b v1.17.0 cd googletest # Main directory of the cloned repository. mkdir build # Create a directory to hold the build output. cd build @@ -124,9 +124,9 @@ match the project in which it is included. #### C++ Standard Version -An environment that supports C++14 is required in order to successfully build +An environment that supports C++17 is required in order to successfully build GoogleTest. One way to ensure this is to specify the standard in the top-level -project, for example by using the `set(CMAKE_CXX_STANDARD 14)` command along +project, for example by using the `set(CMAKE_CXX_STANDARD 17)` command along with `set(CMAKE_CXX_STANDARD_REQUIRED ON)`. If this is not feasible, for example in a C project using GoogleTest for validation, then it can be specified by adding it to the options for cmake via the`-DCMAKE_CXX_FLAGS` option. diff --git a/3rdparty/googletest/googletest/include/gtest/gtest-assertion-result.h b/3rdparty/googletest/googletest/include/gtest/gtest-assertion-result.h index 74eb2b1f3c..954e7c40f3 100644 --- a/3rdparty/googletest/googletest/include/gtest/gtest-assertion-result.h +++ b/3rdparty/googletest/googletest/include/gtest/gtest-assertion-result.h @@ -129,6 +129,13 @@ namespace testing { // // Expected: Foo() is even // Actual: it's 5 +// + +// Returned AssertionResult objects may not be ignored. +// Note: Disabled for SWIG as it doesn't parse attributes correctly. +#if !defined(SWIG) +class [[nodiscard]] AssertionResult; +#endif // !SWIG class GTEST_API_ AssertionResult { public: diff --git a/3rdparty/googletest/googletest/include/gtest/gtest-param-test.h b/3rdparty/googletest/googletest/include/gtest/gtest-param-test.h index 55ee088b93..9e023f96dc 100644 --- a/3rdparty/googletest/googletest/include/gtest/gtest-param-test.h +++ b/3rdparty/googletest/googletest/include/gtest/gtest-param-test.h @@ -174,6 +174,7 @@ TEST_P(DerivedTest, DoesBlah) { #endif // 0 +#include #include #include @@ -413,7 +414,8 @@ internal::CartesianProductHolder Combine(const Generator&... g) { // Synopsis: // ConvertGenerator(gen) // - returns a generator producing the same elements as generated by gen, but -// each element is static_cast to type T before being returned +// each T-typed element is static_cast to a type deduced from the interface +// that accepts this generator, and then returned // // It is useful when using the Combine() function to get the generated // parameters in a custom type instead of std::tuple @@ -441,10 +443,65 @@ internal::CartesianProductHolder Combine(const Generator&... g) { // Combine(Values("cat", "dog"), // Values(BLACK, WHITE)))); // -template -internal::ParamConverterGenerator ConvertGenerator( - internal::ParamGenerator gen) { - return internal::ParamConverterGenerator(gen); +template +internal::ParamConverterGenerator ConvertGenerator( + internal::ParamGenerator gen) { + return internal::ParamConverterGenerator(std::move(gen)); +} + +// As above, but takes a callable as a second argument. The callable converts +// the generated parameter to the test fixture's parameter type. This allows you +// to use a parameter type that does not have a converting constructor from the +// generated type. +// +// Example: +// +// This will instantiate tests in test suite AnimalTest each one with +// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), +// tuple("dog", BLACK), and tuple("dog", WHITE): +// +// enum Color { BLACK, GRAY, WHITE }; +// struct ParamType { +// std::string animal; +// Color color; +// }; +// class AnimalTest +// : public testing::TestWithParam {...}; +// +// TEST_P(AnimalTest, AnimalLooksNice) {...} +// +// INSTANTIATE_TEST_SUITE_P( +// AnimalVariations, AnimalTest, +// ConvertGenerator(Combine(Values("cat", "dog"), Values(BLACK, WHITE)), +// [](std::tuple t) { +// return ParamType{.animal = std::get<0>(t), +// .color = std::get<1>(t)}; +// })); +// +template ()))> +internal::ParamConverterGenerator ConvertGenerator(Gen&& gen, + Func&& f) { + return internal::ParamConverterGenerator( + std::forward(gen), std::forward(f)); +} + +// As above, but infers the T from the supplied std::function instead of +// having the caller specify it. +template ()))> +auto ConvertGenerator(Gen&& gen, Func&& f) { + constexpr bool is_single_arg_std_function = + internal::IsSingleArgStdFunction::value; + if constexpr (is_single_arg_std_function) { + return ConvertGenerator< + typename internal::FuncSingleParamType::type>( + std::forward(gen), std::forward(f)); + } else { + static_assert(is_single_arg_std_function, + "The call signature must contain a single argument."); + } } #define TEST_P(test_suite_name, test_name) \ @@ -469,7 +526,7 @@ internal::ParamConverterGenerator ConvertGenerator( ::testing::internal::CodeLocation(__FILE__, __LINE__)); \ return 0; \ } \ - GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int gtest_registering_dummy_; \ + [[maybe_unused]] static int gtest_registering_dummy_; \ }; \ int GTEST_TEST_CLASS_NAME_(test_suite_name, \ test_name)::gtest_registering_dummy_ = \ @@ -493,39 +550,38 @@ internal::ParamConverterGenerator ConvertGenerator( #define GTEST_GET_FIRST_(first, ...) first #define GTEST_GET_SECOND_(first, second, ...) second -#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \ - static ::testing::internal::ParamGenerator \ - gtest_##prefix##test_suite_name##_EvalGenerator_() { \ - return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \ - } \ - static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \ - const ::testing::TestParamInfo& info) { \ - if (::testing::internal::AlwaysFalse()) { \ - ::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \ - __VA_ARGS__, \ - ::testing::internal::DefaultParamName, \ - DUMMY_PARAM_))); \ - auto t = std::make_tuple(__VA_ARGS__); \ - static_assert(std::tuple_size::value <= 2, \ - "Too Many Args!"); \ - } \ - return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \ - __VA_ARGS__, \ - ::testing::internal::DefaultParamName, \ - DUMMY_PARAM_))))(info); \ - } \ - GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int \ - gtest_##prefix##test_suite_name##_dummy_ = \ - ::testing::UnitTest::GetInstance() \ - ->parameterized_test_registry() \ - .GetTestSuitePatternHolder( \ - GTEST_STRINGIFY_(test_suite_name), \ - ::testing::internal::CodeLocation(__FILE__, __LINE__)) \ - ->AddTestSuiteInstantiation( \ - GTEST_STRINGIFY_(prefix), \ - >est_##prefix##test_suite_name##_EvalGenerator_, \ - >est_##prefix##test_suite_name##_EvalGenerateName_, \ - __FILE__, __LINE__) +#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \ + static ::testing::internal::ParamGenerator \ + gtest_##prefix##test_suite_name##_EvalGenerator_() { \ + return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \ + } \ + static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \ + const ::testing::TestParamInfo& info) { \ + if (::testing::internal::AlwaysFalse()) { \ + ::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \ + __VA_ARGS__, \ + ::testing::internal::DefaultParamName, \ + DUMMY_PARAM_))); \ + auto t = std::make_tuple(__VA_ARGS__); \ + static_assert(std::tuple_size::value <= 2, \ + "Too Many Args!"); \ + } \ + return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \ + __VA_ARGS__, \ + ::testing::internal::DefaultParamName, \ + DUMMY_PARAM_))))(info); \ + } \ + [[maybe_unused]] static int gtest_##prefix##test_suite_name##_dummy_ = \ + ::testing::UnitTest::GetInstance() \ + ->parameterized_test_registry() \ + .GetTestSuitePatternHolder( \ + GTEST_STRINGIFY_(test_suite_name), \ + ::testing::internal::CodeLocation(__FILE__, __LINE__)) \ + ->AddTestSuiteInstantiation( \ + GTEST_STRINGIFY_(prefix), \ + >est_##prefix##test_suite_name##_EvalGenerator_, \ + >est_##prefix##test_suite_name##_EvalGenerateName_, __FILE__, \ + __LINE__) // Allow Marking a Parameterized test class as not needing to be instantiated. #define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \ diff --git a/3rdparty/googletest/googletest/include/gtest/gtest-typed-test.h b/3rdparty/googletest/googletest/include/gtest/gtest-typed-test.h index 305b0b50dd..442e00bd34 100644 --- a/3rdparty/googletest/googletest/include/gtest/gtest-typed-test.h +++ b/3rdparty/googletest/googletest/include/gtest/gtest-typed-test.h @@ -194,34 +194,33 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \ GTEST_NAME_GENERATOR_(CaseName) -#define TYPED_TEST(CaseName, TestName) \ - static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \ - "test-name must not be empty"); \ - template \ - class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ - : public CaseName { \ - private: \ - typedef CaseName TestFixture; \ - typedef gtest_TypeParam_ TypeParam; \ - void TestBody() override; \ - }; \ - GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \ - gtest_##CaseName##_##TestName##_registered_ = \ - ::testing::internal::TypeParameterizedTest< \ - CaseName, \ - ::testing::internal::TemplateSel, \ - GTEST_TYPE_PARAMS_( \ - CaseName)>::Register("", \ - ::testing::internal::CodeLocation( \ - __FILE__, __LINE__), \ - GTEST_STRINGIFY_(CaseName), \ - GTEST_STRINGIFY_(TestName), 0, \ - ::testing::internal::GenerateNames< \ - GTEST_NAME_GENERATOR_(CaseName), \ - GTEST_TYPE_PARAMS_(CaseName)>()); \ - template \ - void GTEST_TEST_CLASS_NAME_(CaseName, \ +#define TYPED_TEST(CaseName, TestName) \ + static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \ + "test-name must not be empty"); \ + template \ + class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ + : public CaseName { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + void TestBody() override; \ + }; \ + [[maybe_unused]] static bool gtest_##CaseName##_##TestName##_registered_ = \ + ::testing::internal::TypeParameterizedTest< \ + CaseName, \ + ::testing::internal::TemplateSel, \ + GTEST_TYPE_PARAMS_( \ + CaseName)>::Register("", \ + ::testing::internal::CodeLocation( \ + __FILE__, __LINE__), \ + GTEST_STRINGIFY_(CaseName), \ + GTEST_STRINGIFY_(TestName), 0, \ + ::testing::internal::GenerateNames< \ + GTEST_NAME_GENERATOR_(CaseName), \ + GTEST_TYPE_PARAMS_(CaseName)>()); \ + template \ + void GTEST_TEST_CLASS_NAME_(CaseName, \ TestName)::TestBody() // Legacy API is deprecated but still available @@ -268,23 +267,22 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); TYPED_TEST_SUITE_P #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -#define TYPED_TEST_P(SuiteName, TestName) \ - namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \ - template \ - class TestName : public SuiteName { \ - private: \ - typedef SuiteName TestFixture; \ - typedef gtest_TypeParam_ TypeParam; \ - void TestBody() override; \ - }; \ - GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \ - gtest_##TestName##_defined_ = \ - GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \ - __FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \ - GTEST_STRINGIFY_(TestName)); \ - } \ - template \ - void GTEST_SUITE_NAMESPACE_( \ +#define TYPED_TEST_P(SuiteName, TestName) \ + namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \ + template \ + class TestName : public SuiteName { \ + private: \ + typedef SuiteName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + void TestBody() override; \ + }; \ + [[maybe_unused]] static bool gtest_##TestName##_defined_ = \ + GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \ + __FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \ + GTEST_STRINGIFY_(TestName)); \ + } \ + template \ + void GTEST_SUITE_NAMESPACE_( \ SuiteName)::TestName::TestBody() // Note: this won't work correctly if the trailing arguments are macros. @@ -292,8 +290,8 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \ typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \ } \ - GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static const char* const \ - GTEST_REGISTERED_TEST_NAMES_(SuiteName) = \ + [[maybe_unused]] static const char* const GTEST_REGISTERED_TEST_NAMES_( \ + SuiteName) = \ GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \ GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__) @@ -305,24 +303,22 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes); REGISTER_TYPED_TEST_SUITE_P #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ -#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \ - static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \ - "test-suit-prefix must not be empty"); \ - GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool \ - gtest_##Prefix##_##SuiteName = \ - ::testing::internal::TypeParameterizedTestSuite< \ - SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \ - ::testing::internal::GenerateTypeList::type>:: \ - Register( \ - GTEST_STRINGIFY_(Prefix), \ - ::testing::internal::CodeLocation(__FILE__, __LINE__), \ - >EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \ - GTEST_STRINGIFY_(SuiteName), \ - GTEST_REGISTERED_TEST_NAMES_(SuiteName), \ - ::testing::internal::GenerateNames< \ - ::testing::internal::NameGeneratorSelector< \ - __VA_ARGS__>::type, \ - ::testing::internal::GenerateTypeList::type>()) +#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \ + static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \ + "test-suit-prefix must not be empty"); \ + [[maybe_unused]] static bool gtest_##Prefix##_##SuiteName = \ + ::testing::internal::TypeParameterizedTestSuite< \ + SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \ + ::testing::internal::GenerateTypeList::type>:: \ + Register(GTEST_STRINGIFY_(Prefix), \ + ::testing::internal::CodeLocation(__FILE__, __LINE__), \ + >EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \ + GTEST_STRINGIFY_(SuiteName), \ + GTEST_REGISTERED_TEST_NAMES_(SuiteName), \ + ::testing::internal::GenerateNames< \ + ::testing::internal::NameGeneratorSelector< \ + __VA_ARGS__>::type, \ + ::testing::internal::GenerateTypeList::type>()) // Legacy API is deprecated but still available #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ diff --git a/3rdparty/googletest/googletest/include/gtest/gtest.h b/3rdparty/googletest/googletest/include/gtest/gtest.h index c899669520..7be0caaf51 100644 --- a/3rdparty/googletest/googletest/include/gtest/gtest.h +++ b/3rdparty/googletest/googletest/include/gtest/gtest.h @@ -1123,7 +1123,7 @@ class GTEST_API_ UnitTest { // This method can only be called from the main thread. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - int Run() GTEST_MUST_USE_RESULT_; + [[nodiscard]] int Run(); // Returns the working directory when the first TEST() or TEST_F() // was executed. The UnitTest object owns the string. @@ -2329,7 +2329,7 @@ TestInfo* RegisterTest(const char* test_suite_name, const char* test_name, // // This function was formerly a macro; thus, it is in the global // namespace and has an all-caps name. -int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_; +[[nodiscard]] int RUN_ALL_TESTS(); inline int RUN_ALL_TESTS() { return ::testing::UnitTest::GetInstance()->Run(); } diff --git a/3rdparty/googletest/googletest/include/gtest/internal/gtest-internal.h b/3rdparty/googletest/googletest/include/gtest/internal/gtest-internal.h index 7e55dc605c..808d89be91 100644 --- a/3rdparty/googletest/googletest/include/gtest/internal/gtest-internal.h +++ b/3rdparty/googletest/googletest/include/gtest/internal/gtest-internal.h @@ -290,17 +290,17 @@ class FloatingPoint { // around may change its bits, although the new value is guaranteed // to be also a NAN. Therefore, don't expect this constructor to // preserve the bits in x when x is a NAN. - explicit FloatingPoint(const RawType& x) { u_.value_ = x; } + explicit FloatingPoint(RawType x) { memcpy(&bits_, &x, sizeof(x)); } // Static methods // Reinterprets a bit pattern as a floating-point number. // // This function is needed to test the AlmostEquals() method. - static RawType ReinterpretBits(const Bits bits) { - FloatingPoint fp(0); - fp.u_.bits_ = bits; - return fp.u_.value_; + static RawType ReinterpretBits(Bits bits) { + RawType fp; + memcpy(&fp, &bits, sizeof(fp)); + return fp; } // Returns the floating-point number that represent positive infinity. @@ -309,16 +309,16 @@ class FloatingPoint { // Non-static methods // Returns the bits that represents this number. - const Bits& bits() const { return u_.bits_; } + const Bits& bits() const { return bits_; } // Returns the exponent bits of this number. - Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } + Bits exponent_bits() const { return kExponentBitMask & bits_; } // Returns the fraction bits of this number. - Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } + Bits fraction_bits() const { return kFractionBitMask & bits_; } // Returns the sign bit of this number. - Bits sign_bit() const { return kSignBitMask & u_.bits_; } + Bits sign_bit() const { return kSignBitMask & bits_; } // Returns true if and only if this is NAN (not a number). bool is_nan() const { @@ -332,23 +332,16 @@ class FloatingPoint { // // - returns false if either number is (or both are) NAN. // - treats really large numbers as almost equal to infinity. - // - thinks +0.0 and -0.0 are 0 DLP's apart. + // - thinks +0.0 and -0.0 are 0 ULP's apart. bool AlmostEquals(const FloatingPoint& rhs) const { // The IEEE standard says that any comparison operation involving // a NAN must return false. if (is_nan() || rhs.is_nan()) return false; - return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <= - kMaxUlps; + return DistanceBetweenSignAndMagnitudeNumbers(bits_, rhs.bits_) <= kMaxUlps; } private: - // The data type used to store the actual floating-point number. - union FloatingPointUnion { - RawType value_; // The raw floating-point number. - Bits bits_; // The bits that represent the number. - }; - // Converts an integer from the sign-and-magnitude representation to // the biased representation. More precisely, let N be 2 to the // power of (kBitCount - 1), an integer x is represented by the @@ -364,7 +357,7 @@ class FloatingPoint { // // Read https://en.wikipedia.org/wiki/Signed_number_representations // for more details on signed number representations. - static Bits SignAndMagnitudeToBiased(const Bits& sam) { + static Bits SignAndMagnitudeToBiased(Bits sam) { if (kSignBitMask & sam) { // sam represents a negative number. return ~sam + 1; @@ -376,14 +369,13 @@ class FloatingPoint { // Given two numbers in the sign-and-magnitude representation, // returns the distance between them as an unsigned number. - static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1, - const Bits& sam2) { + static Bits DistanceBetweenSignAndMagnitudeNumbers(Bits sam1, Bits sam2) { const Bits biased1 = SignAndMagnitudeToBiased(sam1); const Bits biased2 = SignAndMagnitudeToBiased(sam2); return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); } - FloatingPointUnion u_; + Bits bits_; // The bits that represent the number. }; // Typedefs the instances of the FloatingPoint template class that we @@ -894,11 +886,6 @@ class HasDebugStringAndShortDebugString { HasDebugStringType::value && HasShortDebugStringType::value; }; -#ifdef GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL -template -constexpr bool HasDebugStringAndShortDebugString::value; -#endif - // When the compiler sees expression IsContainerTest(0), if C is an // STL-style container class, the first overload of IsContainerTest // will be viable (since both C::iterator* and C::const_iterator* are @@ -1241,30 +1228,40 @@ class FlatTuple // Utility functions to be called with static_assert to induce deprecation // warnings. -GTEST_INTERNAL_DEPRECATED( +[[deprecated( "INSTANTIATE_TEST_CASE_P is deprecated, please use " - "INSTANTIATE_TEST_SUITE_P") -constexpr bool InstantiateTestCase_P_IsDeprecated() { return true; } + "INSTANTIATE_TEST_SUITE_P")]] +constexpr bool InstantiateTestCase_P_IsDeprecated() { + return true; +} -GTEST_INTERNAL_DEPRECATED( +[[deprecated( "TYPED_TEST_CASE_P is deprecated, please use " - "TYPED_TEST_SUITE_P") -constexpr bool TypedTestCase_P_IsDeprecated() { return true; } + "TYPED_TEST_SUITE_P")]] +constexpr bool TypedTestCase_P_IsDeprecated() { + return true; +} -GTEST_INTERNAL_DEPRECATED( +[[deprecated( "TYPED_TEST_CASE is deprecated, please use " - "TYPED_TEST_SUITE") -constexpr bool TypedTestCaseIsDeprecated() { return true; } + "TYPED_TEST_SUITE")]] +constexpr bool TypedTestCaseIsDeprecated() { + return true; +} -GTEST_INTERNAL_DEPRECATED( +[[deprecated( "REGISTER_TYPED_TEST_CASE_P is deprecated, please use " - "REGISTER_TYPED_TEST_SUITE_P") -constexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; } + "REGISTER_TYPED_TEST_SUITE_P")]] +constexpr bool RegisterTypedTestCase_P_IsDeprecated() { + return true; +} -GTEST_INTERNAL_DEPRECATED( +[[deprecated( "INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use " - "INSTANTIATE_TYPED_TEST_SUITE_P") -constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; } + "INSTANTIATE_TYPED_TEST_SUITE_P")]] +constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { + return true; +} } // namespace internal } // namespace testing @@ -1501,8 +1498,7 @@ class NeverThrown { \ private: \ void TestBody() override; \ - GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static ::testing::TestInfo* const \ - test_info_; \ + [[maybe_unused]] static ::testing::TestInfo* const test_info_; \ }; \ \ ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \ diff --git a/3rdparty/googletest/googletest/include/gtest/internal/gtest-param-util.h b/3rdparty/googletest/googletest/include/gtest/internal/gtest-param-util.h index cc7ea53173..a092a86ada 100644 --- a/3rdparty/googletest/googletest/include/gtest/internal/gtest-param-util.h +++ b/3rdparty/googletest/googletest/include/gtest/internal/gtest-param-util.h @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -529,8 +530,7 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase { // prefix). test_base_name is the name of an individual test without // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is // test suite base name and DoBar is test base name. - void AddTestPattern(const char*, - const char* test_base_name, + void AddTestPattern(const char*, const char* test_base_name, TestMetaFactoryBase* meta_factory, CodeLocation code_location) { tests_.emplace_back( @@ -952,11 +952,11 @@ class CartesianProductHolder { std::tuple generators_; }; -template +template class ParamGeneratorConverter : public ParamGeneratorInterface { public: - ParamGeneratorConverter(ParamGenerator gen) // NOLINT - : generator_(std::move(gen)) {} + ParamGeneratorConverter(ParamGenerator gen, Func converter) // NOLINT + : generator_(std::move(gen)), converter_(std::move(converter)) {} ParamIteratorInterface* Begin() const override { return new Iterator(this, generator_.begin(), generator_.end()); @@ -965,13 +965,21 @@ class ParamGeneratorConverter : public ParamGeneratorInterface { return new Iterator(this, generator_.end(), generator_.end()); } + // Returns the std::function wrapping the user-supplied converter callable. It + // is used by the iterator (see class Iterator below) to convert the object + // (of type FROM) returned by the ParamGenerator to an object of a type that + // can be static_cast to type TO. + const Func& TypeConverter() const { return converter_; } + private: class Iterator : public ParamIteratorInterface { public: - Iterator(const ParamGeneratorInterface* base, ParamIterator it, + Iterator(const ParamGeneratorConverter* base, ParamIterator it, ParamIterator end) : base_(base), it_(it), end_(end) { - if (it_ != end_) value_ = std::make_shared(static_cast(*it_)); + if (it_ != end_) + value_ = + std::make_shared(static_cast(base->TypeConverter()(*it_))); } ~Iterator() override = default; @@ -980,7 +988,9 @@ class ParamGeneratorConverter : public ParamGeneratorInterface { } void Advance() override { ++it_; - if (it_ != end_) value_ = std::make_shared(static_cast(*it_)); + if (it_ != end_) + value_ = + std::make_shared(static_cast(base_->TypeConverter()(*it_))); } ParamIteratorInterface* Clone() const override { return new Iterator(*this); @@ -1000,30 +1010,54 @@ class ParamGeneratorConverter : public ParamGeneratorInterface { private: Iterator(const Iterator& other) = default; - const ParamGeneratorInterface* const base_; + const ParamGeneratorConverter* const base_; ParamIterator it_; ParamIterator end_; std::shared_ptr value_; }; // class ParamGeneratorConverter::Iterator ParamGenerator generator_; + Func converter_; }; // class ParamGeneratorConverter -template +template > class ParamConverterGenerator { public: - ParamConverterGenerator(ParamGenerator g) // NOLINT - : generator_(std::move(g)) {} + ParamConverterGenerator(ParamGenerator g) // NOLINT + : generator_(std::move(g)), converter_(Identity) {} + + ParamConverterGenerator(ParamGenerator g, StdFunction converter) + : generator_(std::move(g)), converter_(std::move(converter)) {} template operator ParamGenerator() const { // NOLINT - return ParamGenerator(new ParamGeneratorConverter(generator_)); + return ParamGenerator( + new ParamGeneratorConverter(generator_, + converter_)); } private: - ParamGenerator generator_; + static const GeneratedT& Identity(const GeneratedT& v) { return v; } + + ParamGenerator generator_; + StdFunction converter_; }; +// Template to determine the param type of a single-param std::function. +template +struct FuncSingleParamType; +template +struct FuncSingleParamType> { + using type = std::remove_cv_t>; +}; + +template +struct IsSingleArgStdFunction : public std::false_type {}; +template +struct IsSingleArgStdFunction> : public std::true_type {}; + } // namespace internal } // namespace testing diff --git a/3rdparty/googletest/googletest/include/gtest/internal/gtest-port.h b/3rdparty/googletest/googletest/include/gtest/internal/gtest-port.h index ca18513e77..25b7d194db 100644 --- a/3rdparty/googletest/googletest/include/gtest/internal/gtest-port.h +++ b/3rdparty/googletest/googletest/include/gtest/internal/gtest-port.h @@ -194,7 +194,6 @@ // // Macros for basic C++ coding: // GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. -// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. // GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is // suppressed (constant conditional). // GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127 @@ -260,11 +259,6 @@ // BoolFromGTestEnv() - parses a bool environment variable. // Int32FromGTestEnv() - parses an int32_t environment variable. // StringFromGTestEnv() - parses a string environment variable. -// -// Deprecation warnings: -// GTEST_INTERNAL_DEPRECATED(message) - attribute marking a function as -// deprecated; calling a marked function -// should generate a compiler warning // The definition of GTEST_INTERNAL_CPLUSPLUS_LANG comes first because it can // potentially be used as an #include guard. @@ -275,8 +269,8 @@ #endif #if !defined(GTEST_INTERNAL_CPLUSPLUS_LANG) || \ - GTEST_INTERNAL_CPLUSPLUS_LANG < 201402L -#error C++ versions less than C++14 are not supported. + GTEST_INTERNAL_CPLUSPLUS_LANG < 201703L +#error C++ versions less than C++17 are not supported. #endif // MSVC >= 19.11 (VS 2017 Update 3) supports __has_include. @@ -288,10 +282,14 @@ // Detect C++ feature test macros as gracefully as possible. // MSVC >= 19.15, Clang >= 3.4.1, and GCC >= 4.1.2 support feature test macros. -#if GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L && \ - (!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE()) -#include // C++20 and later -#elif (!defined(__has_include) || GTEST_INTERNAL_HAS_INCLUDE()) +// +// GCC15 warns that is deprecated in C++17 and suggests using +// instead, even though is not available in C++17 mode prior +// to GCC9. +#if GTEST_INTERNAL_CPLUSPLUS_LANG >= 202002L || \ + GTEST_INTERNAL_HAS_INCLUDE() +#include // C++20 or support. +#else #include // Pre-C++20 #endif @@ -772,25 +770,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #define GTEST_HAVE_FEATURE_(x) 0 #endif -// Use this annotation after a variable or parameter declaration to tell the -// compiler the variable/parameter may be used. -// Example: -// -// GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED int foo = bar(); -// -// This can be removed once we only support only C++17 or newer and -// [[maybe_unused]] is available on all supported platforms. -#if GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(maybe_unused) -#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED [[maybe_unused]] -#elif GTEST_HAVE_ATTRIBUTE_(unused) -// This is inferior to [[maybe_unused]] as it can produce a -// -Wused-but-marked-unused warning on optionally used symbols, but it is all we -// have. -#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED __attribute__((__unused__)) -#else -#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED -#endif - // Use this annotation before a function that takes a printf format string. #if GTEST_HAVE_ATTRIBUTE_(format) && defined(__MINGW_PRINTF_FORMAT) // MinGW has two different printf implementations. Ensure the format macro @@ -805,17 +784,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) #endif -// Tell the compiler to warn about unused return values for functions declared -// with this macro. The macro should be used on function declarations -// following the argument list: -// -// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; -#if GTEST_HAVE_ATTRIBUTE_(warn_unused_result) -#define GTEST_MUST_USE_RESULT_ __attribute__((warn_unused_result)) -#else -#define GTEST_MUST_USE_RESULT_ -#endif - // MS C++ compiler emits warning when a conditional expression is compile time // constant. In some contexts this warning is false positive and needs to be // suppressed. Use the following two macros in such cases: @@ -2367,26 +2335,6 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val); } // namespace internal } // namespace testing -#if !defined(GTEST_INTERNAL_DEPRECATED) - -// Internal Macro to mark an API deprecated, for googletest usage only -// Usage: class GTEST_INTERNAL_DEPRECATED(message) MyClass or -// GTEST_INTERNAL_DEPRECATED(message) myFunction(); Every usage of -// a deprecated entity will trigger a warning when compiled with -// `-Wdeprecated-declarations` option (clang, gcc, any __GNUC__ compiler). -// For msvc /W3 option will need to be used -// Note that for 'other' compilers this macro evaluates to nothing to prevent -// compilations errors. -#if defined(_MSC_VER) -#define GTEST_INTERNAL_DEPRECATED(message) __declspec(deprecated(message)) -#elif defined(__GNUC__) -#define GTEST_INTERNAL_DEPRECATED(message) __attribute__((deprecated(message))) -#else -#define GTEST_INTERNAL_DEPRECATED(message) -#endif - -#endif // !defined(GTEST_INTERNAL_DEPRECATED) - #ifdef GTEST_HAS_ABSL // Always use absl::any for UniversalPrinter<> specializations if googletest // is built with absl support. @@ -2527,12 +2475,6 @@ using Variant = ::std::variant; #define GTEST_INTERNAL_HAS_VARIANT 0 #endif -#if (defined(__cpp_constexpr) && !defined(__cpp_inline_variables)) || \ - (defined(GTEST_INTERNAL_CPLUSPLUS_LANG) && \ - GTEST_INTERNAL_CPLUSPLUS_LANG < 201703L) -#define GTEST_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL 1 -#endif - #if (defined(__cpp_lib_three_way_comparison) || \ (GTEST_INTERNAL_HAS_INCLUDE() && \ GTEST_INTERNAL_CPLUSPLUS_LANG >= 201907L)) diff --git a/3rdparty/googletest/googletest/src/gtest-internal-inl.h b/3rdparty/googletest/googletest/src/gtest-internal-inl.h index cc6f00488f..6a39b93be1 100644 --- a/3rdparty/googletest/googletest/src/gtest-internal-inl.h +++ b/3rdparty/googletest/googletest/src/gtest-internal-inl.h @@ -826,6 +826,10 @@ class GTEST_API_ UnitTestImpl { bool catch_exceptions() const { return catch_exceptions_; } private: + // Returns true if a warning should be issued if no tests match the test + // filter flag. + bool ShouldWarnIfNoTestsMatchFilter() const; + struct CompareTestSuitesByPointer { bool operator()(const TestSuite* lhs, const TestSuite* rhs) const { return lhs->name_ < rhs->name_; diff --git a/3rdparty/googletest/googletest/src/gtest.cc b/3rdparty/googletest/googletest/src/gtest.cc index 7ff825468c..09af15179f 100644 --- a/3rdparty/googletest/googletest/src/gtest.cc +++ b/3rdparty/googletest/googletest/src/gtest.cc @@ -192,12 +192,17 @@ static const char kDefaultOutputFormat[] = "xml"; // The default output file. static const char kDefaultOutputFile[] = "test_detail"; +// These environment variables are set by Bazel. +// https://bazel.build/reference/test-encyclopedia#initial-conditions +// // The environment variable name for the test shard index. static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; // The environment variable name for the total number of test shards. static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; // The environment variable name for the test shard status file. static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; +// The environment variable name for the test output warnings file. +static const char kTestWarningsOutputFile[] = "TEST_WARNINGS_OUTPUT_FILE"; namespace internal { @@ -258,6 +263,12 @@ GTEST_DEFINE_bool_( testing::GetDefaultFailFast()), "True if and only if a test failure should stop further test execution."); +GTEST_DEFINE_bool_( + fail_if_no_test_linked, + testing::internal::BoolFromGTestEnv("fail_if_no_test_linked", false), + "True if and only if the test should fail if no test case (including " + "disabled test cases) is linked."); + GTEST_DEFINE_bool_( also_run_disabled_tests, testing::internal::BoolFromGTestEnv("also_run_disabled_tests", false), @@ -5869,6 +5880,23 @@ TestSuite* UnitTestImpl::GetTestSuite( static void SetUpEnvironment(Environment* env) { env->SetUp(); } static void TearDownEnvironment(Environment* env) { env->TearDown(); } +// If the environment variable TEST_WARNINGS_OUTPUT_FILE was provided, appends +// `str` to the file, creating the file if necessary. +#if GTEST_HAS_FILE_SYSTEM +static void AppendToTestWarningsOutputFile(const std::string& str) { + const char* const filename = posix::GetEnv(kTestWarningsOutputFile); + if (filename == nullptr) { + return; + } + auto* const file = posix::FOpen(filename, "a"); + if (file == nullptr) { + return; + } + GTEST_CHECK_(fwrite(str.data(), 1, str.size(), file) == str.size()); + GTEST_CHECK_(posix::FClose(file) == 0); +} +#endif // GTEST_HAS_FILE_SYSTEM + // Runs all tests in this UnitTest object, prints the result, and // returns true if all tests are successful. If any exception is // thrown during a test, the test is considered to be failed, but the @@ -5890,6 +5918,28 @@ bool UnitTestImpl::RunAllTests() { // user didn't call InitGoogleTest. PostFlagParsingInit(); + // Handle the case where the program has no tests linked. + // Sometimes this is a programmer mistake, but sometimes it is intended. + if (total_test_count() == 0) { + constexpr char kNoTestLinkedMessage[] = + "This test program does NOT link in any test case."; + constexpr char kNoTestLinkedFatal[] = + "This is INVALID. Please make sure to link in at least one test case."; + constexpr char kNoTestLinkedWarning[] = + "Please make sure this is intended."; + const bool fail_if_no_test_linked = GTEST_FLAG_GET(fail_if_no_test_linked); + ColoredPrintf( + GTestColor::kRed, "%s %s\n", kNoTestLinkedMessage, + fail_if_no_test_linked ? kNoTestLinkedFatal : kNoTestLinkedWarning); + if (fail_if_no_test_linked) { + return false; + } +#if GTEST_HAS_FILE_SYSTEM + AppendToTestWarningsOutputFile(std::string(kNoTestLinkedMessage) + ' ' + + kNoTestLinkedWarning + '\n'); +#endif // GTEST_HAS_FILE_SYSTEM + } + #if GTEST_HAS_FILE_SYSTEM // Even if sharding is not on, test runners may want to use the // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding @@ -6063,6 +6113,17 @@ bool UnitTestImpl::RunAllTests() { environments_.clear(); } + // Try to warn the user if no tests matched the test filter. + if (ShouldWarnIfNoTestsMatchFilter()) { + const std::string filter_warning = + std::string("filter \"") + GTEST_FLAG_GET(filter) + + "\" did not match any test; no tests were run\n"; + ColoredPrintf(GTestColor::kRed, "WARNING: %s", filter_warning.c_str()); +#if GTEST_HAS_FILE_SYSTEM + AppendToTestWarningsOutputFile(filter_warning); +#endif // GTEST_HAS_FILE_SYSTEM + } + if (!gtest_is_initialized_before_run_all_tests) { ColoredPrintf( GTestColor::kRed, @@ -6231,6 +6292,30 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { return num_selected_tests; } +// Returns true if a warning should be issued if no tests match the test filter +// flag. We can't simply count the number of tests that ran because, for +// instance, test sharding and death tests might mean no tests are expected to +// run in this process, but will run in another process. +bool UnitTestImpl::ShouldWarnIfNoTestsMatchFilter() const { + if (total_test_count() == 0) { + // No tests were linked in to program. + // This case is handled by a different warning. + return false; + } + const PositiveAndNegativeUnitTestFilter gtest_flag_filter( + GTEST_FLAG_GET(filter)); + for (auto* test_suite : test_suites_) { + const std::string& test_suite_name = test_suite->name_; + for (TestInfo* test_info : test_suite->test_info_list()) { + const std::string& test_name = test_info->name_; + if (gtest_flag_filter.MatchesTest(test_suite_name, test_name)) { + return false; + } + } + } + return true; +} + // Prints the given C-string on a single line by replacing all '\n' // characters with string "\\n". If the output takes more than // max_length characters, only prints the first max_length characters @@ -6677,6 +6762,7 @@ static bool ParseGoogleTestFlag(const char* const arg) { GTEST_INTERNAL_PARSE_FLAG(death_test_style); GTEST_INTERNAL_PARSE_FLAG(death_test_use_fork); GTEST_INTERNAL_PARSE_FLAG(fail_fast); + GTEST_INTERNAL_PARSE_FLAG(fail_if_no_test_linked); GTEST_INTERNAL_PARSE_FLAG(filter); GTEST_INTERNAL_PARSE_FLAG(internal_run_death_test); GTEST_INTERNAL_PARSE_FLAG(list_tests);