Is there a simple way to convert C++ enum to string?

后端 未结 30 2784
我在风中等你
我在风中等你 2020-11-22 10:37

Suppose we have some named enums:

enum MyEnum {
      FOO,
      BAR = 0x50
};

What I googled for is a script (any language) that scans all

30条回答
  •  佛祖请我去吃肉
    2020-11-22 10:48

    I want to post this in case someone finds it useful.

    In my case, I simply need to generate ToString() and FromString() functions for a single C++11 enum from a single .hpp file.

    I wrote a python script that parses the header file containing the enum items and generates the functions in a new .cpp file.

    You can add this script in CMakeLists.txt with execute_process, or as a pre-build event in Visual Studio. The .cpp file will be automatically generated, without the need to manually update it each time a new enum item is added.

    generate_enum_strings.py

    # This script is used to generate strings from C++ enums
    
    import re
    import sys
    import os
    
    fileName = sys.argv[1]
    enumName = os.path.basename(os.path.splitext(fileName)[0])
    
    with open(fileName, 'r') as f:
        content = f.read().replace('\n', '')
    
    searchResult = re.search('enum(.*)\{(.*?)\};', content)
    tokens = searchResult.group(2)
    tokens = tokens.split(',')
    tokens = map(str.strip, tokens)
    tokens = map(lambda token: re.search('([a-zA-Z0-9_]*)', token).group(1), tokens)
    
    textOut = ''
    textOut += '\n#include "' + enumName + '.hpp"\n\n'
    textOut += 'namespace myns\n'
    textOut += '{\n'
    textOut += '    std::string ToString(ErrorCode errorCode)\n'
    textOut += '    {\n'
    textOut += '        switch (errorCode)\n'
    textOut += '        {\n'
    
    for token in tokens:
        textOut += '        case ' + enumName + '::' + token + ':\n'
        textOut += '            return "' + token + '";\n'
    
    textOut += '        default:\n'
    textOut += '            return "Last";\n'
    textOut += '        }\n'
    textOut += '    }\n'
    textOut += '\n'
    textOut += '    ' + enumName + ' FromString(const std::string &errorCode)\n'
    textOut += '    {\n'
    textOut += '        if ("' + tokens[0] + '" == errorCode)\n'
    textOut += '        {\n'
    textOut += '            return ' + enumName + '::' + tokens[0] + ';\n'
    textOut += '        }\n'
    
    for token in tokens[1:]:
        textOut += '        else if("' + token + '" == errorCode)\n'
        textOut += '        {\n'
        textOut += '            return ' + enumName + '::' + token + ';\n'
        textOut += '        }\n'
    
    textOut += '\n'
    textOut += '        return ' + enumName + '::Last;\n'
    textOut += '    }\n'
    textOut += '}\n'
    
    fileOut = open(enumName + '.cpp', 'w')
    fileOut.write(textOut)
    

    Example:

    ErrorCode.hpp

    #pragma once
    
    #include 
    #include 
    
    namespace myns
    {
        enum class ErrorCode : uint32_t
        {
            OK = 0,
            OutOfSpace,
            ConnectionFailure,
            InvalidJson,
            DatabaseFailure,
            HttpError,
            FileSystemError,
            FailedToEncrypt,
            FailedToDecrypt,
            EndOfFile,
            FailedToOpenFileForRead,
            FailedToOpenFileForWrite,
            FailedToLaunchProcess,
    
            Last
        };
    
        std::string ToString(ErrorCode errorCode);
        ErrorCode FromString(const std::string &errorCode);
    }
    

    Run python generate_enum_strings.py ErrorCode.hpp

    Result:

    ErrorCode.cpp

    #include "ErrorCode.hpp"
    
    namespace myns
    {
        std::string ToString(ErrorCode errorCode)
        {
            switch (errorCode)
            {
            case ErrorCode::OK:
                return "OK";
            case ErrorCode::OutOfSpace:
                return "OutOfSpace";
            case ErrorCode::ConnectionFailure:
                return "ConnectionFailure";
            case ErrorCode::InvalidJson:
                return "InvalidJson";
            case ErrorCode::DatabaseFailure:
                return "DatabaseFailure";
            case ErrorCode::HttpError:
                return "HttpError";
            case ErrorCode::FileSystemError:
                return "FileSystemError";
            case ErrorCode::FailedToEncrypt:
                return "FailedToEncrypt";
            case ErrorCode::FailedToDecrypt:
                return "FailedToDecrypt";
            case ErrorCode::EndOfFile:
                return "EndOfFile";
            case ErrorCode::FailedToOpenFileForRead:
                return "FailedToOpenFileForRead";
            case ErrorCode::FailedToOpenFileForWrite:
                return "FailedToOpenFileForWrite";
            case ErrorCode::FailedToLaunchProcess:
                return "FailedToLaunchProcess";
            case ErrorCode::Last:
                return "Last";
            default:
                return "Last";
            }
        }
    
        ErrorCode FromString(const std::string &errorCode)
        {
            if ("OK" == errorCode)
            {
                return ErrorCode::OK;
            }
            else if("OutOfSpace" == errorCode)
            {
                return ErrorCode::OutOfSpace;
            }
            else if("ConnectionFailure" == errorCode)
            {
                return ErrorCode::ConnectionFailure;
            }
            else if("InvalidJson" == errorCode)
            {
                return ErrorCode::InvalidJson;
            }
            else if("DatabaseFailure" == errorCode)
            {
                return ErrorCode::DatabaseFailure;
            }
            else if("HttpError" == errorCode)
            {
                return ErrorCode::HttpError;
            }
            else if("FileSystemError" == errorCode)
            {
                return ErrorCode::FileSystemError;
            }
            else if("FailedToEncrypt" == errorCode)
            {
                return ErrorCode::FailedToEncrypt;
            }
            else if("FailedToDecrypt" == errorCode)
            {
                return ErrorCode::FailedToDecrypt;
            }
            else if("EndOfFile" == errorCode)
            {
                return ErrorCode::EndOfFile;
            }
            else if("FailedToOpenFileForRead" == errorCode)
            {
                return ErrorCode::FailedToOpenFileForRead;
            }
            else if("FailedToOpenFileForWrite" == errorCode)
            {
                return ErrorCode::FailedToOpenFileForWrite;
            }
            else if("FailedToLaunchProcess" == errorCode)
            {
                return ErrorCode::FailedToLaunchProcess;
            }
            else if("Last" == errorCode)
            {
                return ErrorCode::Last;
            }
    
            return ErrorCode::Last;
        }
    }
    

提交回复
热议问题