1 /****************************************************************************/ 2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo 3 // Copyright (C) 2011-2019 German Aerospace Center (DLR) and others. 4 // This program and the accompanying materials 5 // are made available under the terms of the Eclipse Public License v2.0 6 // which accompanies this distribution, and is available at 7 // http://www.eclipse.org/legal/epl-v20.html 8 // SPDX-License-Identifier: EPL-2.0 9 /****************************************************************************/ 10 /// @file StringBijection.h 11 /// @author Daniel Krajzewicz 12 /// @author Michael Behrisch 13 /// @author Jakob Erdmann 14 /// @date Mar 2011 15 /// @version $Id$ 16 /// 17 // Bidirectional map between string and something else 18 /****************************************************************************/ 19 #ifndef StringBijection_h 20 #define StringBijection_h 21 22 23 // =========================================================================== 24 // included modules 25 // =========================================================================== 26 27 #include <iostream> 28 #include <map> 29 #include <vector> 30 #include <string> 31 #include <utils/common/UtilExceptions.h> 32 33 // =========================================================================== 34 // class definitions 35 // =========================================================================== 36 /** 37 * Template container for maintaining a bidirectional map between strings and something else 38 * It is not always a bijection since it allows for duplicate entries on both sides if either 39 * checkDuplicates is set to false in the constructor or the insert function or if 40 * the addAlias function is used. 41 */ 42 43 template< class T > 44 class StringBijection { 45 46 public: 47 48 #ifdef _MSC_VER 49 #pragma warning(push) 50 #pragma warning(disable:4510 4512 4610) // no default constructor and no assignment operator; conflicts with initializer 51 #endif 52 struct Entry { 53 const char* str; 54 const T key; 55 }; 56 #ifdef _MSC_VER 57 #pragma warning(pop) 58 #endif 59 60 StringBijection()61 StringBijection() {} 62 63 64 StringBijection(Entry entries[], T terminatorKey, bool checkDuplicates = true) { 65 int i = 0; 66 do { 67 insert(entries[i].str, entries[i].key, checkDuplicates); 68 } while (entries[i++].key != terminatorKey); 69 } 70 71 72 void insert(const std::string str, const T key, bool checkDuplicates = true) { 73 if (checkDuplicates) { 74 if (has(key)) { 75 // cannot use toString(key) because that might create an infinite loop 76 throw InvalidArgument("Duplicate key."); 77 } 78 if (hasString(str)) { 79 throw InvalidArgument("Duplicate string '" + str + "'."); 80 } 81 } 82 myString2T[str] = key; 83 myT2String[key] = str; 84 } 85 86 addAlias(const std::string str,const T key)87 void addAlias(const std::string str, const T key) { 88 myString2T[str] = key; 89 } 90 91 remove(const std::string str,const T key)92 void remove(const std::string str, const T key) { 93 myString2T.erase(str); 94 myT2String.erase(key); 95 } 96 97 get(const std::string & str)98 T get(const std::string& str) const { 99 if (hasString(str)) { 100 return myString2T.find(str)->second; 101 } else { 102 throw InvalidArgument("String '" + str + "' not found."); 103 } 104 } 105 106 getString(const T key)107 const std::string& getString(const T key) const { 108 if (has(key)) { 109 return myT2String.find(key)->second; 110 } else { 111 // cannot use toString(key) because that might create an infinite loop 112 throw InvalidArgument("Key not found."); 113 } 114 } 115 116 hasString(const std::string & str)117 bool hasString(const std::string& str) const { 118 return myString2T.count(str) != 0; 119 } 120 121 has(const T key)122 bool has(const T key) const { 123 return myT2String.count(key) != 0; 124 } 125 126 size()127 int size() const { 128 return (int)myString2T.size(); 129 } 130 131 getStrings()132 std::vector<std::string> getStrings() const { 133 std::vector<std::string> result; 134 typename std::map<T, std::string>::const_iterator it; // learn something new every day 135 for (it = myT2String.begin(); it != myT2String.end(); it++) { 136 result.push_back(it->second); 137 } 138 return result; 139 } 140 141 addKeysInto(std::vector<T> & list)142 void addKeysInto(std::vector<T>& list) const { 143 typename std::map<T, std::string>::const_iterator it; // learn something new every day 144 for (it = myT2String.begin(); it != myT2String.end(); it++) { 145 list.push_back(it->first); 146 } 147 } 148 149 150 private: 151 std::map<std::string, T> myString2T; 152 std::map<T, std::string> myT2String; 153 154 }; 155 156 #endif 157 158 /****************************************************************************/ 159 160