- #include <iostream> 
- #include <utility> 
- #include <map> 
- #include <string> 
- #include <initializer_list> 
- #include <cstring> 
- #include <stdexcept> 
-   
- namespace LiteralSwitch { 
-   
- // simple hash function 
- constexpr unsigned int dbj2Hash(const char* str, size_t size, int index = 0) 
- { 
-     return !str[index] ? 0x1505 : (dbj2Hash(str, size, index + 1) * 0x21) ^ str[index]; 
- } 
-   
-   
- // Create a literal type for short-hand case strings 
- constexpr unsigned int operator"" _C ( const char str[], size_t size) 
- { 
-     return dbj2Hash(str, size - 1); 
- } 
-   
-   
- struct CaseLabel 
- { 
-     typedef const char* label_type; 
-     typedef uint32_t    value_type; 
-     typedef std::pair<const label_type, value_type>  store_type; 
-   
-     constexpr CaseLabel(const char* str) 
-         :   data_(std::make_pair(str, dbj2Hash(str, strlen(str)))) 
-     { 
-     } 
-   
-     constexpr operator value_type() const { return data_.second; } 
-     constexpr operator label_type() const { return data_.first; } 
-     constexpr operator store_type() const { return data_; } 
-   
- private: 
-   
-     const store_type data_; 
- }; 
- struct  compare { 
-     bool operator()(const char *left, const char *right) const 
-     { 
-         return strcmp(left, right) < 0; 
-     } 
- }; 
-   
- struct CaseLabelSet 
-         : private std::map<CaseLabel::label_type, CaseLabel::value_type, compare> 
- { 
-     CaseLabelSet(std::initializer_list<CaseLabel> values) 
-     { 
-         for(auto x : values) insert(x); 
-     } 
-   
-     CaseLabel::value_type operator()(const std::string& label) const 
-     { 
-         return operator()(label.c_str()); 
-     } 
-     CaseLabel::value_type operator()(const char* label) const 
-     { 
-         auto it = find(label); 
-         if(it == end()) 
-         { 
-             throw std::invalid_argument("Case label not found"); 
-         } 
-   
-         return it->second; 
-     } 
- }; 
-   
- } 
-   
- using namespace LiteralSwitch; 
-   
- void Test(const std::string& cond) 
- { 
-     static const CaseLabelSet setValues = {"Hello", "World"}; 
-   
-     try 
-     { 
-         switch(setValues(cond)) 
-         { 
-         case "Hello"_C: std::cout << "Goodbye"; break; 
-         case "World"_C: std::cout << "Planet"; break; 
-         default: std::cout << "BOGUS!"; 
-   
-         } 
-         std::cout << std::endl; 
-     } 
-     catch(std::invalid_argument) 
-     { 
-         std::cout << "exception on unknown switch/case value. should go to default" << std::endl; 
-     } 
- } 
-   
-   
- int main() 
- { 
-     Test("Hello"); 
-     Test("World"); 
-     Test("hello"); 
- } 
-