Add pcg::chunked_map
This commit is contained in:
parent
4ec44bf7a3
commit
8d1be9aebc
1 changed files with 55 additions and 0 deletions
55
libs/pcg/include/psemek/pcg/chunked_map.hpp
Normal file
55
libs/pcg/include/psemek/pcg/chunked_map.hpp
Normal 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_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue