#include <iostream>
#include <string>
#include <vector>
#include <map>


// http://stackoverflow.com/questions/236129/how-to-split-a-string-in-c
std::vector<std::string> split(const std::string &text, char sep) {
    std::vector<std::string> tokens;
    size_t start = 0, end = 0;
    while ((end = text.find(sep, start)) != std::string::npos) {
        tokens.push_back(text.substr(start, end - start));
        start = end + 1;
    }
    tokens.push_back(text.substr(start));
    return tokens;
}

std::vector<std::string> parse(const char* args)
{
    return split(args, ',');
}

std::vector<std::string> parse(const char* args);

template<typename T, typename ...Ts>
std::map<T, std::string> make_map(const char* text, Ts... args)
{
    std::vector<T> keys{args...};
    std::vector<std::string> vals = parse(text);
    auto k = keys.cbegin();
    auto v = vals.cbegin();
    std::map<T, std::string> r;
    for (; k != keys.cend(); k++, v++) {
        r.emplace(*k, *v);
    }
    return r;

}

#define ENUM(name, ...)                                                              \
enum name                                                                            \
{                                                                                    \
    __VA_ARGS__                                                                      \
};                                                                                   \
static std::string to_string(const name v) {                                         \
    static std::map<name, std::string> m {make_map<name>(#__VA_ARGS__, __VA_ARGS__)};\
    return m.at(v);                                                                  \
}


ENUM(Color, Red,Green,Blue)
namespace ns {
ENUM(Alignment, Left,Right)
}

class X
{
public:
    ENUM(Y,A,B,C)
};


int main(int , char**)
{
    std::cout << to_string(Red) << to_string(Blue);
    std::cout << to_string(ns::Left) << to_string(ns::Right);
    std::cout << X::to_string(X::A) << X::to_string(X::B);
    return 0;
}
