365.md
January 22, 2024 ยท View on GitHub
Example
struct foo;
[[maybe_unused]] constexpr auto _ =
define_class(^foo, {std::meta::nsdm_description(^int, {.name = "bar"})});
foo f{.bar = 42}; // has bar int member
Puzzle
- Can you implement template alias
packwhich will pack given struct by sorting members by their size?
template<class T> using pack; // TODO
struct unpacked {
short s;
int i;
bool b;
};
static_assert(12 == sizeof(unpacked));
using packed = pack<unpacked>;
static_assert(8 == sizeof(packed));
static_assert(requires(packed p) { p.i; p.s; p.b; });
Solutions
namespace detail {
template<class T> struct packed;
template<class T> [[nodiscard]] consteval auto pack() {
std::vector members = std::meta::nonstatic_data_members_of(^T);
sort(members, [](auto lhs, auto rhs) consteval { return std::meta::size_of(lhs) < std::meta::size_of(rhs); });
std::vector<std::meta::nsdm_description> new_members{};
for (const auto& member: members) {
new_members.push_back({std::meta::type_of(member), {.name = std::meta::name_of(member)}});
}
return define_class(^packed<T>, new_members);
}
} // namespace detail
template<class T> using pack = [:detail::pack<T>():];
struct unpacked {
short s;
int i;
bool b;
};
static_assert(12 == sizeof(unpacked));
using packed = pack<unpacked>;
static_assert(8 == sizeof(packed));
static_assert(requires(packed p) { p.i; p.s; p.b; });