www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How do I pass a type as parameter in this method?

reply Marc <jckj33 gmail.com> writes:
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
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
Dec 18 2017
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
parent reply Marc <jckj33 gmail.com> writes:
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.
Dec 19 2017
parent reply Dgame <r.schuett.1987 gmail.com> writes:
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); }
Dec 19 2017
parent Marc <jckj33 gmail.com> writes:
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!
Dec 19 2017