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: 2026-06-20 07:41:18 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          26 :     TypeRegistry() = default;
      22             :     TypeRegistry(const TypeRegistry&) = delete;
      23          22 :     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             :     std::vector<KeyType> getIDs() const;
      31             : 
      32             : private:
      33             :     void buildNameIDMap(const std::vector<ValueType>& values);
      34             : 
      35             : private:
      36             :     std::vector<ValueType> values_;
      37             :     std::unordered_map<std::string, KeyType> nameIDMap_;
      38             : };
      39             : 
      40          26 : template <typename ValueType> inline void TypeRegistry<ValueType>::setValues(std::vector<ValueType>&& values)
      41             : {
      42          26 :     if (values.empty())
      43             :     {
      44           0 :         values_.clear();
      45           0 :         nameIDMap_.clear();
      46           0 :         return;
      47             :     }
      48             : 
      49          26 :     const auto MaxCount = std::numeric_limits<KeyType>::max();
      50          26 :     if (values.size() > MaxCount)
      51           0 :         throw ExceptionWithLocation("Too many types: Registry only supports " + std::to_string(MaxCount) + ", but " +
      52             :                                     std::to_string(values.size()) + " were given");
      53             : 
      54          26 :     values_ = std::move(values);
      55          26 :     buildNameIDMap(values_);
      56             : }
      57             : 
      58             : template <typename ValueType> inline const std::vector<ValueType>& TypeRegistry<ValueType>::getValues() const
      59             : {
      60             :     return values_;
      61             : }
      62             : 
      63             : template <typename ValueType>
      64         102 : inline TypeRegistry<ValueType>::KeyType TypeRegistry<ValueType>::getIDFor(const std::string& name) const
      65             : {
      66         102 :     auto iter = nameIDMap_.find(name);
      67         102 :     if (iter == nameIDMap_.end())
      68           0 :         throw ExceptionWithLocation("Couldn't find type with name \"" + name + "\" in registry");
      69             : 
      70         102 :     return iter->second;
      71             : }
      72             : 
      73      363391 : template <typename ValueType> inline const ValueType& TypeRegistry<ValueType>::getByID(KeyType ID) const
      74             : {
      75             : #ifdef DEBUG
      76      363391 :     if (static_cast<std::size_t>(ID) >= values_.size())
      77           0 :         throw ExceptionWithLocation("Index out of range: " + std::to_string(ID) + ", registry size is " +
      78             :                                     std::to_string(values_.size()));
      79             : #endif
      80             : 
      81      363391 :     return values_[ID];
      82             : }
      83             : 
      84             : template <typename ValueType>
      85             : inline std::vector<typename TypeRegistry<ValueType>::KeyType> TypeRegistry<ValueType>::getIDs() const
      86             : {
      87             :     std::vector<KeyType> ids;
      88             :     ids.reserve(values_.size());
      89             :     for (KeyType i = 0; i < static_cast<KeyType>(values_.size()); ++i)
      90             :         ids.push_back(i);
      91             : 
      92             :     return ids;
      93             : }
      94             : 
      95          26 : template <typename ValueType> inline void TypeRegistry<ValueType>::buildNameIDMap(const std::vector<ValueType>& values)
      96             : {
      97          26 :     std::unordered_map<std::string, KeyType> nameIDMap;
      98             : 
      99          99 :     for (KeyType i = 0; i < static_cast<KeyType>(values.size()); ++i)
     100             :     {
     101          73 :         if (nameIDMap.contains(values[i].getName()))
     102           0 :             throw ExceptionWithLocation("Can't build name map: Duplicate type name \"" + values[i].getName() + "\"");
     103             : 
     104          73 :         nameIDMap[values[i].getName()] = i;
     105             :     }
     106             : 
     107          26 :     nameIDMap_ = std::move(nameIDMap);
     108          26 : }
     109             : 
     110             : } // namespace cell
     111             : #endif /* C9F0AFE7_2B64_483A_9B0A_9B7D7DA9DEFC_HPP */

Generated by: LCOV version 1.14