;compile -std=c++23
#include <array>
#include <concepts>
#include <memory>
#include <print>
#include <ranges>
#include <string_view>
#include <utility>
#include <vector>
template <typename T, std::integral auto N, std::integral auto... M>
struct Grid {
public:
constexpr explicit Grid(std::initializer_list<T[N]> rows) {
for (auto&& [i, elem] : rows | std::views::join | std::views::enumerate)
m_cells[i] = elem;
}
constexpr auto rows() const {
return N;
}
constexpr auto columns() const {
return N;
}
constexpr const auto& operator[](std::pair<std::size_t, std::size_t> idx) const {
auto&& [row, col] = idx;
const auto index{ (row * this->columns()) + col };
return m_cells[index];
}
private:
std::array<T, N * N> m_cells{};
};
void print_grid(auto&& grd) {
for (std::size_t row : std::views::iota(0, grd.rows())) {
for (std::size_t col : std::views::iota(0, grd.columns())) {
auto&& val = grd[{ row, col }];
std::print("{}{}", col == 0 ? '\n' : ' ', val);
}
}
std::println();
}
int main() {
const Grid numsA{
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 },
};
const Grid numsB{ {
{ 1, 3, 3 },
{ 7, 1, 3 },
{ 7, 7, 1 },
} };
const Grid alph1{
{ "A1", "B1", "C1", "D1" },
{ "A2", "B2", "C2", "D2" },
{ "A3", "B3", "C3", "D3" },
{ "A4", "B4", "C4", "D4" },
};
const Grid alph2{ {
{ "A1", "B1", "C1", "D1" },
{ "A2", "B2", "C2", "D2" },
{ "A3", "B3", "C3", "D3" },
{ "A4", "B4", "C4", "D4" },
} };
print_grid(numsA);
print_grid(numsB);
print_grid(alph1);
print_grid(alph2);
}