www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Iterating over the tupleof of a struct

reply "Meta" <jared771 gmail.com> writes:
Something weird happens when I try to foreach over test.tupleof. 
If the foreach loop has 2 variables like so:

struct Test
{
	string name = "'null'";
	int id;
}

void main()
{
	auto test = Test();
	assert(test.name == "'null'");
	assert(test.id == 0);
	
	foreach (val1, val2; test.tupleof)
	{
		import std.stdio, std.conv, std.traits;
		writeln(typeof(val1).stringof, "->", val1, " ",
                         typeof(val2).stringof, "->", val2);
	}
}

The following is printed:

ulong->0 string->'null'
ulong->1 int->0



If the foreach only has 1 variable, like this:

	foreach (val; test.tupleof)
	{
		import std.stdio, std.conv, std.traits;
		writeln(typeof(val).stringof, "->", val);
	}

The following is printed instead:

string->'null'
int->0



What is happening here? Are these two extra ulongs the offsets of 
the fields in the struct?
Aug 22 2014
parent reply "Meta" <jared771 gmail.com> writes:
On Saturday, 23 August 2014 at 01:24:10 UTC, Meta wrote:
 What is happening here? Are these two extra ulongs the offsets 
 of the fields in the struct?
And I just realized that that's obviously not the case. It's just an iteration variable. Problem solved.
Aug 22 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Saturday, 23 August 2014 at 01:32:13 UTC, Meta wrote:
 On Saturday, 23 August 2014 at 01:24:10 UTC, Meta wrote:
 What is happening here? Are these two extra ulongs the offsets 
 of the fields in the struct?
And I just realized that that's obviously not the case. It's just an iteration variable. Problem solved.
It is same with arrays: int[] arr = [ 1, 2, 3 ]; // ok, iterates elements foreach (elem; arr) { } // also ok, iterates elements + counts current index foreach (index, elem; arr) { }
Aug 22 2014
next sibling parent "Suliman" <evermind live.ru> writes:
How can I feel struct with foreach loop?

struct ConfigStruct
{
     string [string] key1;
     string [string] key2;
}
ConfigStruct confstruct;

foreach (i, line; readText(ConfigName).splitLines())
{
string [] keyvalue = line.split("=");
confstruct.key1[keyvalue[0]] = keyvalue[1];
}

it's ok for 1 key, but I need iterate through all element of 
struct. For make it's simply let's assume that spited lines are 
equal йшер number of elements in struct.
Aug 22 2014
prev sibling parent reply "Meta" <jared771 gmail.com> writes:
On Saturday, 23 August 2014 at 01:56:06 UTC, Dicebot wrote:
 On Saturday, 23 August 2014 at 01:32:13 UTC, Meta wrote:
 On Saturday, 23 August 2014 at 01:24:10 UTC, Meta wrote:
 What is happening here? Are these two extra ulongs the 
 offsets of the fields in the struct?
And I just realized that that's obviously not the case. It's just an iteration variable. Problem solved.
It is same with arrays: int[] arr = [ 1, 2, 3 ]; // ok, iterates elements foreach (elem; arr) { } // also ok, iterates elements + counts current index foreach (index, elem; arr) { }
Yeah, I got confused as I expected foreach (val1, val2; test.tupleof) { //... } To destructure the result of test.tupleof, but I just got an iteration variable instead.
Aug 23 2014
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/23/2014 10:21 AM, Meta wrote:
 On Saturday, 23 August 2014 at 01:56:06 UTC, Dicebot wrote:
 On Saturday, 23 August 2014 at 01:32:13 UTC, Meta wrote:
 On Saturday, 23 August 2014 at 01:24:10 UTC, Meta wrote:
 What is happening here? Are these two extra ulongs the offsets of
 the fields in the struct?
And I just realized that that's obviously not the case. It's just an iteration variable. Problem solved.
It is same with arrays: int[] arr = [ 1, 2, 3 ]; // ok, iterates elements foreach (elem; arr) { } // also ok, iterates elements + counts current index foreach (index, elem; arr) { }
Yeah, I got confused as I expected foreach (val1, val2; test.tupleof) { //... } To destructure the result of test.tupleof, but I just got an iteration variable instead.
There are a number of inconsistencies around tuples. The behavior you expect is present for ranges that return tuple fronts: import std.stdio; import std.typecons; import std.range; void main() { auto t = [ tuple(1.5, 100), tuple(2.5, 200) ]; foreach (a, b; t.retro) { writefln("%s, %s", a, b); } } Because t.retro is a range, the foreach extracts the members of the tuple and we get the folloing output: 2.5, 200 1.5, 100 Now, remove the .retro part; the range becomes a slice, in which case 'a' becomes the iteration counter and 'b' becomes the tuple value: 0, Tuple!(double, int)(1.5, 100) 1, Tuple!(double, int)(2.5, 200) Is that a WAT? :) Ali
Aug 23 2014
parent "Meta" <jared771 gmail.com> writes:
On Saturday, 23 August 2014 at 20:34:35 UTC, Ali Çehreli wrote:
 There are a number of inconsistencies around tuples. The 
 behavior you expect is present for ranges that return tuple 
 fronts:

 import std.stdio;
 import std.typecons;
 import std.range;

 void main()
 {
     auto t = [ tuple(1.5, 100), tuple(2.5, 200) ];

     foreach (a, b; t.retro) {
         writefln("%s, %s", a, b);
     }
 }

 Because t.retro is a range, the foreach extracts the members of 
 the tuple and we get the folloing output:

 2.5, 200
 1.5, 100

 Now, remove the .retro part; the range becomes a slice, in 
 which case 'a' becomes the iteration counter and 'b' becomes 
 the tuple value:

 0, Tuple!(double, int)(1.5, 100)
 1, Tuple!(double, int)(2.5, 200)

 Is that a WAT? :)

 Ali
I cannot wait until we get proper tuple destructuring and this buggy foreach unpacking dies.
Aug 23 2014