foreach on const(V[K])

Dan dbdavidson at yahoo.com
Tue Nov 27 07:32:07 PST 2012


On Monday, 19 November 2012 at 12:24:56 UTC, Dan wrote:
> I posted this on *learn* a few days back.
> Is this a reasonable language request - to allow for ref of 
> immutable(K) on associative array iteration? If allowed it 
> would enable iteration without casting, because casting could 
> allow for unintended consequences. Maybe there is another way?
>
> The original is at this link and contents are copied below.
> http://forum.dlang.org/post/rxobffxfqbqotyhmrznf@forum.dlang.org
>
> Thanks
> Dan
>
>
> Wouldn't a better form for foreach on associative arrays be one
> of:
>
> *case 1*
> foreach(ref immutable(K) k; ref V v) {
> }
>
> *case 2*
> foreach(ref immutable(K) k; ref const(V) v) {
> }
>
> Both of these would allow for iterating over const associative
> arrays without *copying* the key K. As it stands you can not
> iterate, or even get the length (which under the covers does
> iteration) of a const(V[K]) without casting off const deeply
> because the foreach approach is to copy the keys. But it should
> not need to? Couldn't it allow a reference to the keys and the
> type on iteration of the key should be immutable.
>
> In the example below casting is the only way to get at length 
> and
> on the iteration the keys are (needlessly?) copied.
>
> Thanks,
> Dan
>
> --------- OUTPUT -----------
> Length:
> 1
> Foreach:
> Key dupped
> k => a val => b
> -----------------------------------------------------------------
> import std.stdio;
> const int asPreferred = 0;
> struct Key {
>   this(this){ c=c.dup; writeln("Key dupped"); }
>   char[] c;
> }
> struct Val {
>   this(this){ c=c.dup; writeln("Val dupped"); }
>   char[] c;
> }
> alias Val[Key] Map;
> void foo(ref const(Map) m) {
>   static if(asPreferred) {
>     writeln(m.length);
>     foreach(ref immutable(K) k, ref const(Val) v; m) {}
>   } else {
>     writeln("Length:");
>     writeln((cast(Val[Key])m).length);
>     writeln("Foreach:");
>     foreach(k,ref Val v; cast(Val[Key])m) {
>       writeln("k => ", k.c, " val => ", v.c);
>     }
>   }
> }
>
> void main() {
>   Val[Key] aa = [ Key(['a']) : Val(['b']) ];
>   foo(aa);
> }

At the risk of being too persistent ... are there any opinions on 
this?
It seems a small tweak to the meaning of foreach with associative 
arrays would fix some issues requiring unnecessary casts. It 
should also be more efficient as there would be no need for extra 
copying of keys.

Thanks
Dan



More information about the Digitalmars-d mailing list