Omnifarious icon

Playing around with C++26 reflection

Omnifarious | PRO | 08/24/26 04:33:34 AM UTC | 0 ⭐ | 12799 👁️ | Never ⏰ | [C++, Reflection]
C++ |

1.58 KB

|

Source Code

|

0 👍

/

0 👎

#include <string_view>
#include <string>
#include <charconv>
#include <iostream>
#include <meta>
#include <system_error>
#include <stdexcept>
 
class A {
    int a;
    int b;
    int c;
};
 
template <typename T>
constexpr ::std::u8string to_u8string(T const &val)
{
   char output[128];
   auto result = ::std::to_chars(output, output + 128, val);
   if (result.ec != std::errc()) {
      throw ::std::range_error(::std::make_error_code(result.ec).message());
   } else {
      return ::std::u8string{output, result.ptr};
   }
}
 
template <typename T>
consteval
::std::u8string_view dump_class()
{
    using namespace ::std::meta;
    auto constexpr a = ^^T;
    static_assert(is_complete_type(a));
    static_assert(is_enumerable_type(a));
    ::std::u8string result;
    result += u8"class name: ";
    result += u8display_string_of(a);
    result += u8"\n";
    int counter = 0;
    for (auto member: members_of(a, access_context::unchecked())) {
        result += u8"   member [";
        result += to_u8string(counter++);
        result += u8"] -> ";
        if (has_identifier(member)) {
            result += u8identifier_of(member);
        } else {
            result += u8"<anon> ";
            result += u8display_string_of(member);
        }
        result += u8"\n";
    }
    auto first_char_ptr = define_static_string(result);
    return {first_char_ptr, first_char_ptr + result.size()};
}
 
int main()
{
    constexpr auto cinfo = dump_class<A>();
    ::std::cout.write(reinterpret_cast<char const *>(cinfo.data()), cinfo.size());
    return 0;
}
 

Comments

  • Omnifarious icon
    08/24/26 04:34:12 AM UTC
    text |

    0 B

    |

    0 👍

    /

    0 👎

    g++ -std=c++26 -frelection should work to compile this with gcc 16. Maybe earlier.