How to use boost :: mpl to compile policies?

I used something like the following to write the policy for my application:

The policy classes are as follows:

struct Policy { static void init(); static void cleanup(); //... }; template <class CarT, class CdrT> struct Cons { static void init() { CarT::init(); CdrT::init(); } static void cleanup() { CdrT::cleanup(); CarT::cleanup(); } //... }; 

To create policies:

 typedef Cons<Policy1, Cons<Policy2, Cons<Policy3, Policy4> > > MyPolicy; 

To use MyPolicy:

 init_with<MyPolicy>(...); //... cleanup_with<MyPolicy>(...); 

where will they call:

 MyPolicy::init_options(); // calls Policy1 to 4 init in order 

and

 MyPolicy::cleanup(); // calls Policy1 to 4 cleanup in reverse order 

Essentially, Cons creates a list of types here. This is pretty straight forward. However, the typedef string cons looks ugly. This will be ideal if you have a policy collector that can do this:

 typedef CombinePolicy<Policy1, Policy2, Policy3, Policy4> MyPolicy; 

Since we can have an arbitrary number of policies, CombinePolicy needs to support a variational template in C ++ 0x, which is only available experimentally in advanced compilers. However, it seems that boost: the mpl library solved / worked on the problem using bundle preprocessing tricks. I think I could use something like:

 typedef mpl::list<Policy, Policy2, Policy3, Policy4> Policies; 

and then calls:

 init_with<Policies>(...); 

which would then use:

 typedef iter_fold<Policies, begin<Policies>::type, some_magic_lambda_expression>::type MyPolicy; 

Obviously, I have a little problem with the output of some_magic_lambda_expression. I am sure this is pretty trivial for mpl experts.

Thanks in advance.

+6
c ++ templates metaprogramming boost-mpl
source share
3 answers

Since no one answered the question satisfactorily, I spent some time in the source file boost :: mpl. Man, this is not beautiful with layers of macros and hundreds of lines of specialization classes. Now I am more grateful to the authors of the promotion libraries to make metaprogramming easier and more portable for us. I hope C ++ 0x makes life easier for library writers.

In any case, the solution is simple and elegant.

At first, iter_fold is not what I want, since I could not figure out how to specify an iterator that can be deferred to a null type. So I fiddled with the crease and found the following:

 typedef fold<Policies, Null, Cons<_1, _2> >::type MyPolicy; 

For this to work, I need to provide a Null type and a specialization for Cons:

 struct Null { }; template<class PolicyT> struct Cons<Null, PolicyT> { static void init() { PolicyT::init(); } static void cleanup() { PolicyT::cleanup(); } }; 
+9
source share

I think your problem is more likely a call at runtime than metafiles, because you want to call init functions on real runtime objects.

You can try mpl runtime algorithms, for example:

 for_each<Policies>(InitPolicy()); 

from

 struct InitPolicy() { template<class Policy> void operator() (Policy& p) { p.init_options(); } }; 
+1
source share

I think you are looking for something like:

 typedef iter_fold< Policies, begin<Policies>::type, Cons<_1,_2> >::type MyType; 

You might also want to look into inherit_linearly <> if you use some kind of CRTP code to call basic functions with hard wiring at compile time.

+1
source share

All Articles