I\'m trying to fill a 2D array on compile time with a given function. Here is my code:
template
struct Table
{
int data[H][W];
//std:
This question intrigued me so much that I decided to figure out a solution that would allow the array to be initialised at compile time with a function that took x and y as parameters.
Presumably this could be adapted for any number of dimensions.
#include
#include
// function object that turns x and y into some output value. this is the primary predicate
struct init_cell_xy
{
constexpr init_cell_xy() = default;
constexpr int operator()(int x, int y) const
{
return (1 + x) * (1 + y);
}
};
// function object that applies y to a given x
template
struct init_cell_for_x
{
constexpr init_cell_for_x() = default;
constexpr int operator()(int y) const
{
return _xy(X, y);
}
private:
init_cell_xy _xy;
};
// an array of dimension 1, initialised at compile time
template
struct array1
{
template
constexpr array1(F&& f, std::integer_sequence)
: _values { f(Is)... }
{}
template
constexpr array1(F&& f = init_cell_for_x<>())
: array1(std::forward(f), std::make_integer_sequence())
{}
constexpr auto begin() const { return std::begin(_values); }
constexpr auto end() const { return std::end(_values); }
constexpr auto& operator[](size_t i) const {
return _values[i];
}
private:
int _values[Extent];
friend std::ostream& operator<<(std::ostream& os, const array1& s)
{
os << "[";
auto sep = " ";
for (const auto& i : s) {
os << sep << i;
sep = ", ";
}
return os << " ]";
}
};
// an array of dimension 2 - initialised at compile time
template
struct array2
{
template
constexpr array2(std::integer_sequence)
: _xs { array1(init_cell_for_x())... }
{}
constexpr array2()
: array2(std::make_integer_sequence())
{}
constexpr auto begin() const { return std::begin(_xs); }
constexpr auto end() const { return std::end(_xs); }
constexpr auto& operator[](size_t i) const {
return _xs[i];
}
private:
array1 _xs[XExtent];
friend std::ostream& operator<<(std::ostream& os, const array2& s)
{
os << "[";
auto sep = " ";
for (const auto& i : s) {
os << sep << i;
sep = ",\n ";
}
return os << " ]";
}
};
auto main() -> int
{
using namespace std;
constexpr array2<6,6> a;
cout << a << endl;
return 0;
}