Re: case/switch metaprogramming
Aaron Graham wrote:
I have a switch/case statement that looks something like this:
std::auto_ptr<Dev> dev;
switch (dev_id) {
case 1: dev = std::auto_ptr<Dev>(new devices::Device<1>()); break;
case 2: dev = std::auto_ptr<Dev>(new devices::Device<2>()); break;
case 3: dev = std::auto_ptr<Dev>(new devices::Device<3>()); break;
case 4: dev = std::auto_ptr<Dev>(new devices::Device<4>()); break;
case 5: dev = std::auto_ptr<Dev>(new devices::Device<5>()); break;
....
case 47: dev = std::auto_ptr<Dev>(new devices::Device<47>()); break;
default: dev = std::auto_ptr<Dev>(new devices::Device<0>()); break;
}
Note that the switch can grow arbitrarily large and is very
repetitive. Is there an easy way to use metaprogramming to get the
compiler to generate all this code?
Yes, I believe so. Check this out:
// --------------------- this is just to make it compile
#include <iostream>
class Dev {
public:
virtual ~Dev() {}
};
template<unsigned id> class Device : public Dev {
static const unsigned s_id = id;
public:
Device() { std::cout << "Creating Device<" << id << ">\n"; }
};
// --------------------- here begins the important part:
// presuming creating all devices between 1 and 'hi_id'
template<unsigned hi_id>
Dev* getDeviceFrom(unsigned dev_id) {
if (dev_id > hi_id || dev_id == 0) // here is your 'default:'
return new Device<0>;
if (dev_id == hi_id)
return new Device<hi_id>; // Bingo!
else // dev_id < hi_id
return getDeviceFrom<hi_id-1>(dev_id);
}
template<>
Dev* getDeviceFrom<1>(unsigned i) {
return new Device<1>();
}
// -------------------------------------------------------
#include <time.h>
int main()
{
srand((unsigned)time(0));
Dev *p[10];
for (int i = 0; i < 10; ++i) {
// here instead of the 'switch' I have
unsigned dev_id = rand() % 20; // or whatever
p[i] = getDeviceFrom<30>(dev_id); // out of 30
}
for (int i = 0; i < 10; ++i)
delete p[i];
}
The code is recursive, and you will possibly run quite soon out of
compiler resources (just like with other recursive templates), so
please adjust the total number of devices (here I have 30) to your
bare minimum.
Enjoy!
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]