Fix operator[] for const iota_view and repeat_view (#1525)

* Fix missing operator[] for iota_iterator and repeat_iterator

The iterators of etl::ranges::iota_view and etl::ranges::repeat_view are
random access iterators but they did not define any operator[]. This did
not cause any issues when using mutable views since the implementation
of operator[] provided by view_interface for random access views was
hidden by another implementation using etl::advance. However, this was
not the case for 'operator[] const', which resulted in a build error
when using constant views.

This commit ensures that the operator[] implementation for random access
views is no longer hidden by another implementation in view_interface,
and adds operator[] to both iterators.

* Fix sign conversion error on operator[] for some views

The operator[] definitions provided by view_interface were accepting
size_t arguments. This was causing a compile-time warning
(Wsign-conversion) for the random access views using an iterator with a
signed difference type. This has been observed on etl::ranges::iota_view
and etl::ranges::repeat_view.

No test is added since the tests provided by the previous commit already
produce the warning, causing a build error.

---------

Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
This commit is contained in:
taltenbach 2026-08-04 09:01:42 +02:00 committed by GitHub
parent 7566eceed7
commit 9d92081d1e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 40 additions and 3 deletions

View File

@ -150,7 +150,8 @@ namespace etl
return *etl::prev(cend());
}
constexpr decltype(auto) operator[](size_t i)
template < typename D2 = D, etl::enable_if_t<!etl::is_random_access_iterator< decltype(etl::declval<const D2&>().begin())>::value, int> = 0>
constexpr decltype(auto) operator[](range_difference_t<D2> i)
{
auto it{static_cast<D*>(this)->begin()};
etl::advance(it, i);
@ -158,13 +159,13 @@ namespace etl
}
template < typename D2 = D, etl::enable_if_t<etl::is_random_access_iterator< decltype(etl::declval<const D2&>().begin())>::value, int> = 0>
constexpr decltype(auto) operator[](size_t i)
constexpr decltype(auto) operator[](range_difference_t<D2> i)
{
return static_cast<D*>(this)->begin()[i];
}
template < typename D2 = D, etl::enable_if_t<etl::is_random_access_iterator< decltype(etl::declval<const D2&>().begin())>::value, int> = 0>
constexpr decltype(auto) operator[](size_t i) const
constexpr decltype(auto) operator[](range_difference_t<D2> i) const
{
return cbegin()[i];
}
@ -502,6 +503,11 @@ namespace etl
return _i;
}
constexpr value_type operator[](difference_type n) const
{
return *(*this + n);
}
private:
value_type _i;
@ -673,6 +679,11 @@ namespace etl
return _value;
}
constexpr value_type operator[](difference_type n) const
{
return *(*this + n);
}
private:
value_type _value;

View File

@ -473,6 +473,20 @@ namespace
CHECK_EQUAL(iv3.empty(), true);
}
TEST(test_ranges_iota_view_const)
{
const auto iv = etl::ranges::iota_view(1, 7);
int compare = 1;
for (auto i : iv)
{
CHECK_EQUAL(i, compare);
++compare;
}
CHECK_EQUAL(iv[4], 5);
}
TEST(test_ranges_views_iota)
{
auto iv = etl::ranges::views::iota(1, 7);
@ -540,6 +554,18 @@ namespace
CHECK_EQUAL(iv3.empty(), true);
}
TEST(test_ranges_repeat_view_const)
{
const auto rv = etl::ranges::repeat_view(1, 7);
for (auto i : rv)
{
CHECK_EQUAL(i, 1);
}
CHECK_EQUAL(rv[4], 1);
}
TEST(test_ranges_views_repeat)
{
auto iv = etl::ranges::views::repeat(1, 7);