1

In short, I would like to accomplish the following:

#define CLASS( C ) class C;
#define CLASSES( ... )

CLASSES( Foo, Bar, Golf )    // Expand: class Foo; class Bar; class Golf;

Is there any way to accomplish this using boost?

Currently, I have tried the following:

#include <boost/preprocessor/repetition/repeat.hpp>

#define CLASS( C ) class C;

#define CLASSES( N, ... ) BOOST_PP_REPEAT( N, CLASS, Name) // problem here

CLASSES( 3, Foo, Bar, Golf ) // Expand: class Name; class Name; class Name;

But I don't know how to incorporate __VA_ARGS__ in order to expand different names.

I am open to other suggestions, not strict on boost, but restricted to C++11.

2 Answers 2

1

Here's a BOOST PP example using CLASSES(x, y, z) to expand to class forward declaration statements.

#include <boost/preprocessor/library.hpp> // The whole BOOST_PP library (overkill).

#define CLASSES_SEMI() ;

#define CLASSES_OP(r, data, i, elem) \
    BOOST_PP_IF(i, CLASSES_SEMI, BOOST_PP_EMPTY)() \
    class elem \
    /**/

#define CLASSES_SEQ(seq) \
    BOOST_PP_SEQ_FOR_EACH_I(CLASSES_OP, /*no data*/, seq) \
    /**/

#define CLASSES(...) CLASSES_SEQ(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))

CLASSES(Foo, Bar, Golf);

Generates:

class Foo ; class Bar ; class Golf ;
5
  • thank you for your response! it seems you have a syntax error somewhere. did you test this? Commented Feb 23 at 20:46
  • I did test this. And I just redid it, to be closer in accord with your original question. Using CLASSES instead of STD. What syntax error are you seeing? With which compiler? (I'm using clang.)
    – Eljay
    Commented Feb 23 at 20:48
  • g++ worked for me as well: /usr/local/opt/gcc/bin/g++-13 -E -I $(brew --prefix boost)/include -std=c++17 ConstantinosGlynos.cpp
    – Eljay
    Commented Feb 23 at 20:51
  • also worked with -std=c++11
    – Eljay
    Commented Feb 23 at 20:57
  • works fine. my IDE just needed some time to adjust. thanks! Can you please explain the code and the boost functions you have used? just for the completeness of your answer. Commented Feb 23 at 21:22
1

@Eljay 's post is the accepted answer and works perfectly well. I would just like to complement the accepted answer with an alternative method and the modified version I used from Eljay's answer.

Option 1: No boost

#define DEC_CLASS( C ) class C;

#define EACH_0( ELEM )
#define EACH_1( ELEM, X ) ELEM( X ) 
#define EACH_2( ELEM, X, ... ) ELEM( X ) EACH_1( ELEM, __VA_ARGS__ )
#define EACH_3( ELEM, X, ... ) ELEM( X ) EACH_2( ELEM, __VA_ARGS__ )

#define OPTION( _0, _1, _2, _3, NAME, ... ) NAME

#define CLASSES( ... ) OPTION( _, __VA_ARGS__, EACH_3, EACH_2, EACH_1, EACH_0) ( DEC_CLASS, __VA_ARGS__ )

CLASSES( Foo, Bar, Golf )

Option 2: Using boost (modified version from @Eljay)

#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>

#define DEC_CLASS( r, data, i, elem ) class elem;

#define CLASSES_SEQ( SEQ ) BOOST_PP_SEQ_FOR_EACH_I(DEC_CLASS, , SEQ) 

#define CLASSES(...) CLASSES_SEQ(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))

CLASSES(Foo, Bar, Golf);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.