digitalmars.D.learn - How do I pass a type as parameter in this method?
- Marc (4/12) Dec 18 2017 In that case, if the tuple is empty, the value is the int's type
- =?UTF-8?Q?Ali_=c3=87ehreli?= (45/61) Dec 18 2017 template FirstOrDefault(D) {
- =?UTF-8?Q?Ali_=c3=87ehreli?= (17/18) Dec 18 2017 Here's another experiment:
Imaginary code:int index = FirstOrDefault!(int)(__traits(getAttributes, C.a));In that case, if the tuple is empty, the value is the int's type default value. The method is defined as following:template FirstOrDefault(X)(T...) { static if(T.length > 0) { enum FirstOrDefault = T[0]; } else { enum FirstOrDefault = X.init; } }
Dec 18 2017
On 12/18/2017 02:58 PM, Marc wrote:Imaginary code:template FirstOrDefault(D) { template FirstOrDefault(T...) { static if(T.length > 0) { enum FirstOrDefault = T[0]; } else { enum FirstOrDefault = D.init; } } } template FirstOrDefault_2(T...) { static if(T.length > 1) { enum FirstOrDefault_2 = T[1]; } else { enum FirstOrDefault_2 = T[0].init; } } template FirstOrDefault_3(D) { template of(T...) { static if(T.length > 0) { enum of = T[0]; } else { enum of = D.init; } } } void main() { // This one requires an alias because I could not get rid of "Error: // multiple ! arguments are not allowed". alias IntDefault = FirstOrDefault!int; static assert (IntDefault!() == 0); static assert (IntDefault!([1], "hello") == [1]); static assert (IntDefault!("world", 1.5) == "world"); // This one puts everything into the same argument list static assert (FirstOrDefault_2!(double, "yo") == "yo"); import std.math; static assert (isNaN(FirstOrDefault_2!(double))); // This one invents .of for an arguably more readable syntax static assert (FirstOrDefault_3!int.of!(7) == 7); struct S { int i = 42; } static assert (FirstOrDefault_3!S.of!().i == 42); } Aliint index = FirstOrDefault!(int)(__traits(getAttributes, C.a));In that case, if the tuple is empty, the value is the int's type default value. The method is defined as following:template FirstOrDefault(X)(T...) { static if(T.length > 0) { enum FirstOrDefault = T[0]; } else { enum FirstOrDefault = X.init; } }
Dec 18 2017
On 12/18/2017 03:54 PM, Ali Çehreli wrote:On 12/18/2017 02:58 PM, Marc wrote:Here's another experiment: template FirstOf(T...) { template otherwise(D) { static if (T.length == 0) { enum otherwise = D.init; } else { enum otherwise = T[0]; } } } void main() { static assert (FirstOf!(1.5, "hello").otherwise!int == 1.5); static assert (FirstOf!("world", [1]).otherwise!int == "world"); static assert (FirstOf!().otherwise!int == 0); } Ali
Dec 18 2017
On Tuesday, 19 December 2017 at 00:01:00 UTC, Ali Çehreli wrote:On 12/18/2017 03:54 PM, Ali Çehreli wrote:Thanks four answer. I'll be using this one. I was messing around and getting multiple arguments to template function too. I like the naming too, it made code clear, imo. It's possible to have overload where one take a type name and the other a variable (constant value actually)? something like this (also imaginary code):On 12/18/2017 02:58 PM, Marc wrote:Here's another experiment: template FirstOf(T...) { template otherwise(D) { static if (T.length == 0) { enum otherwise = D.init; } else { enum otherwise = T[0]; } } } void main() { static assert (FirstOf!(1.5, "hello").otherwise!int == 1.5); static assert (FirstOf!("world", [1]).otherwise!int == "world"); static assert (FirstOf!().otherwise!int == 0); } Alitemplate FirstOf(TP...) { template otherwise(D) { static if(TP.length > 0) { enum otherwise = TP[0]; } else { enum otherwise = D.init; } } template otherwise(D value) { static if(TP.length > 0) { enum otherwise = TP[0]; } else { enum otherwise = value; } } }So I can use like this:int index = FirstOf!(myTuple).otherwise!int; int value = FirstOf(myTuple2).otherwise!(10);with my limited template knowledge, I know I can write it like this:template otherwise(D, D value) { static if(TP.length > 0) { enum otherwise = TP[0]; } else { enum otherwise = value; } }So the call would go like this:int value = FirstOf(myTuple2).otherwise!(int, 10);But for simplicity I'd like to infer the type from constant value passed in parameter, in that case, the integer value of 10.
Dec 19 2017
On Tuesday, 19 December 2017 at 15:19:53 UTC, Marc wrote:On Tuesday, 19 December 2017 at 00:01:00 UTC, Ali Çehreli wrote:template FirstOf(T...) { template otherwise(D) { static if (T.length == 0) { enum otherwise = D.init; } else { enum otherwise = T[0]; } } template otherwise(alias value) { static if (T.length == 0) { enum otherwise = value; } else { enum otherwise = T[0]; } } } void main() { static assert (FirstOf!(1.5, "hello").otherwise!int == 1.5); static assert (FirstOf!("world", [1]).otherwise!int == "world"); static assert (FirstOf!().otherwise!int == 0); static assert (FirstOf!(1.5, "hello").otherwise!23 == 1.5); static assert (FirstOf!().otherwise!42 == 42); }On 12/18/2017 03:54 PM, Ali Çehreli wrote:Thanks four answer. I'll be using this one. I was messing around and getting multiple arguments to template function too. I like the naming too, it made code clear, imo. It's possible to have overload where one take a type name and the other a variable (constant value actually)? something like this (also imaginary code):On 12/18/2017 02:58 PM, Marc wrote:Here's another experiment: template FirstOf(T...) { template otherwise(D) { static if (T.length == 0) { enum otherwise = D.init; } else { enum otherwise = T[0]; } } } void main() { static assert (FirstOf!(1.5, "hello").otherwise!int == 1.5); static assert (FirstOf!("world", [1]).otherwise!int == "world"); static assert (FirstOf!().otherwise!int == 0); } Alitemplate FirstOf(TP...) { template otherwise(D) { static if(TP.length > 0) { enum otherwise = TP[0]; } else { enum otherwise = D.init; } } template otherwise(D value) { static if(TP.length > 0) { enum otherwise = TP[0]; } else { enum otherwise = value; } } }So I can use like this:int index = FirstOf!(myTuple).otherwise!int; int value = FirstOf(myTuple2).otherwise!(10);with my limited template knowledge, I know I can write it like this:template otherwise(D, D value) { static if(TP.length > 0) { enum otherwise = TP[0]; } else { enum otherwise = value; } }So the call would go like this:int value = FirstOf(myTuple2).otherwise!(int, 10);But for simplicity I'd like to infer the type from constant value passed in parameter, in that case, the integer value of 10.
Dec 19 2017
On Tuesday, 19 December 2017 at 15:52:57 UTC, Dgame wrote:On Tuesday, 19 December 2017 at 15:19:53 UTC, Marc wrote:Didn't know about alias as template paramter. Exactly what I wanted. Thank you![...]template FirstOf(T...) { template otherwise(D) { static if (T.length == 0) { enum otherwise = D.init; } else { enum otherwise = T[0]; } } template otherwise(alias value) { static if (T.length == 0) { enum otherwise = value; } else { enum otherwise = T[0]; } } } void main() { static assert (FirstOf!(1.5, "hello").otherwise!int == 1.5); static assert (FirstOf!("world", [1]).otherwise!int == "world"); static assert (FirstOf!().otherwise!int == 0); static assert (FirstOf!(1.5, "hello").otherwise!23 == 1.5); static assert (FirstOf!().otherwise!42 == 42); }
Dec 19 2017