#include<cassert>
#include<iostream>
#include<string>
#define CONCATE_(X,Y) X##Y
#define CONCATE(X,Y) CONCATE_(X,Y)
#define UNIQUE(NAME) CONCATE(NAME, __LINE__)
#define MSVC_BUG(MACRO, ARGS) MACRO ARGS
#define NUM_ARGS_2(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, TOTAL, ...) TOTAL
#define NUM_ARGS_1(...) MSVC_BUG(NUM_ARGS_2, (__VA_ARGS__))
#define NUM_ARGS(...) NUM_ARGS_1(__VA_ARGS__, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define VA_MACRO(MACRO, ...) MSVC_BUG(CONCATE, (MACRO, NUM_ARGS(__VA_ARGS__)))(__VA_ARGS__)
#define switch_(X) for(struct { static_assert(not std::is_pointer<decltype(X)>::value, "No Pointers!"); \
const decltype(X)& VALUE_; enum { CASES, DEFAULT, COMPARED } IS_=CASES; } VAR_{X}; \
VAR_.IS_ != VAR_.COMPARED; \
VAR_.IS_ == VAR_.DEFAULT or (VAR_.IS_ = VAR_.COMPARED))
#define default_ {}} if(VAR_.IS_ == VAR_.COMPARED or VAR_.IS_ == VAR_.DEFAULT or \
((VAR_.IS_ = VAR_.DEFAULT) and false)) \
{ VAR_.IS_ = VAR_.COMPARED; CONCATE(default,__LINE__)
#define case_(...) VA_MACRO(case_, __VA_ARGS__)
#define case_1(X) {}} if(VAR_.IS_ == VAR_.COMPARED or VAR_.VALUE_ == X) \
{ VAR_.IS_ = VAR_.COMPARED; CONCATE(case,__LINE__)
#define case_2(X,OP) {}} if(VAR_.IS_ == VAR_.COMPARED or VAR_.VALUE_ OP X) \
{ VAR_.IS_ = VAR_.COMPARED; CONCATE(case,__LINE__)
struct X {
std::string s;
bool operator== (const X& other) const { return s == other.s; }
bool operator== (const std::string& other) const { return s == other; }
};
int main ()
try
{
X x1{"Hello"}, x2{"World"};
switch_(x1)
{{
case_("Hello"): std::cout << "Compared 'Hello'\n"; break;
case_("None"):
default_: std::cout << "Compared 'Default'\n";
case_(x2): { std::cout << "Compared 'World'\n"; break; }
case_("World"): { std::cout << "Duplicate 'World' again!\n"; break; }
}}
}
catch(std::exception& e) { std::cout << "Error: " << e.what() << "\n"; }
I2luY2x1ZGU8Y2Fzc2VydD4KI2luY2x1ZGU8aW9zdHJlYW0+CiNpbmNsdWRlPHN0cmluZz4KCgojZGVmaW5lIENPTkNBVEVfKFgsWSkgWCMjWQojZGVmaW5lIENPTkNBVEUoWCxZKSBDT05DQVRFXyhYLFkpCiNkZWZpbmUgVU5JUVVFKE5BTUUpIENPTkNBVEUoTkFNRSwgX19MSU5FX18pCgojZGVmaW5lIE1TVkNfQlVHKE1BQ1JPLCBBUkdTKSBNQUNSTyBBUkdTCiNkZWZpbmUgTlVNX0FSR1NfMihfMSwgXzIsIF8zLCBfNCwgXzUsIF82LCBfNywgXzgsIF85LCBfMTAsIF8xMSwgXzEyLCBfMTMsIF8xNCwgVE9UQUwsIC4uLikgVE9UQUwKI2RlZmluZSBOVU1fQVJHU18xKC4uLikgTVNWQ19CVUcoTlVNX0FSR1NfMiwgKF9fVkFfQVJHU19fKSkKI2RlZmluZSBOVU1fQVJHUyguLi4pIE5VTV9BUkdTXzEoX19WQV9BUkdTX18sIDE0LCAxMywgMTIsIDExLCAxMCwgOSwgOCwgNywgNiwgNSwgNCwgMywgMiwgMSkKI2RlZmluZSBWQV9NQUNSTyhNQUNSTywgLi4uKSBNU1ZDX0JVRyhDT05DQVRFLCAoTUFDUk8sIE5VTV9BUkdTKF9fVkFfQVJHU19fKSkpKF9fVkFfQVJHU19fKQoKI2RlZmluZSBzd2l0Y2hfKFgpIGZvcihzdHJ1Y3QgeyBzdGF0aWNfYXNzZXJ0KG5vdCBzdGQ6OmlzX3BvaW50ZXI8ZGVjbHR5cGUoWCk+Ojp2YWx1ZSwgIk5vIFBvaW50ZXJzISIpOyBcCiAgICAgICAgICAgICAgICBjb25zdCBkZWNsdHlwZShYKSYgVkFMVUVfOyBlbnVtIHsgQ0FTRVMsIERFRkFVTFQsIENPTVBBUkVEIH0gSVNfPUNBU0VTOyB9IFZBUl97WH07IFwKICAgICAgICAgICAgICAgICAgICAgICBWQVJfLklTXyAhPSBWQVJfLkNPTVBBUkVEOyBcCiAgICAgICAgICAgICAgICAgICAgICAgVkFSXy5JU18gPT0gVkFSXy5ERUZBVUxUIG9yIChWQVJfLklTXyA9IFZBUl8uQ09NUEFSRUQpKQoKI2RlZmluZSBkZWZhdWx0XyB7fX0gaWYoVkFSXy5JU18gPT0gVkFSXy5DT01QQVJFRCBvciBWQVJfLklTXyA9PSBWQVJfLkRFRkFVTFQgb3IgXAogICAgICAgICAgICAgICAgICAgICAgICAoKFZBUl8uSVNfID0gVkFSXy5ERUZBVUxUKSBhbmQgZmFsc2UpKSBcCiAgICAgICAgICAgICAgICAgICAgIHsgVkFSXy5JU18gPSBWQVJfLkNPTVBBUkVEOyBDT05DQVRFKGRlZmF1bHQsX19MSU5FX18pCgojZGVmaW5lIGNhc2VfKC4uLikgVkFfTUFDUk8oY2FzZV8sIF9fVkFfQVJHU19fKQojZGVmaW5lIGNhc2VfMShYKSAgICB7fX0gaWYoVkFSXy5JU18gPT0gVkFSXy5DT01QQVJFRCBvciBWQVJfLlZBTFVFXyA9PSBYKSBcCiAgICAgICAgICAgICAgICAgICAgICAgICB7IFZBUl8uSVNfID0gVkFSXy5DT01QQVJFRDsgQ09OQ0FURShjYXNlLF9fTElORV9fKQojZGVmaW5lIGNhc2VfMihYLE9QKSB7fX0gaWYoVkFSXy5JU18gPT0gVkFSXy5DT01QQVJFRCBvciBWQVJfLlZBTFVFXyBPUCBYKSBcCiAgICAgICAgICAgICAgICAgICAgICAgICB7IFZBUl8uSVNfID0gVkFSXy5DT01QQVJFRDsgQ09OQ0FURShjYXNlLF9fTElORV9fKQoKc3RydWN0IFggeyAKICBzdGQ6OnN0cmluZyBzOwogIGJvb2wgb3BlcmF0b3I9PSAoY29uc3QgWCYgb3RoZXIpIGNvbnN0IHsgcmV0dXJuIHMgPT0gb3RoZXIuczsgfQogIGJvb2wgb3BlcmF0b3I9PSAoY29uc3Qgc3RkOjpzdHJpbmcmIG90aGVyKSBjb25zdCB7IHJldHVybiBzID09IG90aGVyOyB9Cn07CgppbnQgbWFpbiAoKQp0cnkKeyAKICBYIHgxeyJIZWxsbyJ9LCB4MnsiV29ybGQifTsKICBzd2l0Y2hfKHgxKQogIHt7CiAgY2FzZV8oIkhlbGxvIik6ICAgc3RkOjpjb3V0IDw8ICJDb21wYXJlZCAnSGVsbG8nXG4iOyBicmVhazsKICBjYXNlXygiTm9uZSIpOgogIGRlZmF1bHRfOiAgICAgICAgIHN0ZDo6Y291dCA8PCAiQ29tcGFyZWQgJ0RlZmF1bHQnXG4iOyAKICBjYXNlXyh4Mik6ICAgICAgeyBzdGQ6OmNvdXQgPDwgIkNvbXBhcmVkICdXb3JsZCdcbiI7IGJyZWFrOyB9CiAgY2FzZV8oIldvcmxkIik6IHsgc3RkOjpjb3V0IDw8ICJEdXBsaWNhdGUgJ1dvcmxkJyBhZ2FpbiFcbiI7IGJyZWFrOyB9CiAgfX0KfQpjYXRjaChzdGQ6OmV4Y2VwdGlvbiYgZSkgeyBzdGQ6OmNvdXQgPDwgIkVycm9yOiAiIDw8IGUud2hhdCgpIDw8ICJcbiI7IH0K