blob: 30316c9a623cb049fd06216bfe3cc28458ffcae9 [file] [log] [blame] [edit]
// Copyright 2026 The Abseil Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "absl/extend/internal/aggregate.h"
#include <tuple>
#include <type_traits>
#include <utility>
#include "gtest/gtest.h"
#include "absl/base/config.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace aggregate_internal {
namespace {
TEST(Qualifiers, Collapse) {
EXPECT_EQ(kRef | kRefRef, kRef);
EXPECT_NE(kConst, kVolatile);
EXPECT_NE(kConst, kRef);
EXPECT_NE(kConst, kRefRef);
EXPECT_NE(kVolatile, kRef);
EXPECT_NE(kVolatile, kRefRef);
EXPECT_NE(kRef, kRefRef);
}
TEST(ExtractQualifiers, Works) {
EXPECT_EQ(ExtractQualifiers<int>(), 0);
EXPECT_EQ(ExtractQualifiers<int&>(), kRef);
EXPECT_EQ(ExtractQualifiers<int&&>(), kRefRef);
EXPECT_EQ(ExtractQualifiers<const int>(), kConst);
EXPECT_EQ(ExtractQualifiers<const int&>(), kConst | kRef);
EXPECT_EQ(ExtractQualifiers<const int&&>(), kConst | kRefRef);
EXPECT_EQ(ExtractQualifiers<volatile int>(), kVolatile);
EXPECT_EQ(ExtractQualifiers<volatile int&>(), kVolatile | kRef);
EXPECT_EQ(ExtractQualifiers<volatile int&&>(), kVolatile | kRefRef);
EXPECT_EQ(ExtractQualifiers<volatile const int>(), kVolatile | kConst);
EXPECT_EQ(ExtractQualifiers<volatile const int&>(),
kVolatile | kConst | kRef);
EXPECT_EQ(ExtractQualifiers<volatile const int&&>(),
kVolatile | kConst | kRefRef);
}
TEST(ApplyQualifiers, OnBareType) {
EXPECT_TRUE((std::is_same_v<typename ApplyQualifiers<int, 0>::type, int>));
EXPECT_TRUE(
(std::is_same_v<typename ApplyQualifiers<int, kRef>::type, int&>));
EXPECT_TRUE(
(std::is_same_v<typename ApplyQualifiers<int, kRefRef>::type, int&&>));
EXPECT_TRUE(
(std::is_same_v<typename ApplyQualifiers<int, kConst>::type, const int>));
EXPECT_TRUE(
(std::is_same_v<typename ApplyQualifiers<int, kConst | kRef>::type,
const int&>));
EXPECT_TRUE(
(std::is_same_v<typename ApplyQualifiers<int, kConst | kRefRef>::type,
const int&&>));
EXPECT_TRUE((std::is_same_v<typename ApplyQualifiers<int, kVolatile>::type,
volatile int>));
EXPECT_TRUE(
(std::is_same_v<typename ApplyQualifiers<int, kVolatile | kRef>::type,
volatile int&>));
EXPECT_TRUE(
(std::is_same_v<typename ApplyQualifiers<int, kVolatile | kRefRef>::type,
volatile int&&>));
EXPECT_TRUE(
(std::is_same_v<typename ApplyQualifiers<int, kVolatile | kConst>::type,
volatile const int>));
EXPECT_TRUE((std::is_same_v<
typename ApplyQualifiers<int, kVolatile | kConst | kRef>::type,
volatile const int&>));
EXPECT_TRUE(
(std::is_same_v<
typename ApplyQualifiers<int, kVolatile | kConst | kRefRef>::type,
volatile const int&&>));
}
TEST(ApplyQualifiers, OnConstType) {
EXPECT_TRUE((
std::is_same_v<typename ApplyQualifiers<const int, 0>::type, const int>));
EXPECT_TRUE((std::is_same_v<typename ApplyQualifiers<const int, kRef>::type,
const int&>));
EXPECT_TRUE(
(std::is_same_v<typename ApplyQualifiers<const int, kRefRef>::type,
const int&&>));
EXPECT_TRUE((std::is_same_v<typename ApplyQualifiers<const int, kConst>::type,
const int>));
EXPECT_TRUE(
(std::is_same_v<typename ApplyQualifiers<const int, kConst | kRef>::type,
const int&>));
EXPECT_TRUE((std::is_same_v<
typename ApplyQualifiers<const int, kConst | kRefRef>::type,
const int&&>));
EXPECT_TRUE(
(std::is_same_v<typename ApplyQualifiers<const int, kVolatile>::type,
const volatile int>));
EXPECT_TRUE((std::is_same_v<
typename ApplyQualifiers<const int, kVolatile | kRef>::type,
const volatile int&>));
EXPECT_TRUE((std::is_same_v<
typename ApplyQualifiers<const int, kVolatile | kRefRef>::type,
const volatile int&&>));
EXPECT_TRUE((std::is_same_v<
typename ApplyQualifiers<const int, kVolatile | kConst>::type,
volatile const int>));
EXPECT_TRUE(
(std::is_same_v<
typename ApplyQualifiers<const int, kVolatile | kConst | kRef>::type,
volatile const int&>));
EXPECT_TRUE(
(std::is_same_v<typename ApplyQualifiers<const int, kVolatile | kConst |
kRefRef>::type,
volatile const int&&>));
}
TEST(CorrectQualifiers, Type) {
struct A {
int val;
int&& rval;
const int cval;
const int& clval;
const int&& crval;
};
A a{
3, // .val
static_cast<int&&>(a.val), // .rval
3, // .cval
a.cval, // .clval
static_cast<const int&&>(a.cval) // .crval
};
auto&& [v, r, c, cl, cr] = a;
testing::StaticAssertTypeEq<decltype(CorrectQualifiers<A, decltype(v)>(v)),
int&&>();
testing::StaticAssertTypeEq<decltype(CorrectQualifiers<A, decltype(r)>(r)),
int&&>();
testing::StaticAssertTypeEq<decltype(CorrectQualifiers<A, decltype(c)>(c)),
const int&&>();
testing::StaticAssertTypeEq<decltype(CorrectQualifiers<A, decltype(cl)>(cl)),
const int&>();
testing::StaticAssertTypeEq<decltype(CorrectQualifiers<A&, decltype(v)>(v)),
int&>();
testing::StaticAssertTypeEq<decltype(CorrectQualifiers<A&, decltype(r)>(r)),
int&&>();
testing::StaticAssertTypeEq<decltype(CorrectQualifiers<A&, decltype(c)>(c)),
const int&>();
testing::StaticAssertTypeEq<decltype(CorrectQualifiers<A&, decltype(cl)>(cl)),
const int&>();
testing::StaticAssertTypeEq<
decltype(CorrectQualifiers<const A&, decltype(v)>(v)), const int&>();
testing::StaticAssertTypeEq<
decltype(CorrectQualifiers<const A&, decltype(r)>(r)), int&&>();
}
TEST(RemoveQualifiersAndReferencesFromTuple, Type) {
EXPECT_TRUE(
(std::is_same_v<RemoveQualifiersAndReferencesFromTuple<std::tuple<
int, int&, const int&, volatile const int&>>::type,
std::tuple<int, int, int, int>>));
}
TEST(Unpack, Basic) {
struct A1 {
int a;
};
struct A2 {
int a;
int b;
};
struct A3 {
int a;
int&& b;
};
{
A1 a;
auto [f1] = Unpack(a);
EXPECT_EQ(&f1, &a.a);
}
{
A2 a;
auto [f1, f2] = Unpack(a);
EXPECT_EQ(&f1, &a.a);
EXPECT_EQ(&f2, &a.b);
}
{
int b = 0;
A3 a{0, std::move(b)}; // NOLINT(performance-move-const-arg)
auto [f1, f2] = Unpack(a);
EXPECT_EQ(&f1, &a.a);
EXPECT_EQ(&f2, &a.b);
}
}
TEST(Unpack, Types) {
struct A3 {
int field_v;
const int& field_l;
int&& field_r;
};
int x = 0, y = 0;
A3 my_struct{0, x, std::move(y)}; // NOLINT(performance-move-const-arg)
auto unpacked = Unpack(my_struct);
const auto& const_lvalue_ref = my_struct;
auto unpacked_const_lvalue_ref = Unpack(const_lvalue_ref);
auto unpacked_rvalue_ref = Unpack(std::move(my_struct));
testing::StaticAssertTypeEq<decltype(unpacked),
std::tuple<int&, const int&, int&&>>();
testing::StaticAssertTypeEq<decltype(unpacked_const_lvalue_ref),
std::tuple<const int&, const int&, int&&>>();
testing::StaticAssertTypeEq<decltype(unpacked_rvalue_ref),
std::tuple<int&&, const int&, int&&>>();
}
TEST(Unpack, Const) {
struct A1 {
const int a;
};
struct A2 {
const int a;
const int b;
};
struct A3 {
const int a;
const int& b;
int&& c;
};
{
A1 a{};
auto [f1] = Unpack(a);
EXPECT_EQ(&f1, &a.a);
}
{
A2 a{};
auto [f1, f2] = Unpack(a);
EXPECT_EQ(&f1, &a.a);
EXPECT_EQ(&f2, &a.b);
}
{
int b = 0, c = 0;
A3 a{0, b, std::move(c)}; // NOLINT(performance-move-const-arg)
auto [f1, f2, f3] = Unpack(a);
EXPECT_EQ(&f1, &a.a);
EXPECT_EQ(&f2, &a.b);
EXPECT_EQ(&f3, &a.c);
}
}
TEST(Unpack, BaseClass) {
struct Base {};
struct A2 : Base {
int a1, a2;
};
A2 a;
auto [f1, f2] = Unpack(a);
EXPECT_EQ(&f1, &a.a1);
EXPECT_EQ(&f2, &a.a2);
}
// Not supported on older compilers due to mysterious compiler bug(s) that are
// somewhat difficult to track down. (See b/478243383.)
//
// TODO(b/479561657): Enable this unconditionally.
#if !defined(_MSC_VER) || _MSC_VER >= 1939
TEST(Unpack, Immovable) {
struct Immovable {
Immovable() = default;
Immovable(Immovable&&) = delete;
};
struct A2 {
const Immovable& a;
Immovable&& b;
};
Immovable i1, i2;
A2 a{i1, std::move(i2)};
auto [f1, f2] = Unpack(a);
EXPECT_EQ(&f1, &a.a);
EXPECT_EQ(&f2, &a.b);
}
#endif // _MSC_VER >= 1939
TEST(Unpack, Empty) {
struct Empty {};
EXPECT_TRUE((std::is_same_v<std::tuple<>, decltype(Unpack(Empty{}))>));
Empty lvalue_empty;
EXPECT_TRUE((std::is_same_v<std::tuple<>, decltype(Unpack(lvalue_empty))>));
struct EmptyWithBase : Empty {};
EXPECT_TRUE(
(std::is_same_v<std::tuple<>, decltype(Unpack(EmptyWithBase{}))>));
}
TEST(Unpack, Autodetect) {
struct NoBases {
int i = 7;
} no_bases;
auto [i2] = Unpack(no_bases);
EXPECT_EQ(i2, 7);
struct Base {};
struct OneBase : Base {
int j = 17;
} one_base;
auto [j2] = Unpack(one_base);
EXPECT_EQ(j2, 17);
constexpr auto try_unpack =
[](auto&& v) -> decltype(NumBases(std::forward<decltype(v)>(v))) {};
struct Base2 {};
struct TwoBases : Base, Base2 {
int k;
};
EXPECT_FALSE((std::is_invocable_v<decltype(try_unpack), TwoBases>));
}
TEST(Unpack, FailsSubstitution) {
struct Aggregate {
int i;
};
struct NonAggregate {
explicit NonAggregate(int) {}
int i;
};
const auto unpack =
[](auto&& v) -> decltype(Unpack(std::forward<decltype(v)>(v))) {};
EXPECT_TRUE((std::is_invocable_v<decltype(unpack), Aggregate>));
EXPECT_FALSE((std::is_invocable_v<decltype(unpack), NonAggregate>));
}
// Not supported on older compilers due to mysterious compiler bug(s) that are
// somewhat difficult to track down. (See b/478243383.)
//
// TODO(b/479561657): Enable this unconditionally.
#if !defined(_MSC_VER) || _MSC_VER >= 1939
template <int N, class T>
void CheckTupleElementsEqualToIndex(const T& t) {
if constexpr (N > 0) {
EXPECT_EQ(std::get<N - 1>(t), N - 1);
CheckTupleElementsEqualToIndex<N - 1>(t);
}
}
TEST(Unpack, CorrectOrder1) {
struct S1 {
int a0 = 0;
};
CheckTupleElementsEqualToIndex<1>(Unpack(S1()));
}
TEST(Unpack, CorrectOrder2) {
struct S2 {
int a0 = 0, a1 = 1;
};
CheckTupleElementsEqualToIndex<2>(Unpack(S2()));
}
TEST(Unpack, CorrectOrder3) {
struct S3 {
int a0 = 0, a1 = 1, a2 = 2;
};
CheckTupleElementsEqualToIndex<3>(Unpack(S3()));
}
TEST(Unpack, CorrectOrder4) {
struct S4 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3;
};
CheckTupleElementsEqualToIndex<4>(Unpack(S4()));
}
TEST(Unpack, CorrectOrder5) {
struct S5 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4;
};
CheckTupleElementsEqualToIndex<5>(Unpack(S5()));
}
TEST(Unpack, CorrectOrder6) {
struct S6 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5;
};
CheckTupleElementsEqualToIndex<6>(Unpack(S6()));
}
TEST(Unpack, CorrectOrder7) {
struct S7 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6;
};
CheckTupleElementsEqualToIndex<7>(Unpack(S7()));
}
TEST(Unpack, CorrectOrder8) {
struct S8 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7;
};
CheckTupleElementsEqualToIndex<8>(Unpack(S8()));
}
TEST(Unpack, CorrectOrder9) {
struct S9 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8;
};
CheckTupleElementsEqualToIndex<9>(Unpack(S9()));
}
TEST(Unpack, CorrectOrder10) {
struct S10 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9;
};
CheckTupleElementsEqualToIndex<10>(Unpack(S10()));
}
TEST(Unpack, CorrectOrder11) {
struct S11 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10;
};
CheckTupleElementsEqualToIndex<11>(Unpack(S11()));
}
TEST(Unpack, CorrectOrder12) {
struct S12 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11;
};
CheckTupleElementsEqualToIndex<12>(Unpack(S12()));
}
TEST(Unpack, CorrectOrder13) {
struct S13 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12;
};
CheckTupleElementsEqualToIndex<13>(Unpack(S13()));
}
TEST(Unpack, CorrectOrder14) {
struct S14 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13;
};
CheckTupleElementsEqualToIndex<14>(Unpack(S14()));
}
TEST(Unpack, CorrectOrder15) {
struct S15 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14;
};
CheckTupleElementsEqualToIndex<15>(Unpack(S15()));
}
TEST(Unpack, CorrectOrder16) {
struct S16 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15;
};
CheckTupleElementsEqualToIndex<16>(Unpack(S16()));
}
TEST(Unpack, CorrectOrder17) {
struct S17 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16;
};
CheckTupleElementsEqualToIndex<17>(Unpack(S17()));
}
TEST(Unpack, CorrectOrder18) {
struct S18 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17;
};
CheckTupleElementsEqualToIndex<18>(Unpack(S18()));
}
TEST(Unpack, CorrectOrder19) {
struct S19 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18;
};
CheckTupleElementsEqualToIndex<19>(Unpack(S19()));
}
TEST(Unpack, CorrectOrder20) {
struct S20 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19;
};
CheckTupleElementsEqualToIndex<20>(Unpack(S20()));
}
TEST(Unpack, CorrectOrder21) {
struct S21 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20;
};
CheckTupleElementsEqualToIndex<21>(Unpack(S21()));
}
TEST(Unpack, CorrectOrder22) {
struct S22 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21;
};
CheckTupleElementsEqualToIndex<22>(Unpack(S22()));
}
TEST(Unpack, CorrectOrder23) {
struct S23 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22;
};
CheckTupleElementsEqualToIndex<23>(Unpack(S23()));
}
TEST(Unpack, CorrectOrder24) {
struct S24 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23;
};
CheckTupleElementsEqualToIndex<24>(Unpack(S24()));
}
TEST(Unpack, CorrectOrder25) {
struct S25 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24;
};
CheckTupleElementsEqualToIndex<25>(Unpack(S25()));
}
TEST(Unpack, CorrectOrder26) {
struct S26 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25;
};
CheckTupleElementsEqualToIndex<26>(Unpack(S26()));
}
TEST(Unpack, CorrectOrder27) {
struct S27 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26;
};
CheckTupleElementsEqualToIndex<27>(Unpack(S27()));
}
TEST(Unpack, CorrectOrder28) {
struct S28 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27;
};
CheckTupleElementsEqualToIndex<28>(Unpack(S28()));
}
TEST(Unpack, CorrectOrder29) {
struct S29 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28;
};
CheckTupleElementsEqualToIndex<29>(Unpack(S29()));
}
TEST(Unpack, CorrectOrder30) {
struct S30 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29;
};
CheckTupleElementsEqualToIndex<30>(Unpack(S30()));
}
TEST(Unpack, CorrectOrder31) {
struct S31 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30;
};
CheckTupleElementsEqualToIndex<31>(Unpack(S31()));
}
TEST(Unpack, CorrectOrder32) {
struct S32 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31;
};
CheckTupleElementsEqualToIndex<32>(Unpack(S32()));
}
#ifndef _MSC_VER // MSVC constexpr evaluation hits a default limit
TEST(Unpack, CorrectOrder33) {
struct S33 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32;
};
CheckTupleElementsEqualToIndex<33>(Unpack(S33()));
}
TEST(Unpack, CorrectOrder34) {
struct S34 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33;
};
CheckTupleElementsEqualToIndex<34>(Unpack(S34()));
}
TEST(Unpack, CorrectOrder35) {
struct S35 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33, a34 = 34;
};
CheckTupleElementsEqualToIndex<35>(Unpack(S35()));
}
TEST(Unpack, CorrectOrder36) {
struct S36 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33, a34 = 34, a35 = 35;
};
CheckTupleElementsEqualToIndex<36>(Unpack(S36()));
}
TEST(Unpack, CorrectOrder37) {
struct S37 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33, a34 = 34, a35 = 35, a36 = 36;
};
CheckTupleElementsEqualToIndex<37>(Unpack(S37()));
}
TEST(Unpack, CorrectOrder38) {
struct S38 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33, a34 = 34, a35 = 35, a36 = 36,
a37 = 37;
};
CheckTupleElementsEqualToIndex<38>(Unpack(S38()));
}
TEST(Unpack, CorrectOrder39) {
struct S39 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33, a34 = 34, a35 = 35, a36 = 36,
a37 = 37, a38 = 38;
};
CheckTupleElementsEqualToIndex<39>(Unpack(S39()));
}
TEST(Unpack, CorrectOrder40) {
struct S40 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33, a34 = 34, a35 = 35, a36 = 36,
a37 = 37, a38 = 38, a39 = 39;
};
CheckTupleElementsEqualToIndex<40>(Unpack(S40()));
}
TEST(Unpack, CorrectOrder41) {
struct S41 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33, a34 = 34, a35 = 35, a36 = 36,
a37 = 37, a38 = 38, a39 = 39, a40 = 40;
};
CheckTupleElementsEqualToIndex<41>(Unpack(S41()));
}
TEST(Unpack, CorrectOrder42) {
struct S42 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33, a34 = 34, a35 = 35, a36 = 36,
a37 = 37, a38 = 38, a39 = 39, a40 = 40, a41 = 41;
};
CheckTupleElementsEqualToIndex<42>(Unpack(S42()));
}
TEST(Unpack, CorrectOrder43) {
struct S43 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33, a34 = 34, a35 = 35, a36 = 36,
a37 = 37, a38 = 38, a39 = 39, a40 = 40, a41 = 41, a42 = 42;
};
CheckTupleElementsEqualToIndex<43>(Unpack(S43()));
}
TEST(Unpack, CorrectOrder44) {
struct S44 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33, a34 = 34, a35 = 35, a36 = 36,
a37 = 37, a38 = 38, a39 = 39, a40 = 40, a41 = 41, a42 = 42, a43 = 43;
};
CheckTupleElementsEqualToIndex<44>(Unpack(S44()));
}
TEST(Unpack, CorrectOrder45) {
struct S45 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33, a34 = 34, a35 = 35, a36 = 36,
a37 = 37, a38 = 38, a39 = 39, a40 = 40, a41 = 41, a42 = 42, a43 = 43,
a44 = 44;
};
CheckTupleElementsEqualToIndex<45>(Unpack(S45()));
}
TEST(Unpack, CorrectOrder46) {
struct S46 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33, a34 = 34, a35 = 35, a36 = 36,
a37 = 37, a38 = 38, a39 = 39, a40 = 40, a41 = 41, a42 = 42, a43 = 43,
a44 = 44, a45 = 45;
};
CheckTupleElementsEqualToIndex<46>(Unpack(S46()));
}
TEST(Unpack, CorrectOrder47) {
struct S47 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33, a34 = 34, a35 = 35, a36 = 36,
a37 = 37, a38 = 38, a39 = 39, a40 = 40, a41 = 41, a42 = 42, a43 = 43,
a44 = 44, a45 = 45, a46 = 46;
};
CheckTupleElementsEqualToIndex<47>(Unpack(S47()));
}
TEST(Unpack, CorrectOrder48) {
struct S48 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33, a34 = 34, a35 = 35, a36 = 36,
a37 = 37, a38 = 38, a39 = 39, a40 = 40, a41 = 41, a42 = 42, a43 = 43,
a44 = 44, a45 = 45, a46 = 46, a47 = 47;
};
CheckTupleElementsEqualToIndex<48>(Unpack(S48()));
}
TEST(Unpack, CorrectOrder49) {
struct S49 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33, a34 = 34, a35 = 35, a36 = 36,
a37 = 37, a38 = 38, a39 = 39, a40 = 40, a41 = 41, a42 = 42, a43 = 43,
a44 = 44, a45 = 45, a46 = 46, a47 = 47, a48 = 48;
};
CheckTupleElementsEqualToIndex<49>(Unpack(S49()));
}
TEST(Unpack, CorrectOrder50) {
struct S50 {
int a0 = 0, a1 = 1, a2 = 2, a3 = 3, a4 = 4, a5 = 5, a6 = 6, a7 = 7, a8 = 8,
a9 = 9, a10 = 10, a11 = 11, a12 = 12, a13 = 13, a14 = 14, a15 = 15,
a16 = 16, a17 = 17, a18 = 18, a19 = 19, a20 = 20, a21 = 21, a22 = 22,
a23 = 23, a24 = 24, a25 = 25, a26 = 26, a27 = 27, a28 = 28, a29 = 29,
a30 = 30, a31 = 31, a32 = 32, a33 = 33, a34 = 34, a35 = 35, a36 = 36,
a37 = 37, a38 = 38, a39 = 39, a40 = 40, a41 = 41, a42 = 42, a43 = 43,
a44 = 44, a45 = 45, a46 = 46, a47 = 47, a48 = 48, a49 = 49;
};
CheckTupleElementsEqualToIndex<50>(Unpack(S50()));
}
// When adding support for more fields, add corresponding CorrectOrderNN test(s)
// here.
#endif // _MSC_VER
#endif // _MSC_VER >= 1939
} // namespace
} // namespace aggregate_internal
ABSL_NAMESPACE_END
} // namespace absl