Add pcg::chunked_map

This commit is contained in:
Nikita Lisitsa 2021-03-07 21:18:27 +03:00
parent 4ec44bf7a3
commit 8d1be9aebc

View file

@ -0,0 +1,55 @@
#pragma once
#include <psemek/util/function.hpp>
#include <psemek/util/array.hpp>
#include <psemek/geom/box.hpp>
#include <unordered_map>
namespace psemek::pcg
{
template <typename T, std::size_t N>
struct chunked_map
{
using generator_func = util::function<util::array<T, N>(geom::box<int, N> const &)>;
chunked_map(std::size_t chunk_size, generator_func generator)
: chunk_size_(chunk_size)
, generator_(std::move(generator))
{}
T const & operator()(geom::vector<int, N> p)
{
geom::vector<int, N> 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<int, 2> 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<std::size_t, N> 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<geom::vector<int, N>, util::array<T, N>> chunks_;
};
}