Playing around with C++26 reflection
  1. #include <string_view>
  2. #include <string>
  3. #include <charconv>
  4. #include <iostream>
  5. #include <meta>
  6. #include <system_error>
  7. #include <stdexcept>
  8.  
  9. class A {
  10. int a;
  11. int b;
  12. int c;
  13. };
  14.  
  15. template <typename T>
  16. constexpr ::std::u8string to_u8string(T const &val)
  17. {
  18. char output[128];
  19. auto result = ::std::to_chars(output, output + 128, val);
  20. if (result.ec != std::errc()) {
  21. throw ::std::range_error(::std::make_error_code(result.ec).message());
  22. } else {
  23. return ::std::u8string{output, result.ptr};
  24. }
  25. }
  26.  
  27. template <typename T>
  28. consteval
  29. ::std::u8string_view dump_class()
  30. {
  31. using namespace ::std::meta;
  32. auto constexpr a = ^^T;
  33. static_assert(is_complete_type(a));
  34. static_assert(is_enumerable_type(a));
  35. ::std::u8string result;
  36. result += u8"class name: ";
  37. result += u8display_string_of(a);
  38. result += u8"\n";
  39. int counter = 0;
  40. for (auto member: members_of(a, access_context::unchecked())) {
  41. result += u8" member [";
  42. result += to_u8string(counter++);
  43. result += u8"] -> ";
  44. if (has_identifier(member)) {
  45. result += u8identifier_of(member);
  46. } else {
  47. result += u8"<anon> ";
  48. result += u8display_string_of(member);
  49. }
  50. result += u8"\n";
  51. }
  52. auto first_char_ptr = define_static_string(result);
  53. return {first_char_ptr, first_char_ptr + result.size()};
  54. }
  55.  
  56. int main()
  57. {
  58. constexpr auto cinfo = dump_class<A>();
  59. ::std::cout.write(reinterpret_cast<char const *>(cinfo.data()), cinfo.size());
  60. return 0;
  61. }
  62.  
Pasted 2026-08-23 11:25:04

Short link: