From 1919e780940e03ed3c60acf1b6bf871df8336e13 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 4 Dec 2024 15:01:50 -0800 Subject: [PATCH] [reflection] Add customization point for users to supply reflection info This is useful e.g. in really big structs that can have reflection info provided by codegen --- include/fixed_containers/reflection.hpp | 15 ++++++++++----- include/fixed_containers/tuples.hpp | 11 ++++++++++- test/reflection_test.cpp | 25 +++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/include/fixed_containers/reflection.hpp b/include/fixed_containers/reflection.hpp index 98266042..c4cc030e 100644 --- a/include/fixed_containers/reflection.hpp +++ b/include/fixed_containers/reflection.hpp @@ -211,11 +211,16 @@ constexpr auto field_names_of_impl(const T& instance) return output; } -template -inline constexpr auto FIELD_NAMES = - field_names_of_impl{})>(std::decay_t{}); } // namespace fixed_containers::reflection_detail +namespace fixed_containers::reflection::customize +{ +template +inline constexpr auto FIELD_NAMES = fixed_containers::reflection_detail::field_names_of_impl< + fixed_containers::reflection_detail::field_count_of_impl(std::decay_t{})>(std::decay_t{}); + +} // namespace fixed_containers::reflection::customize + namespace fixed_containers::reflection { template @@ -225,14 +230,14 @@ template requires(Reflectable>) constexpr std::size_t field_count_of() { - return reflection_detail::FIELD_NAMES>.size(); + return fixed_containers::reflection::customize::FIELD_NAMES>.size(); } template requires(Reflectable>) constexpr const auto& field_names_of() { - return reflection_detail::FIELD_NAMES>; + return fixed_containers::reflection::customize::FIELD_NAMES>; } template diff --git a/include/fixed_containers/tuples.hpp b/include/fixed_containers/tuples.hpp index 0a5fade1..dead783e 100644 --- a/include/fixed_containers/tuples.hpp +++ b/include/fixed_containers/tuples.hpp @@ -7,13 +7,22 @@ #include #include -namespace fixed_containers::tuples +namespace fixed_containers::tuples::customize { template constexpr auto as_tuple_view(T& data) { return as_tuple_view_detail::as_tuple_view(data); } +} // namespace fixed_containers::tuples::customize + +namespace fixed_containers::tuples +{ +template +constexpr auto as_tuple_view(T& data) +{ + return fixed_containers::tuples::customize::as_tuple_view(data); +} template requires(std::tuple_size_v> == 0) diff --git a/test/reflection_test.cpp b/test/reflection_test.cpp index 2e49f84c..f6e449bc 100644 --- a/test/reflection_test.cpp +++ b/test/reflection_test.cpp @@ -605,4 +605,29 @@ TEST(Reflection, MockFailingAddressOfOperator) } // namespace fixed_containers +struct MyCustomStruct +{ + int a{}; + int b{}; + int c{}; + double d{}; // Customization will ignore this field to show the customization is applied +}; + +template <> +constexpr auto fixed_containers::tuples::customize::as_tuple_view<3, MyCustomStruct>( + MyCustomStruct& data) +{ + return std::tie(data.a, data.b, data.c); +} + +template <> +inline constexpr auto fixed_containers::reflection::customize::FIELD_NAMES = + make_fixed_vector({ + "a", + "b", + "c", + }); + +static_assert(fixed_containers::reflection::field_names_of().size() == 3); + #endif