I am working on a kind of "data-variable" framework. Here, structs are defined and adapted as Boost.Fusion sequences using the macro BOOST_FUSION_DEFINE_ASSOC_STRUCT
.
Brief context:
To define two adapted structs foo
and bar
, I use:
#define VAR(VARNAME) vardefs::VARNAME
#define VAR_PARENTHESES(VARNAME) (vardefs)(VARNAME)
// ========================================================
#ifndef VARNAME_
#define VARNAME_ foo // <- Variable name
namespace VAR(VARNAME_)::keys{
struct foo1;
struct foo2;
struct foo3;
}
namespace VAR(VARNAME_) { struct index; }
BOOST_FUSION_DEFINE_ASSOC_STRUCT(
VAR_PARENTHESES(VARNAME_), type,
(char, foo1, VAR(VARNAME_)::keys::foo1)
(int, foo2, VAR(VARNAME_)::keys::foo2)
(float, foo3, VAR(VARNAME_)::keys::foo3)
)
#endif
#undef VARNAME_
// --------------------------------------------------------
// ========================================================
#ifndef VARNAME_
#define VARNAME_ bar // <- Variable name
namespace VAR(VARNAME_)::keys{
struct bar1;
struct bar2;
}
namespace VAR(VARNAME_) { struct index; }
BOOST_FUSION_DEFINE_ASSOC_STRUCT(
VAR_PARENTHESES(VARNAME_), type,
(double, bar1, VAR(VARNAME_)::keys::bar1)
(float, bar2, VAR(VARNAME_)::keys::bar2)
)
#endif
#undef VARNAME_
// --------------------------------------------------------
Now one can create instances of foo
and bar
by using:
VAR(foo)::type fooI;
VAR(bar)::type barI;
The associative keys can be used like this:
auto a = boost::fusion::at_key<VAR(foo)::keys::foo3>(fooI).
auto b = boost::fusion::at_key<VAR(bar)::keys::bar2>(barI).
This approach might be useful down the line.
Lastly, there are tags for the structs themselves:
VAR(bar)::index
VAR(foo)::index
I can use the later as type-keys in other Boost.Fusion sequences, e.g. boost::fusion::map
.
Question:
Notice that, for each of the two structs, and since I am defining an associative sequence, I have to use the struct-field names (foo1
, bar2
, ...) three times each.
What I would like instead, is to define the above two structs as this:
// ========================================================
DEFINE_DATAVAR_STRUCT(
foo,
(char, foo1)
(int, foo2)
(float, foo3)
)
// --------------------------------------------------------
// ========================================================
DEFINE_DATAVAR_STRUCT(
bar,
(double, bar1)
(float, bar2)
)
// --------------------------------------------------------
I only need to define the variadic macro DEFINE_DATAVAR_STRUCT
. This is what I need help for. The problem for me, is to reuse variadic arguments so that they can appear in more than place in the generated code. Somehow, Boost.Fusion is doing this with no problem somehow (by relying on Boost.PP).
My own research:
I have looked at the Boost.PP library, but I am not doing very good progress here. Since the Boost.Fusion library is doing this already, there must be a way to achieve the same variadic functionality, similar to the BOOST_FUSION_DEFINE_ASSOC_STRUCT
macro.
The Boost.Fusion macro BOOST_FUSION_DEFINE_ASSOC_STRUCT
is defined on lines 40-50 in .../define_assoc_struct.hpp. It seems much of the magic to build these macros is to be found in .../define_struct.hpp (especially the macro BOOST_FUSION_DEFINE_STRUCT_IMPL
on line 413). This file also takes advantage of a lot of Boost.PP.
Compiler: Microsoft Visual Studio 2015 Update 3 (GCC, Clang are not options right now).
Boost: 1.64.0.
__VA_ARGS__
, so that I can get same variadic behaviour as the Boost.Fusion macro. Perhaps I can just copy the Boost.Fusion implementation, not sure. I will update the question a bit. – Ole Thomsen Buus