44 static constexpr std::array component_cells{ComponentCells...};
45 static constexpr std::size_t row_count = Rows;
46 static constexpr std::size_t row_cell_count = (ComponentCells + ...);
47 static constexpr std::size_t byte_stride = row_cell_count *
sizeof(T);
49 template <std::
size_t I,
template <
typename>
typename Decorator = std::type_identity>
50 requires(I < component_cells.size())
51 using component_span = std::span<typename Decorator<T>::type, std::get<I>(component_cells)>;
53 template <std::
size_t I,
template <
typename>
typename Decorator = std::type_identity>
54 requires(I < component_cells.size())
55 using component_byte_span =
56 std::span<typename Decorator<std::byte>::type, std::get<I>(component_cells) *
sizeof(T)>;
66 template <std::
size_t Row, std::
size_t I>
67 requires(Row < Rows && I < component_cells.size())
69 auto iter = get_component_iter<Row, I, false>(*
this);
71 return component_span<I>{iter, iter + component_span<I>::extent};
80 template <std::
size_t Row, std::
size_t I>
81 requires(Row < Rows && I < component_cells.size())
83 auto iter = get_component_iter<Row, I, false>(*
this);
85 return component_span<I, std::add_const>{iter, iter + component_span<I, std::add_const>::extent};
94 template <std::
size_t Row, std::
size_t I>
95 requires(Row < Rows && I < component_cells.size())
96 void
set_component(component_byte_span<I, std::add_const> data) noexcept {
97 auto iter = get_component_iter<Row, I, true>(*
this);
99 std::ranges::copy(data.data(), data.data() + data.size(), iter);
108 template <std::
size_t Row, std::
size_t I>
109 requires(Row < Rows && I < component_cells.size())
119 return std::as_writable_bytes(std::span{buffer_});
127 return std::as_bytes(std::span{buffer_});
131 template <std::
size_t Row, std::
size_t I,
bool AsBytes,
typename Self>
134 static auto get_component_iter(Self&& self) noexcept {
136 static constexpr std::size_t offset =
137 std::accumulate(component_cells.begin(), component_cells.begin() + I, 0U) + Row * row_cell_count;
139 auto component_data = std::forward<Self>(self).buffer_.data() + offset;
141 if constexpr (AsBytes) {
143 if constexpr (std::is_const_v<std::remove_reference_t<Self>>) {
144 return reinterpret_cast<const std::byte*
>(component_data);
146 return reinterpret_cast<std::byte*
>(component_data);
149 return component_data;
153 std::array<T, row_cell_count * Rows> buffer_;