Path: blob/main/src/utils/common/SequentialStringBijection.h
169678 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2011-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file SequentialStringBijection.h14/// @author Jakob Erdmann15/// @date June 202416///17// Bidirectional map between string and sequential interger-like-keys (i.e. default enum values)1819/****************************************************************************/20#pragma once21#include <config.h>22#include <iostream>23#include <map>24#include <vector>25#include <string>26#include <utils/common/UtilExceptions.h>2728// ===========================================================================29// class definitions30// ===========================================================================31/**32* Template container for maintaining a bidirectional map between strings and something else33* It is not always a bijection since it allows for duplicate entries on both sides if either34* checkDuplicates is set to false in the constructor or the insert function or if35* the addAlias function is used.36*/3738class SequentialStringBijection {3940public:4142#ifdef _MSC_VER43#pragma warning(push)44#pragma warning(disable:4510 4512 4610) // no default constructor and no assignment operator; conflicts with initializer45#endif46struct Entry {47const char* str;48int key;49};50#ifdef _MSC_VER51#pragma warning(pop)52#endif535455SequentialStringBijection() {}565758SequentialStringBijection(Entry entries[], int terminatorKey, bool checkDuplicates = true) {59int i = 0;60myT2String.resize(terminatorKey + 1);61do {62insert(entries[i].str, entries[i].key, checkDuplicates);63} while (entries[i++].key != terminatorKey);64}656667void insert(const std::string str, int key, bool checkDuplicates = true) {68if (checkDuplicates) {69if (has(key)) {70// cannot use toString(key) because that might create an infinite loop71throw InvalidArgument("Duplicate key.");72}73if (hasString(str)) {74throw InvalidArgument("Duplicate string '" + str + "'.");75}76}77myString2T[str] = key;78myT2String[key] = str;79}808182void addAlias(const std::string str, int key) {83myString2T[str] = key;84}858687void remove(const std::string str, int key) {88myString2T.erase(str);89myT2String[key] = "";90}919293int get(const std::string& str) const {94if (hasString(str)) {95return myString2T.find(str)->second;96} else {97throw InvalidArgument("String '" + str + "' not found.");98}99}100101102const std::string& getString(int key) const {103if ((int)myT2String.size() > key) {104return myT2String[key];105} else {106// cannot use toString(key) because that might create an infinite loop107throw InvalidArgument("Key not found.");108}109}110111112bool hasString(const std::string& str) const {113return myString2T.count(str) != 0;114}115116117bool has(int key) const {118return (int)myT2String.size() > key && myT2String[key] != "";119}120121122int size() const {123return (int)myString2T.size();124}125126127std::vector<std::string> getStrings() const {128return myT2String;129}130131132std::vector<int> getValues() const {133std::vector<int> result;134for (auto item : myString2T) {135result.push_back(item.second);136}137return result;138}139140141void addKeysInto(std::vector<int>& list) const {142typename std::map<std::string, int>::const_iterator it; // learn something new every day143for (it = myString2T.begin(); it != myString2T.end(); it++) {144list.push_back(it->second);145}146}147148149private:150std::map<std::string, int> myString2T;151std::vector<std::string> myT2String;152153};154155156