Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/common/SequentialStringBijection.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 SequentialStringBijection.h
15
/// @author Jakob Erdmann
16
/// @date June 2024
17
///
18
// Bidirectional map between string and sequential interger-like-keys (i.e. default enum values)
19
20
/****************************************************************************/
21
#pragma once
22
#include <config.h>
23
#include <iostream>
24
#include <map>
25
#include <vector>
26
#include <string>
27
#include <utils/common/UtilExceptions.h>
28
29
// ===========================================================================
30
// class definitions
31
// ===========================================================================
32
/**
33
* Template container for maintaining a bidirectional map between strings and something else
34
* It is not always a bijection since it allows for duplicate entries on both sides if either
35
* checkDuplicates is set to false in the constructor or the insert function or if
36
* the addAlias function is used.
37
*/
38
39
class SequentialStringBijection {
40
41
public:
42
43
#ifdef _MSC_VER
44
#pragma warning(push)
45
#pragma warning(disable:4510 4512 4610) // no default constructor and no assignment operator; conflicts with initializer
46
#endif
47
struct Entry {
48
const char* str;
49
int key;
50
};
51
#ifdef _MSC_VER
52
#pragma warning(pop)
53
#endif
54
55
56
SequentialStringBijection() {}
57
58
59
SequentialStringBijection(Entry entries[], int terminatorKey, bool checkDuplicates = true) {
60
int i = 0;
61
myT2String.resize(terminatorKey + 1);
62
do {
63
insert(entries[i].str, entries[i].key, checkDuplicates);
64
} while (entries[i++].key != terminatorKey);
65
}
66
67
68
void insert(const std::string str, int key, bool checkDuplicates = true) {
69
if (checkDuplicates) {
70
if (has(key)) {
71
// cannot use toString(key) because that might create an infinite loop
72
throw InvalidArgument("Duplicate key.");
73
}
74
if (hasString(str)) {
75
throw InvalidArgument("Duplicate string '" + str + "'.");
76
}
77
}
78
myString2T[str] = key;
79
myT2String[key] = str;
80
}
81
82
83
void addAlias(const std::string str, int key) {
84
myString2T[str] = key;
85
}
86
87
88
void remove(const std::string str, int key) {
89
myString2T.erase(str);
90
myT2String[key] = "";
91
}
92
93
94
int get(const std::string& str) const {
95
if (hasString(str)) {
96
return myString2T.find(str)->second;
97
} else {
98
throw InvalidArgument("String '" + str + "' not found.");
99
}
100
}
101
102
103
const std::string& getString(int key) const {
104
if ((int)myT2String.size() > key) {
105
return myT2String[key];
106
} else {
107
// cannot use toString(key) because that might create an infinite loop
108
throw InvalidArgument("Key not found.");
109
}
110
}
111
112
113
bool hasString(const std::string& str) const {
114
return myString2T.count(str) != 0;
115
}
116
117
118
bool has(int key) const {
119
return (int)myT2String.size() > key && myT2String[key] != "";
120
}
121
122
123
int size() const {
124
return (int)myString2T.size();
125
}
126
127
128
std::vector<std::string> getStrings() const {
129
return myT2String;
130
}
131
132
133
std::vector<int> getValues() const {
134
std::vector<int> result;
135
for (auto item : myString2T) {
136
result.push_back(item.second);
137
}
138
return result;
139
}
140
141
142
void addKeysInto(std::vector<int>& list) const {
143
typename std::map<std::string, int>::const_iterator it; // learn something new every day
144
for (it = myString2T.begin(); it != myString2T.end(); it++) {
145
list.push_back(it->second);
146
}
147
}
148
149
150
private:
151
std::map<std::string, int> myString2T;
152
std::vector<std::string> myT2String;
153
154
};
155
156