Support indexing util::array with arbitrary array-like types
This commit is contained in:
parent
8571bc9c6d
commit
249ca33aab
1 changed files with 75 additions and 10 deletions
|
|
@ -9,6 +9,38 @@
|
|||
namespace psemek::util
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct is_array : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_array<T, std::void_t<decltype(std::declval<T&>()[0])>>
|
||||
: std::true_type
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
constexpr bool is_array_v = is_array<T>::value;
|
||||
|
||||
template <typename ... Ts>
|
||||
struct is_index;
|
||||
|
||||
template <>
|
||||
struct is_index<>
|
||||
: std::false_type
|
||||
{};
|
||||
|
||||
template <typename T, typename ... Ts>
|
||||
struct is_index<T, Ts...>
|
||||
: std::bool_constant<!is_array_v<T>>
|
||||
{};
|
||||
|
||||
template <typename ... Ts>
|
||||
constexpr bool is_index_v = is_index<Ts...>::value;
|
||||
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct array
|
||||
{
|
||||
|
|
@ -62,14 +94,27 @@ namespace psemek::util
|
|||
return dims_[2];
|
||||
}
|
||||
|
||||
T & operator()(dims_type const & index);
|
||||
T const & operator()(dims_type const & index) const;
|
||||
template <typename Index>
|
||||
std::enable_if_t<detail::is_array_v<Index>, T &>
|
||||
operator()(Index const & index);
|
||||
|
||||
template <typename Index>
|
||||
std::enable_if_t<detail::is_array_v<Index>, T const &>
|
||||
operator()(Index const & index) const;
|
||||
|
||||
template <typename ... Ixs>
|
||||
T & operator()(Ixs ... ixs);
|
||||
std::enable_if_t<detail::is_index_v<Ixs...>, T &>
|
||||
operator()(Ixs ... ixs);
|
||||
|
||||
template <typename ... Ixs>
|
||||
T const & operator()(Ixs ... ixs) const;
|
||||
std::enable_if_t<detail::is_index_v<Ixs...>, T const &>
|
||||
operator()(Ixs ... ixs) const;
|
||||
|
||||
template <typename I>
|
||||
T & operator()(std::initializer_list<I> const & index);
|
||||
|
||||
template <typename I>
|
||||
T const & operator()(std::initializer_list<I> const & index) const;
|
||||
|
||||
array copy() const;
|
||||
|
||||
|
|
@ -127,8 +172,8 @@ namespace psemek::util
|
|||
return false;
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
std::size_t index(std::array<std::size_t, N> const & i, std::array<std::size_t, N> const & dims)
|
||||
template <std::size_t N, typename Index>
|
||||
std::size_t index(Index const & i, std::array<std::size_t, N> const & dims)
|
||||
{
|
||||
std::size_t r = 0;
|
||||
for (std::size_t d = N; d --> 0;)
|
||||
|
|
@ -278,20 +323,25 @@ namespace psemek::util
|
|||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
T & array<T, N>::operator()(dims_type const & index)
|
||||
template <typename Index>
|
||||
std::enable_if_t<detail::is_array_v<Index>, T &>
|
||||
array<T, N>::operator()(Index const & index)
|
||||
{
|
||||
return data_[detail::index(index, dims_)];
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
T const & array<T, N>::operator()(dims_type const & index) const
|
||||
template <typename Index>
|
||||
std::enable_if_t<detail::is_array_v<Index>, T const &>
|
||||
array<T, N>::operator()(Index const & index) const
|
||||
{
|
||||
return data_[detail::index(index, dims_)];
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
template <typename ... Ixs>
|
||||
T & array<T, N>::operator()(Ixs ... ixs)
|
||||
std::enable_if_t<detail::is_index_v<Ixs...>, T &>
|
||||
array<T, N>::operator()(Ixs ... ixs)
|
||||
{
|
||||
dims_type dims{static_cast<std::size_t>(ixs)...};
|
||||
return (*this)(dims);
|
||||
|
|
@ -299,12 +349,27 @@ namespace psemek::util
|
|||
|
||||
template <typename T, std::size_t N>
|
||||
template <typename ... Ixs>
|
||||
T const & array<T, N>::operator()(Ixs ... ixs) const
|
||||
std::enable_if_t<detail::is_index_v<Ixs...>, T const &>
|
||||
array<T, N>::operator()(Ixs ... ixs) const
|
||||
{
|
||||
dims_type dims{static_cast<std::size_t>(ixs)...};
|
||||
return (*this)(dims);
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
template <typename I>
|
||||
T & array<T, N>::operator()(std::initializer_list<I> const & index)
|
||||
{
|
||||
return data_[detail::index(std::data(index), dims_)];
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
template <typename I>
|
||||
T const & array<T, N>::operator()(std::initializer_list<I> const & index) const
|
||||
{
|
||||
return data_[detail::index(std::data(index), dims_)];
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
array<T, N> array<T, N>::copy() const
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue