#pragma once
// ----------------------------------------------------------------------------
// string_switch_case.h
//
// These macros together implement switch-case functionality for C strings and
// std::string. When first encountered, the switch-case structure does two
// passes. The first pass is a one-time initialization of a std::map with the
// strings as keys, and line numbers as values, to get the unique keys needed
// for a numeric switch-case. All subsequent passes use the std::map to
// retrieve an unsigned integer for a given string, that was mapped during the
// first pass, to use for a numeric switch case. This switch-case approach can
// be used repeatedly and even nested. An example of the usage is as follows:
//
// switch_string(a)
// {
// case_string("first string")
// printf("first string");
// break;
// case_string("second string")
// printf("second string");
// case_string("third string")
// printf("falls through to third string");
// break;
// default_case_string
// printf("default");
// }
// end_switch_string
//
// The end_switch_string macro is required after the closing brace of the
// switch-case structure. Each case_string statement must be on a unique line.
// Each case_string has its own local scope. A case_string statement is
// ignored if declared within scope brackets beneath a sibling case statement.
// ----------------------------------------------------------------------------
#include <map>
#include <string>
// switch macro
#define switch_string(a) while (true) { static std::map<std::string, unsigned int> _string_lookup_; static bool _init_ = true; unsigned int _val_ = 0; if (!_init_) { std::map<std::string, unsigned int>::iterator _iter_ = _string_lookup_.find(a); if (_iter_ != _string_lookup_.end()) { _val_ = (*_iter_).second; } else { _val_ = 0xffffffff; } } switch(_val_) { case 0:
// case macro
#define case_string(a) } case __LINE__: if (_init_) _string_lookup_.insert (std::pair<std::string, unsigned int>(a, __LINE__)); else {
// default case macro
#define default_case_string } default: if (!_init_) {
// required macro for the end of the switch-case
#define end_switch_string } if (_init_) { _init_ = false; } else { break; } }