Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/common/StringBijection.h
169678 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2011-2025 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
template< class T >
40
class StringBijection {
41
42
public:
43
44
#ifdef _MSC_VER
45
#pragma warning(push)
46
#pragma warning(disable:4510 4512 4610) // no default constructor and no assignment operator; conflicts with initializer
47
#endif
48
/// @brief bijection entry
49
struct Entry {
50
const std::string str;
51
const T key;
52
};
53
#ifdef _MSC_VER
54
#pragma warning(pop)
55
#endif
56
57
/// @brief default constructor
58
StringBijection() {}
59
60
/// @brief parameter constructor
61
StringBijection(Entry entries[], T terminatorKey, bool checkDuplicates = true) {
62
int i = 0;
63
do {
64
insert(entries[i].str, entries[i].key, checkDuplicates);
65
} while (entries[i++].key != terminatorKey);
66
}
67
68
/// @brief insert string and their associated key
69
void insert(const std::string str, const T key, bool checkDuplicates = true) {
70
if (checkDuplicates) {
71
if (has(key)) {
72
// cannot use toString(key) because that might create an infinite loop
73
throw InvalidArgument("Duplicate key.");
74
}
75
if (hasString(str)) {
76
throw InvalidArgument("Duplicate string '" + str + "'.");
77
}
78
}
79
myString2T[str] = key;
80
myT2String[key] = str;
81
}
82
83
/// @brief add alias to the given key
84
void addAlias(const std::string str, const T key) {
85
myString2T[str] = key;
86
}
87
88
/// @brief remove string
89
void remove(const std::string str, const T key) {
90
myString2T.erase(str);
91
myT2String.erase(key);
92
}
93
94
/// @brief get key
95
T get(const std::string& str) const {
96
if (hasString(str)) {
97
return myString2T.find(str)->second;
98
} else {
99
throw InvalidArgument("String '" + str + "' not found.");
100
}
101
}
102
103
/// @brief get string
104
const std::string& getString(const T key) const {
105
if (has(key)) {
106
return myT2String.find(key)->second;
107
} else {
108
// cannot use toString(key) because that might create an infinite loop
109
throw InvalidArgument("Key not found.");
110
}
111
}
112
113
/// @brief check if the given string exist
114
bool hasString(const std::string& str) const {
115
return myString2T.count(str) != 0;
116
}
117
118
/// @brief check if the given key exist
119
bool has(const T key) const {
120
return myT2String.count(key) != 0;
121
}
122
123
/// @brief get number of key-attributes
124
int size() const {
125
return (int)myString2T.size();
126
}
127
128
/// @brief get all strings
129
std::vector<std::string> getStrings() const {
130
std::vector<std::string> result;
131
for (auto item : myT2String) {
132
result.push_back(item.second);
133
}
134
return result;
135
}
136
137
/// @brief get all keys
138
std::vector<T> getValues() const {
139
std::vector<T> result;
140
for (auto item : myT2String) {
141
result.push_back(item.first);
142
}
143
return result;
144
}
145
146
/// @brief add the given list of keys
147
void addKeysInto(std::vector<T>& list) const {
148
typename std::map<T, std::string>::const_iterator it; // learn something new every day
149
for (it = myT2String.begin(); it != myT2String.end(); it++) {
150
list.push_back(it->first);
151
}
152
}
153
154
/// @brief get multiline string (all strings concatenated and separated by '\n')
155
/// @note this will be removed after unifying all FXFileDialog
156
std::string getMultilineString() const {
157
std::string result;
158
if (myT2String.size() > 0) {
159
for (auto item : myT2String) {
160
result.append(item.second + "\n");
161
}
162
result.pop_back();
163
}
164
return result;
165
}
166
167
private:
168
/// @brief map with the keys vinculated with strings
169
std::map<std::string, T> myString2T;
170
171
/// @brief map with the strings vinculated with keys
172
std::map<T, std::string> myT2String;
173
};
174
175