0

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.

3
  • 1
    Maybe instead of trying to do this in one go with BOOST_PP_LOCAL_ITERATE, do it in two with a combination of BOOST_PP_LOCAL_ITERATE and BOOST_PP_ITERATE. Use BOOST_PP_ITERATE to do the outer loop and BOOST_PP_LOCAL_ITERATE for the inner. Commented Sep 18, 2023 at 22:58
  • You were correct, I'll expand your comment into an answer as this has solved the problem. Commented Sep 19, 2023 at 0:16
  • 1
    Glad to give you the right direction. It's been long enough since I actually used boost's preprocessor iteration that I wasn't at all comfortable trying to throw together a quick example. Commented Sep 19, 2023 at 0:28

1 Answer 1

0

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.