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

Reply via email to