www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Passing a single tuple or multiple values

reply jmh530 <john.michael.hall gmail.com> writes:
In the code below, is it possible to combine both bar functions 
into one function (I just put some random foo function to get it 
to work)?

When I try to do it, I get errors that
no property 'expand' for type '(Tuple!(int, int))'
I think it has something to do with T... being considered a 
tuple. I also can't seem to do something using T.length because 
it is two regardless.

import std.typecons : isTuple, tuple;
import std.stdio : writeln;

auto foo(T...)(T x)
{
	T[0] y;
	foreach (i, e; x)
	{
		y += e;
	}
	return y;
}

auto bar(T)(T x)
{
	static if (isTuple!T)
	{
		return foo(x.expand);
	}
}

auto bar(T...)(T x)
{
	return foo(x);
}

void main()
{
	auto x = tuple(1, 2);
	auto y = bar(x);
	auto z = bar(x.expand);
	writeln(y);
	writeln(z);
}
Jul 18 2016
parent reply John <johnch_atms hotmail.com> writes:
On Tuesday, 19 July 2016 at 01:22:01 UTC, jmh530 wrote:
 import std.typecons : isTuple, tuple;
 import std.stdio : writeln;

 auto foo(T...)(T x)
 {
 	T[0] y;
 	foreach (i, e; x)
 	{
 		y += e;
 	}
 	return y;
 }

 auto bar(T)(T x)
 {
 	static if (isTuple!T)
 	{
 		return foo(x.expand);
 	}
 }

 auto bar(T...)(T x)
 {
 	return foo(x);
 }
auto bar(T...)(T x) { static if (T.length == 1 && isTuple!(T[0])) return foo(x.expand); else return foo(x); }
 void main()
 {
 	auto x = tuple(1, 2);
 	auto y = bar(x);
 	auto z = bar(x.expand);
 	writeln(y);
 	writeln(z);
 }
Jul 19 2016
next sibling parent jmh530 <john.michael.hall gmail.com> writes:
On Tuesday, 19 July 2016 at 07:23:52 UTC, John wrote:
 auto bar(T...)(T x)
 {
   static if (T.length == 1 && isTuple!(T[0]))
     return foo(x.expand);
   else
     return foo(x);
 }

 void main()
 {
 	auto x = tuple(1, 2);
 	auto y = bar(x);
 	auto z = bar(x.expand);
 	writeln(y);
 	writeln(z);
 }
I was leaving out the T[0] in the isTuple!
Jul 19 2016
prev sibling parent reply jmh530 <john.michael.hall gmail.com> writes:
On Tuesday, 19 July 2016 at 07:23:52 UTC, John wrote:
 auto bar(T...)(T x)
 {
   static if (T.length == 1 && isTuple!(T[0]))
     return foo(x.expand);
   else
     return foo(x);
 }
Hmm, this actually doesn't seem to be resolving my issue. I'm still getting the error about not being able to expand x. I tried it like below and got the same error. auto bar(T...)(T x) { static if (T.length > 1) { return foo(x); } else static if (T.length == 1 && isTuple!(T)) { return foo(x.expand); } }
Jul 19 2016
parent reply Lodovico Giaretta <lodovico giaretart.net> writes:
On Tuesday, 19 July 2016 at 13:33:41 UTC, jmh530 wrote:
 On Tuesday, 19 July 2016 at 07:23:52 UTC, John wrote:
 auto bar(T...)(T x)
 {
   static if (T.length == 1 && isTuple!(T[0]))
     return foo(x.expand);
   else
     return foo(x);
 }
Hmm, this actually doesn't seem to be resolving my issue. I'm still getting the error about not being able to expand x. I tried it like below and got the same error. auto bar(T...)(T x) { static if (T.length > 1) { return foo(x); } else static if (T.length == 1 && isTuple!(T)) { return foo(x.expand); } }
As you have to do `isTuple!(T[0])`, you also have to do `x[0].expand`. That's because T... works "as if" it was an array of types, and x, being of type T, it works "as if" it was an array of values. So you have to use an index in both cases.
Jul 19 2016
parent reply Lodovico Giaretta <lodovico giaretart.net> writes:
On Tuesday, 19 July 2016 at 15:36:42 UTC, Lodovico Giaretta wrote:
 As you have to do `isTuple!(T[0])`, you also have to do 
 `x[0].expand`.
 That's because T... works "as if" it was an array of types, and 
 x, being of type T, it works "as if" it was an array of values. 
 So you have to use an index in both cases.
You can find this out from the error, which says that you can't expand an object of type `(Tuple!(int, int))`. Note the surrounding parenthesis: they tell you that what you have is not a Tuple, but an AliasSeq whose only member is a Tuple. If you do `[0]` on it, you obtain the correct type, i.e. `Tuple!(int, int)`, without the parenthesis.
Jul 19 2016
parent jmh530 <john.michael.hall gmail.com> writes:
On Tuesday, 19 July 2016 at 15:40:20 UTC, Lodovico Giaretta wrote:
 You can find this out from the error, which says that you can't 
 expand an object of type `(Tuple!(int, int))`. Note the 
 surrounding parenthesis: they tell you that what you have is 
 not a Tuple, but an AliasSeq whose only member is a Tuple. If 
 you do `[0]` on it, you obtain the correct type, i.e. 
 `Tuple!(int, int)`, without the parenthesis.
Ah.
Jul 19 2016