#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=8,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;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8bWFwPgoKCi8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjM2MTI5L2hvdy10by1zcGxpdC1hLXN0cmluZy1pbi1jCnN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiBzcGxpdChjb25zdCBzdGQ6OnN0cmluZyAmdGV4dCwgY2hhciBzZXApIHsKICAgIHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiB0b2tlbnM7CiAgICBzaXplX3Qgc3RhcnQgPSAwLCBlbmQgPSAwOwogICAgd2hpbGUgKChlbmQgPSB0ZXh0LmZpbmQoc2VwLCBzdGFydCkpICE9IHN0ZDo6c3RyaW5nOjpucG9zKSB7CiAgICAgICAgdG9rZW5zLnB1c2hfYmFjayh0ZXh0LnN1YnN0cihzdGFydCwgZW5kIC0gc3RhcnQpKTsKICAgICAgICBzdGFydCA9IGVuZCArIDE7CiAgICB9CiAgICB0b2tlbnMucHVzaF9iYWNrKHRleHQuc3Vic3RyKHN0YXJ0KSk7CiAgICByZXR1cm4gdG9rZW5zOwp9CgpzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz4gcGFyc2UoY29uc3QgY2hhciogYXJncykKewogICAgcmV0dXJuIHNwbGl0KGFyZ3MsICcsJyk7Cn0KCnN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiBwYXJzZShjb25zdCBjaGFyKiBhcmdzKTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIC4uLlRzPgpzdGQ6Om1hcDxULCBzdGQ6OnN0cmluZz4gbWFrZV9tYXAoY29uc3QgY2hhciogdGV4dCwgVHMuLi4gYXJncykKewogICAgc3RkOjp2ZWN0b3I8VD4ga2V5c3thcmdzLi4ufTsKICAgIHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiB2YWxzID0gcGFyc2UodGV4dCk7CiAgICBhdXRvIGsgPSBrZXlzLmNiZWdpbigpOwogICAgYXV0byB2ID0gdmFscy5jYmVnaW4oKTsKICAgIHN0ZDo6bWFwPFQsIHN0ZDo6c3RyaW5nPiByOwogICAgZm9yICg7IGsgIT0ga2V5cy5jZW5kKCk7IGsrKywgdisrKSB7CiAgICAgICAgci5lbXBsYWNlKCprLCAqdik7CiAgICB9CiAgICByZXR1cm4gcjsKCn0KCiNkZWZpbmUgRU5VTShuYW1lLCAuLi4pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCmVudW0gbmFtZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCnsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICBfX1ZBX0FSR1NfXyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCn07ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCnN0YXRpYyBzdGQ6OnN0cmluZyB0b19zdHJpbmcoY29uc3QgbmFtZSB2KSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICBzdGF0aWMgc3RkOjptYXA8bmFtZSwgc3RkOjpzdHJpbmc+IG0ge21ha2VfbWFwPG5hbWU+KCNfX1ZBX0FSR1NfXywgX19WQV9BUkdTX18pfTtcCiAgICByZXR1cm4gbS5hdCh2KTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCn0KCgpFTlVNKENvbG9yLCBSZWQsR3JlZW4sQmx1ZSkKbmFtZXNwYWNlIG5zIHsKRU5VTShBbGlnbm1lbnQsIExlZnQsUmlnaHQpCn0KCmNsYXNzIFgKewpwdWJsaWM6CiAgICBFTlVNKFksQT04LEIsQykKfTsKCgppbnQgbWFpbihpbnQgLCBjaGFyKiopCnsKICAgIHN0ZDo6Y291dCA8PCB0b19zdHJpbmcoUmVkKSA8PCB0b19zdHJpbmcoQmx1ZSk7CiAgICBzdGQ6OmNvdXQgPDwgdG9fc3RyaW5nKG5zOjpMZWZ0KSA8PCB0b19zdHJpbmcobnM6OlJpZ2h0KTsKICAgIHN0ZDo6Y291dCA8PCBYOjp0b19zdHJpbmcoWDo6QSkgPDwgWDo6dG9fc3RyaW5nKFg6OkIpOwogICAgcmV0dXJuIDA7Cn0K
prog.cpp: In static member function 'static std::string X::to_string(X::Y)':
prog.cpp:60:13: error: lvalue required as left operand of assignment
ENUM(Y,A=8,B,C)
^
prog.cpp:47:72: note: in definition of macro 'ENUM'
static std::map<name, std::string> m {make_map<name>(#__VA_ARGS__, __VA_ARGS__)};\
^
prog.cpp:47:84: error: no matching function for call to 'std::map<X::Y, std::basic_string<char> >::map(<brace-enclosed initializer list>)'
static std::map<name, std::string> m {make_map<name>(#__VA_ARGS__, __VA_ARGS__)};\
^
prog.cpp:60:5: note: in expansion of macro 'ENUM'
ENUM(Y,A=8,B,C)
^
In file included from /usr/include/c++/5/map:61:0,
from prog.cpp:4:
/usr/include/c++/5/bits/stl_map.h:273:9: note: candidate: template<class _InputIterator> std::map<_Key, _Tp, _Compare, _Alloc>::map(_InputIterator, _InputIterator, const _Compare&, const allocator_type&)
map(_InputIterator __first, _InputIterator __last,
^
/usr/include/c++/5/bits/stl_map.h:273:9: note: template argument deduction/substitution failed:
/usr/include/c++/5/bits/stl_map.h:256:9: note: candidate: template<class _InputIterator> std::map<_Key, _Tp, _Compare, _Alloc>::map(_InputIterator, _InputIterator)
map(_InputIterator __first, _InputIterator __last)
^
/usr/include/c++/5/bits/stl_map.h:256:9: note: template argument deduction/substitution failed:
/usr/include/c++/5/bits/stl_map.h:239:9: note: candidate: template<class _InputIterator> std::map<_Key, _Tp, _Compare, _Alloc>::map(_InputIterator, _InputIterator, const allocator_type&)
map(_InputIterator __first, _InputIterator __last,
^
/usr/include/c++/5/bits/stl_map.h:239:9: note: template argument deduction/substitution failed:
/usr/include/c++/5/bits/stl_map.h:233:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::map(std::initializer_list<std::pair<const _Key, _Tp> >, const allocator_type&) [with _Key = X::Y; _Tp = std::basic_string<char>; _Compare = std::less<X::Y>; _Alloc = std::allocator<std::pair<const X::Y, std::basic_string<char> > >; std::map<_Key, _Tp, _Compare, _Alloc>::allocator_type = std::allocator<std::pair<const X::Y, std::basic_string<char> > >]
map(initializer_list<value_type> __l, const allocator_type& __a)
^
/usr/include/c++/5/bits/stl_map.h:233:7: note: candidate expects 2 arguments, 1 provided
/usr/include/c++/5/bits/stl_map.h:227:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::map(std::map<_Key, _Tp, _Compare, _Alloc>&&, const allocator_type&) [with _Key = X::Y; _Tp = std::basic_string<char>; _Compare = std::less<X::Y>; _Alloc = std::allocator<std::pair<const X::Y, std::basic_string<char> > >; std::map<_Key, _Tp, _Compare, _Alloc>::allocator_type = std::allocator<std::pair<const X::Y, std::basic_string<char> > >]
map(map&& __m, const allocator_type& __a)
^
/usr/include/c++/5/bits/stl_map.h:227:7: note: candidate expects 2 arguments, 1 provided
/usr/include/c++/5/bits/stl_map.h:223:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::map(const std::map<_Key, _Tp, _Compare, _Alloc>&, const allocator_type&) [with _Key = X::Y; _Tp = std::basic_string<char>; _Compare = std::less<X::Y>; _Alloc = std::allocator<std::pair<const X::Y, std::basic_string<char> > >; std::map<_Key, _Tp, _Compare, _Alloc>::allocator_type = std::allocator<std::pair<const X::Y, std::basic_string<char> > >]
map(const map& __m, const allocator_type& __a)
^
/usr/include/c++/5/bits/stl_map.h:223:7: note: candidate expects 2 arguments, 1 provided
/usr/include/c++/5/bits/stl_map.h:219:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::map(const allocator_type&) [with _Key = X::Y; _Tp = std::basic_string<char>; _Compare = std::less<X::Y>; _Alloc = std::allocator<std::pair<const X::Y, std::basic_string<char> > >; std::map<_Key, _Tp, _Compare, _Alloc>::allocator_type = std::allocator<std::pair<const X::Y, std::basic_string<char> > >]
map(const allocator_type& __a)
^
/usr/include/c++/5/bits/stl_map.h:219:7: note: conversion of argument 1 would be ill-formed:
/usr/include/c++/5/bits/stl_map.h:211:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::map(std::initializer_list<std::pair<const _Key, _Tp> >, const _Compare&, const allocator_type&) [with _Key = X::Y; _Tp = std::basic_string<char>; _Compare = std::less<X::Y>; _Alloc = std::allocator<std::pair<const X::Y, std::basic_string<char> > >; std::map<_Key, _Tp, _Compare, _Alloc>::allocator_type = std::allocator<std::pair<const X::Y, std::basic_string<char> > >]
map(initializer_list<value_type> __l,
^
/usr/include/c++/5/bits/stl_map.h:211:7: note: conversion of argument 1 would be ill-formed:
/usr/include/c++/5/bits/stl_map.h:196:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::map(std::map<_Key, _Tp, _Compare, _Alloc>&&) [with _Key = X::Y; _Tp = std::basic_string<char>; _Compare = std::less<X::Y>; _Alloc = std::allocator<std::pair<const X::Y, std::basic_string<char> > >]
map(map&& __x)
^
/usr/include/c++/5/bits/stl_map.h:196:7: note: conversion of argument 1 would be ill-formed:
/usr/include/c++/5/bits/stl_map.h:185:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::map(const std::map<_Key, _Tp, _Compare, _Alloc>&) [with _Key = X::Y; _Tp = std::basic_string<char>; _Compare = std::less<X::Y>; _Alloc = std::allocator<std::pair<const X::Y, std::basic_string<char> > >]
map(const map& __x)
^
/usr/include/c++/5/bits/stl_map.h:185:7: note: conversion of argument 1 would be ill-formed:
/usr/include/c++/5/bits/stl_map.h:174:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::map(const _Compare&, const allocator_type&) [with _Key = X::Y; _Tp = std::basic_string<char>; _Compare = std::less<X::Y>; _Alloc = std::allocator<std::pair<const X::Y, std::basic_string<char> > >; std::map<_Key, _Tp, _Compare, _Alloc>::allocator_type = std::allocator<std::pair<const X::Y, std::basic_string<char> > >]
map(const _Compare& __comp,
^
/usr/include/c++/5/bits/stl_map.h:174:7: note: conversion of argument 1 would be ill-formed:
/usr/include/c++/5/bits/stl_map.h:162:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::map() [with _Key = X::Y; _Tp = std::basic_string<char>; _Compare = std::less<X::Y>; _Alloc = std::allocator<std::pair<const X::Y, std::basic_string<char> > >]
map()
^
/usr/include/c++/5/bits/stl_map.h:162:7: note: candidate expects 0 arguments, 1 provided