tess 0.4.0
Performance-first tile and path simulation substrate
Loading...
Searching...
No Matches
chunk_page.h
1#pragma once
2
3#include <tess/core/shape.h>
4
5#include <array>
6#include <cstddef>
7#include <span>
8#include <tuple>
9#include <type_traits>
10
11namespace tess {
12
19template <typename Tag, typename Value>
20struct Field {
21 using tag_type = Tag;
22 using value_type = Value;
23};
24
25namespace detail {
26
27template <typename Field>
28using FieldTag =
29 typename Field::tag_type; // NOLINT(readability-redundant-typename)
30
31template <typename Tag, typename Field>
32inline constexpr bool field_has_tag_v = std::is_same_v<Tag, FieldTag<Field>>;
33
34template <typename Tag, typename... Fields>
35inline constexpr bool contains_field_tag_v =
36 (false || ... || field_has_tag_v<Tag, Fields>);
37
38template <typename... Fields>
39struct UniqueFieldTags : std::true_type {};
40
41template <typename Field, typename... Rest>
42struct UniqueFieldTags<Field, Rest...>
43 : std::bool_constant<
44 !contains_field_tag_v<typename Field::tag_type, Rest...> &&
45 UniqueFieldTags<Rest...>::value> {};
46
47template <typename... Fields>
48inline constexpr bool unique_field_tags_v = UniqueFieldTags<Fields...>::value;
49
50template <typename Tag, typename... Fields>
51struct FieldValue;
52
53template <typename Tag, typename Field, typename... Rest>
54struct FieldValue<Tag, Field, Rest...>
55 : std::conditional_t<field_has_tag_v<Tag, Field>,
56 std::type_identity<typename Field::value_type>,
57 FieldValue<Tag, Rest...>> {};
58
59template <typename Tag>
60struct FieldValue<Tag> {};
61
62template <typename Tag, std::size_t Index, typename... Fields>
63struct FieldIndex;
64
65template <typename Tag, std::size_t Index, typename Field, typename... Rest>
66struct FieldIndex<Tag, Index, Field, Rest...>
67 : std::conditional_t<field_has_tag_v<Tag, Field>,
68 std::integral_constant<std::size_t, Index>,
69 FieldIndex<Tag, Index + 1, Rest...>> {};
70
71template <typename Tag, std::size_t Index>
72struct FieldIndex<Tag, Index> {};
73
74} // namespace detail
75
77template <typename... Fields>
78inline constexpr bool is_valid_field_schema_v =
79 detail::unique_field_tags_v<Fields...>;
80
88template <typename... Fields>
90 static_assert(is_valid_field_schema_v<Fields...>,
91 "FieldSchema field tags must be unique.");
92
93 static constexpr std::size_t field_count = sizeof...(Fields);
94
95 template <typename Tag>
96 static constexpr bool contains = detail::contains_field_tag_v<Tag, Fields...>;
97
98 template <typename Tag>
99 using value_type = detail::FieldValue<Tag, Fields...>::type;
100
101 template <typename Tag>
102 static constexpr std::size_t index =
103 detail::FieldIndex<Tag, 0, Fields...>::value;
104};
105
107template <typename Shape, typename Schema>
109
119template <typename Shape, typename... Fields>
120class ChunkPage<Shape, FieldSchema<Fields...>> {
121 public:
122 using shape_type = Shape;
123 using schema_type = FieldSchema<Fields...>;
124
125 static constexpr std::uint64_t local_tile_count =
126 ShapeTraits<Shape>::local_tile_count;
127 static constexpr std::size_t field_count = schema_type::field_count;
128 static constexpr std::size_t byte_size =
129 (std::size_t{0} + ... +
130 sizeof(std::array<typename Fields::value_type, local_tile_count>));
131
133 constexpr ChunkPage(ChunkKey key, ChunkCoord3 coord) noexcept
134 : chunk_key_(key), chunk_coord_(coord) {}
135
143 constexpr void reset(ChunkKey key, ChunkCoord3 coord) noexcept {
144 chunk_key_ = key;
145 chunk_coord_ = coord;
146 std::apply(
147 [](auto&... arrays) {
148 (arrays.fill(typename std::remove_reference_t<
149 decltype(arrays)>::value_type{}),
150 ...);
151 },
152 fields_);
153 }
154
156 [[nodiscard]] constexpr ChunkKey chunk_key() const noexcept {
157 return chunk_key_;
158 }
159
161 [[nodiscard]] constexpr ChunkCoord3 chunk_coord() const noexcept {
162 return chunk_coord_;
163 }
164
171 template <typename Tag>
172 [[nodiscard]] constexpr auto field_span() noexcept
173 -> std::span<typename schema_type::template value_type<Tag>> {
174 auto& values = field_array<Tag>();
175 return {values.data(), values.size()};
176 }
177
179 template <typename Tag>
180 [[nodiscard]] constexpr auto field_span() const noexcept
181 -> std::span<const typename schema_type::template value_type<Tag>> {
182 const auto& values = field_array<Tag>();
183 return {values.data(), values.size()};
184 }
185
192 template <typename Tag>
193 [[nodiscard]] constexpr auto field(LocalTileId id) noexcept
194 -> schema_type::template value_type<Tag>& {
195 return field_array<Tag>()[id.value];
196 }
197
199 template <typename Tag>
200 [[nodiscard]] constexpr auto field(LocalTileId id) const noexcept
201 -> const schema_type::template value_type<Tag>& {
202 return field_array<Tag>()[id.value];
203 }
204
205 private:
206 template <typename Field>
207 using FieldArray = std::array<typename Field::value_type, local_tile_count>;
208
209 template <typename Tag>
210 [[nodiscard]] constexpr auto field_array() noexcept
211 -> FieldArray<std::tuple_element_t<schema_type::template index<Tag>,
212 std::tuple<Fields...>>>& {
213 return std::get<schema_type::template index<Tag>>(fields_);
214 }
215
216 template <typename Tag>
217 [[nodiscard]] constexpr auto field_array() const noexcept
218 -> const FieldArray<std::tuple_element_t<schema_type::template index<Tag>,
219 std::tuple<Fields...>>>& {
220 return std::get<schema_type::template index<Tag>>(fields_);
221 }
222
223 ChunkKey chunk_key_;
224 ChunkCoord3 chunk_coord_;
225 std::tuple<FieldArray<Fields>...> fields_{};
226};
227
228} // namespace tess
constexpr auto field_span() const noexcept -> std::span< const typename schema_type::template value_type< Tag > >
Definition chunk_page.h:180
constexpr ChunkPage(ChunkKey key, ChunkCoord3 coord) noexcept
Definition chunk_page.h:133
constexpr auto field(LocalTileId id) noexcept -> schema_type::template value_type< Tag > &
Definition chunk_page.h:193
constexpr auto field(LocalTileId id) const noexcept -> const schema_type::template value_type< Tag > &
Definition chunk_page.h:200
constexpr auto field_span() noexcept -> std::span< typename schema_type::template value_type< Tag > >
Definition chunk_page.h:172
constexpr ChunkKey chunk_key() const noexcept
Definition chunk_page.h:156
constexpr void reset(ChunkKey key, ChunkCoord3 coord) noexcept
Definition chunk_page.h:143
constexpr ChunkCoord3 chunk_coord() const noexcept
Definition chunk_page.h:161
Definition chunk_page.h:108
Definition shape.h:39
Definition shape.h:67
Definition chunk_page.h:89
Definition chunk_page.h:20
Definition shape.h:59
Definition shape.h:225