I have a similar Problem as in this question. I want to get the size of struct at compile time, including all the substructs without the compiler specific padding added.
struct Bar {
BOOST_HANA_DEFINE_STRUCT(Bar,
(std::uint8_t, a),
(std::uint16_t, b)
);
};
struct Foo {
BOOST_HANA_DEFINE_STRUCT(Foo,
(std::uint8_t, a),
(std::uint16_t, b),
(std::uint32_t, c),
(std::uint64_t, d),
(Bar, bar)
);
};
template <typename T>
constexpr auto bytesize() -> size_t
{
if constexpr (std::is_arithmetic<T>::value || std::is_enum<T>::value)
return sizeof(T);
else if constexpr (std::is_class<T>::value)
{
return hana::fold_left(
hana::accessors<T>(), 0, [](auto total, auto member) {
// I want to call bytesize recusively here:
return bytesize<decltype(hana::second(member)(std::declval<T>()))>() + total;
});
}
}
static_assert(bytesize<Foo>() == 18);
As I don't want to include the padding, I expect the size of the struct Foo
to be 18 (including the size of the substruct Bar
) but the code in the linked question does include the padding in the calculation and gives me a size of 19. The problem lies therein that the function should call bytesize recursively on all structs it encounters.
A minimal example which does not work as intended can be found here.
You have issue with returned types which are not what you expect (extra &&
). std::decay_t
fixes the issue:
return hana::fold_left(
hana::accessors<T>(), 0, [](auto total, auto member) {
using member_type = std::decay_t<decltype(hana::second(member)(std::declval<T>()))>;
constexpr auto member_size = bytesize<member_type>();
return total + member_size;
});