lundi 15 mai 2023

How does magic_enum library can output enum value as string with msvc?

The magic_enum library provides way to retrieve an enum value as its name, in the form of a string. For instance:

#include <iostream>

#include "magic_enum.hpp"

enum class Dummy : uint16_t {
    first,
    second,
    third,
};

int main() {
    std::cout << magic_enum::enum_name<Dummy::first>()
              << std::endl;  // outputs "first"}

Does some can explain here how magic_enum actually implements enum_name with msvc?

I managed to reproduce this behavior with clang/gcc by passing the enum value to a template function and using __PRETTY_FUNCTION__ inside, for instance:

template<typename Enum_T, Enum_T Value_E> class EnumValueNameAsString
{
    static constexpr std::string_view Get()
    {
        auto constexpr end = std::string_view(__PRETTY_FUNCTION__).find_last_of(';');
        if constexpr (end == std::string_view::npos)
        {
            return std::string_view("Failure");
        }
        auto constexpr start
            = std::string_view(__PRETTY_FUNCTION__).find_last_of('=', end);
        if constexpr (start == std::string_view::npos)
        {
            return std::string_view(
                "Failure");
        }
        // 0 <= start < end
        if constexpr (end - start <= 2)
        {
            return std::string_view(
                "Failure");
        }
        return std::string_view(__PRETTY_FUNCTION__).substr(start + 2, end - start - 2);
    }

public:
    static constexpr std::string_view Name = Get();
};

But for C++, using __FUNCSIG__ instead of __PRETTY_FUNCTION__, I cannot achieve the expected result as __FUNCSIG__ actually is class std::basic_string_view<char,struct std::char_traits<char> > __cdecl EnumValueNameAsString<enum Dummy,0>::Get(void) The enum value name is nowhere in the string.





Aucun commentaire:

Enregistrer un commentaire