From 0af976647f49ff0944c5971ae0a45d6fcdf1ecca Mon Sep 17 00:00:00 2001 From: Lawrence Wolf-Sonkin Date: Thu, 4 Apr 2024 12:37:50 -0700 Subject: [gtest] Use `std::index_sequence` and friends instead of rolling our own * Applies for `std::index_sequence`, `std::make_index_sequence`, and `std::index_sequence_for` replacing `IndexSequence`, `MakeIndexSequence` and IndexSequenceFor` * Also deleted implementation helper `DoubleSequence` * The standard interfaces [have been in the standard library since C++14](https://en.cppreference.com/w/cpp/utility/integer_sequence), which [is the minimum supported C++ version by Google Test](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md) PiperOrigin-RevId: 621939977 Change-Id: Id264266f08da66c0fa2a6e6fbb8f86fd3cb3a421 --- googlemock/include/gmock/gmock-actions.h | 6 +-- googlemock/include/gmock/gmock-matchers.h | 56 +++++++++++----------- .../include/gmock/internal/gmock-internal-utils.h | 14 +++--- googlemock/src/gmock-internal-utils.cc | 5 +- googletest/include/gtest/internal/gtest-internal.h | 54 ++++----------------- .../include/gtest/internal/gtest-param-util.h | 8 ++-- googletest/test/gtest_unittest.cc | 16 ------- 7 files changed, 56 insertions(+), 103 deletions(-) diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index fab9993..7e17b30 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -2135,13 +2135,13 @@ struct ActionImpl : ImplBase::type { R operator()(Args&&... arg) const { static constexpr size_t kMaxArgs = sizeof...(Args) <= 10 ? sizeof...(Args) : 10; - return Apply(MakeIndexSequence{}, - MakeIndexSequence<10 - kMaxArgs>{}, + return Apply(std::make_index_sequence{}, + std::make_index_sequence<10 - kMaxArgs>{}, args_type{std::forward(arg)...}); } template - R Apply(IndexSequence, IndexSequence, + R Apply(std::index_sequence, std::index_sequence, const args_type& args) const { // Impl need not be specific to the signature of action being implemented; // only the implementing function body needs to have all of the specific diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index c4149f2..6b6b437 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -490,12 +490,12 @@ class MatcherBaseImpl> { template operator ::testing::Matcher() const { // NOLINT(runtime/explicit) - return Apply(MakeIndexSequence{}); + return Apply(std::make_index_sequence{}); } private: template - ::testing::Matcher Apply(IndexSequence) const { + ::testing::Matcher Apply(std::index_sequence) const { return ::testing::Matcher( new typename Derived::template gmock_Impl( std::get(params_)...)); @@ -3152,8 +3152,8 @@ class PairMatcher { }; template -auto UnpackStructImpl(const T& t, IndexSequence, 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)...); @@ -3161,97 +3161,97 @@ auto UnpackStructImpl(const T& t, IndexSequence, int) #if defined(__cpp_structured_bindings) && __cpp_structured_bindings >= 201606 template -auto UnpackStructImpl(const T& t, MakeIndexSequence<1>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<1>, char) { const auto& [a] = t; return std::tie(a); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<2>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<2>, char) { const auto& [a, b] = t; return std::tie(a, b); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<3>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<3>, char) { const auto& [a, b, c] = t; return std::tie(a, b, c); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<4>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<4>, char) { const auto& [a, b, c, d] = t; return std::tie(a, b, c, d); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<5>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<5>, char) { const auto& [a, b, c, d, e] = t; return std::tie(a, b, c, d, e); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<6>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<6>, char) { const auto& [a, b, c, d, e, f] = t; return std::tie(a, b, c, d, e, f); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<7>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<7>, char) { const auto& [a, b, c, d, e, f, g] = t; return std::tie(a, b, c, d, e, f, g); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<8>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<8>, char) { const auto& [a, b, c, d, e, f, g, h] = t; return std::tie(a, b, c, d, e, f, g, h); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<9>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<9>, char) { const auto& [a, b, c, d, e, f, g, h, i] = t; return std::tie(a, b, c, d, e, f, g, h, i); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<10>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<10>, char) { const auto& [a, b, c, d, e, f, g, h, i, j] = t; return std::tie(a, b, c, d, e, f, g, h, i, j); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<11>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<11>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<12>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<12>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<13>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<13>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<14>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<14>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<15>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<15>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<16>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<16>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<17>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<17>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<18>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<18>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r); } template -auto UnpackStructImpl(const T& t, MakeIndexSequence<19>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<19>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s); } @@ -3259,8 +3259,8 @@ auto UnpackStructImpl(const T& t, MakeIndexSequence<19>, char) { template auto UnpackStruct(const T& t) - -> decltype((UnpackStructImpl)(t, MakeIndexSequence{}, 0)) { - return (UnpackStructImpl)(t, MakeIndexSequence{}, 0); + -> decltype((UnpackStructImpl)(t, std::make_index_sequence{}, 0)) { + return (UnpackStructImpl)(t, std::make_index_sequence{}, 0); } // Helper function to do comma folding in C++11. @@ -3273,7 +3273,7 @@ template class FieldsAreMatcherImpl; template -class FieldsAreMatcherImpl> +class FieldsAreMatcherImpl> : public MatcherInterface { using UnpackedType = decltype(UnpackStruct(std::declval())); @@ -3355,8 +3355,8 @@ class FieldsAreMatcher { template operator Matcher() const { // NOLINT return Matcher( - new FieldsAreMatcherImpl>( - matchers_)); + new FieldsAreMatcherImpl>(matchers_)); } private: diff --git a/googlemock/include/gmock/internal/gmock-internal-utils.h b/googlemock/include/gmock/internal/gmock-internal-utils.h index ead6d7c..b7685f5 100644 --- a/googlemock/include/gmock/internal/gmock-internal-utils.h +++ b/googlemock/include/gmock/internal/gmock-internal-utils.h @@ -44,6 +44,7 @@ #include // NOLINT #include #include +#include #include #include "gmock/internal/gmock-port.h" @@ -420,7 +421,7 @@ struct RemoveConstFromKey > { GTEST_API_ void IllegalDoDefault(const char* file, int line); template -auto ApplyImpl(F&& f, Tuple&& args, IndexSequence) +auto ApplyImpl(F&& f, Tuple&& args, std::index_sequence) -> decltype(std::forward(f)( std::get(std::forward(args))...)) { return std::forward(f)(std::get(std::forward(args))...); @@ -428,12 +429,13 @@ auto ApplyImpl(F&& f, Tuple&& args, IndexSequence) // Apply the function to a tuple of arguments. template -auto Apply(F&& f, Tuple&& args) -> decltype(ApplyImpl( - std::forward(f), std::forward(args), - MakeIndexSequence::type>::value>())) { +auto Apply(F&& f, Tuple&& args) + -> decltype(ApplyImpl( + std::forward(f), std::forward(args), + std::make_index_sequence::type>::value>())) { return ApplyImpl(std::forward(f), std::forward(args), - MakeIndexSequence::type>::value>()); } diff --git a/googlemock/src/gmock-internal-utils.cc b/googlemock/src/gmock-internal-utils.cc index 5c2ce0d..96c7e30 100644 --- a/googlemock/src/gmock-internal-utils.cc +++ b/googlemock/src/gmock-internal-utils.cc @@ -44,6 +44,7 @@ #include #include // NOLINT #include +#include #include #include "gmock/gmock.h" @@ -211,14 +212,14 @@ constexpr char UnBase64Impl(char c, const char* const base64, char carry) { } template -constexpr std::array UnBase64Impl(IndexSequence, +constexpr std::array UnBase64Impl(std::index_sequence, const char* const base64) { return { {UnBase64Impl(UndoWebSafeEncoding(static_cast(I)), base64, 0)...}}; } constexpr std::array UnBase64(const char* const base64) { - return UnBase64Impl(MakeIndexSequence<256>{}, base64); + return UnBase64Impl(std::make_index_sequence<256>{}, base64); } static constexpr char kBase64[] = diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h index 4661248..cffb8e1 100644 --- a/googletest/include/gtest/internal/gtest-internal.h +++ b/googletest/include/gtest/internal/gtest-internal.h @@ -1137,40 +1137,6 @@ class NativeArray { void (NativeArray::*clone_)(const Element*, size_t); }; -// Backport of std::index_sequence. -template -struct IndexSequence { - using type = IndexSequence; -}; - -// Double the IndexSequence, and one if plus_one is true. -template -struct DoubleSequence; -template -struct DoubleSequence, sizeofT> { - using type = IndexSequence; -}; -template -struct DoubleSequence, sizeofT> { - using type = IndexSequence; -}; - -// Backport of std::make_index_sequence. -// It uses O(ln(N)) instantiation depth. -template -struct MakeIndexSequenceImpl - : DoubleSequence::type, - N / 2>::type {}; - -template <> -struct MakeIndexSequenceImpl<0> : IndexSequence<> {}; - -template -using MakeIndexSequence = typename MakeIndexSequenceImpl::type; - -template -using IndexSequenceFor = typename MakeIndexSequence::type; - template struct Ignore { Ignore(...); // NOLINT @@ -1179,7 +1145,7 @@ struct Ignore { template struct ElemFromListImpl; template -struct ElemFromListImpl> { +struct ElemFromListImpl> { // We make Ignore a template to solve a problem with MSVC. // A non-template Ignore would work fine with `decltype(Ignore(I))...`, but // MSVC doesn't understand how to deal with that pack expansion. @@ -1190,9 +1156,8 @@ struct ElemFromListImpl> { template struct ElemFromList { - using type = - decltype(ElemFromListImpl::type>::Apply( - static_cast(nullptr)...)); + using type = decltype(ElemFromListImpl>::Apply( + static_cast(nullptr)...)); }; struct FlatTupleConstructTag {}; @@ -1217,9 +1182,9 @@ template struct FlatTupleBase; template -struct FlatTupleBase, IndexSequence> +struct FlatTupleBase, std::index_sequence> : FlatTupleElemBase, Idx>... { - using Indices = IndexSequence; + using Indices = std::index_sequence; FlatTupleBase() = default; template explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args) @@ -1254,14 +1219,15 @@ struct FlatTupleBase, IndexSequence> // implementations. // FlatTuple and ElemFromList are not recursive and have a fixed depth // regardless of T... -// MakeIndexSequence, on the other hand, it is recursive but with an +// std::make_index_sequence, on the other hand, it is recursive but with an // instantiation depth of O(ln(N)). template class FlatTuple : private FlatTupleBase, - typename MakeIndexSequence::type> { - using Indices = typename FlatTupleBase< - FlatTuple, typename MakeIndexSequence::type>::Indices; + std::make_index_sequence> { + using Indices = + typename FlatTupleBase, + std::make_index_sequence>::Indices; public: FlatTuple() = default; diff --git a/googletest/include/gtest/internal/gtest-param-util.h b/googletest/include/gtest/internal/gtest-param-util.h index 1fc500f..cc7ea53 100644 --- a/googletest/include/gtest/internal/gtest-param-util.h +++ b/googletest/include/gtest/internal/gtest-param-util.h @@ -807,12 +807,12 @@ class ValueArray { template operator ParamGenerator() const { // NOLINT - return ValuesIn(MakeVector(MakeIndexSequence())); + return ValuesIn(MakeVector(std::make_index_sequence())); } private: template - std::vector MakeVector(IndexSequence) const { + std::vector MakeVector(std::index_sequence) const { return std::vector{static_cast(v_.template Get())...}; } @@ -842,7 +842,7 @@ class CartesianProductGenerator template class IteratorImpl; template - class IteratorImpl> + class IteratorImpl> : public ParamIteratorInterface { public: IteratorImpl(const ParamGeneratorInterface* base, @@ -933,7 +933,7 @@ class CartesianProductGenerator std::shared_ptr current_value_; }; - using Iterator = IteratorImpl::type>; + using Iterator = IteratorImpl>; std::tuple...> generators_; }; diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index 5d7cfb0..edbe2ea 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -7482,22 +7482,6 @@ TEST(NativeArrayTest, WorksForTwoDimensionalArray) { EXPECT_EQ(a, na.begin()); } -// IndexSequence -TEST(IndexSequence, MakeIndexSequence) { - using testing::internal::IndexSequence; - using testing::internal::MakeIndexSequence; - EXPECT_TRUE( - (std::is_same, MakeIndexSequence<0>::type>::value)); - EXPECT_TRUE( - (std::is_same, MakeIndexSequence<1>::type>::value)); - EXPECT_TRUE( - (std::is_same, MakeIndexSequence<2>::type>::value)); - EXPECT_TRUE(( - std::is_same, MakeIndexSequence<3>::type>::value)); - EXPECT_TRUE( - (std::is_base_of, MakeIndexSequence<3>>::value)); -} - // ElemFromList TEST(ElemFromList, Basic) { using testing::internal::ElemFromList; -- cgit v0.12