Thread overview
How do I pass a type as parameter in this method?
Dec 18, 2017
Marc
Dec 18, 2017
Ali Çehreli
Dec 19, 2017
Ali Çehreli
Dec 19, 2017
Marc
Dec 19, 2017
Dgame
Dec 19, 2017
Marc
December 18, 2017
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
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
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
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
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
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!