Is there a trait or meta function or anything to check at compile time if a sequence is actually an adapted struct, so that I could e.g. get its member names? I saw people doing that by exclusion, something along the lines of “if it’s not a vector but it’s still a sequence, then it must be a struct” (I am making up because I don’t remember precisely). I didn’t think it’s a sufficient condition, there probably should be something better in fusion to achieve that. Couldn’t find it though. Please share if you know. Thanks.
I don't know if there is a better way, but you can use:
template <typename T>
using is_adapted_struct=std::is_same<typename boost::fusion::traits::tag_of<T>::type,boost::fusion::struct_tag>;
This will work with structs adapted with BOOST_FUSION_ADAPT_STRUCT
or defined with BOOST_FUSION_DEFINE_STRUCT
and I believe also their named and templated variations (but not with the BOOST_FUSION_ADAPT_ASSOC_STRUCT
and its variations (you would need to replace struct_tag
with assoc_struct_tag
for it to work)). I think (and this might be a problem for your use case) that this will also return true for classes adapted with BOOST_FUSION_ADAPT_ADT
.
#include <iostream>
#include <type_traits>
#include <boost/fusion/include/tag_of.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/vector.hpp>
struct adapted
{
int foo;
double bar;
};
BOOST_FUSION_ADAPT_STRUCT(adapted, foo, bar);
struct not_adapted{};
template <typename T>
using is_adapted_struct=std::is_same<typename boost::fusion::traits::tag_of<T>::type,boost::fusion::struct_tag>;
int main()
{
static_assert(is_adapted_struct<adapted>::value);
static_assert(!is_adapted_struct<not_adapted>::value);
static_assert(!is_adapted_struct<boost::fusion::vector<int,double>>::value);
}