On Wednesday, 27 June 2012 at 21:38:28 UTC, Jonathan M Davis
wrote:
On Wednesday, June 27, 2012 22:29:01 Roman D. Boiko wrote:
On Wednesday, 27 June 2012 at 20:14:53 UTC, Steven
Schveighoffer
wrote:
> Removal of that element is perfectly possible, you just need
> to
> maintain a reference to its predecessor. Which SList's range
> does not keep track of. It all depends on tradeoffs of what
> you want for performance, vs. features. It's why I contend
> that generic singly linked list is difficult to create. Can't
> please everyone.
Yes, I agree.
> And iterators are not necessary, ranges are quite possible.
In this respect it is not only a performance vs. features
tradeoff, semantics is (usually) different. Of course, we might
use a range for what is semantically an iterator. But it feels
unnatural for me.
E.g., to point to an element in the middle of some range we
would
need to create another range and pass it to a function along
with
the original range. I would hesitate to call them ranges unless
that is explicitly a goal for some particular application. If
that was the case, it would require an explicit explanation.
(IMO)
If you want a single element, then use take, takeExactly, or
takeOne. For
instance, that's what you do when you want to use remove in
std.container
(though apparently takeOne was missed as pointed out earlier in
this thread,
which needs to be remedied). It is true that dealing with
ranges in this sort
of situation is a bit more problematic than it is with
iterators, but the
take* functions take care of it as long as the container
properly takes them
into account (which std.container's containers are supposed to
do). And if all
you care about is having a range with one element and not
whether the range is
passable to a function on it's associated container, then the
take* functions
work just fine regardless of whether the container properly
takes them into
account. It's only an issue with the container, because the
container needs
its original range type rather than some arbitrary range which
may have
nothing to do with that container (the same happens with
iterators - you just
don't tend to wrap them in other types in the same way that
happens with
ranges).
- Jonathan M Davis
It depends entirely on intended semantics and use cases. There is
a difference between a range, an iterator, and a link (pointer)
to some container node. I meant a link when I used the term
"iterator".
To illustrate, imagine a tree container. A link could point to
some node, which could be used conceptually as a container. A
range would define a subset of either element values or links for
some traversal. So a range semantically implies an ordering, and
is quite different from a link. An iterator seems to be closer to
a range in this respect, that's why I admitted that I used the
term incorrectly.