Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
December 18, 2017 How do I pass a type as parameter in this method? | ||||
---|---|---|---|---|
| ||||
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; > } > } |
December 18, 2017 Re: How do I pass a type as parameter in this method? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc | On 12/18/2017 02:58 PM, Marc wrote: > 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; >> } >> } 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); } Ali |
December 18, 2017 Re: How do I pass a type as parameter in this method? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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
|
December 19, 2017 Re: How do I pass a type as parameter in this method? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Tuesday, 19 December 2017 at 00:01:00 UTC, Ali Çehreli wrote: > 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 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): > template 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. |
December 19, 2017 Re: How do I pass a type as parameter in this method? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc | 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:
>> 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
>
> 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):
>
>> template 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.
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);
}
|
December 19, 2017 Re: How do I pass a type as parameter in this method? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dgame | On Tuesday, 19 December 2017 at 15:52:57 UTC, Dgame wrote:
> On Tuesday, 19 December 2017 at 15:19:53 UTC, Marc 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);
> }
Didn't know about alias as template paramter. Exactly what I wanted. Thank you!
|
Copyright © 1999-2021 by the D Language Foundation