Browse Source

Add 'infinite_sparce_cube.hpp'

master
Archivist 1 month ago
parent
commit
ab3f8d9442
1 changed files with 96 additions and 0 deletions
  1. +96
    -0
      infinite_sparce_cube.hpp

+ 96
- 0
infinite_sparce_cube.hpp View File

@ -0,0 +1,96 @@
#pragma once
#include <vector>
#include <array>
template<typename T, size_t chunk_size = 16>
struct cube {
struct chunk_elem_t {
size_t coord;
T elem;
};
struct chunk_t {
std::array<std::array<std::vector<chunk_elem_t>, chunk_size>, chunk_size> data;
};
struct row_t {
size_t coord;
std::shared_ptr<chunk_t> value;
};
struct column_t {
size_t coord;
std::vector<row_t> value;
};
std::vector<column_t> chunks;
std::optional<T> at(size_t x, size_t y, size_t z) {
auto column = std::ranges::find_if(chunks, [&](const column_t& col) {
return col.coord == y/chunk_size;
});
if(column == chunks.end()) return std::nullopt;
auto row = std::ranges::find_if(column->value, [&](const row_t& row) {
return row.coord == x/chunk_size;
});
if(column->value.end() == row) return std::nullopt;
auto& chunk_segment = row->value->data.at(x%chunk_size).at(y%chunk_size);
auto position = std::ranges::find_if(chunk_segment, [&](const chunk_elem_t& item) {
return item.coord == z;
});
if(position == chunk_segment.end()) return std::nullopt;
return position->elem;
}
void set(size_t x, size_t y, size_t z, T&& value) {
auto column = std::ranges::find_if(chunks, [&](const column_t& col) {
return col.coord == y/chunk_size;
});
if(column == chunks.end()) {
auto chunk = std::make_shared<chunk_t>();
chunks.push_back(column_t{
.coord = y / chunk_size,
.value = {
row_t{
.coord = x/chunk_size,
.value = chunk
}
}
});
chunk->data.at(x%chunk_size).at(y%chunk_size).push_back(chunk_elem_t{
.coord = z,
.elem = std::move(value)
});
return;
}
auto row = std::ranges::find_if(column->value, [&](const row_t& row) {
return row.coord == x/chunk_size;
});
if(column->value.end() == row) {
auto chunk = std::make_shared<chunk_t>();
column->value.push_back(
row_t{
.coord = x/chunk_size,
.value = chunk
}
);
chunk->data.at(x%chunk_size).at(y%chunk_size).push_back(chunk_elem_t{
.coord = z,
.elem = std::move(value)
});
return;
}
auto& chunk_segment = row->value->data.at(x%chunk_size).at(y%chunk_size);
auto position = std::ranges::find_if(chunk_segment, [&](const chunk_elem_t& item) {
return item.coord == z;
});
if(position == chunk_segment.end()) {
chunk_segment.push_back(chunk_elem_t{
.coord = z,
.elem = std::move(value)
});
return;
}
position->elem = std::move(value);
}
};

Loading…
Cancel
Save