[c++] enum to string in modern C++11 / C++14 / C++17 and future C++20

I took the idea from @antron and implemented it differently: generating a true enum class.

This implementation meets all the requirements listed in original question but currently has only one real limitation: it assumes the enum values are either not provided or, if provided, must start with 0 and go up sequentially without gaps.

This is not an intrinsic limitation - simply that I don't use ad-hoc enum values. If this is needed, one can replace vector lookup with traditional switch/case implementation.

The solution uses some c++17 for inline variables but this can be easily avoided if needed. It also uses boost:trim because of simplicity.

Most importantly, it takes only 30 lines of code and no black magic macros. The code is below. It's meant to be put in header and included in multiple compilation modules.

It can be used the same way as was suggested earlier in this thread:

ENUM(Channel, int, Red, Green = 1, Blue)
std::out << "My name is " << Channel::Green;
//prints My name is Green

Pls let me know if this is useful and how it can be improved further.


#include <boost/algorithm/string.hpp>   
struct EnumSupportBase {
  static std::vector<std::string> split(const std::string s, char delim) {
    std::stringstream ss(s);
    std::string item;
    std::vector<std::string> tokens;
    while (std::getline(ss, item, delim)) {
        auto pos = item.find_first_of ('=');
        if (pos != std::string::npos)
            item.erase (pos);
        boost::trim (item);
        tokens.push_back(item);
    }
    return tokens;
  }
};
#define ENUM(EnumName, Underlying, ...) \
    enum class EnumName : Underlying { __VA_ARGS__, _count }; \
    struct EnumName ## Support : EnumSupportBase { \
        static inline std::vector<std::string> _token_names = split(#__VA_ARGS__, ','); \
        static constexpr const char* get_name(EnumName enum_value) { \
            int index = (int)enum_value; \
            if (index >= (int)EnumName::_count || index < 0) \
               return "???"; \
            else \
               return _token_names[index].c_str(); \
        } \
    }; \
    inline std::ostream& operator<<(std::ostream& os, const EnumName & es) { \
        return os << EnumName##Support::get_name(es); \
    } 

Examples related to c++

Method Call Chaining; returning a pointer vs a reference? How can I tell if an algorithm is efficient? Difference between opening a file in binary vs text How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Install Qt on Ubuntu #include errors detected in vscode Cannot open include file: 'stdio.h' - Visual Studio Community 2017 - C++ Error How to fix the error "Windows SDK version 8.1" was not found? Visual Studio 2017 errors on standard headers How do I check if a Key is pressed on C++

Examples related to string

How to split a string in two and store it in a field String method cannot be found in a main class method Kotlin - How to correctly concatenate a String Replacing a character from a certain index Remove quotes from String in Python Detect whether a Python string is a number or a letter How does String substring work in Swift How does String.Index work in Swift swift 3.0 Data to String? How to parse JSON string in Typescript

Examples related to enums

Enums in Javascript with ES6 Check if value exists in enum in TypeScript Why Python 3.6.1 throws AttributeError: module 'enum' has no attribute 'IntFlag'? TypeScript enum to object array How can I loop through enum values for display in radio buttons? How to get all values from python enum class? Get enum values as List of String in Java 8 enum to string in modern C++11 / C++14 / C++17 and future C++20 Implementing Singleton with an Enum (in Java) Swift: Convert enum value to String?

Examples related to c++17

How to enable C++17 compiling in Visual Studio? What are the new features in C++17? enum to string in modern C++11 / C++14 / C++17 and future C++20 Iterator invalidation rules What are Aggregates and PODs and how/why are they special?

Examples related to c++20

enum to string in modern C++11 / C++14 / C++17 and future C++20