codex
Loading...
Searching...
No Matches
soa.hpp
Go to the documentation of this file.
1#ifndef CODEX_REFLECTION_SOA_HPP
2#define CODEX_REFLECTION_SOA_HPP
3
4#include <span>
5
6#include "detail/soa.hpp"
7#include "fields.hpp"
8
9namespace codex::refl {
10
22template<typename T, typename S = detail::storage_descriptor>
23class SOA : detail::storage<T, S> {
25public:
27 // Should be `base_type::value_type`, but that generates an ICE(!?).
28 template<std::size_t I>
29 using field_type =
30 std::decay_t<std::tuple_element_t<I, field_tuple_t<T>>>;
31 // Container interface.
32 std::size_t size(void) const { return this->field<0>().size(); }
33 void push_back(T &&t = {});
34 // Idiosyncratic container interface.
40 T operator[](std::size_t i) const;
42 void set(std::size_t i, const T &t);
44 void set(std::size_t i, T &&t);
46 template<std::size_t I> std::span<field_type<I>> field(void);
47 template<std::size_t I> std::span<const field_type<I>> field(void) const;
48};
49
50template<typename T, typename S>
51T SOA<T, S>::operator[](std::size_t i) const {
52 T ret = {};
53 this->for_each_i(i, [t = field_tuple(ret)](auto fi, auto &x) {
54 std::get<fi()>(t) = x;
55 });
56 return ret;
57}
58
59template<typename T, typename S>
60void SOA<T, S>::push_back(T &&t) {
61 using detail::field_storage;
62 this->for_each([&t]<typename F, std::size_t I>(field_storage<S, I, F> &v) {
63 v.push_back(std::get<I>(field_tuple(CODEX_FWD(t))));
64 });
65}
66
67template<typename T, typename S>
68void SOA<T, S>::set(std::size_t i, const T &t) {
69 this->for_each_i(i, [&t](auto vi, auto &x) {
70 x = std::get<vi()>(field_tuple(t));
71 });
72}
73
74template<typename T, typename S>
75void SOA<T, S>::set(std::size_t i, T &&t) {
76 this->for_each_i(i, [&t](auto vi, auto &x) {
77 x = std::get<vi()>(field_tuple(std::move(t)));
78 });
79}
80
81template<typename T, typename S>
82template<std::size_t I>
83auto SOA<T, S>::field(void) -> std::span<field_type<I>> {
84 using F = field_type<I>;
85 return *static_cast<detail::field_storage<S, I, F>*>(this);
86}
87
88template<typename T, typename S>
89template<std::size_t I>
90auto SOA<T, S>::field(void) const -> std::span<const field_type<I>> {
91 using F = field_type<I>;
92 return *static_cast<const detail::field_storage<S, I, F>*>(this);
93}
94
95}
96
97#endif
Transparently stores T objects as contiguous arrays of each field.
Definition soa.hpp:23
T operator[](std::size_t i) const
Indexed access to an element.
std::decay_t< std::tuple_element_t< I, field_tuple_t< T > > > field_type
(Value/decayed) type of field with index I.
Definition soa.hpp:29
std::size_t size(void) const
Definition soa.hpp:32
std::span< const field_type< I > > field(void) const
void push_back(T &&t={})
void set(std::size_t i, const T &t)
Stores the value of each field of t.
void set(std::size_t i, T &&t)
Stores the value of each field of t.
std::span< field_type< I > > field(void)
Provides access to the contiguous storage of field I.
#define x
Definition gcc14.c:1
constexpr codex::vec3 v
Definition rotate_test.cpp:12
Definition fields.hpp:8
auto field_tuple(T &&t)
Constructs a tuple of references to each field of T, in order.
Definition fields.hpp:35
codex::refl::field_tuple_t< E > T
Definition soa.cpp:9
#define CODEX_FWD(x)
Definition utils.hpp:8
#define t(a)
Definition std2.c:10