15 #include "absl/container/internal/compressed_tuple.h"
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
22 #include "absl/container/internal/test_instance_tracker.h"
23 #include "absl/memory/memory.h"
24 #include "absl/types/any.h"
25 #include "absl/types/optional.h"
26 #include "absl/utility/utility.h"
43 template <
typename T,
typename U>
52 namespace container_internal {
59 EXPECT_EQ(
sizeof(
int),
sizeof(CompressedTuple<int>));
73 TEST(CompressedTupleTest, OneMoveOnRValueConstructionTemp) {
75 CompressedTuple<CopyableMovableInstance> x1(CopyableMovableInstance(1));
82 TEST(CompressedTupleTest, OneMoveOnRValueConstructionMove) {
85 CopyableMovableInstance
i1(1);
86 CompressedTuple<CopyableMovableInstance> x1(
std::move(
i1));
93 TEST(CompressedTupleTest, OneMoveOnRValueConstructionMixedTypes) {
95 CopyableMovableInstance
i1(1);
96 CopyableMovableInstance
i2(2);
98 CompressedTuple<CopyableMovableInstance, CopyableMovableInstance&, Empty<0>>
106 struct IncompleteType;
107 CompressedTuple<CopyableMovableInstance, IncompleteType&, Empty<0>>
108 MakeWithIncomplete(CopyableMovableInstance
i1,
111 return CompressedTuple<CopyableMovableInstance, IncompleteType&, Empty<0>>{
115 struct IncompleteType {};
116 TEST(CompressedTupleTest, OneMoveOnRValueConstructionWithIncompleteType) {
118 CopyableMovableInstance
i1(1);
120 struct DerivedType : IncompleteType {
int value = 0;};
124 CompressedTuple<CopyableMovableInstance, IncompleteType&, Empty<0>> x1 =
128 EXPECT_EQ(
static_cast<DerivedType&
>(x1.get<1>()).value, 7);
134 TEST(CompressedTupleTest,
135 OneMoveOnRValueConstructionMixedTypes_BraceInitPoisonPillExpected) {
137 CopyableMovableInstance
i1(1);
138 CopyableMovableInstance
i2(2);
139 CompressedTuple<CopyableMovableInstance, CopyableMovableInstance&, Empty<0>>
153 TEST(CompressedTupleTest, OneCopyOnLValueConstruction) {
155 CopyableMovableInstance
i1(1);
157 CompressedTuple<CopyableMovableInstance> x1(
i1);
161 tracker.ResetCopiesMovesSwaps();
163 CopyableMovableInstance
i2(2);
164 const CopyableMovableInstance& i2_ref =
i2;
165 CompressedTuple<CopyableMovableInstance> x2(i2_ref);
170 TEST(CompressedTupleTest, OneMoveOnRValueAccess) {
172 CopyableMovableInstance
i1(1);
173 CompressedTuple<CopyableMovableInstance>
x(
std::move(
i1));
174 tracker.ResetCopiesMovesSwaps();
181 TEST(CompressedTupleTest, OneCopyOnLValueAccess) {
184 CompressedTuple<CopyableMovableInstance>
x(CopyableMovableInstance(0));
188 CopyableMovableInstance t =
x.get<0>();
193 TEST(CompressedTupleTest, ZeroCopyOnRefAccess) {
196 CompressedTuple<CopyableMovableInstance>
x(CopyableMovableInstance(0));
200 CopyableMovableInstance&
t1 =
x.get<0>();
201 const CopyableMovableInstance& t2 =
x.get<0>();
208 TEST(CompressedTupleTest, Access) {
212 CompressedTuple<int, Empty<0>,
S>
x(7, {},
S{
"ABC"});
218 TEST(CompressedTupleTest, NonClasses) {
219 CompressedTuple<int, const char*>
x(7,
"ABC");
224 TEST(CompressedTupleTest, MixClassAndNonClass) {
238 TEST(CompressedTupleTest, Nested) {
239 CompressedTuple<int, CompressedTuple<int>,
240 CompressedTuple<int, CompressedTuple<int>>>
241 x(1, CompressedTuple<int>(2),
242 CompressedTuple<
int, CompressedTuple<int>>(3, CompressedTuple<int>(4)));
249 CompressedTuple<Empty<0>, CompressedTuple<Empty<0>>>>
251 std::set<Empty<0>*> empties{&
y.get<0>(), &
y.get<1>(), &
y.get<2>().get<0>(),
252 &
y.get<2>().get<1>().get<0>()};
266 sizeof(CompressedTuple<CompressedTuple<char, char>,
267 CompressedTuple<char, char>>));
271 struct CT_Empty : CompressedTuple<Empty<0>> {};
272 CompressedTuple<Empty<0>, CT_Empty> nested_empty;
273 auto contained = nested_empty.get<0>();
274 auto nested = nested_empty.get<1>().get<0>();
280 std::string s =
"Very long string that goes in the heap";
281 CompressedTuple<int, int&, std::string, std::string&>
x(
i,
i, s, s);
284 EXPECT_EQ(s,
"Very long string that goes in the heap");
295 TEST(CompressedTupleTest, NoElements) {
297 static_cast<void>(
x);
301 TEST(CompressedTupleTest, MoveOnlyElements) {
302 CompressedTuple<std::unique_ptr<std::string>> str_tup(
303 absl::make_unique<std::string>(
"str"));
305 CompressedTuple<CompressedTuple<std::unique_ptr<std::string>>,
306 std::unique_ptr<int>>
307 x(
std::move(str_tup), absl::make_unique<int>(5));
312 std::unique_ptr<std::string> x0 =
std::move(
x.get<0>()).get<0>();
313 std::unique_ptr<int> x1 =
std::move(
x).get<1>();
319 TEST(CompressedTupleTest, MoveConstructionMoveOnlyElements) {
320 CompressedTuple<std::unique_ptr<std::string>>
base(
321 absl::make_unique<std::string>(
"str"));
328 TEST(CompressedTupleTest, AnyElements) {
330 CompressedTuple<any, any&>
x(any(5),
a);
331 EXPECT_EQ(absl::any_cast<int>(
x.get<0>()), 5);
332 EXPECT_EQ(absl::any_cast<std::string>(
x.get<1>()),
"str");
335 EXPECT_EQ(absl::any_cast<float>(
x.get<1>()), 0.5);
338 TEST(CompressedTupleTest, Constexpr) {
339 struct NonTrivialStruct {
340 constexpr NonTrivialStruct() =
default;
341 constexpr
int value()
const {
return v; }
344 struct TrivialStruct {
345 TrivialStruct() =
default;
346 constexpr
int value()
const {
return v; }
349 constexpr CompressedTuple<int, double, CompressedTuple<int>,
Empty<0>>
x(
350 7, 1.25, CompressedTuple<int>(5), {});
351 constexpr
int x0 =
x.get<0>();
352 constexpr
double x1 =
x.get<1>();
353 constexpr
int x2 =
x.get<2>().get<0>();
361 #if !defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4
362 constexpr CompressedTuple<Empty<0>, TrivialStruct,
int> trivial = {};
364 constexpr
int trivial1 = trivial.get<1>().
value();
365 constexpr
int trivial2 = trivial.get<2>();
374 constexpr
CallType non_trivial0 = non_trivial.get<0>().
value();
375 constexpr
int non_trivial1 = non_trivial.get<1>().
value();
382 static constexpr
char data[] =
"DEF";
383 constexpr CompressedTuple<const char*>
z(
data);
384 constexpr
const char* z1 =
z.get<0>();
387 #if defined(__clang__)
389 constexpr
int x2m =
absl::move(
x.get<2>()).get<0>();
396 #if defined(__clang__) || defined(__GNUC__)
397 TEST(CompressedTupleTest, EmptyFinalClass) {
399 int f()
const {
return 5; }
401 CompressedTuple<S>
x;
407 TEST(CompressedTupleTest, DISABLED_NestedEbo) {
410 CompressedTuple<Empty1, CompressedTuple<Empty2>,
int>
x;
411 CompressedTuple<Empty1, Empty2, int>
y;