Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2021-11-12 19:54:27


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.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk