|
Boost : |
From: Helmut Zeisel (HZ2012_at_[hidden])
Date: 2022-01-02 21:03:11
Do you really need a nested array?
You could also use a flat array and an adapter for the index, e,g,
template<typename T, typename U>
concept is_convertible_to = std::is_convertible_v<T, U>;
template<typename T, typename Index>
struct array_adapter
{
std::array<T, Index::size()> m_a;
constexpr array_adapter(is_convertible_to<T> auto ... t) requires
(sizeof...(t) == Index::size()): m_a{t ...} {}
constexpr T operator()(is_convertible_to<std::size_t> auto ... i)
const
requires (sizeof...(i) == Index::dim())
{
return m_a[Index{}(i...)];
}
constexpr T& operator()(is_convertible_to<std::size_t> auto ... i)
requires (sizeof...(i) == Index::dim())
{
return m_a[Index{}(i...)];
}
};
For Index, you might e.g. use
template<std::size_t ... N>
struct row_major_index
{
static constexpr std::size_t size()
{
return (N*...);
}
template<std::size_t i>
constexpr static std::size_t first(is_convertible_to<std::size_t>
auto... n)
{
if constexpr(i == 0)
{
return std::get<0>(std::make_tuple(n...));
}
else
{
return
std::get<i>(std::make_tuple(n...))+std::get<i>(std::make_tuple(N...))*f
irst<i-1>(n...);
}
}
constexpr std::size_t operator()(is_convertible_to<std::size_t>
auto... n)
{
return first<sizeof...(n)-1>(n...);
}
static constexpr std::size_t dim()
{
return sizeof...(N);
}
};
This can be used as follows:
nt main()
{
static const int N1 = 2;
static const int N2 = 3;
static const int N3 = 4;
array_adapter<double,
row_major_index<N1,N2,N3>>
a{111.,112.,113.,114.,
121.,122.,123.,124.,
131.,132.,133.,134.,
211.,212.,213.,214.,
221.,222.,223.,224.,
231.,232.,233.,234.};
for(int n1=0; n1 != N1; ++n1)
{
for(int n2=0; n2!=N2; ++n2)
{
for(int n3=0; n3!=N3; ++n3)
{
std::cout << "a(" << n1 << "," << n2 << "," << n3 << ")="
<< a(n1,n2,n3) << std::endl;
}
}
}
return 0;
}
Of course, this could be generaized to different types of arrays (e.g.
std:.vecrtor) usng some policy class and
template<typename T, typename Index, typename Policy> struct
array_index_adapter { ... };
Helmut
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk