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; the SparseResident mapping lands in a later slice.");
28template <
typename World>
29struct NodeIndexSpace<World, AlwaysResident> {
34 static constexpr bool is_dense =
true;
36 explicit NodeIndexSpace(
const World& )
noexcept {}
38 [[nodiscard]]
constexpr bool is_resident_index(
39 std::uint64_t )
const noexcept {
43 [[nodiscard]]
constexpr std::size_t offset(
44 std::uint64_t index)
const noexcept {
45 return static_cast<std::size_t
>(index);
49 static constexpr std::size_t npos_offset =
50 std::numeric_limits<std::size_t>::max();
52 [[nodiscard]]
constexpr std::size_t resident_offset(
53 std::uint64_t index)
const noexcept {
54 return static_cast<std::size_t
>(index);
57 [[nodiscard]]
constexpr std::size_t capacity_hint() const noexcept {
58 static_assert(World::chunk_count <=
59 std::numeric_limits<std::size_t>::max() /
60 World::local_tile_count);
61 return static_cast<std::size_t
>(World::chunk_count *
62 World::local_tile_count);
73template <
typename World>
74struct NodeIndexSpace<World, SparseResident> {
75 using shape_type =
typename World::shape_type;
76 static constexpr bool is_dense =
false;
77 static constexpr std::uint64_t local_tile_count = World::local_tile_count;
79 explicit NodeIndexSpace(
const World& world) noexcept : world_(&world) {}
81 [[nodiscard]]
bool is_resident_index(std::uint64_t index)
const noexcept {
82 return world_->resident_slot(chunk_key_of(index)) != World::npos_slot;
85 [[nodiscard]] std::size_t offset(std::uint64_t index)
const noexcept {
86 const auto slot = world_->resident_slot(chunk_key_of(index));
87 return slot *
static_cast<std::size_t
>(local_tile_count) + local_of(index);
90 static constexpr std::size_t npos_offset =
91 std::numeric_limits<std::size_t>::max();
97 [[nodiscard]] std::size_t resident_offset(
98 std::uint64_t index)
const noexcept {
99 const auto slot = world_->resident_slot(chunk_key_of(index));
100 if (slot == World::npos_slot) {
103 return slot *
static_cast<std::size_t
>(local_tile_count) + local_of(index);
106 [[nodiscard]] std::size_t capacity_hint() const noexcept {
107 return world_->capacity() *
static_cast<std::size_t
>(local_tile_count);
111 using Storage =
typename ShapeTraits<shape_type>::TileKeyStorage;
113 [[nodiscard]]
static ChunkKey chunk_key_of(std::uint64_t index)
noexcept {
114 return chunk_key<shape_type>(
115 TileKey<shape_type>{
static_cast<Storage
>(index)});
118 [[nodiscard]]
static std::size_t local_of(std::uint64_t index)
noexcept {
119 return static_cast<std::size_t
>(
120 local_tile_id<shape_type>(
121 TileKey<shape_type>{
static_cast<Storage
>(index)})