It can be implemented. And the following can work:
constexpr auto a = to_array({1, 2}, {4, 5, 6});
// ^ std::array<std::array<int, 3>, 2>
constexpr auto b = to_array("nice", "thing");
// ^ std::array<std::array<char, 6>, 2>
Here is the code:
template <typename T, std::size_t... N>
constexpr auto to_array(const T(&... arr)[N]) {
constexpr size_t COLS = detail::max<N...>();
return detail::to_2d_array_from_pack<sizeof...(N), COLS>(arr...);
}
With the following helpers:
namespace detail {
template <std::size_t N1, std::size_t... Ns>
constexpr size_t max() {
if constexpr(sizeof...(Ns) == 0) return N1;
else {
constexpr size_t max_rest = max<Ns...>();
return N1 > max_rest ? N1: max_rest;
}
}
template <std::size_t TargetSize, typename T, std::size_t N, std::size_t... I>
constexpr auto to_array(std::index_sequence<I...>, const T (&arr)[N]) {
return std::array<T, TargetSize>{arr[I]...};
}
template <std::size_t TargetSize, typename T, std::size_t N>
constexpr auto to_array(const T(&arr)[N]) {
return to_array<TargetSize>(std::make_index_sequence<N>{}, arr);
}
template <std::size_t TargetRows, std::size_t TargetCols, typename T, std::size_t... N>
constexpr auto to_2d_array_from_pack(const T(&... arr)[N]) {
using TargetType = std::remove_cv_t<T>;
return std::array<std::array<TargetType, TargetCols>, TargetRows> {to_array<TargetCols>(arr)...};
}
} // end of namespace detail
Above supports only 2D arrays. To support 3D arrays we can add:
template <typename T, std::size_t... N, std::size_t... M>
constexpr auto to_array(const T(&... arr)[N][M]) {
constexpr size_t Y_SIZE = detail::max<N...>();
constexpr size_t Z_SIZE = detail::max<M...>();
using TargetType = std::remove_cv_t<T>;
return std::array<std::array<std::array<TargetType, Z_SIZE>, Y_SIZE>, sizeof...(N)> {
detail::to_2d_array_from_array_of_arrays<Y_SIZE, Z_SIZE>(std::make_index_sequence<N>{}, arr)...
};
}
With the following helper in namespace detail
:
template <std::size_t TargetRows, std::size_t TargetCols, typename T,
std::size_t N, std::size_t M, std::size_t... I>
constexpr auto to_2d_array_from_array_of_arrays(std::index_sequence<I...>, const T (&arr)[N][M]) {
return to_2d_array_from_pack<TargetRows, TargetCols>(arr[I]...);
}