Removing from SList (std.container)...

Roman D. Boiko rb at d-coding.com
Wed Jun 27 14:57:29 PDT 2012


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.


More information about the Digitalmars-d-learn mailing list