What if a container's end()
returns an iterator of a different type than begin()
? Does it violate some principles the iterators are based on?
Sample code that I found in cppcoro library:
namespace detail
{
struct generator_sentinel {};
template<typename T>
class generator_iterator
{
//normal iterator implementation with `operator++` and `operator==` goes here.
friend bool operator==(const generator_iterator& it, generator_sentinel) noexcept
{
return !it.m_coroutine || it.m_coroutine.done();
}
friend bool operator!=(const generator_iterator& it, generator_sentinel s) noexcept
{
return !(it == s);
}
friend bool operator==(generator_sentinel s, const generator_iterator& it) noexcept
{
return (it == s);
}
friend bool operator!=(generator_sentinel s, const generator_iterator& it) noexcept
{
return it != s;
}
...
};
}
template<typename T>
class [[nodiscard]] generator
{
public:
using promise_type = detail::generator_promise<T>;
using iterator = detail::generator_iterator<T>;
...
iterator begin()
{
if (m_coroutine)
{
m_coroutine.resume();
if (m_coroutine.done())
{
m_coroutine.promise().rethrow_if_exception();
}
}
return iterator{ m_coroutine };
}
detail::generator_sentinel end() noexcept
{
return detail::generator_sentinel{};
}
};