Macro repeat almost the same code

I need to write the same code depending on the compile-time constant parameter, something like:

map["text 0"] = vec[0];
map["text 1"] = vec[1];
...
map["text n"] = vec[n];

The problem is that I don’t know nwhen I write the code, I get it as a template parameter. The obvious solution is to use one loop and generate "text k"within the loop and use vec[k], but this is the overhead of the run time when it needs to be done at compile time. Another solution would be to specialize the function for different values n, but in this way I will have to write the same code manually several times, and there is no reason to create it.

I know that there are several smart macros that can repeat such things N times (for example, a BOOST_PP_REPEATmacro family), but I can not find one solution for my specific problem.

Do you have a solution to this problem?

+5
source share
3 answers

Unless you have really tight performance limits, there is no reason to worry about overhead in runtime. In any case, inserts will be performed at run time, and input time will definitely dominate the time required to change the character in the string.

In addition, macros are difficult to debug and maintain: avoid them if possible. Here I would suggest to deploy a simple loop:

std::string s = "text 0";
std::map<std::string, int> m;
for (int i = 0; i < N; i++)
{
    m[s] = vec[i];
    s[5] = '1' + i; // This is going to be the run-time overhead...
}

9, ++ 11 to_string() :

std::string const s = "text ";
std::map<std::string, int> m;
for (int i = 0; i < N; i++)
{
    m[s + std::to_string(i)] = vec[i];
}

, . , , .

+4

, :

#include <boost/preprocessor.hpp> 
//... or just the required sub-headers

// Will generate code for 0, 1, ... (N_END - 1)
#define N_END 10

#define ONE_ASSIGNMENT(maZ, maIter, maData) \
    if (maIter <= n) map["text " BOOST_PP_STRINGIZE(maIter)] = vec[maIter];

BOOST_PP_REPEAT(N_END, ONE_ASSIGNMENT, %%) //this generates the code

#undef ONE_ASSIGNMENT
#undef N_END

, if() (n), , , .

%% " ". maData, , - (, "text "), .

0

Repetition does not seem to be a problem for me, but compilation is the time to convert int to string and subsequent concatenation. The problem of repetition can be solved by the following methodology (untested):

template<k,l> struct fill_vector {
    static void doIt (... & vec) {
        vec [INT_TO_TEXT (k)] = k;
        fill_vector<k+1,l-1>::doIt (vec);
    }
};

template<k> struct fill_vector<k,0> {
    static void doIt (... & vec) {
        vec [INT_TO_TEXT (k)] = k;
    }
};

//...

fill_vector<0,n>::doIt (vec);

Maybe someone has an idea how to implement INT_TO_TEXT

0
source

All Articles