Add util::array iterators over range of indices

This commit is contained in:
Nikita Lisitsa 2020-09-30 07:23:05 +03:00
parent 4bb287eb70
commit e520b464e4

View file

@ -96,6 +96,10 @@ namespace psemek::util
void fill(T const & value);
auto index_begin() const;
auto index_end() const;
auto indices() const;
private:
std::unique_ptr<T[]> data_;
std::array<std::size_t, N> dims_;
@ -148,6 +152,75 @@ namespace psemek::util
return false;
}
template <std::size_t N>
struct array_index_iterator
{
std::array<std::size_t, N> idx;
std::array<std::size_t, N> dims;
bool end;
std::array<std::size_t, N> const & operator*() const { return idx; }
array_index_iterator & operator ++()
{
end = next(idx, dims);
return *this;
}
};
struct array_index_iterator_sentinel
{};
template <std::size_t N>
bool operator == (array_index_iterator<N> const & it, array_index_iterator_sentinel)
{
return it.end;
}
template <std::size_t N>
bool operator != (array_index_iterator<N> const & it, array_index_iterator_sentinel)
{
return !it.end;
}
template <std::size_t N>
struct array_index_range
{
std::array<std::size_t, N> dims;
array_index_iterator<N> begin() const
{
std::array<std::size_t, N> idx;
for (std::size_t i = 0; i < N; ++i)
idx[i] = 0;
return {idx, dims, false};
}
array_index_iterator_sentinel end() const
{
return {};
}
};
}
template <typename T, std::size_t N>
auto array<T, N>::index_begin() const
{
return indices().begin();
}
template <typename T, std::size_t N>
auto array<T, N>::index_end() const
{
return indices().end();
}
template <typename T, std::size_t N>
auto array<T, N>::indices() const
{
return detail::array_index_range<N>{dims_};
}
template <typename T, std::size_t N>