diff --git a/include/fixed_containers/reflection.hpp b/include/fixed_containers/reflection.hpp index cf736b89..95507e84 100644 --- a/include/fixed_containers/reflection.hpp +++ b/include/fixed_containers/reflection.hpp @@ -175,7 +175,9 @@ constexpr void for_each_field_entry(const T& instance, Func func) LayerTracker<> layer_tracker{}; __builtin_dump_struct(&instance, converter, in_out{layer_tracker}); - assert(layer_tracker.is_null_layer()); + assert(layer_tracker.is_null_layer() && + "If you are hitting this, a possible reason can be that clang-16 or lower has a limit " + "in total field count. See unit tests for more info."); } enum class RecursionType diff --git a/test/reflection_test.cpp b/test/reflection_test.cpp index 621176f5..54e33a1f 100644 --- a/test/reflection_test.cpp +++ b/test/reflection_test.cpp @@ -48,6 +48,92 @@ struct MyColors ChildStruct purple; }; +struct RecursiveFieldCount8 +{ + double a1; + double a2; + double a3; + double a4; + double a5; + int a6; + int a7; + int a8; +}; + +struct RecursiveFieldCount9 +{ + double a1; + double a2; + double a3; + double a4; + double a5; + int a6; + int a7; + int a8; + int a9; +}; + +struct RecursiveFieldCount10 +{ + RecursiveFieldCount9 ten1; // The entry itself counts +}; + +struct RecursiveFieldCount99 +{ + RecursiveFieldCount9 ten1; + RecursiveFieldCount9 ten2; + RecursiveFieldCount9 ten3; + RecursiveFieldCount9 ten4; + RecursiveFieldCount9 ten5; + RecursiveFieldCount9 ten6; + RecursiveFieldCount9 ten7; + RecursiveFieldCount9 ten8; + RecursiveFieldCount9 ten9; + int a1; + int a2; + int a3; + int a4; + int a5; + int a6; + int a7; + int a8; + int a9; +}; + +struct RecursiveFieldCount100 +{ + RecursiveFieldCount99 one_hundred1; +}; + +struct RecursiveFieldCount193 +{ + RecursiveFieldCount99 one_hundred1; + RecursiveFieldCount9 ten1; + RecursiveFieldCount9 ten2; + RecursiveFieldCount9 ten3; + RecursiveFieldCount9 ten4; + RecursiveFieldCount9 ten5; + RecursiveFieldCount9 ten6; + RecursiveFieldCount9 ten7; + RecursiveFieldCount9 ten8; + RecursiveFieldCount9 ten9; + int a1; + int a2; + int a3; +}; + +struct RecursiveFieldCount194 +{ + RecursiveFieldCount193 f; +}; + +struct RecursiveFieldCount300 +{ + RecursiveFieldCount99 one_hundred1; + RecursiveFieldCount99 one_hundred2; + RecursiveFieldCount99 one_hundred3; +}; + struct NonConstexprDefaultConstructibleWithFields { int a; @@ -251,6 +337,42 @@ TEST(Reflection, NonConstexprDefaultConstructible) static_assert(!FIELD_INFO.at(1).providing_base_class_name().has_value()); } +TEST(Reflection, FieldCountLimits) +{ + using enum reflection_detail::RecursionType; + using reflection_detail::field_count_of; + static_assert( + consteval_compare:: + equal<9, field_count_of()>); + static_assert( + consteval_compare:: + equal<10, field_count_of()>); + static_assert( + consteval_compare:: + equal<99, field_count_of()>); + static_assert( + consteval_compare:: + equal<100, field_count_of()>); + static_assert( + consteval_compare:: + equal<193, field_count_of()>); + + // Before clang-17, there is a limit in recursive number of fields. + // The limit is around 200 fields, but is affected by level of recursion, so it is 193 here + // due to the way the structs are defined. +#if defined(__clang__) && __clang_major__ >= 17 + static_assert( + consteval_compare:: + equal<194, field_count_of()>); + static_assert( + consteval_compare:: + equal<300, field_count_of()>); +#else + EXPECT_DEATH((field_count_of()), ""); + EXPECT_DEATH((field_count_of()), ""); +#endif +} + } // namespace fixed_containers #endif