You could do it like this:
#define TYPES (type_A)(type_B)(type_X)
#define GENERATE_TUPLE(maR, maNamespace, maIndex, maType) \
BOOST_PP_COMMA_IF(maIndex) boost::optional<maNamespace :: maType>
#define GENERATE_GETTER(maR, maNamespace, maIndex, maType) \
boost::optional<maNamespace :: maType> const& maType () const { return boost::get<maIndex>(data); }
struct E1
{
typedef boost::tuple<
BOOST_PP_SEQ_FOR_EACH_I(GENERATE_TUPLE, N, TYPES)
> data_type;
BOOST_PP_SEQ_FOR_EACH_I(GENERATE_GETTER, N, TYPES)
data_type data;
};
The N
argument corresponds to the maNamespace
parameter. You can of course use this argument in any other way (it's just passed through verbatim), such as hardcoding N
into the macros (and passing a dummy in the argument), or encoding even the identifier data
in there, etc.