
Gero Peterhoff wrote:
Hello, first of all, thank you very much for the great work. But I miss the support for unions. Is that correct? namespace boost { namespace describe { #define BOOST_DESCRIBE_UNION(C, Public) \ static_assert(std::is_union<C>::value, "BOOST_DESCRIBE_UNION should only be used with union types"); \ BOOST_DESCRIBE_PUBLIC_MEMBERS_(C BOOST_DESCRIBE_PP_UNPACK Public) \ BOOST_DESCRIBE_PROTECTED_MEMBERS_(C) \ BOOST_DESCRIBE_PRIVATE_MEMBERS_(C) } // describe } // boost
Interesting point. In principle, BOOST_DESCRIBE_STRUCT and BOOST_DESCRIBE_CLASS should support unions, and a separate macro shouldn't be needed. So the static_assert on is_class is probably too strict and needs to be relaxed. However, I suspect that most code supporting described classes won't work correctly when passed a union. The examples in the documentation don't, so they would need to be updated with a check for is_class.
I also miss the support for std::get. Is that correct? namespace boost { namespace describe { #define BOOST_DESCRIBE_GET(C) \ template <std::size_t Index> \ inline constexpr const auto& get(const C& arg) noexcept \ { \ static_assert(std::is_class<C>::value || std::is_union<C>::value, "BOOST_DESCRIBE_GET should only be used with class, struct or union types"); \ using members = boost::describe::describe_members<C, boost::describe::mod_any_access>; \ static_assert(Index < boost::mp11::mp_size<members>()); \ return arg.*boost::mp11::mp_at_c<members, Index>().pointer; \ } \ template <std::size_t Index> \ inline constexpr auto& get(C& arg) noexcept \ { \ static_assert(std::is_class<C>::value || std::is_union<C>::value, "BOOST_DESCRIBE_GET should only be used with class, struct or union types"); \ using members = boost::describe::describe_members<C, boost::describe::mod_any_access>; \ static_assert(Index < boost::mp11::mp_size<members>()); \ return arg.*boost::mp11::mp_at_c<members, Index>().pointer; \ } } // describe } // boost
It's not clear why this needs to be std::get; adding overloads to namespace std is undefined behavior. It might be better off as a helper function in some namespace of your own. And a helper function of your own wouldn't need to be defined via a macro, it can be templated on C. template<std::size_t Index, class C> inline constexpr auto& get(C& arg) noexcept { using members = boost::describe::describe_members<C, boost::describe::mod_any_access>; static_assert(Index < boost::mp11::mp_size<members>()); return arg.*boost::mp11::mp_at_c<members, Index>().pointer; }
Do you have an idea how to implement __builtin_constant_p for all compilers?
I can't think of a way.