Instantiating templates and classes with a preliminary forcing process

Working with the seemingly standard demonstrations w

, x

, y

, z

, suppose I have the following macro, trying to convert to a preprocessor macro "iterability"

#define INSTANTIATE_FUNC(rtype, func_name, ...)  \
    template rtype func_name< w > (__VA_ARGS__); \
    template rtype func_name< x > (__VA_ARGS__); \
    template rtype func_name< y > (__VA_ARGS__); \
    template rtype func_name< z > (__VA_ARGS__);

      

For completeness, let's say we are trying to create the following

struct w { static constexpr int data = 0; };
struct x { static constexpr int data = 1; };
struct y { static constexpr int data = 2; };
struct z { static constexpr int data = 3; };

template <class Data>
void printData(const std::string &prefix) {
    std::cout << prefix << Data::data << std::endl;
}

INSTANTIATE_FUNC(void, printData, const std::string &prefix)

      

I've made minimal sense with the build system for convenience, so that if you're interested in trying, you don't need to recreate everything :)

I can't figure out how to approach this. The only functional (but not useful) hit

#include <boost/preprocessor/list/for_each.hpp>

#define LIST (w, (x, (y, (z, BOOST_PP_NIL))))
#define MACRO(r, data, elem) template void data < elem > (const std::string &prefix);

#define INSTANTIATE_FUNC(rtype, func_name, ...) \
    BOOST_PP_LIST_FOR_EACH(MACRO, func_name, LIST)

      

This works, but clearly doesn't match.

  • Why doesn't this work for sequences as well?

    #include <boost/preprocessor/seq/for_each.hpp>
    // this does work, my code included the wrong header
    // on what I was testing with (seq/for_each_i.hpp)
    
    #define SEQ (x)(y)(z)(w)
    #define INSTANTIATE_FUNC(rtype, func_name, ...) \
        BOOST_PP_SEQ_FOR_EACH(MACRO, func_name, SEQ)
    
          

  • How do I approach creation template rtype func_name < {w,x,y,z} > {args,in,__VA_ARGS__}

    ? I've tried a few different things, but the problem seems to fail, for example, just fetch w

    and then walk through __VA_ARGS__

    then continue. I am trying to somehow get it BOOST_PP_LIST_FOR_EACH_R

    to work. Is that at least the right thing to do?

  • As a sanity check, you cannot define a macro in the macro on the right? Something in the spirit

    #define INSTANTIATE_FUNC(rtype, func_name, ...) \
        #define MACRO_##func_name(r, data, elem) data < elem > (__VA_ARGS__); \
        BOOST_PP_LIST_FOR_EACH(MACRO_##func_name, func_name, LIST)
    
          

Ultimately I am working towards the goal of including an extra extension LIST

/ SEQ

( SEQ

for which it is much easier) if that means anything. Thanks for any suggestions / resources.

+3


source to share


1 answer


Your problem seems to be that you need to deliver multiple chunks of data to MACRO

in BOOST_PP_(LIST|SEQ)_FOR_EACH

and you can only use one "slot". What you seem to be missing is that you can group these chunks, for example in a tuple, and then access the various elements within yours MACRO

with BOOST_PP_TUPLE_ELEM

. Something like this might work:

//These are not required, just to help with readability
#define MACRO_GET_RETURN_TYPE(TUPLE)  BOOST_PP_TUPLE_ELEM(3,0,TUPLE)
#define MACRO_GET_FUNC_NAME(TUPLE)  BOOST_PP_TUPLE_ELEM(3,1,TUPLE)
#define MACRO_GET_ARGS_SEQ(TUPLE)  BOOST_PP_TUPLE_ELEM(3,2,TUPLE)


#define MACRO(_, DATA, ELEM) template MACRO_GET_RETURN_TYPE(DATA) MACRO_GET_FUNC_NAME(DATA) < ELEM > (BOOST_PP_SEQ_ENUM(MACRO_GET_ARGS_SEQ(DATA)));

// with boost seq
#define SEQ (x)(y)(z)(w)

#define INSTANTIATE_FUNC(rtype, func_name, ...) \
    BOOST_PP_SEQ_FOR_EACH(MACRO, (rtype,func_name,BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)), SEQ)

      



Live on Wandbox

PS: No, you cannot define a macro inside a macro, and the code you posted here works for sequences, the one in your gist is not associated with the wrong title.

+1


source







All Articles