#ifndef MAGIC_ENUM_HPP #define MAGIC_ENUM_HPP #include #include #include #include #include # if defined(__clang__) # define PRETTY_FUNCTION_NAME __PRETTY_FUNCTION__ # define ENUM_OFFSET 2 # elif defined(__GNUC__) # define PRETTY_FUNCTION_NAME __PRETTY_FUNCTION__ # define ENUM_OFFSET 51 # elif defined(_MSC_VER) # define PRETTY_FUNCTION_NAME __FUNCSIG__ # define ENUM_OFFSET 17 # endif namespace OHOS { namespace Sharing { namespace magic_enum { const int MAGIC_ENUM_RANGE_MAX = 1024; template constexpr std::string_view get_enum_value_name() { std::string_view name{PRETTY_FUNCTION_NAME, sizeof(PRETTY_FUNCTION_NAME) - ENUM_OFFSET}; for (std::size_t i = name.size(); i > 0; --i) { if (!((name[i - 1] >= '0' && name[i - 1] <= '9') || (name[i - 1] >= 'a' && name[i - 1] <= 'z') || (name[i - 1] >= 'A' && name[i - 1] <= 'Z') || (name[i - 1] == '_'))) { name.remove_prefix(i); break; } } if (name.size() > 0 && ((name.front() >= 'a' && name.front() <= 'z') || (name.front() >= 'A' && name.front() <= 'Z') || (name.front() == '_'))) { return name; } return {}; // Invalid name. } template constexpr bool is_valid() { return get_enum_value_name().size() != 0; } template constexpr auto make_integer_list_wrapper(std::integer_sequence) { constexpr int half_size = sizeof...(Is) / 2; return std::integer_sequence(); } constexpr auto test_integer_sequence_v = make_integer_list_wrapper(std::make_integer_sequence()); template constexpr size_t get_enum_size(std::integer_sequence) { constexpr std::array valid{is_valid(Is)>()...}; constexpr std::size_t count = [](decltype((valid)) valid_) constexpr noexcept->std::size_t { auto count_ = std::size_t{0}; for (std::size_t i_ = 0; i_ < valid_.size(); ++i_) { if (valid_[i_]) { ++count_; } } return count_; }(valid); return count; } template constexpr std::size_t enum_size_v = get_enum_size(test_integer_sequence_v); template constexpr auto get_all_valid_values(std::integer_sequence) { constexpr std::array valid{is_valid(Is)>()...}; constexpr std::array integer_value{Is...}; std::array> values{}; for (std::size_t i = 0, v = 0; i < sizeof...(Is); ++i) { if (valid[i]) { values[v++] = integer_value[i]; } } return values; } template constexpr auto get_all_valid_names(std::integer_sequence) { constexpr std::array names{get_enum_value_name(Is)>()...}; std::array> valid_names{}; for (std::size_t i = 0, v = 0; i < names.size(); ++i) { if (names[i].size() != 0) { valid_names[v++] = names[i]; } } return valid_names; } template constexpr auto enum_names_v = get_all_valid_names(test_integer_sequence_v); template constexpr auto enum_values_v = get_all_valid_values(test_integer_sequence_v); template constexpr E string2enum(const std::string_view str) { constexpr auto valid_names = enum_names_v; constexpr auto valid_values = enum_values_v; constexpr auto enum_size = enum_size_v; for (size_t i = 0; i < enum_size; ++i) { if (str == valid_names[i]) { return static_cast(valid_values[i]); } } return E{}; } template constexpr std::string_view enum2string(E V) { constexpr auto valid_names = enum_names_v; constexpr auto valid_values = enum_values_v; constexpr auto enum_size = enum_size_v; for (size_t i = 0; i < enum_size; ++i) { if (static_cast(V) == valid_values[i]) { return valid_names[i]; } } return ""; } template constexpr auto enum_name(E value) { int num = static_cast(value); if (num > MAGIC_ENUM_RANGE_MAX / 2 || num < -(MAGIC_ENUM_RANGE_MAX / 2)) { // 2: maxnum return std::to_string(static_cast(value)); } else { return std::string(enum2string(value)); } } } // namespace magic_enum } // namespace Sharing } // namespace OHOS #endif // MAGIC_ENUM_HPP