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)...));
|
||||
};
|
||||
|
||||
struct FlatTupleConstructTag {};
|
||||
|
||||
template <typename... T>
|
||||
class FlatTuple;
|
||||
|
||||
@ -1219,7 +1221,9 @@ template <typename... T, size_t I>
|
||||
struct FlatTupleElemBase<FlatTuple<T...>, I> {
|
||||
using value_type = typename ElemFromList<I, T...>::type;
|
||||
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;
|
||||
};
|
||||
|
||||
@ -1231,8 +1235,30 @@ struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
|
||||
: FlatTupleElemBase<FlatTuple<T...>, Idx>... {
|
||||
using Indices = IndexSequence<Idx...>;
|
||||
FlatTupleBase() = default;
|
||||
explicit FlatTupleBase(T... t)
|
||||
: FlatTupleElemBase<FlatTuple<T...>, Idx>(std::move(t))... {}
|
||||
template <typename... Args>
|
||||
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.
|
||||
@ -1253,17 +1279,17 @@ class FlatTuple
|
||||
|
||||
public:
|
||||
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>
|
||||
const typename ElemFromList<I, T...>::type& Get() const {
|
||||
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;
|
||||
}
|
||||
using FlatTuple::FlatTupleBase::Apply;
|
||||
using FlatTuple::FlatTupleBase::Get;
|
||||
};
|
||||
|
||||
// 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 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) \
|
||||
::testing::internal::AssertHelper(result_type, file, line, message) \
|
||||
= ::testing::Message()
|
||||
|
@ -783,10 +783,15 @@ internal::ParamGenerator<typename Container::value_type> ValuesIn(
|
||||
namespace internal {
|
||||
// Used in the Values() function to provide polymorphic capabilities.
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4100)
|
||||
#endif
|
||||
|
||||
template <typename... Ts>
|
||||
class ValueArray {
|
||||
public:
|
||||
ValueArray(Ts... v) : v_{std::move(v)...} {}
|
||||
explicit ValueArray(Ts... v) : v_(std::move(v)...) {}
|
||||
|
||||
template <typename T>
|
||||
operator ParamGenerator<T>() const { // NOLINT
|
||||
@ -802,6 +807,10 @@ class ValueArray {
|
||||
FlatTuple<Ts...> v_;
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <typename... T>
|
||||
class CartesianProductGenerator
|
||||
: public ParamGeneratorInterface<::std::tuple<T...>> {
|
||||
|
@ -64,6 +64,7 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) {
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
@ -7533,6 +7534,142 @@ TEST(FlatTuple, Basic) {
|
||||
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) {
|
||||
using testing::internal::FlatTuple;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user