Not at the moment, no. But it's not rocket science. The macro essentially creates a struct like this one:
struct S {
// How many fields are in this struct?
static constexpr unsigned int FIELD_COUNT = 5;
// Full specializations are not allowed inside classes, so add a dummy parameter that is equivalent to S
template
struct FieldTraits;
// Partial specialization for the first field
template
struct FieldTraits {
using type = int;
static constexpr std::size_t OFFSET = offsetof(S, anInt);
static constexpr const char* name() { return "anInt"; }
static constexpr type& value(S& self) { return self.anInt; }
};
// The first field itself
int anInt;
// Partial specialization for the second field
template
struct FieldTraits {
using type = bool;
static constexpr std::size_t OFFSET = offsetof(S, aBool);
static constexpr const char* name() { return "aBool"; }
static constexpr type& value(S& self) { return self.aBool; }
};
// The second field itself
bool aBool;
...
};
Now that we have the meta-information about the struct's fields, we can process them:
// Meta-function to process a struct's fields
template
struct ForEach {
template
static void apply(T& object, Functor f)
{
// Get the field's value and call the functor with it
auto value = T::FieldTraits::value(object);
f(value);
// Next field
ForEach::apply(object, f);
};
};
// Partial specialization to end iteration
template
struct ForEach {
template
static void apply(T& object, Functor f)
{
};
};
And finally a bit of syntactic sugar:
template
void forEachField(T& object, Functor f)
{
ForEach::apply(object, f);
}
*(omitted for the sake of clarity: dealing with const objects, using rvalue references and std::forward for the functor to make the code work with non-copyable functors)