Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
December 22, 2006 Multiple Specialization? | ||||
---|---|---|---|---|
| ||||
I'm not sure what else you could call this... My idea for multiple specialization is to be able to associate multiple types with a single template. Take for example: template temp(T){ } template temp(T : int, T : long){ } // Specialized Template It would use the specialized template if T == int OR T == short I have two designs for this, the first you see above. Because the order of template arguments is important, all types must come in succession: template temp(T1, T2 : int, T2 : long, T3){ } // OK template temp(T1, T2 : int, T3, T2 : long){ } // Error - T2 is not in succession This is important, because the compiler can't be sure if T2 or T3 comes first: (T1, T2, T3) or (T1, T3, T2) My second design is to use braces: template temp(T1, T2 : {int, long}, T3){ } I also think you could use tuples somehow, but I have no idea how you could write that. But take for example: template tuple(T...){ alias T tuple; } template temp(T : tuple!(int, long)){ } I think tuples would work best because you can define aliases for them, where as you can't define an alias for the two other designs: alias tuple!(byte, short, int long) intset; template temp(T1 : intset, T2 : intset){ } What could this be used for? Suppose you wanted to make a specialized template for all int types? Or float types? Or char types? You would have to duplicate the template multiple times, especially if you have two or more types: template temp(T1 : {byte, short, int, long}, T2 : {byte, short, int long}){ } This would normally require you to define 16 specialized templates. |
December 22, 2006 Re: Multiple Specialization? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Xinok | Xinok wrote: > I'm not sure what else you could call this... > > My idea for multiple specialization is to be able to associate multiple types > with a single template. Take for example: > > template temp(T){ } > template temp(T : int, T : long){ } // Specialized Template > It would use the specialized template if T == int OR T == short > > I have two designs for this, the first you see above. Because the order of > template arguments is important, all types must come in succession: > template temp(T1, T2 : int, T2 : long, T3){ } // OK > template temp(T1, T2 : int, T3, T2 : long){ } // Error - T2 is not in succession > This is important, because the compiler can't be sure if T2 or T3 comes first: > (T1, T2, T3) or (T1, T3, T2) > > My second design is to use braces: > template temp(T1, T2 : {int, long}, T3){ } > > I also think you could use tuples somehow, but I have no idea how you could > write that. But take for example: > template tuple(T...){ alias T tuple; } > template temp(T : tuple!(int, long)){ } Or even just: template temp(T : (int, long)) { } > > I think tuples would work best because you can define aliases for them, where > as you can't define an alias for the two other designs: > alias tuple!(byte, short, int long) intset; > template temp(T1 : intset, T2 : intset){ } > > > What could this be used for? Suppose you wanted to make a specialized template > for all int types? Or float types? Or char types? You would have to duplicate > the template multiple times, especially if you have two or more types: > template temp(T1 : {byte, short, int, long}, T2 : {byte, short, int long}){ } > This would normally require you to define 16 specialized templates. Or one template with a long static if at the beginning, which can be annoying for, say, template functions. Its an interesting idea at the least -- but I'm not sure what it might take in the compiler. -- Chris Nicholson-Sauls |
December 22, 2006 Re: Multiple Specialization? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Nicholson-Sauls | Chris Nicholson-Sauls wrote: > Xinok wrote: > >> I'm not sure what else you could call this... >> >> My idea for multiple specialization is to be able to associate multiple types >> with a single template. Take for example: >> >> template temp(T){ } >> template temp(T : int, T : long){ } // Specialized Template >> It would use the specialized template if T == int OR T == short I agree with Chris that grouping the types seems like a better idea. Repeating T is asking for trouble. (T : {a, b}) or somesuch. Or maybe multiple colons (T :a:b) >> What could this be used for? Suppose you wanted to make a specialized template >> for all int types? Or float types? Or char types? You would have to duplicate >> the template multiple times, especially if you have two or more types: >> template temp(T1 : {byte, short, int, long}, T2 : {byte, short, int long}){ } >> This would normally require you to define 16 specialized templates. > > > Or one template with a long static if at the beginning, which can be annoying for, say, template functions. Its an interesting idea at the least -- but I'm not sure what it might take in the compiler. Yeh, static if(is(...)) is the way I'd do this now. That also allows you to accept "any type implicitly convertable to T" which covers a lot of real-world cases. For the most part you don't care if it's one of 16 specific types, you care if it can be assigned to an 'int' or if an int can be assigned to it. Personally, I have yet to use specialization, because of it's annoying "feature" of disabling IFTI. (At least that's the way it seemed the last time I tried it -- correct me if I'm wrong there) I would love for it to become usable. But right now static if is more flexible and powerful. I agree that it would be nice if the same power were available via the specialization syntax. --bb |
December 23, 2006 Re: Multiple Specialization? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | I don't like the idea of using parenthesis or braces. I'm trying to create a design which wouldn't require adding a new syntax to D. I really like the idea of using tuples, that is if multiple specialization were to be added to D. Tuples are already a part of D, so it wouldn't require adding anything new. Also, tuples have a few features which could come in handy with multiple specialization. The first feature I already mentioned, you can define aliases for tuples. alias tuple!(byte, short, int, long) intset; template temp(T : intset){ } Second, the splitting operator: template temp(T : intset[1..length]){ } // short, int, long Third, tuples can take both types and constants, so they could be used to specialize variables too. template temp(int V : tuple!(15, 30, 45)){ } |
December 23, 2006 Re: Multiple Specialization? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Xinok | Xinok wrote: > I don't like the idea of using parenthesis or braces. > I'm trying to create a design which wouldn't require adding a new syntax to D. > > I really like the idea of using tuples, that is if multiple specialization were to > be added to D. This is an idea I had one walk.. using something like a static switch. I thought this would be a more natural step for D to get some pattern matching on template arguments. So from code I have seen in minid (which brilliant): public int write(T)(MDState s) { MDFile i = cast(MDFile)s.getInstanceParam(0, this); T val; static if(is(T == ubyte) || is(T == ushort) || is(T == int)) val = s.getIntParam(1); else static if(is(T == float)) val = s.getFloatParam(1); else static if(is(T == char) || is(T == wchar) || is(T == dchar)) val = s.getCharParam(1); //.. snip return 0; } a static switch version: public int write(T)(MDState s) { MDFile i = cast(MDFile)s.getInstanceParam(0, this); T val; static switch(T) { case(ubyte): case(ushort): case(int): val = s.getIntParam(1); break; case(float): val = s.getFloatParam(1); break; case(char): case(wchar): case(dchar): val = s.getCharParam(1); break; } //.. snip return 0; } and I imagined having static switch and case been able to handle type tuples if for example the function prototype was public int write(T...)(MDState s) // no example because I am lazy Does this make sense? - Paul |
December 23, 2006 Re: Multiple Specialization? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul Findlay | Paul Findlay wrote: > This is an idea I had one walk.. using something like a static switch. [...] > a static switch version: > > > public int write(T)(MDState s) > { > MDFile i = cast(MDFile)s.getInstanceParam(0, this); > > T val; > > static switch(T) { > case(ubyte): case(ushort): case(int): > val = s.getIntParam(1); > break; > case(float): > val = s.getFloatParam(1); > break; > case(char): case(wchar): case(dchar): > val = s.getCharParam(1); > break; > } > //.. snip > > return 0; > } > > and I imagined having static switch and case been able to handle type > tuples if for example the function prototype was > > public int write(T...)(MDState s) > // no example because I am lazy > > Does this make sense? > > - Paul Yes I was thinking of posting about the same concept my self. (I second the ides) |
Copyright © 1999-2021 by the D Language Foundation