C++ compile-time reflection 1-get the enumeration type name
Note: I am original, if you find similarities, you will be responsible for the consequences
Sometimes we need to get type information. Type name, enumeration value name, etc. C++ does not support compile-time reflection for the time being (C++ 23/26 will support), but we can implement it ourselves, the disadvantage is that it will delay compilation speed.
Development environment:
Support msvc , clang and g++ , C++17 or above is required
achieve:
// enum_info.hpp
#ifndef ENUM_INFO_HPP
#define ENUM_INFO_HPP
#include <cstddef>
#include <string_view>
#include <type_traits>
namespace enum_info
{
using string_view = std::string_view;
namespace details
{
template <typename Enum_type>
constexpr auto enum_type_name() noexcept
{
// 静态断言, Enum_type 必须是枚举类型
static_assert(std::is_enum_v<Enum_type>, " requires Enum_type == enum");
#if defined(__clang__)
// __PRETTY_FUNCTION__:
// auto enum_info::details::enum_type_name() [Enum_type = B]
constexpr std::size_t prefix = sizeof("auto enum_info::details::enum_type_name() [Enum_type = ") - 1;
constexpr std::size_t suffix = sizeof("]") - 1;
constexpr string_view name{
__PRETTY_FUNCTION__ + prefix, sizeof(__PRETTY_FUNCTION__) - prefix - suffix - 1 };
#elif defined(__GNUC__)
// __PRETTY_FUNCTION__:
// constexpr auto enum_info::details::enum_type_name() [with Enum_type = B]
constexpr std::size_t prefix = sizeof("constexpr auto enum_info::details::enum_type_name() [with Enum_type = ") - 1;
constexpr std::size_t suffix = sizeof("]") - 1;
constexpr string_view name{
__PRETTY_FUNCTION__ + prefix, sizeof(__PRETTY_FUNCTION__) - prefix - suffix - 1 };
#elif defined(_MSC_VER)
// __FUNCSIG__:
// auto __cdecl enum_info::details::enum_type_name<enum main::B>(void) noexcept
constexpr std::size_t prefix = sizeof("auto __cdecl enum_info::details::enum_type_name<enum ") - 1;
constexpr std::size_t suffix = sizeof(">(void) noexcept") - 1;
constexpr string_view name{
__FUNCSIG__ + prefix, sizeof(__FUNCSIG__) - prefix - suffix - 1 };
#endif
return name;
}
} // details
template <typename Enum_type>
inline constexpr string_view enum_type_name_v = details::enum_type_name<Enum_type>();
} // enum_info
#endif // !ENUM_INFO_HPP
principle:
When the template is instantiated, the compiler will replace __FUNCSIG__
or replace __PRETTY_FUNCTION__
the function information including the template parameter information
- clang will code above is
__PRETTY_FUNCTION__
replacedauto enum_info::details::enum_type_name() [Enum_type = B]
- gcc will code above is
__PRETTY_FUNCTION__
replacedconstexpr auto enum_info::details::enum_type_name() [with Enum_type = B]
- msvc will code above is
__FUNCSIG__
replacedauto __cdecl enum_info::details::enum_type_name<enum main::B>(void)
Only the offset is needed later to get the name of the enumeration type
use:
// main.cpp
// clang编译器
#include <iostream>
#include "enum_info.hpp"
enum class my_enum
{
};
int main(void)
{
std::cout << enum_info::enum_type_name_v<my_enum> << std::endl;
(void)getchar();
return 0;
}
In the next issue, we will get the name of the enumeration value.