Skip to content

Commit

Permalink
365 - Did you know about C++26 static reflection proposal (5/N)?
Browse files Browse the repository at this point in the history
  • Loading branch information
krzysztof-jusiak committed Jan 22, 2024
1 parent 5ff2660 commit 1552a7a
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* [Did you know about C++26 static reflection proposal (2/N)?](https://github.com/tip-of-the-week/cpp/blob/master/tips/362.md)
* [Did you know about C++26 static reflection proposal (3/N)?](https://github.com/tip-of-the-week/cpp/blob/master/tips/363.md)
* [Did you know about C++26 static reflection proposal (4/N)?](https://github.com/tip-of-the-week/cpp/blob/master/tips/364.md)
* [Did you know about C++26 static reflection proposal (5/N)?](https://github.com/tip-of-the-week/cpp/blob/master/tips/365.md)
* [Did you know that C++26 added `Pack Indexing`?](https://github.com/tip-of-the-week/cpp/blob/master/tips/358.md)
* [Did you know about C++26 proposal - `variadic friends`?](https://github.com/tip-of-the-week/cpp/blob/master/tips/352.md)
* [Did you know about C++26 proposal - `inplace_vector`?](https://github.com/tip-of-the-week/cpp/blob/master/tips/351.md)
Expand Down
72 changes: 72 additions & 0 deletions tips/365.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<details open><summary>Info</summary><p>

* **Did you know about C++26 static reflection proposal (5/N)?**

* https://wg21.link/P2996

</p></details><details open><summary>Example</summary><p>

```cpp
struct foo;
[[maybe_unused]] constexpr auto _ =
define_class(^foo, {std::meta::nsdm_description(^int, {.name = "bar"})});
foo f{.bar = 42}; // has bar int member
```
> https://godbolt.org/z/aqxanTe3r
</p></details><details open><summary>Puzzle</summary><p>
* **Can you implement template alias `pack` which will pack given struct by sorting members by their size?**
```cpp
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; });
```

> https://godbolt.org/z/hnPvsE9h3
</p></details>

</p></details><details><summary>Solutions</summary><p>

```cpp
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; });
```
> https://godbolt.org/z/ExYfTv4nK
</p></details>

0 comments on commit 1552a7a

Please sign in to comment.