digitalmars.D.learn - Instantiating templates where type is known only at run time
- Craig Dillabaugh (63/63) Nov 19 2013 this question came up in some C++ work I am doing, but since the
- bearophile (8/15) Nov 19 2013 In D there is no "type switch" but there are type tuples, where
- Craig Dillabaugh (3/18) Nov 19 2013 Thanks very much.
this question came up in some C++ work I am doing, but since the solutions are likely nicer in D, I wanted to ask how it could be solved in D. First for some motivation. I am doing image processing work where the images are simply an array of data, where the data type can be any numeric type. The data is stored as binary files and assume I have some way of figuring out the data type for an image. Say I want to implement the function along the following lines, and imagine I have a sane reason for wanting to do such a thing: // Assume images are of the same dimensions. Result is // saved in Out. void add(T,U,V)(Image!T A, Image!U B, Image!V Out) { ... } Now assume I have three variables ImgAType, ImgBType, and ImgCType (I refer to these variables without specifying their type, but hopefully it is clear what is going on) then to implement add() I end up with a lengthy if..else statement or nasty nested switch ... case statements to handle all the possible combinations of ubyte, short, uint, float, double for each of the three image types. I will use an if() version example: if( ImgAType == SHT && ImgBType == UINT && ImgCType == DBL ) { Image!short A = new Image!short( filename_of_A ); Image!uint B = new Image!uint( filename_of_B ); Image!double Out = new Image!double( filename_of_Out ); add(A,B,Out); } else { //next case and so on .... } Since the types can be any numeric type there are a lot of 'combinations' of images. I won't add a float and double together and generate a ubyte image, but there are still many valid combinations. However, any way you slice it you end up with a very long, repetitive bunch of code. A co-worker of mine came up with (or found) the following solution. I thought is was clever. It cuts down on repetitive code, but man is it ugly: void add( ImgAType, ImgBType, ImgCType, //File names ) { if( ImgAType == UBYTE) AddStep1!ubyte(ImgBType, ImgCType, //Files ); else if( ImgAType == SHT) AddStep1!short(ImgBType, ImgCType, //Files ); //and so on } void AddStep1(T)(ImgBType, ImgCType, //File names ) { if( ImgBType == UBYTE) AddStep2!(T,ubyte)(ImgCType, //Files ); else if( ImgBType == SHT) AddStep2!(T,short)(ImgCType, //Files ); //and so on. } void AddStep2(T,U)(ImgCType, //File names ) { if( ImgCType == UBYTE) AddStep3!(T,U,ubyte)( //Files ); else if(ImgCType == SHT) AddStep3!(T,U,short)( //Files ); //and so on } void AddStep3(T,U,V)( //File names ) { //Do the actual work! } Anyway, I hope that is clear what we are trying to do. So my question is, is there a nice way in D to instantiate all the necessary templated functions, and call the correct version at run time, without resorting one of the methods above. Anyway, thanks to whoever takes the time to read all that, let alone come up with an answer.
Nov 19 2013
Craig Dillabaugh:// Assume images are of the same dimensions. Result is // saved in Out. void add(T,U,V)(Image!T A, Image!U B, Image!V Out) { ... }Take a look at the "out" annotation in D.Anyway, thanks to whoever takes the time to read all that, let alone come up with an answer.In D there is no "type switch" but there are type tuples, where you can put a sequence of all your types, and you can iterate on them statically with a foreach, to instantiate your templates. So your C++ code probably becomes nicer in D. Bye, bearophile
Nov 19 2013
On Tuesday, 19 November 2013 at 12:53:50 UTC, bearophile wrote:Craig Dillabaugh:Thanks very much. Craig// Assume images are of the same dimensions. Result is // saved in Out. void add(T,U,V)(Image!T A, Image!U B, Image!V Out) { ... }Take a look at the "out" annotation in D.Anyway, thanks to whoever takes the time to read all that, let alone come up with an answer.In D there is no "type switch" but there are type tuples, where you can put a sequence of all your types, and you can iterate on them statically with a foreach, to instantiate your templates. So your C++ code probably becomes nicer in D. Bye, bearophile
Nov 19 2013