Jason,
The type "std::iterator<T>", is not dumb.
Actually this type is a controller over the container it was templated for.
In other words, the "std::iterator<T>" specialization knows exactly what it encloses. And that is manifested in the implementation of the operators:

operator ++ // the 2 flavors 
operator --   // also the 2 flavors,  post and pre
operator *

For a random access iterator these operators are trivial and mimic the plain pointer behavior.

But for "std::list", "std::set"...etc they are not trivial since they need to know how to jump to the next element and dereference it.

Knowing this, we can conclude that these "std::iterator" specializations have a knowledge of their container elements, thus they know where that container ends, they just need to call "std::end(container)"

The proper question is: where in the implementation we should call "std::end"?

If we put it inside the operators which move the index (like "operator++()"), it will not be efficient since we are adding 2 instructions, (especially if the access to the elements is linear like in the forward list), the extra instructions are:
-1 a fetch for a value, namely "std::end"
-2 and a test against it.

So, the silliest solution is to add a member method to the "std::iterator" class i.e

operator bool() const noexcept {return *this == m_containerPtr->end();}

So in a bool context it will be called naturally. Expl

while (++iter) {};

Otherwise,  there is no cost for what you don't use.

This member function is, strangely, absent in all specifications of the different types of iterators classes.(legacyrandom..., legacyfoward...etc).


My proposal for "null_iter" if of different paradigm.
But for now, i would like to read your comments on the above.
I will elaborate the paradigm of "null_iter", if need raises.

Regards
Nadir






Sent from my Galaxy


-------- Original message --------
From: Jason McKesson via Std-Proposals <std-proposals@lists.isocpp.org>
Date: 11/24/22 4:26 AM (GMT+04:00)
To: std-proposals@lists.isocpp.org
Cc: Jason McKesson <jmckesson@gmail.com>
Subject: Re: [std-proposals] Helper type

On Wed, Nov 23, 2022 at 7:02 PM organicoman via Std-Proposals
<std-proposals@lists.isocpp.org> wrote:
>
> Hello gents,
> I would like to suggest the following helper type:
> "null_iter"
> It is of type iterator but convertible to the boolean value "false", much like the type: "nullptr"
> This value "null_iter" is returned by all container iterators types (vector::iterator, list::iterator, set::iterator...etc) to denote the end of the container when you apply the increment or decrement operators.
> For exple:
> --------- code snippet -------
> std::vector<int> v{1,2,3,4};
> auto iter = v.begin();
> while(++iter)
> {
>     //
> }
> ------- end of snippet------
>
>  When "iter" hits "v.end()", it will return "null_iter" which will be converted to "false" then the loop stops.
>
> What do you think?

This is a bad idea.

Many iterators do not know when they are at the end; iterators are
frequently very dumb. Pointers are iterators into contiguous arrays,
so there's no way to even implement "null_iter". Indeed, the *entire
point* of the iterator model is that you need a second object to know
what the "end" even is. This allows you to iterate through a
subsection of a sequence of values without having to create a new
object that represents this subsection.

You're trying to convert the iterator model into a different model of
iteration. Such a model is workable (what you want is a range-centric
model, where a range is the basic unit, and all operations on a range
produce other ranges. The position of a single element is a "range" of
one value), but it is not interchangeable with the iterator model.
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals