3#include <tess/core/shape.h>
4#include <tess/storage/residency.h>
5#include <tess/storage/world.h>
11namespace tess::detail {
21template <
typename World,
typename Res
idency =
typename World::res
idency_type>
22struct NodeIndexSpace {
23 static_assert(
sizeof(World) == 0,
24 "NodeIndexSpace has no specialization for this residency "
25 "policy. AlwaysResident and SparseResident are both "
26 "specialized below; a custom residency policy needs its "
27 "own specialization.");
30template <
typename World>
31struct NodeIndexSpace<World, AlwaysResident> {
36 static constexpr bool is_dense =
true;
38 explicit NodeIndexSpace(
const World& )
noexcept {}
40 [[nodiscard]]
constexpr bool is_resident_index(
41 std::uint64_t )
const noexcept {
45 [[nodiscard]]
constexpr std::size_t offset(
46 std::uint64_t index)
const noexcept {
47 return static_cast<std::size_t
>(index);
51 static constexpr std::size_t npos_offset =
52 std::numeric_limits<std::size_t>::max();
54 [[nodiscard]]
constexpr std::size_t resident_offset(
55 std::uint64_t index)
const noexcept {
56 return static_cast<std::size_t
>(index);
59 [[nodiscard]]
constexpr std::size_t capacity_hint() const noexcept {
60 static_assert(World::chunk_count <=
61 std::numeric_limits<std::size_t>::max() /
62 World::local_tile_count);
63 return static_cast<std::size_t
>(World::chunk_count *
64 World::local_tile_count);
75template <
typename World>
76struct NodeIndexSpace<World, SparseResident> {
77 using shape_type =
typename World::shape_type;
78 static constexpr bool is_dense =
false;
79 static constexpr std::uint64_t local_tile_count = World::local_tile_count;
81 explicit NodeIndexSpace(
const World& world) noexcept : world_(&world) {}
83 [[nodiscard]]
bool is_resident_index(std::uint64_t index)
const noexcept {
84 return world_->resident_slot(chunk_key_of(index)) != World::npos_slot;
87 [[nodiscard]] std::size_t offset(std::uint64_t index)
const noexcept {
88 const auto slot = world_->resident_slot(chunk_key_of(index));
89 return slot *
static_cast<std::size_t
>(local_tile_count) + local_of(index);
92 static constexpr std::size_t npos_offset =
93 std::numeric_limits<std::size_t>::max();
98 [[nodiscard]] std::size_t resident_offset(
99 std::uint64_t index)
const noexcept {
100 const auto slot = world_->resident_slot(chunk_key_of(index));
101 if (slot == World::npos_slot) {
104 return slot *
static_cast<std::size_t
>(local_tile_count) + local_of(index);
107 [[nodiscard]] std::size_t capacity_hint() const noexcept {
108 return world_->capacity() *
static_cast<std::size_t
>(local_tile_count);
112 using Storage =
typename ShapeTraits<shape_type>::TileKeyStorage;
114 [[nodiscard]]
static ChunkKey chunk_key_of(std::uint64_t index)
noexcept {
115 return chunk_key<shape_type>(
116 TileKey<shape_type>{
static_cast<Storage
>(index)});
119 [[nodiscard]]
static std::size_t local_of(std::uint64_t index)
noexcept {
120 return static_cast<std::size_t
>(
121 local_tile_id<shape_type>(
122 TileKey<shape_type>{
static_cast<Storage
>(index)})