LCOV - code coverage report
Current view: top level - src/utils/common - StringBijection.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 25 38 65.8 %
Date: 2024-05-02 15:31:40 Functions: 93 103 90.3 %

          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             : };

Generated by: LCOV version 1.14