C++ Smart Enum.

Shiva

Admin
Joined
Jul 31, 2019
Topics
522
Messages
4,091
Solutions
194
Reaction score
13,963
Location
Berlin
Kaynak : https://stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types-as-string-in-c
Normalde enum = id gibi kullanılamıyordu. şuan iki türlü kullanılabilir..

C++:
#define SMART_ENUM(enumTypeArg, ...)                                                     \
namespace enumTypeArg {                                                                  \
    __VA_ARGS__;                                                                         \
    std::ostream& operator<<(std::ostream& os, const enumTypeArg& val) {                 \
            os << swissarmyknife::enums::to_string(#__VA_ARGS__, val);                   \
            return os;                                                                   \
    }                                                                                    \
                                                                                     \
    std::string to_string(const enumTypeArg& val) {                                      \
            return swissarmyknife::enums::to_string(#__VA_ARGS__, val);                  \
    }                                                                                    \
                                                                                     \
    enumTypeArg from_string(const std::string &str) {                                    \
            return swissarmyknife::enums::from_string<enumTypeArg>(#__VA_ARGS__, str);   \
    }                                                                                    \
}                                                                                        \


namespace swissarmyknife {
    namespace enums {
        static inline void ltrim(std::string& s) {
            s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) {
                return !std::isspace(ch);
                }));
        }

        static inline void rtrim(std::string& s) {
            s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) {
                return !std::isspace(ch);
                }).base(), s.end());
        }

        static inline void trim(std::string& s) {
            ltrim(s);
            rtrim(s);
        }

        static inline std::string to_string(const std::string completeEnumDeclaration, size_t enumVal) throw (std::runtime_error) {
            size_t begin = completeEnumDeclaration.find_first_of('{');
            size_t end = completeEnumDeclaration.find_last_of('}');
            const std::string identifiers = completeEnumDeclaration.substr(begin + 1, end);

            size_t count = 0;
            size_t found = 0;
            do {
                found = identifiers.find_first_of(",}", found + 1);

                if (enumVal == count) {
                    std::string identifiersSubset = identifiers.substr(0, found);
                    size_t beginId = identifiersSubset.find_last_of("{,");
                    identifiersSubset = identifiersSubset.substr(beginId + 1);
                    trim(identifiersSubset);
                    auto subsedBegin = identifiersSubset.substr(0, identifiersSubset.find("="));
                    trim(subsedBegin);
                    return subsedBegin;
                }

                ++count;
            } while (found != std::string::npos);

            throw std::runtime_error("The enum declaration provided doesn't contains this state.");
        }

        template <typename EnumType>
        static inline EnumType from_string(const std::string completeEnumDeclaration, const std::string& enumStr) throw (std::runtime_error) {
            size_t begin = completeEnumDeclaration.find_first_of('{');
            size_t end = completeEnumDeclaration.find_last_of('}');
            const std::string identifiers = completeEnumDeclaration.substr(begin + 1, end);
            //kaynak https://stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types-as-string-in-c
            //modified by *** alıntıdır. rc
            size_t count = 0;
            size_t found = 0;
            do {
                found = identifiers.find_first_of(",}", found + 1);

                std::string identifiersSubset = identifiers.substr(0, found);
                size_t beginId = identifiersSubset.find_last_of("{,");
                identifiersSubset = identifiersSubset.substr(beginId + 1);
                trim(identifiersSubset);

                auto subsedBegin = identifiersSubset.substr(0,identifiersSubset.find("=") );
                trim(subsedBegin);
                if (subsedBegin == enumStr) {
                    auto fCountSTR = identifiersSubset.substr(identifiersSubset.find("=") + 1);
                    auto fCount = atoi(fCountSTR.c_str());
                    return static_cast<EnumType>(count);
                }

                ++count;
            } while (found != std::string::npos);

            throw std::runtime_error("No valid enum value for the provided string");
        }

    }
}

SMART_ENUM(ChampionId,
enum  ChampionId
{
    Unknown = 0,
    Aatrox = 1,
    Ahri = 2,
    Akali = 3,
    Alistar = 4,
    Amumu = 5,
    Anivia = 6,
    Annie = 7,
    Ashe = 8,
    AurelionSol = 9,
    Azir = 10,
    Bard = 11,
    Blitzcrank = 12,
    Brand = 13,
    Braum = 14,
    Caitlyn = 15,
    Camille = 16,
    Cassiopeia = 17,
    Chogath = 18,
    Corki = 19,
    Darius = 20,
    Diana = 21,
    Draven = 22,
    DrMundo = 23,
    Ekko = 24,
    Elise = 25,
    Evelynn = 26,
    Ezreal = 27,
    Fiddlesticks = 28,
    Fiora = 29,
    Fizz = 30,
    Galio = 31,
    Gangplank = 32,
    Garen = 33,
    Gnar = 34,
    Gragas = 35,
    Graves = 36,
    Hecarim = 37,
    Heimerdinger = 38,
    Illaoi = 39,
    Irelia = 40,
    Ivern = 41,
    Janna = 42,
    JarvanIV = 43,
    Jax = 44,
    Jayce = 45,
    Jhin = 46,
    Jinx = 47,
    Kalista = 48,
    Karma = 49,
    Karthus = 50,
    Kassadin = 51,
    Katarina = 52,
    Kayle = 53,
    Kayn = 54,
    Kennen = 55,
    Khazix = 56,
    Kindred = 57,
    Kled = 58,
    KogMaw = 59,
    Leblanc = 60,
    LeeSin = 61,
    Leona = 62,
    Lissandra = 63,
    Lucian = 64,
    Lulu = 65,
    Lux = 66,
    Malphite = 67,
    Malzahar = 68,
    Maokai = 69,
    MasterYi = 70,
    MissFortune = 71,
    MonkeyKing = 72,
    Mordekaiser = 73,
    Morgana = 74,
    Nami = 75,
    Nasus = 76,
    Nautilus = 77,
    Nidalee = 78,
    Nocturne = 79,
    Nunu = 80,
    Olaf = 81,
    Orianna = 82,
    Ornn = 83,
    Pantheon = 84,
    Poppy = 85,
    PracticeTool_TargetDummy = 86,
    Quinn = 87,
    Rakan = 88,
    Rammus = 89,
    RekSai = 90,
    Renekton = 91,
    Rengar = 92,
    Riven = 93,
    Rumble = 94,
    Ryze = 95,
    Sejuani = 96,
    Shaco = 97,
    Shen = 98,
    Shyvana = 99,
    Singed = 100,
    Sion = 101,
    Sivir = 102,
    Skarner = 103,
    Sona = 104,
    Soraka = 105,
    Swain = 106,
    Syndra = 107,
    TahmKench = 108,
    Taliyah = 109,
    Talon = 110,
    Taric = 111,
    Teemo = 112,
    Thresh = 113,
    Tristana = 114,
    Trundle = 115,
    Tryndamere = 116,
    TwistedFate = 117,
    Twitch = 118,
    Udyr = 119,
    Urgot = 120,
    Varus = 121,
    Vayne = 122,
    Veigar = 123,
    Velkoz = 124,
    Vi = 125,
    Viktor = 126,
    Vladimir = 127,
    Volibear = 128,
    Warwick = 129,
    Xayah = 130,
    Xerath = 131,
    XinZhao = 132,
    Yasuo = 133,
    Yorick = 134,
    Zac = 135,
    Zed = 136,
    Ziggs = 137,
    Zilean = 138,
    Zoe = 139,
    Zyra = 140,
    Kaisa = 141,
    Pyke = 142,
    Neeko = 143,
    Sylas = 144,
    Yuumi = 145,
    Qiyana = 146,
    Senna = 147,
    Aphelios = 148,
    Sett = 149
})

int main()
{
    std::cout << ChampionId::Ezreal << std::endl;
    //to a string
    std::string ChampStr = ChampionId::to_string(ChampionId::Ezreal);
    //from a string
    ChampionId::ChampionId ChampIDEnum = ChampionId::from_string("Ezreal");
    std::printf("ChampId : %d - %s", ChampIDEnum, ChampStr.c_str());

}
 

Top