extend the api of foreach to allow for foreach(key,value;data)
for user data types,
and user defined "autodecoding"
related debates
the (unnesery) deperacation of "implict casts" of array indexes to int https://forum.dlang.org/thread/qdsypzjwptbebffktohx@forum.dlang.org
key'd ranges in general https://forum.dlang.org/thread/akczwyrmlpocihmaitbz@forum.dlang.org
definitions
keyd range: a struct that defines the functions front,popFront,empty and key
autodecoding: when a data structure is implicitly transformed into a range by a imported function and ufcs (not string specific)
foreach header: the part of the foreach call that comes before the ;
priority
-
if the template header and data combo are currently valid, dont change behavior(whatever that looks like)
-
if the data is a keyd range but the foreach header has a key; define key to be range.key and value to be range.front; handle ref if possible
-
if data is not a range, attempt to call opSlice to see if thats a range (static arrays)
-
if data does not have an opSlice, "autodecode"
data.toRange!(details from foreach header)
foreach header parsing
because ref isnt on types I dont believe you can pass "ref int" into a template, and maybe theres something about named arguments, I believe this should be handled with strings.
unattributed arguments are replaced with void, so the user can handle hard cases tuples as they wish(2d iteration, or zipped ranges)
foreach(int k,value:ref @safe v;...)
would be parsed as ("int","value:ref @safe") Im unsure what user code does with "@safe" but let the user figure it out
foreach(a,b,c,d,e,f,g;...)
would be parsed as (void,void,void,void,void,void)
keyd range example code
struct strangecounter{
int front;
int last;
void popFront(){front++;}
int key()=>front*front;
bool empty()=> last>=front;
}
foreach(k,v;strangecounter(0,10)){
writeln(k,":",v);//0:0, 1:1, 4:2,9:3.....
}
foreach(ref k,v;strangecounter(0,10))
would fail to compile, some complaint about lvalues or suggesting the user to define a torange!("ref",void)
foreach(k,ref v;strangecounter(0,10))
would compile
foreach(size_t k,v;strangecounter(0,10))
would fail to compile, suggesting the user to define a torange!("size_t",void)
foreach(a,b,c;strangecounter(0,10))
would fail to compile, and suggesting the user define a torange!(void,void,void)
foreach(v;strangecounter(0,10))
would compile (using keys are optional)
torange example code
handling int indexing
auto torange(string s:"int",T)(ref T[] array){
struct myrange{
int key_;
auto key()=>key_;//unref's key
auto front()=>array[key];
auto popFront(){key_++;}
auto empty()=>arra.length>=key;
}
return myrange;
}
foreach(int i,v;array){//compiles