A bunch of random code samples
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

96 lignes
2.4 KiB

#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);
}
};