[Preprocessor] Auitomatic switch generation for template class instanciation

Hi all, I am currently completly lost with boost::preprocessor. I am trying to automatically generate a switch ... case structure with this lib and I cannot figure how I can do what I want. Here is the problem. I have a class templated over 2 parameters (in reality, more ...). At run time, I need to choose a specific instanciation for a user given values. An example : class MyDataEnergy { // ... }; class AnotherDataEnergy { // ... }; class MyPriorEnergy { // ... }; class AnotherPriorEnergy { // ... }; template <typename DataEnergyType , typename PriorEnergyType> class MyModel : public DataEnergyType , public PriorEnergyType { // ... }; Now, somewhere in the code, a user specifies which energies to use, and I have to instanciate MyModel with those energies: // ... int priorType = ValueComingFromSomewhere(); int dataType = AnotherValueComingFromSomewhere(); switch(priorType) { case 0: switch(dataType) { case 0: { MyModel<MyPriorEnergy,MyDataEnergy> aModel; aModel.SetInput(...); aModel.Optimize(...); } break; case 1: { MyModel<MyPriorEnergy,AnotherDataEnergy> aModel; aModel.SetInput(...); aModel.Optimize(...); } break; default: break; } case 1: switch(dataType) { case 0: { MyModel<MyPriorEnergy,MyDataEnergy> aModel; aModel.SetInput(...); aModel.Optimize(...); } break; case 1: { MyModel<MyPriorEnergy,AnotherDataEnergy> aModel; aModel.SetInput(...); aModel.Optimize(...); } break; default: break; } default: break; } I would like to know if there is a way to automate the above switch generation. As I have 5 templates, and not only 2, this will really helps ... I tried using BOOST_PP_SEQ_FOR_EACH but did not came to a result. Then, there is a lot of duplication in the above code. Am I doing the right way ? Hope you could help, Best regards, Olivier -- Dr. Olivier Tournaire Chargé de recherches MATIS - Institut Géographique National 73, Ave de Paris 94165 St Mandé cedex, France tel: (+33) 1 43 98 80 00 - 71 25 fax: (+33) 1 43 98 85 81

Hello Oliver, See inline below.. On Sun, 23 Nov 2008 15:31:12 +0100 "Olivier Tournaire" <olitour@gmail.com> wrote:
switch(priorType) { case 0: switch(dataType) { case 0: { MyModel<MyPriorEnergy,MyDataEnergy> aModel; aModel.SetInput(...); aModel.Optimize(...); } break; case 1: { MyModel<MyPriorEnergy,AnotherDataEnergy> aModel; aModel.SetInput(...); aModel.Optimize(...); } break; default: break; } case 1: switch(dataType) { case 0: { MyModel<MyPriorEnergy,MyDataEnergy> aModel; aModel.SetInput(...); aModel.Optimize(...); } break; case 1: { MyModel<MyPriorEnergy,AnotherDataEnergy> aModel; aModel.SetInput(...); aModel.Optimize(...); } break; default: break; } default: break; }
I would like to know if there is a way to automate the above switch generation. As I have 5 templates, and not only 2, this will really helps ... I tried using BOOST_PP_SEQ_FOR_EACH but did not came to a result. Then, there is a lot of duplication in the above code. Am I doing the right way ?
Looks like an awful lot of repetition, and would have to take a closer look at your problem for advice on design. However, to get you going, below is the Boost.PP work to do what you want - but think even that could be done better.. #include <boost/preprocessor/repetition/repeat.hpp> #include <boost/preprocessor/seq/for_each_i.hpp> #define ECKY(r, data, i, elem) \ case i: \ { \ MyModel<MyPriorEnergy, elem> aModel; \ aModel.SetInput(...); \ aModel.Optimize(...); \ } \ break; /**/ #define BAR(z, n, text) \ case n: \ swtich(dataType) \ { \ BOOST_PP_SEQ_FOR_EACH_I(ECKY, n, text) \ default: \ break; \ } /**/ #define FOO(n, seq) \ switch(priorType) \ { \ BOOST_PP_REPEAT(n, BAR, seq) \ default: \ break; \ } FOO(2, (MyDataEnergy)(AnotherDataEnergy)) Cheers, -- Manfred 24 November, 2008

Thank you Manfred. [...]
Looks like an awful lot of repetition, and would have to take a closer look at your problem for advice on design. However, to get you going, below is the Boost.PP work to do what you want - but think even that could be done better..
This is the design of the lib I use. The class I need is templated and policy based. Usually, when I know the instanciation I would like to have, I define a typedef and use it in the rest of the programm. Now, to be more generic, the programm need to let a user choose how to instanciate the class. If you have any idea about a better design, I will be very interesting in reading it. Best regards, Olivier -- Dr. Olivier Tournaire MATIS - Institut Géographique National 73, Ave de Paris 94165 St Mandé cedex, France tel: (+33) 1 43 98 80 00 - 71 25 fax: (+33) 1 43 98 85 81

On Sun, 23 Nov 2008 18:04:18 +0100 "Olivier Tournaire" <olitour@gmail.com> wrote:
Thank you Manfred.
[...]
Looks like an awful lot of repetition, and would have to take a closer look at your problem for advice on design. However, to get you going, below is the Boost.PP work to do what you want - but think even that could be done better..
This is the design of the lib I use. The class I need is templated and policy based. Usually, when I know the instanciation I would like to have, I define a typedef and use it in the rest of the programm. Now, to be more generic, the programm need to let a user choose how to instanciate the class. If you have any idea about a better design, I will be very interesting in reading it.
Of the top of my head, you might want to look down Boost.variant - sure enough under the hood it may probably be a glorified switch (don't quote me on that), but your code will be all the better for it. Cheers, -- Manfred
participants (2)
-
Manfred Doudar
-
Olivier Tournaire