Googletest export
Add helper methos to internal FlatTuple. Refactor constructors. PiperOrigin-RevId: 336306681
This commit is contained in:
parent
0555b0eacb
commit
2cf1f99b97
@ -1209,6 +1209,8 @@ struct ElemFromList {
|
|||||||
static_cast<T (*)()>(nullptr)...));
|
static_cast<T (*)()>(nullptr)...));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FlatTupleConstructTag {};
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
class FlatTuple;
|
class FlatTuple;
|
||||||
|
|
||||||
@ -1219,7 +1221,9 @@ template <typename... T, size_t I>
|
|||||||
struct FlatTupleElemBase<FlatTuple<T...>, I> {
|
struct FlatTupleElemBase<FlatTuple<T...>, I> {
|
||||||
using value_type = typename ElemFromList<I, T...>::type;
|
using value_type = typename ElemFromList<I, T...>::type;
|
||||||
FlatTupleElemBase() = default;
|
FlatTupleElemBase() = default;
|
||||||
explicit FlatTupleElemBase(value_type t) : value(std::move(t)) {}
|
template <typename Arg>
|
||||||
|
explicit FlatTupleElemBase(FlatTupleConstructTag, Arg&& t)
|
||||||
|
: value(std::forward<Arg>(t)) {}
|
||||||
value_type value;
|
value_type value;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1231,8 +1235,30 @@ struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
|
|||||||
: FlatTupleElemBase<FlatTuple<T...>, Idx>... {
|
: FlatTupleElemBase<FlatTuple<T...>, Idx>... {
|
||||||
using Indices = IndexSequence<Idx...>;
|
using Indices = IndexSequence<Idx...>;
|
||||||
FlatTupleBase() = default;
|
FlatTupleBase() = default;
|
||||||
explicit FlatTupleBase(T... t)
|
template <typename... Args>
|
||||||
: FlatTupleElemBase<FlatTuple<T...>, Idx>(std::move(t))... {}
|
explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args)
|
||||||
|
: FlatTupleElemBase<FlatTuple<T...>, Idx>(FlatTupleConstructTag{},
|
||||||
|
std::forward<Args>(args))... {}
|
||||||
|
|
||||||
|
template <size_t I>
|
||||||
|
const typename ElemFromList<I, T...>::type& Get() const {
|
||||||
|
return FlatTupleElemBase<FlatTuple<T...>, I>::value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t I>
|
||||||
|
typename ElemFromList<I, T...>::type& Get() {
|
||||||
|
return FlatTupleElemBase<FlatTuple<T...>, I>::value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
auto Apply(F&& f) -> decltype(std::forward<F>(f)(this->Get<Idx>()...)) {
|
||||||
|
return std::forward<F>(f)(Get<Idx>()...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
auto Apply(F&& f) const -> decltype(std::forward<F>(f)(this->Get<Idx>()...)) {
|
||||||
|
return std::forward<F>(f)(Get<Idx>()...);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Analog to std::tuple but with different tradeoffs.
|
// Analog to std::tuple but with different tradeoffs.
|
||||||
@ -1253,17 +1279,17 @@ class FlatTuple
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
FlatTuple() = default;
|
FlatTuple() = default;
|
||||||
explicit FlatTuple(T... t) : FlatTuple::FlatTupleBase(std::move(t)...) {}
|
template <typename... Args,
|
||||||
|
typename = typename std::enable_if<
|
||||||
|
!std::is_same<void(FlatTuple), void(typename std::decay<
|
||||||
|
Args>::type...)>::value &&
|
||||||
|
(sizeof...(T) >= 1)>::type>
|
||||||
|
explicit FlatTuple(Args&&... args)
|
||||||
|
: FlatTuple::FlatTupleBase(FlatTupleConstructTag{},
|
||||||
|
std::forward<Args>(args)...) {}
|
||||||
|
|
||||||
template <size_t I>
|
using FlatTuple::FlatTupleBase::Apply;
|
||||||
const typename ElemFromList<I, T...>::type& Get() const {
|
using FlatTuple::FlatTupleBase::Get;
|
||||||
return static_cast<const FlatTupleElemBase<FlatTuple, I>*>(this)->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t I>
|
|
||||||
typename ElemFromList<I, T...>::type& Get() {
|
|
||||||
return static_cast<FlatTupleElemBase<FlatTuple, I>*>(this)->value;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Utility functions to be called with static_assert to induce deprecation
|
// Utility functions to be called with static_assert to induce deprecation
|
||||||
@ -1296,6 +1322,14 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
|
|||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
struct tuple_size<testing::internal::FlatTuple<Ts...>>
|
||||||
|
: std::integral_constant<size_t, sizeof...(Ts)> {};
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
#define GTEST_MESSAGE_AT_(file, line, message, result_type) \
|
#define GTEST_MESSAGE_AT_(file, line, message, result_type) \
|
||||||
::testing::internal::AssertHelper(result_type, file, line, message) \
|
::testing::internal::AssertHelper(result_type, file, line, message) \
|
||||||
= ::testing::Message()
|
= ::testing::Message()
|
||||||
|
@ -783,10 +783,15 @@ internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
// Used in the Values() function to provide polymorphic capabilities.
|
// Used in the Values() function to provide polymorphic capabilities.
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4100)
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
class ValueArray {
|
class ValueArray {
|
||||||
public:
|
public:
|
||||||
ValueArray(Ts... v) : v_{std::move(v)...} {}
|
explicit ValueArray(Ts... v) : v_(std::move(v)...) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
operator ParamGenerator<T>() const { // NOLINT
|
operator ParamGenerator<T>() const { // NOLINT
|
||||||
@ -802,6 +807,10 @@ class ValueArray {
|
|||||||
FlatTuple<Ts...> v_;
|
FlatTuple<Ts...> v_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
class CartesianProductGenerator
|
class CartesianProductGenerator
|
||||||
: public ParamGeneratorInterface<::std::tuple<T...>> {
|
: public ParamGeneratorInterface<::std::tuple<T...>> {
|
||||||
|
@ -64,6 +64,7 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) {
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -7533,6 +7534,142 @@ TEST(FlatTuple, Basic) {
|
|||||||
EXPECT_EQ(5.1, tuple.Get<1>());
|
EXPECT_EQ(5.1, tuple.Get<1>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
std::string AddIntToString(int i, const std::string& s) {
|
||||||
|
return s + std::to_string(i);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST(FlatTuple, Apply) {
|
||||||
|
using testing::internal::FlatTuple;
|
||||||
|
|
||||||
|
FlatTuple<int, std::string> tuple{5, "Hello"};
|
||||||
|
|
||||||
|
// Lambda.
|
||||||
|
EXPECT_TRUE(tuple.Apply([](int i, const std::string& s) -> bool {
|
||||||
|
return i == static_cast<int>(s.size());
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Function.
|
||||||
|
EXPECT_EQ(tuple.Apply(AddIntToString), "Hello5");
|
||||||
|
|
||||||
|
// Mutating operations.
|
||||||
|
tuple.Apply([](int& i, std::string& s) {
|
||||||
|
++i;
|
||||||
|
s += s;
|
||||||
|
});
|
||||||
|
EXPECT_EQ(tuple.Get<0>(), 6);
|
||||||
|
EXPECT_EQ(tuple.Get<1>(), "HelloHello");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ConstructionCounting {
|
||||||
|
ConstructionCounting() { ++default_ctor_calls; }
|
||||||
|
~ConstructionCounting() { ++dtor_calls; }
|
||||||
|
ConstructionCounting(const ConstructionCounting&) { ++copy_ctor_calls; }
|
||||||
|
ConstructionCounting(ConstructionCounting&&) noexcept { ++move_ctor_calls; }
|
||||||
|
ConstructionCounting& operator=(const ConstructionCounting&) {
|
||||||
|
++copy_assignment_calls;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
ConstructionCounting& operator=(ConstructionCounting&&) noexcept {
|
||||||
|
++move_assignment_calls;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Reset() {
|
||||||
|
default_ctor_calls = 0;
|
||||||
|
dtor_calls = 0;
|
||||||
|
copy_ctor_calls = 0;
|
||||||
|
move_ctor_calls = 0;
|
||||||
|
copy_assignment_calls = 0;
|
||||||
|
move_assignment_calls = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int default_ctor_calls;
|
||||||
|
static int dtor_calls;
|
||||||
|
static int copy_ctor_calls;
|
||||||
|
static int move_ctor_calls;
|
||||||
|
static int copy_assignment_calls;
|
||||||
|
static int move_assignment_calls;
|
||||||
|
};
|
||||||
|
|
||||||
|
int ConstructionCounting::default_ctor_calls = 0;
|
||||||
|
int ConstructionCounting::dtor_calls = 0;
|
||||||
|
int ConstructionCounting::copy_ctor_calls = 0;
|
||||||
|
int ConstructionCounting::move_ctor_calls = 0;
|
||||||
|
int ConstructionCounting::copy_assignment_calls = 0;
|
||||||
|
int ConstructionCounting::move_assignment_calls = 0;
|
||||||
|
|
||||||
|
TEST(FlatTuple, ConstructorCalls) {
|
||||||
|
using testing::internal::FlatTuple;
|
||||||
|
|
||||||
|
// Default construction.
|
||||||
|
ConstructionCounting::Reset();
|
||||||
|
{ FlatTuple<ConstructionCounting> tuple; }
|
||||||
|
EXPECT_EQ(ConstructionCounting::default_ctor_calls, 1);
|
||||||
|
EXPECT_EQ(ConstructionCounting::dtor_calls, 1);
|
||||||
|
EXPECT_EQ(ConstructionCounting::copy_ctor_calls, 0);
|
||||||
|
EXPECT_EQ(ConstructionCounting::move_ctor_calls, 0);
|
||||||
|
EXPECT_EQ(ConstructionCounting::copy_assignment_calls, 0);
|
||||||
|
EXPECT_EQ(ConstructionCounting::move_assignment_calls, 0);
|
||||||
|
|
||||||
|
// Copy construction.
|
||||||
|
ConstructionCounting::Reset();
|
||||||
|
{
|
||||||
|
ConstructionCounting elem;
|
||||||
|
FlatTuple<ConstructionCounting> tuple{elem};
|
||||||
|
}
|
||||||
|
EXPECT_EQ(ConstructionCounting::default_ctor_calls, 1);
|
||||||
|
EXPECT_EQ(ConstructionCounting::dtor_calls, 2);
|
||||||
|
EXPECT_EQ(ConstructionCounting::copy_ctor_calls, 1);
|
||||||
|
EXPECT_EQ(ConstructionCounting::move_ctor_calls, 0);
|
||||||
|
EXPECT_EQ(ConstructionCounting::copy_assignment_calls, 0);
|
||||||
|
EXPECT_EQ(ConstructionCounting::move_assignment_calls, 0);
|
||||||
|
|
||||||
|
// Move construction.
|
||||||
|
ConstructionCounting::Reset();
|
||||||
|
{ FlatTuple<ConstructionCounting> tuple{ConstructionCounting{}}; }
|
||||||
|
EXPECT_EQ(ConstructionCounting::default_ctor_calls, 1);
|
||||||
|
EXPECT_EQ(ConstructionCounting::dtor_calls, 2);
|
||||||
|
EXPECT_EQ(ConstructionCounting::copy_ctor_calls, 0);
|
||||||
|
EXPECT_EQ(ConstructionCounting::move_ctor_calls, 1);
|
||||||
|
EXPECT_EQ(ConstructionCounting::copy_assignment_calls, 0);
|
||||||
|
EXPECT_EQ(ConstructionCounting::move_assignment_calls, 0);
|
||||||
|
|
||||||
|
// Copy assignment.
|
||||||
|
// TODO(ofats): it should be testing assignment operator of FlatTuple, not its
|
||||||
|
// elements
|
||||||
|
ConstructionCounting::Reset();
|
||||||
|
{
|
||||||
|
FlatTuple<ConstructionCounting> tuple;
|
||||||
|
ConstructionCounting elem;
|
||||||
|
tuple.Get<0>() = elem;
|
||||||
|
}
|
||||||
|
EXPECT_EQ(ConstructionCounting::default_ctor_calls, 2);
|
||||||
|
EXPECT_EQ(ConstructionCounting::dtor_calls, 2);
|
||||||
|
EXPECT_EQ(ConstructionCounting::copy_ctor_calls, 0);
|
||||||
|
EXPECT_EQ(ConstructionCounting::move_ctor_calls, 0);
|
||||||
|
EXPECT_EQ(ConstructionCounting::copy_assignment_calls, 1);
|
||||||
|
EXPECT_EQ(ConstructionCounting::move_assignment_calls, 0);
|
||||||
|
|
||||||
|
// Move assignment.
|
||||||
|
// TODO(ofats): it should be testing assignment operator of FlatTuple, not its
|
||||||
|
// elements
|
||||||
|
ConstructionCounting::Reset();
|
||||||
|
{
|
||||||
|
FlatTuple<ConstructionCounting> tuple;
|
||||||
|
tuple.Get<0>() = ConstructionCounting{};
|
||||||
|
}
|
||||||
|
EXPECT_EQ(ConstructionCounting::default_ctor_calls, 2);
|
||||||
|
EXPECT_EQ(ConstructionCounting::dtor_calls, 2);
|
||||||
|
EXPECT_EQ(ConstructionCounting::copy_ctor_calls, 0);
|
||||||
|
EXPECT_EQ(ConstructionCounting::move_ctor_calls, 0);
|
||||||
|
EXPECT_EQ(ConstructionCounting::copy_assignment_calls, 0);
|
||||||
|
EXPECT_EQ(ConstructionCounting::move_assignment_calls, 1);
|
||||||
|
|
||||||
|
ConstructionCounting::Reset();
|
||||||
|
}
|
||||||
|
|
||||||
TEST(FlatTuple, ManyTypes) {
|
TEST(FlatTuple, ManyTypes) {
|
||||||
using testing::internal::FlatTuple;
|
using testing::internal::FlatTuple;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user