I considered this issue in my current project (https://github.com/uonrobotics/ctmd) and redefined mdarray to use the std::array container when rank_dynamic() is 0.
namespace detail {
template <extents_c extent_t>
[[nodiscard]] inline constexpr size_t static_mdarray_size() noexcept {
if constexpr (extent_t::rank() == 0) {
return 0;
} else {
return []<size_t... Is>(std::index_sequence<Is...>) {
return (extent_t::static_extent(Is) * ...);
}(std::make_index_sequence<extent_t::rank()>{});
}
}
} // namespace detail
template <size_t Rank, class IndexType = size_t>
using dims = dextents<IndexType, Rank>
template <typename T, extents_c extent_t>
using mdarray = std::conditional_t<
extent_t::rank_dynamic() == 0,
std::experimental::mdarray<
T, extent_t, layout_right,
std::array<T, detail::static_mdarray_size<extent_t>()>>,
std::experimental::mdarray<T, extent_t, layout_right, std::vector<T>>>;
With this definition, the mdarray can be instantiated as a constexpr when the rank is static, for example:
constexpr auto a = mdarray<T, extents<size_t, 2, 1, 2>>{std::array<T, 4>{1, 2, 3, 4}};
Alternatively, it can be created as a non-constexpr object with dynamic extents:
const auto a = mdarray<T, dims<3>>{std::vector<T>{1, 2, 3, 4}, dims<3>{2, 1, 2}};
Is this approach helpful for your problem?