Sign in to follow this  
popsoftheyear

[c++] Macros, templates, and member function pointers

Recommended Posts

So I've got a library that needs to do things reasonably fast - for image processing. I've examined various open source libraries such as GIL and CImg (and others to a lesser extent). These 2 in particular use templates to keep from generating the SAME code with different types for various bit depth(ed?) images. This seems ... well ... like the only way to do it besides hand coding a function for each bit depth or using macros, which are both bad ideas I would think, if they can be avoided (and they can). Now this library needs to support huge images up to 2^64 bytes in size, regardless of RAM, be invisible to whether it actually is using straight RAM or some kind of file mapping, support various channel depths (1, 8, 16, 32) and channel counts (1, 3), and have a common interface so I can just call something along the lines of Image.DoOperationOn(AnotherImage) regardless of the format of Image OR the format of AnotherImage, if different. After noticing that I was mostly doing a bunch of copying and pasting, and finding ways around this, I ended up with really great (or maybe really really bad?) classes like this ImageBlitter class, which has only ~550 lines of code including comments and empty lines, that has methods for Image arithematic, sub-pixel accurate scaling, automatically handles LODs as well as tiling (for those huge images) for all operations (scaling an image onto another with different tile sizes is harder than you'd think), and has a unique function for each bit depth (doing 2-image pixel arithematic by counting bytes and going through a for loop for each pixel of each image is out of the question). The caveat to this relatively small (in written code) class is that it incorporates: A member function pointer which points to run-time chosen template instantiations. This choice occurs in functions that are generated by macros. The template functions themselves, which get instantiated, are also generated by macros. Essentially to define a specific blitting operation I simply write:
CREATEBASICOPCALLER(Add);   // Create function AddToImage(...)

// Create template BlitAdd_<T>(...)
CREATEBASICOPIMPL(Add, OutArr.Set(DestXI, OutArr.Get(DestXI) + InArr.Get(SrcXI)));
and then I declare the public function and private template function by hand in the header. Of course this requires you to be 100% familiar with what is actually inside those macros... Anyway, this works really well, and also there are other specifics added that allow me to generate special functions which defer from the normal pattern, without copy and paste syndrome, so I can, say, use special optimizations for special situations, or do unorthodox operations. The only real problem to this is that to debug you have to go through the generated assembly, which doesn't bother me too much. Is all this really bad? Or is it one of those situations where you do what you can... It actually seems like the ONLY viable route to me... Cheers -Scott [Edited by - popsoftheyear on July 2, 2008 2:14:53 PM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this