BOOST Preprocessor BOOST_PP_LOCAL_ITERATE nested loops

122 Views Asked by At

I have a templated C++ function:

template<int i, int j> void foo();

I would like to define it in a .cpp file and instantiate it explicitely. The parameters i and j have the same admissible range of values, from 1 to N included. So far, for a function with a single template parameter such as

template<int i> void foo();

I've been using the Boost Preprocessor library like so:

#define BOOST_PP_LOCAL_MACRO(n)\
template void foo<n>();
#define BOOST_PP_LOCAL_LIMITS (1,N)
#include BOOST_PP_LOCAL_ITERATE()

This macro expands to N lines with n spanning 1 to N, each instantiating the function for the current value of n.

Is it possible to implement a nested loop using this library? Is it even theoretically possible given how the C preprocessor works?

I have searched for answers on stackoverflow with no success. Question Generate nested for loops using C preprocessor is similar to mine but (unlike the author), I would prefer to use the BOOST_PP lib if possible. My attempts to modify the above macro have been clueless to the point I don't think they are significant.

1

There are 1 best solutions below

0
Sardine On

Following @SoronelHaetir's comment, I have implemented the following.

In a file foo_instantiate.ixx:

#if !BOOST_PP_IS_ITERATING
   #ifndef FILE_H_
   #define FILE_H_
   #include <boost/preprocessor/iteration/iterate.hpp>
   #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, MAXITER, "foo_instantiate.ixx"))
   #include BOOST_PP_ITERATE()
   #endif
#else
   #include <boost/preprocessor/repetition/repeat_from_to.hpp>
   #define INSTANTIATE(z,n,t) template void foo<1+n,BOOST_PP_ITERATION(),0>();
   BOOST_PP_REPEAT_FROM_TO(0, MAXITER, INSTANTIATE, )
   #undef INSTANTIATE
#endif

This is implements a kind of file recursion. PP #includes the file specified as string (here itself) in the range defined by BOOST_PP_ITERATION_PARAMS_1 (inclusive). Now, in each of these inclusions, macros will again be expanded. This allows us to use standard BOOST_PP iterative macros, here BOOST_PP_REPEAT_FROM_TO. The current file inclusion iteration is obtained through BOOST_PP_ITERATION(). So this effectively works as a nested loop. Note that BOOST_PP_REPEAT_FROM_TO excludes the last index.

I have called this file so in order to differentiate it from header files and to avoid issues with globbing for .cxx files in CMake. In the appropriate cxx file (say foo.cxx), I simply #include <foo_instantiate.ixx>. As a side note, CMake automatically generates a target foo.cxx.i (preprocessor output) which greatly helps in debugging these macros.