From 3a7708c0827407733fb0e498c013290d6cfc5cfd Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sun, 30 Jun 2024 14:43:32 -0700 Subject: [PATCH] WIP --- test/sub_struct_view_test.cpp | 134 +++++++++++++++++++++++++++++++--- 1 file changed, 122 insertions(+), 12 deletions(-) diff --git a/test/sub_struct_view_test.cpp b/test/sub_struct_view_test.cpp index c2bca572..bcc77b4e 100644 --- a/test/sub_struct_view_test.cpp +++ b/test/sub_struct_view_test.cpp @@ -1,10 +1,13 @@ #include "fixed_containers/sub_struct_view.hpp" #include "fixed_containers/fixed_map.hpp" +#include "fixed_containers/fixed_set.hpp" +#include "fixed_containers/fixed_vector.hpp" #include "fixed_containers/reflection.hpp" #include +#include #include namespace fixed_containers::sub_struct_view @@ -25,8 +28,27 @@ struct FlatSubStruct1 const double* retain1; const float* retain2; }; + } // namespace +template +static auto extract_field_to_offset_map(const S& instance = {}) +{ + FixedMap()> field_to_offset{}; + reflection::for_each_field(instance, + [&](const std::string_view& name, T& field) + { + const std::byte* base_pointer = + reinterpret_cast(&instance); + const std::byte* field_pointer = + reinterpret_cast(&field); + field_to_offset.try_emplace( + name, std::distance(base_pointer, field_pointer)); + }); + + return field_to_offset; +} + TEST(SubStructView, Flat) { FlatSuperStruct1 flat_super_struct_1{}; @@ -35,33 +57,121 @@ TEST(SubStructView, Flat) FlatSubStruct1 flat_sub_struct_1{}; - FixedMap field_to_offset{}; - std::size_t current_offset{}; - - reflection::for_each_field(flat_sub_struct_1, - [&](const std::string_view& name, T& /*field*/) - { - field_to_offset.try_emplace(name, current_offset); - current_offset += sizeof(T); - }); + auto field_to_offset_map = extract_field_to_offset_map(flat_sub_struct_1); reflection::for_each_field(flat_super_struct_1, [&](const std::string_view& name, T& field) { - auto it = field_to_offset.find(name); - if (it == field_to_offset.cend()) + auto it = field_to_offset_map.find(name); + if (it == field_to_offset_map.cend()) { return; } std::byte* byte_ptr = reinterpret_cast(&flat_sub_struct_1); - const std::size_t offset = it->second; + const std::ptrdiff_t offset = it->second; std::advance(byte_ptr, offset); T** field_in_struct = reinterpret_cast(byte_ptr); *field_in_struct = &field; }); + ASSERT_TRUE(flat_sub_struct_1.retain1 == &flat_super_struct_1.retain1); ASSERT_TRUE(flat_sub_struct_1.retain2 == &flat_super_struct_1.retain2); } + +namespace +{ +struct PointXYZ +{ + double x{}; + double y{}; + double z{}; +}; + +struct FlatSuperStruct2 +{ + int ignore1{}; + std::array retain1{}; + float ignore2{}; +}; + +struct PointXZ +{ + const double* x{}; + const double* z{}; +}; + + +template +class StridedArrayView +{ + FixedVector()> field_pointers_{}; + std::ptrdiff_t stride_; + +public: + template + void update(P& parent) + { + field_pointers_.clear(); + stride_ = sizeof(P); + + T flat_sub_struct_1{}; + + auto field_to_offset_map = extract_field_to_offset_map(flat_sub_struct_1); + + reflection::for_each_field(parent, + [&](const std::string_view& name, F& field) + { + auto it = field_to_offset_map.find(name); + if (it == field_to_offset_map.cend()) + { + return; + } + + std::byte* byte_ptr = + reinterpret_cast(&flat_sub_struct_1); + const std::ptrdiff_t offset = it->second; + std::advance(byte_ptr, offset); + F** field_in_struct = reinterpret_cast(byte_ptr); + *field_in_struct = &field; + }); + } + + T at(const std::size_t i) const + { + T instance{}; + std::size_t field_i = 0; + reflection::for_each_field(instance, + [&](const std::string_view& /*name*/, F& field) + { + const PointerAndStride& current_pointer_and_stride = + field_pointers_and_strides_.at(field_i); + std::byte* byte_ptr = reinterpret_cast( + current_pointer_and_stride.pointer); + const auto offset = current_pointer_and_stride.stride * + static_cast(i); + std::advance(byte_ptr, offset); + F* field_in_struct = reinterpret_cast(byte_ptr); + field = *field_in_struct; + field_i++; + }); + + return instance; + } +}; + +struct FlatSubStruct2 +{ + StridedArrayView retain1{}; +}; + +} // namespace + +TEST(SubStructView, ArraysOfStructs) +{ + StridedArrayView view{}; + (void)view.at(0).x; +} + } // namespace fixed_containers::sub_struct_view