Using boost::fusion
is possible to iterate an adapted structure and get the name of each member of that structure.
Is there a way to retrieve also the name of the structure some way?
What I woulld like to do is the following: given the current scenario
namespace inner {
struct test_struct {
int a;
int b;
} }
BOOST_FUSION_ADAPT_STRUCT( inner::test_struct, a, b );
I'd like to have a function that will return "test_struct" (or "inner::test_struct" )
I did check the header file[*] containing struct_size
and other extension classes but I haven't found any with that purpose.
Do you know if there is anything out there to do that?
[*] boost/fusion/adapted/struct/detail/extension.hpp
That's not a feature. You can see it by inspecting the output of the preprocessor.
You can see the struct_member_name
extension, but no such literals for the struct name:
namespace boost {
namespace fusion {
namespace traits {
template <> struct tag_of<inner::test_struct> { typedef struct_tag type; };
template <> struct tag_of<inner::test_struct const> {
typedef struct_tag type;
};
} // namespace traits
namespace extension {
template <> struct access::struct_member<inner::test_struct, 0> {
struct deduced_attr_type {
static const inner::test_struct& obj;
typedef boost::type_of::remove_cv_ref_t<decltype(obj.a)> type;
};
typedef deduced_attr_type::type attribute_type;
typedef attribute_type type;
template <typename Seq> struct apply {
typedef typename add_reference<
typename mpl::eval_if<is_const<Seq>, add_const<attribute_type>,
mpl::identity<attribute_type>>::type>::type
type;
constexpr static type call(Seq& seq) { return seq.a; }
};
};
template <> struct struct_member_name<inner::test_struct, 0> {
typedef char const* type;
constexpr static type call() { return "a"; }
};
template <> struct access::struct_member<inner::test_struct, 1> {
struct deduced_attr_type {
static const inner::test_struct& obj;
typedef boost::type_of::remove_cv_ref_t<decltype(obj.b)> type;
};
typedef deduced_attr_type::type attribute_type;
typedef attribute_type type;
template <typename Seq> struct apply {
typedef typename add_reference<
typename mpl::eval_if<is_const<Seq>, add_const<attribute_type>,
mpl::identity<attribute_type>>::type>::type
type;
constexpr static type call(Seq& seq) { return seq.b; }
};
};
template <> struct struct_member_name<inner::test_struct, 1> {
typedef char const* type;
constexpr static type call() { return "b"; }
};
template <> struct struct_size<inner::test_struct> : mpl::int_<2> {};
template <> struct struct_is_view<inner::test_struct> : mpl::false_ {};
} // namespace extension
} // namespace fusion
namespace mpl {
template <typename> struct sequence_tag;
template <> struct sequence_tag<inner::test_struct> {
typedef fusion::fusion_sequence_tag type;
};
template <> struct sequence_tag<inner::test_struct const> {
typedef fusion::fusion_sequence_tag type;
};
} // namespace mpl
} // namespace boost
As always, it may not be too hard to add your own macro to get the extra information. See e.g. Parsing Selector struct with alternating tokens using Boost Spirit X3 or Boost fusion sequence type and name identification for structs and class