From 8d1be9aebca1a9b2e0709d9115e9891b64182aa3 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Sun, 7 Mar 2021 21:18:27 +0300 Subject: [PATCH] Add pcg::chunked_map --- libs/pcg/include/psemek/pcg/chunked_map.hpp | 55 +++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 libs/pcg/include/psemek/pcg/chunked_map.hpp diff --git a/libs/pcg/include/psemek/pcg/chunked_map.hpp b/libs/pcg/include/psemek/pcg/chunked_map.hpp new file mode 100644 index 00000000..d5312c8f --- /dev/null +++ b/libs/pcg/include/psemek/pcg/chunked_map.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include +#include +#include + +#include + +namespace psemek::pcg +{ + + template + struct chunked_map + { + using generator_func = util::function(geom::box const &)>; + + chunked_map(std::size_t chunk_size, generator_func generator) + : chunk_size_(chunk_size) + , generator_(std::move(generator)) + {} + + T const & operator()(geom::vector p) + { + geom::vector ip; + for (std::size_t i = 0; i < N; ++i) + { + ip[i] = (p[i] >= 0) ? (p[i] / chunk_size_) : -((- p[i] + chunk_size_ - 1) / chunk_size_); + } + + auto it = chunks_.find(ip); + if (it == chunks_.end()) + { + geom::box box; + for (std::size_t i = 0; i < N; ++i) + { + box[i] = {ip[i] * chunk_size_, (ip[i] + 1) * chunk_size_}; + } + it = chunks_.insert(std::pair{ip, generator_(box)}).first; + } + + std::array t; + for (std::size_t i = 0; i < N; ++i) + t[i] = p[i] - ip[i] * chunk_size_; + + return it->second(t); + } + + private: + int const chunk_size_; + generator_func generator_; + mutable std::unordered_map, util::array> chunks_; + + }; + +}