RangeExtra

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Thu Apr 23 11:37:37 PDT 2009


dsimcha wrote:
> I'm loving the new Phobos, and have been playing around with ranges, alias
> this, etc.  I've compiled a list of a few range types that I have at least
> partial implementations of for personal use that were overlooked by Andrei, et
> al. in the initial release of the new Phobos.  Please tell me which of these
> are generally useful and should be cleaned up and released, which ones are too
> niche to belong in Phobos, which ones std.range can already do by some
> slightly non-obvious idiom, and which ones, if any, are already in the works.

I think these are fantastic. Some comments within.

> CapacityArray:  A range that covers a builtin array and gives it a capacity
> field.  All operations that don't have to do with appending are forwarded to
> the underlying array via alias this (modulo a few compiler bugs), meaning that
> a CapacityArray has an identical compile time interface to a builtin array,
> and is implicitly convertible to one.

Upon more thinking, I think we'll have to bit the bullet and define 
Array!T and Slice!T. Then dmd rewrites:

[ a, b, c ] -> .Array!(typeof(a))(a, b, c)
T[new] -> .Array!(T)
new T[n] -> .Array!(T)(n)
T[] -> .Slice!(T)

It seems increasingly clear that slices alone can't quite cut the mustard.

So your CapacityArray will essentially be the basis of Array.

> Reindex:  Takes a zero-indexed random access range and converts it to a range
> with an arbitrary base index.  Useful for one-indexed arrays to fit
> mathematical notation conventions, etc.

Hm. I'd take the opportunity to actually reindex the range in an 
arbitrary way, e.g. by computing a separate index for it and using it 
transparently. I see little utility in just changing base (I tried such 
based_vector code for C++ and it created more confusion than it removed.)

> Comb:  Given a random-access range, iterate over all unordered pairs, triples,
> etc. of elements in the underlying range.  front(), opIndex(), etc. would
> return tuples or structs containing static arrays.  Note that to do this
> efficiently, the number of elements (pair, triplet, etc.) would have to be
> known at compile time.

Sounds cool.

> Joint:  Kind of like std.range.Zip, but returns a tuple of values of the
> elements in the underlying ranges instead of a proxy of pointers to the
> elements of the underlying range.  Zip is great for what it's designed for,
> but sometimes the pointer/reference semantics are problematic.

Joint is a risque name, but the idea is good. My preference would be to 
look into using alias this with Zip for a seamless experience though. 
After all, once you have a seamless Zip, creating copies out of it is 
the easy part. Besides, Joint can only make for an input range as people 
can't save references returned by front(). Zip can be as strong a range 
as possible.

> Rotated:  Gives a rotated view of a random access range without modifying the
> underlying range.  Also has a put() method.  Given an underlying range of
> length L, this provides an efficient way to remember the last L elements seen
> by the range:

I think that's very related to Cycle.

http://www.digitalmars.com/d/2.0/phobos/std_range.html#Cycle

Keep the great ideas coming!


Andrei



More information about the Digitalmars-d mailing list