fork download
  1. #include<cassert>
  2. #include<iostream>
  3. #include<string>
  4.  
  5.  
  6. #define CONCATE_(X,Y) X##Y
  7. #define CONCATE(X,Y) CONCATE_(X,Y)
  8. #define UNIQUE(NAME) CONCATE(NAME, __LINE__)
  9.  
  10. #define MSVC_BUG(MACRO, ARGS) MACRO ARGS
  11. #define NUM_ARGS_2(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, TOTAL, ...) TOTAL
  12. #define NUM_ARGS_1(...) MSVC_BUG(NUM_ARGS_2, (__VA_ARGS__))
  13. #define NUM_ARGS(...) NUM_ARGS_1(__VA_ARGS__, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
  14. #define VA_MACRO(MACRO, ...) MSVC_BUG(CONCATE, (MACRO, NUM_ARGS(__VA_ARGS__)))(__VA_ARGS__)
  15.  
  16. #define switch_(X) for(struct { static_assert(not std::is_pointer<decltype(X)>::value, "No Pointers!"); \
  17.   const decltype(X)& VALUE_; enum { CASES, DEFAULT, COMPARED } IS_=CASES; } VAR_{X}; \
  18.   VAR_.IS_ != VAR_.COMPARED; \
  19.   VAR_.IS_ == VAR_.DEFAULT or (VAR_.IS_ = VAR_.COMPARED))
  20.  
  21. #define default_ {}} if(VAR_.IS_ == VAR_.COMPARED or VAR_.IS_ == VAR_.DEFAULT or \
  22.   ((VAR_.IS_ = VAR_.DEFAULT) and false)) \
  23.   { VAR_.IS_ = VAR_.COMPARED; CONCATE(default,__LINE__)
  24.  
  25. #define case_(...) VA_MACRO(case_, __VA_ARGS__)
  26. #define case_1(X) {}} if(VAR_.IS_ == VAR_.COMPARED or VAR_.VALUE_ == X) \
  27.   { VAR_.IS_ = VAR_.COMPARED; CONCATE(case,__LINE__)
  28. #define case_2(X,OP) {}} if(VAR_.IS_ == VAR_.COMPARED or VAR_.VALUE_ OP X) \
  29.   { VAR_.IS_ = VAR_.COMPARED; CONCATE(case,__LINE__)
  30.  
  31. struct X {
  32. std::string s;
  33. bool operator== (const X& other) const { return s == other.s; }
  34. bool operator== (const std::string& other) const { return s == other; }
  35. };
  36.  
  37. int main ()
  38. try
  39. {
  40. X x1{"Hello"}, x2{"World"};
  41. switch_(x1)
  42. {{
  43. case_("Hello"): std::cout << "Compared 'Hello'\n"; break;
  44. case_("None"):
  45. default_: std::cout << "Compared 'Default'\n";
  46. case_(x2): { std::cout << "Compared 'World'\n"; break; }
  47. case_("World"): { std::cout << "Duplicate 'World' again!\n"; break; }
  48. }}
  49. }
  50. catch(std::exception& e) { std::cout << "Error: " << e.what() << "\n"; }
  51.  
Success #stdin #stdout 0.01s 5548KB
stdin
Standard input is empty
stdout
Compared 'Hello'