tess 1.0.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 <concepts>
7#include <cstddef>
8#include <span>
9#include <tuple>
10#include <type_traits>
11
12namespace tess {
13
15template <typename Value>
17 std::is_object_v<Value> && std::same_as<Value, std::remove_cv_t<Value>> &&
18 std::is_nothrow_default_constructible_v<Value> &&
19 std::is_trivially_copyable_v<Value> &&
20 std::is_trivially_copy_assignable_v<Value> &&
21 std::is_trivially_destructible_v<Value>;
22
29template <typename Tag, typename Value>
30struct Field {
31 using tag_type = Tag;
32 using value_type = Value;
33
34 static_assert(
36 "tess::Field value must be an unqualified, nothrow-default-constructible "
37 "object that is trivially copyable, assignable, and destructible");
38};
39
40namespace detail {
41
42template <typename Field>
43using FieldTag =
44 typename Field::tag_type; // NOLINT(readability-redundant-typename)
45
46template <typename Tag, typename Field>
47inline constexpr bool field_has_tag_v = std::is_same_v<Tag, FieldTag<Field>>;
48
49template <typename Tag, typename... Fields>
50inline constexpr bool contains_field_tag_v =
51 (false || ... || field_has_tag_v<Tag, Fields>);
52
53template <typename... Fields>
54struct UniqueFieldTags : std::true_type {};
55
56template <typename Field, typename... Rest>
57struct UniqueFieldTags<Field, Rest...>
58 : std::bool_constant<
59 !contains_field_tag_v<typename Field::tag_type, Rest...> &&
60 UniqueFieldTags<Rest...>::value> {};
61
62template <typename... Fields>
63inline constexpr bool unique_field_tags_v = UniqueFieldTags<Fields...>::value;
64
65template <typename Tag, typename... Fields>
66struct FieldValue;
67
68template <typename Tag, typename Field, typename... Rest>
69struct FieldValue<Tag, Field, Rest...>
70 : std::conditional_t<field_has_tag_v<Tag, Field>,
71 std::type_identity<typename Field::value_type>,
72 FieldValue<Tag, Rest...>> {};
73
74template <typename Tag>
75struct FieldValue<Tag> {};
76
77template <typename Tag, std::size_t Index, typename... Fields>
78struct FieldIndex;
79
80template <typename Tag, std::size_t Index, typename Field, typename... Rest>
81struct FieldIndex<Tag, Index, Field, Rest...>
82 : std::conditional_t<field_has_tag_v<Tag, Field>,
83 std::integral_constant<std::size_t, Index>,
84 FieldIndex<Tag, Index + 1, Rest...>> {};
85
86template <typename Tag, std::size_t Index>
87struct FieldIndex<Tag, Index> {};
88
89} // namespace detail
90
92template <typename... Fields>
93inline constexpr bool is_valid_field_schema_v =
94 detail::unique_field_tags_v<Fields...>;
95
103template <typename... Fields>
105 static_assert(is_valid_field_schema_v<Fields...>,
106 "FieldSchema field tags must be unique.");
107
108 static constexpr std::size_t field_count = sizeof...(Fields);
109
110 template <typename Tag>
111 static constexpr bool contains = detail::contains_field_tag_v<Tag, Fields...>;
112
113 template <typename Tag>
114 using value_type = detail::FieldValue<Tag, Fields...>::type;
115
116 template <typename Tag>
117 static constexpr std::size_t index =
118 detail::FieldIndex<Tag, 0, Fields...>::value;
119};
120
122template <typename Shape, typename Schema>
124
136template <typename Shape, typename... Fields>
137class ChunkPage<Shape, FieldSchema<Fields...>> {
138 public:
139 using shape_type = Shape;
140 using schema_type = FieldSchema<Fields...>;
141
142 static constexpr std::uint64_t local_tile_count =
143 ShapeTraits<Shape>::local_tile_count;
144 static constexpr std::size_t field_count = schema_type::field_count;
145 static constexpr std::size_t byte_size =
146 (std::size_t{0} + ... +
147 sizeof(std::array<typename Fields::value_type, local_tile_count>));
148
150 constexpr ChunkPage(ChunkKey key, ChunkCoord3 coord) noexcept
151 : chunk_key_(key), chunk_coord_(coord) {}
152
162 constexpr void reset(ChunkKey key, ChunkCoord3 coord) noexcept {
163 chunk_key_ = key;
164 chunk_coord_ = coord;
165 std::apply(
166 [](auto&... arrays) {
167 (arrays.fill(typename std::remove_reference_t<
168 decltype(arrays)>::value_type{}),
169 ...);
170 },
171 fields_);
172 }
173
175 [[nodiscard]] constexpr ChunkKey chunk_key() const noexcept {
176 return chunk_key_;
177 }
178
180 [[nodiscard]] constexpr ChunkCoord3 chunk_coord() const noexcept {
181 return chunk_coord_;
182 }
183
190 template <typename Tag>
191 [[nodiscard]] constexpr auto field_span() noexcept
192 -> std::span<typename schema_type::template value_type<Tag>> {
193 auto& values = field_array<Tag>();
194 return {values.data(), values.size()};
195 }
196
198 template <typename Tag>
199 [[nodiscard]] constexpr auto field_span() const noexcept
200 -> std::span<const typename schema_type::template value_type<Tag>> {
201 const auto& values = field_array<Tag>();
202 return {values.data(), values.size()};
203 }
204
211 template <typename Tag>
212 [[nodiscard]] constexpr auto field(LocalTileId id) noexcept
213 -> schema_type::template value_type<Tag>& {
214 return field_array<Tag>()[id.value];
215 }
216
218 template <typename Tag>
219 [[nodiscard]] constexpr auto field(LocalTileId id) const noexcept
220 -> const schema_type::template value_type<Tag>& {
221 return field_array<Tag>()[id.value];
222 }
223
224 private:
225 template <typename Field>
226 using FieldArray = std::array<typename Field::value_type, local_tile_count>;
227
228 template <typename Tag>
229 [[nodiscard]] constexpr auto field_array() noexcept
230 -> FieldArray<std::tuple_element_t<schema_type::template index<Tag>,
231 std::tuple<Fields...>>>& {
232 return std::get<schema_type::template index<Tag>>(fields_);
233 }
234
235 template <typename Tag>
236 [[nodiscard]] constexpr auto field_array() const noexcept
237 -> const FieldArray<std::tuple_element_t<schema_type::template index<Tag>,
238 std::tuple<Fields...>>>& {
239 return std::get<schema_type::template index<Tag>>(fields_);
240 }
241
242 ChunkKey chunk_key_;
243 ChunkCoord3 chunk_coord_;
244 std::tuple<FieldArray<Fields>...> fields_{};
245};
246
247} // namespace tess
constexpr auto field_span() const noexcept -> std::span< const typename schema_type::template value_type< Tag > >
Definition chunk_page.h:199
constexpr ChunkPage(ChunkKey key, ChunkCoord3 coord) noexcept
Definition chunk_page.h:150
constexpr auto field(LocalTileId id) noexcept -> schema_type::template value_type< Tag > &
Definition chunk_page.h:212
constexpr auto field(LocalTileId id) const noexcept -> const schema_type::template value_type< Tag > &
Definition chunk_page.h:219
constexpr auto field_span() noexcept -> std::span< typename schema_type::template value_type< Tag > >
Definition chunk_page.h:191
constexpr ChunkKey chunk_key() const noexcept
Definition chunk_page.h:175
constexpr void reset(ChunkKey key, ChunkCoord3 coord) noexcept
Definition chunk_page.h:162
constexpr ChunkCoord3 chunk_coord() const noexcept
Definition chunk_page.h:180
Definition chunk_page.h:123
Definition chunk_page.h:16
Definition shape.h:58
Definition shape.h:86
Definition chunk_page.h:104
Definition chunk_page.h:30
Definition shape.h:78
Definition shape.h:296