c_cpp C ++ 11内省的“枚举”

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp C ++ 11内省的“枚举”相关的知识,希望对你有一定的参考价值。

#ifndef ENUMPP_HPP
#define ENUMPP_HPP

#include <initializer_list>
#include <utility>
#include <array>
#include <ostream>

template<typename T, std::size_t TotalValues>
struct Enum;

template<typename T>
struct EnumValue
{
    constexpr EnumValue(const char* name, T value) :
        name{name},
        value{value}
    {}

    const char* const name;
    const T value;

    constexpr operator T() const
    {
        return value;
    }
};

template<typename T>
constexpr bool operator==(const EnumValue<T>& lhs, const EnumValue<T>& rhs)
{
    return lhs.name == rhs.name;
}

template<typename T>
constexpr bool operator!=(const EnumValue<T>& lhs, const EnumValue<T>& rhs)
{
    return !(lhs.name == rhs.name);
}

template<typename T>
std::ostream& operator<<(std::ostream& os, const EnumValue<T>& value)
{
    return os << value.name;
}

template<typename T>
constexpr EnumValue<T> enumValue(const char* name, T value)
{
    return { name, value };
}

namespace detail
{
    template<typename T, std::size_t TotalValues>
    using ValuesArray = std::array<EnumValue<T>, TotalValues>;

    template<typename T, std::size_t TotalValues>
    struct FullValue : public EnumValue<T>
    {
        constexpr FullValue(EnumValue<T> value, std::size_t index, const ValuesArray<T, TotalValues>& allValues) :
            EnumValue<T>{value.name, value.value},
            index{index},
            allValues(allValues)
        {}

        const std::size_t index;
        const ValuesArray<T, TotalValues> allValues;
    };

    template<typename T, std::size_t TotalValues>
    constexpr FullValue<T, TotalValues> findByName(const ValuesArray<T, TotalValues>& allValues, const char* name, std::size_t i = 0)
    {
        return (allValues[i].name == name) ? FullValue<T, TotalValues>{allValues[i], i, allValues} : findByName(allValues, name, i + 1);
    }

    template<typename T, std::size_t TotalValues>
    constexpr FullValue<T, TotalValues> findByValue(const ValuesArray<T, TotalValues>& allValues, T value, std::size_t i = 0)
    {
        return (allValues[i].value == value) ? FullValue<T, TotalValues>{allValues[i], i, allValues} : findByValue(allValues, value, i + 1);
    }
}

template<typename T, std::size_t TotalValues>
struct Enum
{
    using ValuesArray = detail::ValuesArray<T, TotalValues>;
    using Value = detail::FullValue<T, TotalValues>;

    template<typename... Values>
    constexpr Enum(Values&&... values) :
        values{std::forward<Values>(values)...}
    {}

    const ValuesArray values;

    constexpr Value value(const char* name) const
    {
        return detail::findByName(values, name);
    }

    constexpr Value value(T value) const
    {
        return detail::findByValue(values, value);
    }

    constexpr Value operator[](const char* name) const
    {
        return value(name);
    }
};

template<typename T, typename... Values>
constexpr Enum<T, sizeof...(Values)> enum_(Values&&... values)
{
    return { std::forward<Values>(values)... };
}

#ifdef ENUMPP_MAIN

#include <iostream>

int main()
{
    constexpr auto myEnum = enum_<int>(
        enumValue("hello", 1),
        enumValue("world", 2)
    );

    constexpr auto hello = myEnum["hello"];
    using Type = std::integral_constant<int, hello.value>;
    // Compile time error "array out of bounds"
    // using WrongType = std::integral_constant<int, myEnum.value(42)>;

    std::cout << hello << " (" << static_cast<int>(hello) << ")" << std::endl;
    std::cout << "2 (" << myEnum.value(2) << ")" << std::endl;
}

#endif // ENUMPP_MAIN

#endif // ENUMPP_HPP

以上是关于c_cpp C ++ 11内省的“枚举”的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 两种枚举

c_cpp 组合 - 枚举所有

c_cpp bcb枚举文件

c_cpp 使用命名的枚举作为字节

c_cpp 容易枚举到字符串

c_cpp 在C ++中使用内部枚举和联合的状态对象的例子