A bunch of random code samples
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

96 satır
2.4 KiB

  1. #pragma once
  2. #include <vector>
  3. #include <array>
  4. template<typename T, size_t chunk_size = 16>
  5. struct cube {
  6. struct chunk_elem_t {
  7. size_t coord;
  8. T elem;
  9. };
  10. struct chunk_t {
  11. std::array<std::array<std::vector<chunk_elem_t>, chunk_size>, chunk_size> data;
  12. };
  13. struct row_t {
  14. size_t coord;
  15. std::shared_ptr<chunk_t> value;
  16. };
  17. struct column_t {
  18. size_t coord;
  19. std::vector<row_t> value;
  20. };
  21. std::vector<column_t> chunks;
  22. std::optional<T> at(size_t x, size_t y, size_t z) {
  23. auto column = std::ranges::find_if(chunks, [&](const column_t& col) {
  24. return col.coord == y/chunk_size;
  25. });
  26. if(column == chunks.end()) return std::nullopt;
  27. auto row = std::ranges::find_if(column->value, [&](const row_t& row) {
  28. return row.coord == x/chunk_size;
  29. });
  30. if(column->value.end() == row) return std::nullopt;
  31. auto& chunk_segment = row->value->data.at(x%chunk_size).at(y%chunk_size);
  32. auto position = std::ranges::find_if(chunk_segment, [&](const chunk_elem_t& item) {
  33. return item.coord == z;
  34. });
  35. if(position == chunk_segment.end()) return std::nullopt;
  36. return position->elem;
  37. }
  38. void set(size_t x, size_t y, size_t z, T&& value) {
  39. auto column = std::ranges::find_if(chunks, [&](const column_t& col) {
  40. return col.coord == y/chunk_size;
  41. });
  42. if(column == chunks.end()) {
  43. auto chunk = std::make_shared<chunk_t>();
  44. chunks.push_back(column_t{
  45. .coord = y / chunk_size,
  46. .value = {
  47. row_t{
  48. .coord = x/chunk_size,
  49. .value = chunk
  50. }
  51. }
  52. });
  53. chunk->data.at(x%chunk_size).at(y%chunk_size).push_back(chunk_elem_t{
  54. .coord = z,
  55. .elem = std::move(value)
  56. });
  57. return;
  58. }
  59. auto row = std::ranges::find_if(column->value, [&](const row_t& row) {
  60. return row.coord == x/chunk_size;
  61. });
  62. if(column->value.end() == row) {
  63. auto chunk = std::make_shared<chunk_t>();
  64. column->value.push_back(
  65. row_t{
  66. .coord = x/chunk_size,
  67. .value = chunk
  68. }
  69. );
  70. chunk->data.at(x%chunk_size).at(y%chunk_size).push_back(chunk_elem_t{
  71. .coord = z,
  72. .elem = std::move(value)
  73. });
  74. return;
  75. }
  76. auto& chunk_segment = row->value->data.at(x%chunk_size).at(y%chunk_size);
  77. auto position = std::ranges::find_if(chunk_segment, [&](const chunk_elem_t& item) {
  78. return item.coord == z;
  79. });
  80. if(position == chunk_segment.end()) {
  81. chunk_segment.push_back(chunk_elem_t{
  82. .coord = z,
  83. .elem = std::move(value)
  84. });
  85. return;
  86. }
  87. position->elem = std::move(value);
  88. }
  89. };