RFC on range design for D2
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Tue Sep 9 14:55:37 PDT 2008
Steven Schveighoffer wrote:
> "Andrei Alexandrescu" wrote
> <snip>
>
> Excellent ideas! I think the best part is about how you almost never need
> individual iterators, only ever ranges. Perfectly explained!
>
> One issue that you might not have considered is using a container as a data
> structure, and not using it for algorithms. For example, how would one
> specify that one wants to remove a specific element, not a range of
> elements. Having a construct that points to a specific element but not any
> specific end element might be a requirement for non-algorithmic reasons.
I'm sure you know and imply this, but just to clarify for everybody:
Modifying the topology of the container is a task carried by the
primitives of the container. Ranges can "look" at the topology and
change elements sitting in it, but not alter the topology.
Much like in STL, there's a container primitive for removing a range. It
will return a range too, namely the range starting at the deleted
position. Removing an element is really removing a range of one element
- just a particular case.
> Also, some ranges might become invalid later on whereas the iterators would
> not. Take for example a Hash container. If you have to rehash the table, a
> range now might not make any sense, as the 'end' element may have moved to
> be before the 'begin' element. But an iterator that points to a given
> element will still be valid (and could be used for removal). In fact, I
> don't think ranges make a lot of sense for things like Hash where there
> isn't any defined order. But you still should have a 'pointer' type to
> support O(1) removal.
Iterators can be easily defined over hashtables, but indeed they are
easily invalidated if implemented efficiently.
> One doesn't see any of these problems with arrays, because with arrays, you
> are guaranteed to have contiguous memory.
>
> What I'm trying to say is there may be a reason to have pointers for certain
> containers, even though they might be unsafe.
A pointer to an element can be taken as &(r.first). The range may or may
not allow that, it's up to it.
> My personal pet peeve of many container implementations is not being able to
> remove elements from a container while iterating. For example, I have a
> linked list of open file descriptors, iterate over the list, closing and
> removing those that are done (which should be O(1) per removal). In many
> container implementations, iteration implies immutable, which means you have
> to add references to the elements to remove to another list to then remove
> afterwards (somtimes at the cost of O(n) per removal. grrrr.) I hope
> ranges will support removal while traversing.
In STL removing from a list while iterating is easy and efficient,
albeit verbose as always:
list<Filedesc> lst;
for (list<Filedesc>::iterator i = lst.begin(); i != lst.end(); )
{
if (should_remove) i = lst.erase(i);
else ++i;
}
In Phobos things will be something like:
List!(Filedesc) lst;
for (auto r = lst.all; !r.isEmpty; )
{
if (should_remove) r = lst.erase(take(1, r));
else r.next;
}
Andrei
More information about the Digitalmars-d-announce
mailing list