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