Policy-based Design in C++

I have a programming problem at work and a possible solution. The only thing wrong with the solution is that it is too big. “Too big” will make sense once I’ve described the problem and the solution.

The solution comes from the book Modern C++ Design by Andrei Alexandrescu, Addison-Wesley, 2001. It is a good solution in theory but the practice is, as always, much more involved than the theory.

I can’t really create a new definition of policy-based design but to me, it provides a way of creating a class that encapsulates functionality from a variety of other places in an easy-to-maintain way. Like most coding problems, this is a problem of avoiding redundant code. Most of my software development problems are related to removing redundant code. Anything that doesn’t fall into this category is usually not a design problem and is a matter of just typing in the code needed to accomplish the task at hand.

The book mentioned above uses a smart pointer class as an example of the problem. The smart pointer class should have flexibility in how it manages memory, handles multi-threading, and other things of this sort. By using C++ templates, the smart pointer class described in the book is really built using a set of classes where the smart pointer class has smart pointer class functionality and a memory management class is used for memory management. Another thread management class handles multi-threaded issues. That’s all great until you add a few additional requirements. Let’s add my requirements:

1. One of the policy classes needs to share a policy with the container. In other words, the thread management class needs to have a memory management policy. It can and should be the same policy used by the overall smart pointer class. I’m not really using smart pointers, memory allocation, and thread management, but the problem is the same.

2. There is a whole lot more code that I am writing and having all of the code in headers files is cumbersome. I’m not writing a smart pointer, I’m writing code to run special algorithms on FPGA chips on a plug-in PCIe card.

3. I don’t have just two policies. I have at least three and maybe four and each of them needs access to the other policies. This makes me questions the whole concept of policy based design. How do I create a policy for the hardware device itself and then have a few levels of policies above that in a hierarchy? it’s all doable and even the hierarchy itself works as far as creating the templates. For instance:

/*
* This is the hardware device class. It will be derived from a class
* that is pure and virtual and that root defined the public interface
* to whatever we create with these classes.
*/
class DevicePolicy : protected RootInterface
{
};
/*
* This is the FPGA programming class. It will be derived from a
* DevicePolicy class and will provide access to a specific set of
* FPGA code.
*/
template <class DevicePolicy> class FPGAPolicy : protected DevicePolicy
{
};
/*
* This is the algorithm class. It will be derived from a FPGAPolicy
* class and will provide access to a specific algorithm for a specific
* FPGA program.
*/
template <class DevicePolicy, template <class DevicePolicy> class FPGAPolicy > class AlgorithmPolicy : protected FPGAPolicy <devicepolicy>
{
};
/*
* This is the class that encapsulates the rest of the policy
* classes. This is not really needed but it makes it more clear
* than if the various algorithm classes (created later) are used
* to create the final concrete object.
*/
template <class DevicePolicy, template <class DevicePolicy> class FPGAPolicy , template <class DevicePolicy, template <class DevicePolicy> class FPGAPolicy > class AlgorithmPolicy> class AlgorithmContainer : protected AlgorithmPolicy<devicepolicy ,FPGAPolicy>
{
};
/*
* Example typedef used for creating a final object based on the policies.
*/
typedef AlgorithmContainer <devicepolicy ,FPGAPolicy ,AlgorithmPolicy> AlgorithmXYZ;

The template stuff needed for this is a bit complicated looking because of the template nesting. I can’t even describe exactly how it works since I got to this point by simply nesting the template stuff again and again for each additional level of the hierarchy. Another level would make the template code unreadable if it’s not already unreadable as-is.

The whole problem is that I have an almost identical algorithm for an almost identical FPGA program for an almost identical hardware device. Each level has a tiny difference or no difference at all but, more importantly, there are differences at the lowest level of the hierarchy but sometimes no differences at the higher levels. A policy based design like this allows me to create the final set of code so that it includes the proper class at each level to get the functionality that is unique at that level.

There may be other ways to handle this. For instance, I can have the classes all separate and then use some sort of creator to allocate the proper derived class at runtime for each level. The creator would do something like this:

That last line will create an object and will pass in the objects that define the device, the FPGA program, and the algorithm. This is uglier because of having to create each object and pass it the lower level object. On the other hand, there are no templates so the code can be in a library.

I’m going to give this second idea a little thought and will probably write something once I know what solution I will try.