DMD 0.170 release
Bill Baxter
wbaxter at gmail.com
Tue Oct 17 08:00:58 PDT 2006
Bruno Medeiros wrote:
> Walter Bright wrote:
>
>> Added foreach_reverse, which addresses a serious shortcoming.
>>
>> http://www.digitalmars.com/d/changelog.html
>
>
> foreach_reverse addresses a serious shortcoming? What is that, if
> instead of:
> foreach_reverse(Foo f; aggregate) { ...
> I can do:
> foreach(Foo f; &aggregate.opApplyReverse) { ...
>
> The latter form is both more general (allows any kind of iterators) and
> more simple/orthogonal (no extra special statements are needed).
I agree. Allowing any delegate to be used is a good move I think. But
the incremental value added by 'foreach_reverse' and 'opApplyReverse'
are minimal once you can already use any delegate as the aggregate.
It would be nice to be able to write a function like "reversed" and then
just do
foreach(Foo f; reversed(aggregate)) { ...
To me that seems like a more clean and natural way to support a variety
of iteration strategies without adding special-cased reverse iterators
to the language.
Here's a somewhat limited version of that idea:
It's limited by my lack of template-fu, so it just works for arrays, and
you have to explicitly pass too many template parameters:
class _rev_proxy(AggregateT, ElemT)
{
this(AggregateT theObj) {
obj = theObj;
}
int opApply(int delegate(inout ElemT) dg)
{
int done = 0;
for (int i = obj.length-1; i >=0; i--)
{
done = dg(obj[i]);
if (done)
break;
}
return done;
}
private:
AggregateT obj;
}
_rev_proxy!(AggregateT,ElemT) reversed(AggregateT,ElemT)(AggregateT array)
{
return new _rev_proxy!(AggregateT,ElemT)(array);
}
unittest
{
void testrev() {
int[] aint = [1,2,3,4,5,6,7];
real[] areal = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0];
foreach(int i; reversed!(int[],int)(aint))
{
printf("%d\n",i);
}
foreach(real r; reversed!(real[],real)(areal))
//foreach(real r; areal)
{
printf("%f\n",cast(float)(r));
}
}
testrev();
}
I would guess this could probably be expanded with more template-fu so
that any class which supports a particular protocol (e.g. has a .length
and [] operator, or a reversed() method) can automatically be reversed.
And then as a last resort you could always write your own
specialization of reversed!() particularly for your class.
--bb
More information about the Digitalmars-d-announce
mailing list