Support more than one argument in fractal octaves construction

This commit is contained in:
Nikita Lisitsa 2020-12-13 22:40:41 +03:00
parent b7fdc4959e
commit 57e8aa39af

View file

@ -4,6 +4,7 @@
#include <psemek/util/assert.hpp>
#include <vector>
#include <tuple>
namespace psemek::pcg
{
@ -17,6 +18,9 @@ namespace psemek::pcg
template <typename Arg>
fractal(std::vector<Arg> args, std::vector<value_type> weights);
template <typename ... Args>
fractal(std::piecewise_construct_t, std::vector<std::tuple<Args...>> args, std::vector<value_type> weights);
template <typename ... Args>
value_type operator ()(Args const & ... args) const
{
@ -41,6 +45,34 @@ namespace psemek::pcg
octaves.emplace_back(std::move(args[i]));
}
namespace detail
{
template <typename C, typename Tuple, std::size_t ... Is>
void emplace_back_from_tuple_impl(C & c, Tuple && tuple, std::index_sequence<Is...>)
{
c.emplace_back(std::get<Is>(tuple)...);
}
template <typename C, typename Tuple>
void emplace_back_from_tuple(C & c, Tuple && tuple)
{
emplace_back_from_tuple_impl(c, std::forward<Tuple>(tuple), std::make_index_sequence<std::tuple_size_v<Tuple>>{});
}
}
template <typename Generator>
template <typename ... Args>
fractal<Generator>::fractal(std::piecewise_construct_t, std::vector<std::tuple<Args...>> args, std::vector<value_type> weights)
{
assert(args.size() == weights.size());
this->weights = std::move(weights);
octaves.reserve(args.size());
for (std::size_t i = 0; i < args.size(); ++i)
detail::emplace_back_from_tuple(octaves, std::forward<std::tuple<Args...>>(args[i]));
}
template <typename Generator>
typename fractal<Generator>::value_type fractal<Generator>::operator()(geom::vector<value_type, dimension> const & p) const
{