text: /**
   *
   *
   * Description: see header file.
   *
   *
   * \author: Vasile Mihai Ghete - HEPHY Vienna
   *          Vladimir Rekovic - extend for overlap removal
   *
   * $Date$
   * $Revision$
   *
   */
  
  // this class header
  #include "L1Trigger/L1TGlobal/interface/GlobalDefinitions.h"
  
  // system include files
  #include <cstring>
  
  // user include files
  #include "FWCore/MessageLogger/interface/MessageLogger.h"
  namespace {
  template <class T>
  struct entry {                                                                                                                                                    
    char const* label;
    T           value;
  };
  
  constexpr bool same(char const *x, char const *y) {
    return !*x && !*y     ? true                                                                                                                                
         : /* default */    (*x == *y && same(x+1, y+1));                                                                                                       
  }
  
  template <class T>
  constexpr T keyToValue(char const *label, entry<T> const *entries) {                                                                                  
    return !entries->label ? entries->value                         
         : same(entries->label, label) ? entries->value
         : /*default*/                   keyToValue(label, entries+1);                                                                                 
  }
  
  template <class T>
  constexpr char const*valueToKey(T value, entry<T> const *entries) {
    return !entries->label ? entries->label
         : entries->value == value ? entries->label
         : /*default*/       valueToKey(value, entries+1);
  }
  constexpr entry<l1t::L1GtBoardType> l1GtBoardTypeStringToEnumMap[] = {
              {"l1t::MP7", l1t::MP7},
              {"l1t::BoardNull", l1t::BoardNull},
              {nullptr, (l1t::L1GtBoardType)-1}
  };
  
  
  // l1t::GtConditionType
  constexpr entry<l1t::GtConditionType> l1GtConditionTypeStringToEnumMap[] = {
          {"l1t::TypeNull", l1t::TypeNull},
          {"l1t::Type1s", l1t::Type1s},
          {"l1t::Type2s", l1t::Type2s},
          {"l1t::Type2wsc", l1t::Type2wsc},
          {"l1t::Type2cor", l1t::Type2cor},
          {"l1t::Type3s", l1t::Type3s},
          {"l1t::Type4s", l1t::Type4s},
          {"l1t::TypeETM", l1t::TypeETM},
          {"l1t::TypeETT", l1t::TypeETT},
          {"l1t::TypeHTT", l1t::TypeHTT},
          {"l1t::TypeHTM", l1t::TypeHTM},
  	{"l1t::TypeETMHF", l1t::TypeETMHF},
  	{"l1t::TypeTowerCount", l1t::TypeTowerCount},
  	{"l1t::TypeMinBiasHFP0", l1t::TypeMinBiasHFP0},
  	{"l1t::TypeMinBiasHFM0", l1t::TypeMinBiasHFM0},
  	{"l1t::TypeMinBiasHFP1", l1t::TypeMinBiasHFP1},
  	{"l1t::TypeMinBiasHFM1", l1t::TypeMinBiasHFM1},
          {"l1t::TypeExternal", l1t::TypeExternal},
          {nullptr, (l1t::GtConditionType) - 1},
          {"l1t::Type2corWithOverlapRemoval", l1t::Type2corWithOverlapRemoval},
  	{"l1t::TypeCent0", l1t::TypeCent0},
  	{"l1t::TypeCent1", l1t::TypeCent1},
  	{"l1t::TypeCent2", l1t::TypeCent2},
  	{"l1t::TypeCent3", l1t::TypeCent3},
  	{"l1t::TypeCent4", l1t::TypeCent4},
  	{"l1t::TypeCent5", l1t::TypeCent5},
  	{"l1t::TypeCent6", l1t::TypeCent6},
  	{"l1t::TypeCent7", l1t::TypeCent7},
  	{"l1t::TypeAsymEt", l1t::TypeAsymEt},
  	{"l1t::TypeAsymHt", l1t::TypeAsymHt},
  	{"l1t::TypeAsymEtHF", l1t::TypeAsymEtHF},
  	{"l1t::TypeAsymHtHF", l1t::TypeAsymHtHF}
  };
  
  // l1t::GtConditionCategory
  constexpr entry<l1t::GtConditionCategory> l1GtConditionCategoryStringToEnumMap[] = {
    {"l1t::CondNull", l1t::CondNull},
    {"l1t::CondMuon", l1t::CondMuon},
    {"l1t::CondCalo", l1t::CondCalo},
    {"l1t::CondEnergySum", l1t::CondEnergySum},
    {"l1t::CondCorrelation", l1t::CondCorrelation},
    {"l1t::CondExternal", l1t::CondExternal},
    {nullptr, (l1t::GtConditionCategory) - 1},
    {"l1t::CondCorrelationWithOverlapRemoval", l1t::CondCorrelationWithOverlapRemoval}
  };
  
  }
  // l1t::L1GtBoardType
  l1t::L1GtBoardType l1t::l1GtBoardTypeStringToEnum(const std::string& label) {
      l1t::L1GtBoardType value = keyToValue(label.c_str(), l1GtBoardTypeStringToEnumMap);
      if (value == (l1t::L1GtBoardType) - 1) {
          edm::LogInfo("L1TGlobal") << "\n  '" << label
                  << "' is not a recognized l1t::L1GtBoardType. \n  Return l1t::BoardNull.";
          value = l1t::BoardNull;
      }
  
      if (value == l1t::BoardNull) {
          edm::LogInfo("L1TGlobal")
                  << "\n  l1t::BoardNull means no valid board type defined!";
      }
  
      return value;
  }
  
  std::string l1t::l1GtBoardTypeEnumToString(const l1t::L1GtBoardType& boardType) {
      char const *result= valueToKey(boardType, l1GtBoardTypeStringToEnumMap);
      if (boardType == l1t::BoardNull) {
          edm::LogInfo("L1TGlobal")
                  << "\n  l1t::BoardNull means no valid board type defined!";
      }
      if (!result) {
        edm::LogInfo("L1TGlobal") << "\n  '" << boardType
                    << "' is not a recognized l1t::L1GtBoardType. "
                    << "\n  Return l1t::BoardNull, which means no valid board type defined!";
        return "l1t::BoardNull";
      }
      return result;
  }
  
  
  
  
  
  l1t::GtConditionType l1t::l1GtConditionTypeStringToEnum(const std::string& label) {
      l1t::GtConditionType value = keyToValue(label.c_str(), l1GtConditionTypeStringToEnumMap);
  
      // in case of unrecognized l1t::GtConditionType, return l1t::TypeNull
      // to be dealt by the corresponding module
      if (value == (l1t::GtConditionType) -1) {
          edm::LogInfo("L1TGlobal")  << "\n  '" << label
                  << "' is not a recognized l1t::GtConditionType. \n  Return l1t::TypeNull.";
  
          value = l1t::TypeNull;
      }
  
      if (value == l1t::TypeNull) {
          edm::LogInfo("L1TGlobal")
                  << "\n  l1t::TypeNull means no valid condition type defined!";
      }
  
      return value;
  }
  
  std::string l1t::l1GtConditionTypeEnumToString(const l1t::GtConditionType& conditionType) {
    const char *result = valueToKey(conditionType, l1GtConditionTypeStringToEnumMap);
    if (conditionType == l1t::TypeNull)
      edm::LogInfo("L1TGlobal") 
        << "\n  Return l1t::TypeNull, which means no valid condition type defined!";
    if (!result) {
      result = "l1t::TypeNull";
      edm::LogInfo("L1TGlobal") << "\n  '" << conditionType
              << "' is not a recognized l1t::GtConditionType. "
              << "\n  Return l1t::TypeNull, which means no valid condition type defined!";
    }
    return result;
  }
  
  l1t::GtConditionCategory l1t::l1GtConditionCategoryStringToEnum(const std::string& label) {
    l1t::GtConditionCategory value = keyToValue(label.c_str(), l1GtConditionCategoryStringToEnumMap);
    // in case of unrecognized l1t::GtConditionCategory, return l1t::CondNull
    // to be dealt by the corresponding module
    if (value == (l1t::GtConditionCategory) -1) {
      edm::LogInfo("L1TGlobal") << "\n  '" << label
              << "' is not a recognized l1t::GtConditionCategory. \n  Return l1t::CondNull.";
  
      value = l1t::CondNull;
    }
  
    if (value == l1t::CondNull) {
        edm::LogInfo("L1TGlobal")
                << "\n  l1t::CondNull means no valid condition category defined!";
    }
  
    return value;
  }
  
  std::string l1t::l1GtConditionCategoryEnumToString(const l1t::GtConditionCategory& conditionCategory) {
    char const *result = valueToKey(conditionCategory, l1GtConditionCategoryStringToEnumMap);
    if (conditionCategory == l1t::CondNull)
      edm::LogInfo("L1TGlobal")
              << "\n  Return l1t::CondNull, which means no valid condition category defined!";
      
    if (!result) {
      result = "l1t::CondNull";
      edm::LogInfo("L1TGlobal") << "\n  '" << conditionCategory
              << "' is not a recognized l1t::GtConditionCategory. "
              << "\n  Return l1t::CondNull, which means no valid condition category defined!";
    }
  
    return result;
  }
  