struct_reflection_test.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "common/struct_reflection.h"
  5. #include <gtest/gtest.h>
  6. #include <tuple>
  7. namespace Carbon::StructReflection {
  8. namespace {
  9. struct ZeroFields {};
  10. struct OneField {
  11. int x;
  12. };
  13. struct TwoFields {
  14. int x;
  15. int y;
  16. };
  17. struct SixFields {
  18. int one;
  19. int two;
  20. int three;
  21. int four;
  22. int five;
  23. int six;
  24. };
  25. struct ReferenceField {
  26. int& ref;
  27. };
  28. struct NoDefaultConstructor {
  29. explicit NoDefaultConstructor(int n) : v(n) {}
  30. int v;
  31. };
  32. struct OneFieldNoDefaultConstructor {
  33. NoDefaultConstructor x;
  34. };
  35. struct TwoFieldsNoDefaultConstructor {
  36. NoDefaultConstructor x;
  37. NoDefaultConstructor y;
  38. };
  39. TEST(StructReflectionTest, CanListInitialize) {
  40. {
  41. using Type = OneField;
  42. using Field = Internal::AnyField<Type>;
  43. static_assert(Internal::CanListInitialize<Type>(nullptr));
  44. static_assert(Internal::CanListInitialize<Type, Field>(nullptr));
  45. static_assert(!Internal::CanListInitialize<Type, Field, Field>(0));
  46. }
  47. {
  48. using Type = OneFieldNoDefaultConstructor;
  49. using Field = Internal::AnyField<Type>;
  50. static_assert(!Internal::CanListInitialize<Type>(0));
  51. static_assert(Internal::CanListInitialize<Type, Field>(nullptr));
  52. static_assert(!Internal::CanListInitialize<Type, Field, Field>(0));
  53. }
  54. }
  55. TEST(StructReflectionTest, CountFields) {
  56. static_assert(Internal::CountFields<ZeroFields>() == 0);
  57. static_assert(Internal::CountFields<OneField>() == 1);
  58. static_assert(Internal::CountFields<TwoFields>() == 2);
  59. static_assert(Internal::CountFields<SixFields>() == 6);
  60. static_assert(Internal::CountFields<ReferenceField>() == 1);
  61. static_assert(Internal::CountFields<OneFieldNoDefaultConstructor>() == 1);
  62. }
  63. TEST(StructReflectionTest, EmptyStruct) {
  64. std::tuple<> fields = AsTuple(ZeroFields());
  65. static_cast<void>(fields);
  66. }
  67. TEST(StructReflectionTest, OneField) {
  68. std::tuple<int> fields = AsTuple(OneField{.x = 1});
  69. EXPECT_EQ(std::get<0>(fields), 1);
  70. }
  71. TEST(StructReflectionTest, TwoFields) {
  72. std::tuple<int, int> fields = AsTuple(TwoFields{.x = 1, .y = 2});
  73. EXPECT_EQ(std::get<0>(fields), 1);
  74. EXPECT_EQ(std::get<1>(fields), 2);
  75. }
  76. TEST(StructReflectionTest, SixFields) {
  77. std::tuple<int, int, int, int, int, int> fields = AsTuple(SixFields{
  78. .one = 1, .two = 2, .three = 3, .four = 4, .five = 5, .six = 6});
  79. EXPECT_EQ(std::get<0>(fields), 1);
  80. EXPECT_EQ(std::get<1>(fields), 2);
  81. EXPECT_EQ(std::get<2>(fields), 3);
  82. EXPECT_EQ(std::get<3>(fields), 4);
  83. EXPECT_EQ(std::get<4>(fields), 5);
  84. EXPECT_EQ(std::get<5>(fields), 6);
  85. }
  86. TEST(StructReflectionTest, NoDefaultConstructor) {
  87. std::tuple<NoDefaultConstructor, NoDefaultConstructor> fields =
  88. AsTuple(TwoFieldsNoDefaultConstructor{.x = NoDefaultConstructor(1),
  89. .y = NoDefaultConstructor(2)});
  90. EXPECT_EQ(std::get<0>(fields).v, 1);
  91. EXPECT_EQ(std::get<1>(fields).v, 2);
  92. }
  93. TEST(StructReflectionTest, ReferenceField) {
  94. int n = 0;
  95. std::tuple<int&> fields = AsTuple(ReferenceField{.ref = n});
  96. EXPECT_EQ(&std::get<0>(fields), &n);
  97. }
  98. } // namespace
  99. } // namespace Carbon::StructReflection