// Part of the Carbon Language project, under the Apache License v2.0 with LLVM // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include "common/struct_reflection.h" #include #include namespace Carbon::StructReflection { namespace { struct ZeroFields {}; struct OneField { int x; }; struct TwoFields { int x; int y; }; struct SixFields { int one; int two; int three; int four; int five; int six; }; struct ReferenceField { int& ref; }; struct NoDefaultConstructor { explicit NoDefaultConstructor(int n) : v(n) {} int v; }; struct OneFieldNoDefaultConstructor { NoDefaultConstructor x; }; struct TwoFieldsNoDefaultConstructor { NoDefaultConstructor x; NoDefaultConstructor y; }; TEST(StructReflectionTest, CanListInitialize) { { using Type = OneField; using Field = Internal::AnyField; static_assert(Internal::CanListInitialize(nullptr)); static_assert(Internal::CanListInitialize(nullptr)); static_assert(!Internal::CanListInitialize(0)); } { using Type = OneFieldNoDefaultConstructor; using Field = Internal::AnyField; static_assert(!Internal::CanListInitialize(0)); static_assert(Internal::CanListInitialize(nullptr)); static_assert(!Internal::CanListInitialize(0)); } } TEST(StructReflectionTest, CountFields) { static_assert(Internal::CountFields() == 0); static_assert(Internal::CountFields() == 1); static_assert(Internal::CountFields() == 2); static_assert(Internal::CountFields() == 6); static_assert(Internal::CountFields() == 1); static_assert(Internal::CountFields() == 1); } TEST(StructReflectionTest, EmptyStruct) { std::tuple<> fields = AsTuple(ZeroFields()); static_cast(fields); } TEST(StructReflectionTest, OneField) { std::tuple fields = AsTuple(OneField{.x = 1}); EXPECT_EQ(std::get<0>(fields), 1); } TEST(StructReflectionTest, TwoFields) { std::tuple fields = AsTuple(TwoFields{.x = 1, .y = 2}); EXPECT_EQ(std::get<0>(fields), 1); EXPECT_EQ(std::get<1>(fields), 2); } TEST(StructReflectionTest, SixFields) { std::tuple fields = AsTuple(SixFields{ .one = 1, .two = 2, .three = 3, .four = 4, .five = 5, .six = 6}); EXPECT_EQ(std::get<0>(fields), 1); EXPECT_EQ(std::get<1>(fields), 2); EXPECT_EQ(std::get<2>(fields), 3); EXPECT_EQ(std::get<3>(fields), 4); EXPECT_EQ(std::get<4>(fields), 5); EXPECT_EQ(std::get<5>(fields), 6); } TEST(StructReflectionTest, NoDefaultConstructor) { std::tuple fields = AsTuple(TwoFieldsNoDefaultConstructor{.x = NoDefaultConstructor(1), .y = NoDefaultConstructor(2)}); EXPECT_EQ(std::get<0>(fields).v, 1); EXPECT_EQ(std::get<1>(fields).v, 2); } TEST(StructReflectionTest, ReferenceField) { int n = 0; std::tuple fields = AsTuple(ReferenceField{.ref = n}); EXPECT_EQ(&std::get<0>(fields), &n); } } // namespace } // namespace Carbon::StructReflection