#pragma once #include #include template struct cube { struct chunk_elem_t { size_t coord; T elem; }; struct chunk_t { std::array, chunk_size>, chunk_size> data; }; struct row_t { size_t coord; std::shared_ptr value; }; struct column_t { size_t coord; std::vector value; }; std::vector chunks; std::optional 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(); 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(); 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); } };