C++ Logo

std-proposals

Advanced search

Re: n-dimensional container

From: Barry Revzin <barry.revzin_at_[hidden]>
Date: Sun, 23 May 2021 22:01:28 -0500
On Sun, May 23, 2021 at 5:16 PM ci7od57x--- via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Hallo, World!
>
> If would be nice to have something in the standard library which makes it
> easy to create an n-dimensional container of some type just by providing
> the container (e.g., vector or list) the member-type and n.
>
>
> A possible implementation written in C++11 could look like this:
>
>
> template <
> template <typename...> class C,
> std::size_t N,
> typename H, typename... T>
> struct nested {
> using type = C<
> typename nested<C, N - 1, H, T...>::type, T...>;
> };
>
> template <
> template <typename...> class C,
> typename H, typename... T>
> struct nested<C, 0, H, T...> {
> using type = H;
> };
>
> template <
> template <typename...> class C,
> std::size_t N,
> typename H, typename... T>
> using nested_t = typename nested<C, N, H, T...>::type;
>
>
>
> If is using template template parameters.
>
> 'nested' can e.g., be used like this:
>
>
> static_assert(std::is_same<
> nested_t<std::vector, 0, int>,
> int
> >::value);
>
> static_assert(std::is_same<
> nested_t<std::vector, 1, int>,
> std::vector<int>
> >::value);
>
> static_assert(std::is_same<
> nested_t<std::vector, 2, int>,
> std::vector<std::vector<int>>
> >::value);
>
> static_assert(std::is_same<
> nested_t<std::vector, 3, int>,
> std::vector<std::vector<std::vector<int>>>
> >::value);
>
> static_assert(std::is_same<
> nested_t<std::vector, 4, int>,
> std::vector<std::vector<std::vector<std::vector<int>>>>
> >::value);
>
> static_assert(std::is_same<
> nested_t<std::vector, 5, int>,
>
> std::vector<std::vector<std::vector<std::vector<std::vector<int>>>>>
> >::value);
>
> static_assert(std::is_same<
> nested_t<std::vector, 6, int>,
>
> std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<int>>>>>>
> >::value);
>
>
> All asserts will pass.
>
>
> I think this feature is useful, because it makes code more readable
> (nested_t<std::vector, 3, int> instead of
> std::vector<std::vector<std::vector<int>>>; you don't need to count the
> std::vectors) and it is also easier to add or remove an dimension (you just
> need to change one number). You can also write an function template, that
> takes the number of dimensions of something as a template parameter, which
> makes the code more generic.
>
> The right order of the template parameters and name are two of the things
> that need to be discussed. I also considered the names 'matrix' (because
> you can use it to create an n-dimensional matrix) and 'n_dimensional'
> instead of 'nested'. Furthermore there should also be a way to create
> multidimensional std::arrays. (And maybe std::maps?)
>
> Is that a feature worth writing a proposal for?
>

This specifically, no.

But this specifically can be composed from smaller parts. You could, for
instance, use Boost.Mp11, with which the answer to most metaprogramming
problems is a short one-liner (https://godbolt.org/z/oajefrd33):

template <template <typename...> class Z, size_t N, class V>
using nested = mp_reverse_fold<mp_repeat_c<mp_list<mp_quote<Z>>, N>, V,
mp_invoke_q>;

And when we do get reflection, it'll probably become possible to implement
Mp11 in a way that's even more user- and compiler-friendly. But until
then... it exists.

Barry

Received on 2021-05-23 22:01:46