LCOV - code coverage report
Current view: top level - cell - TypeRegistry.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 22 29 75.9 %
Date: 2025-12-06 00:15:40 Functions: 12 12 100.0 %

          Line data    Source code
       1             : #ifndef C9F0AFE7_2B64_483A_9B0A_9B7D7DA9DEFC_HPP
       2             : #define C9F0AFE7_2B64_483A_9B0A_9B7D7DA9DEFC_HPP
       3             : 
       4             : #include "ExceptionWithLocation.hpp"
       5             : #include "Types.hpp"
       6             : 
       7             : #include <cstdint>
       8             : #include <string>
       9             : #include <unordered_map>
      10             : #include <vector>
      11             : 
      12             : namespace cell
      13             : {
      14             : 
      15             : template <typename ValueType> class TypeRegistry
      16             : {
      17             : public:
      18             :     using KeyType = std::uint16_t;
      19             : 
      20             : public:
      21          24 :     TypeRegistry() = default;
      22             :     TypeRegistry(const TypeRegistry&) = delete;
      23          20 :     TypeRegistry(TypeRegistry&&) = default;
      24             : 
      25             :     void setValues(std::vector<ValueType>&& values);
      26             :     const std::vector<ValueType>& getValues() const;
      27             : 
      28             :     KeyType getIDFor(const std::string& name) const;
      29             :     const ValueType& getByID(KeyType ID) const;
      30             : 
      31             : private:
      32             :     void buildNameIDMap(const std::vector<ValueType>& values);
      33             : 
      34             : private:
      35             :     std::vector<ValueType> values_;
      36             :     std::unordered_map<std::string, KeyType> nameIDMap_;
      37             : };
      38             : 
      39          24 : template <typename ValueType> inline void TypeRegistry<ValueType>::setValues(std::vector<ValueType>&& values)
      40             : {
      41          24 :     if (values.empty())
      42             :     {
      43           0 :         values_.clear();
      44           0 :         nameIDMap_.clear();
      45           0 :         return;
      46             :     }
      47             : 
      48          24 :     const auto MaxCount = std::numeric_limits<KeyType>::max();
      49          24 :     if (values.size() > MaxCount)
      50           0 :         throw ExceptionWithLocation("Too many types: Registry only supports " + std::to_string(MaxCount) + ", but " +
      51             :                                     std::to_string(values.size()) + " were given");
      52             : 
      53          24 :     values_ = std::move(values);
      54          24 :     buildNameIDMap(values_);
      55             : }
      56             : 
      57             : template <typename ValueType> inline const std::vector<ValueType>& TypeRegistry<ValueType>::getValues() const
      58             : {
      59             :     return values_;
      60             : }
      61             : 
      62             : template <typename ValueType>
      63          91 : inline TypeRegistry<ValueType>::KeyType TypeRegistry<ValueType>::getIDFor(const std::string& name) const
      64             : {
      65          91 :     auto iter = nameIDMap_.find(name);
      66          91 :     if (iter == nameIDMap_.end())
      67           0 :         throw ExceptionWithLocation("Couldn't find type with name \"" + name + "\" in registry");
      68             : 
      69          91 :     return iter->second;
      70             : }
      71             : 
      72      363295 : template <typename ValueType> inline const ValueType& TypeRegistry<ValueType>::getByID(KeyType ID) const
      73             : {
      74             : #ifdef DEBUG
      75      363295 :     if (static_cast<std::size_t>(ID) >= values_.size())
      76           0 :         throw ExceptionWithLocation("Index out of range: " + std::to_string(ID) + ", registry size is " +
      77             :                                     std::to_string(values_.size()));
      78             : #endif
      79             : 
      80      363295 :     return values_[ID];
      81             : }
      82             : 
      83          24 : template <typename ValueType> inline void TypeRegistry<ValueType>::buildNameIDMap(const std::vector<ValueType>& values)
      84             : {
      85          24 :     std::unordered_map<std::string, KeyType> nameIDMap;
      86             : 
      87          91 :     for (KeyType i = 0; i < static_cast<KeyType>(values.size()); ++i)
      88             :     {
      89          67 :         if (nameIDMap.contains(values[i].getName()))
      90           0 :             throw ExceptionWithLocation("Can't build name map: Duplicate type name \"" + values[i].getName() + "\"");
      91             : 
      92          67 :         nameIDMap[values[i].getName()] = i;
      93             :     }
      94             : 
      95          24 :     nameIDMap_ = std::move(nameIDMap);
      96          24 : }
      97             : 
      98             : } // namespace cell
      99             : #endif /* C9F0AFE7_2B64_483A_9B0A_9B7D7DA9DEFC_HPP */

Generated by: LCOV version 1.14