Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-15 08:27:39

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2017-2019 CERN for the benefit of the Acts project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include <Acts/Utilities/Concepts.hpp>
0012 #include <Acts/Utilities/Logger.hpp>
0013 
0014 #include <algorithm>
0015 #include <cstddef>
0016 #include <memory>
0017 #include <ostream>
0018 #include <stdexcept>
0019 #include <string>
0020 #include <string_view>
0021 #include <type_traits>
0022 #include <typeinfo>
0023 #include <unordered_map>
0024 #include <utility>
0025 #include <vector>
0026 
0027 namespace ActsExamples {
0028 
0029 /// A container to store arbitrary objects with ownership transfer.
0030 ///
0031 /// This is an append-only container that takes ownership of the objects
0032 /// added to it. Once an object has been added, it can only be read but not
0033 /// be modified. Trying to replace an existing object is considered an error.
0034 /// Its lifetime is bound to the lifetime of the white board.
0035 class WhiteBoard {
0036  public:
0037   WhiteBoard(std::unique_ptr<const Acts::Logger> logger =
0038                  Acts::getDefaultLogger("WhiteBoard", Acts::Logging::INFO),
0039              std::unordered_map<std::string, std::string> objectAliases = {});
0040 
0041   // A WhiteBoard holds unique elements and can not be copied
0042   WhiteBoard(const WhiteBoard& other) = delete;
0043   WhiteBoard& operator=(const WhiteBoard&) = delete;
0044 
0045   bool exists(const std::string& name) const;
0046 
0047  private:
0048   /// Store an object on the white board and transfer ownership.
0049   ///
0050   /// @param name Non-empty identifier to store it under
0051   /// @param object Movable reference to the transferable object
0052   /// @throws std::invalid_argument on empty or duplicate name
0053   template <typename T>
0054   void add(const std::string& name, T&& object);
0055 
0056   /// Get access to a stored object.
0057   ///
0058   /// @param[in] name Identifier for the object
0059   /// @return reference to the stored object
0060   /// @throws std::out_of_range if no object is stored under the requested name
0061   template <typename T>
0062   const T& get(const std::string& name) const;
0063 
0064  private:
0065   /// Find similar names for suggestions with levenshtein-distance
0066   std::vector<std::string_view> similarNames(const std::string_view& name,
0067                                              int distThreshold,
0068                                              std::size_t maxNumber) const;
0069 
0070   // type-erased value holder for move-constructible types
0071   struct IHolder {
0072     virtual ~IHolder() = default;
0073     virtual const std::type_info& type() const = 0;
0074   };
0075   template <Acts::Concepts::nothrow_move_constructible T>
0076   struct HolderT : public IHolder {
0077     T value;
0078 
0079     HolderT(T&& v) : value(std::move(v)) {}
0080     const std::type_info& type() const override { return typeid(T); }
0081   };
0082 
0083   std::unique_ptr<const Acts::Logger> m_logger;
0084   std::unordered_map<std::string, std::shared_ptr<IHolder>> m_store;
0085   std::unordered_map<std::string, std::string> m_objectAliases;
0086 
0087   const Acts::Logger& logger() const { return *m_logger; }
0088 
0089   static std::string typeMismatchMessage(const std::string& name,
0090                                          const char* req, const char* act);
0091 
0092   template <typename T>
0093   friend class WriteDataHandle;
0094 
0095   template <typename T>
0096   friend class ReadDataHandle;
0097 };
0098 
0099 }  // namespace ActsExamples
0100 
0101 inline ActsExamples::WhiteBoard::WhiteBoard(
0102     std::unique_ptr<const Acts::Logger> logger,
0103     std::unordered_map<std::string, std::string> objectAliases)
0104     : m_logger(std::move(logger)), m_objectAliases(std::move(objectAliases)) {}
0105 
0106 template <typename T>
0107 inline void ActsExamples::WhiteBoard::add(const std::string& name, T&& object) {
0108   if (name.empty()) {
0109     throw std::invalid_argument("Object can not have an empty name");
0110   }
0111   if (0 < m_store.count(name)) {
0112     throw std::invalid_argument("Object '" + name + "' already exists");
0113   }
0114   auto holder = std::make_shared<HolderT<T>>(std::forward<T>(object));
0115   m_store.emplace(name, holder);
0116   ACTS_VERBOSE("Added object '" << name << "' of type " << typeid(T).name());
0117   if (auto it = m_objectAliases.find(name); it != m_objectAliases.end()) {
0118     m_store[it->second] = holder;
0119     ACTS_VERBOSE("Added alias object '" << it->second << "'");
0120   }
0121 }
0122 
0123 template <typename T>
0124 inline const T& ActsExamples::WhiteBoard::get(const std::string& name) const {
0125   ACTS_VERBOSE("Attempt to get object '" << name << "' of type "
0126                                          << typeid(T).name());
0127   auto it = m_store.find(name);
0128   if (it == m_store.end()) {
0129     const auto names = similarNames(name, 10, 3);
0130 
0131     std::stringstream ss;
0132     if (!names.empty()) {
0133       ss << ", similar ones are: [ ";
0134       for (std::size_t i = 0; i < std::min(3ul, names.size()); ++i) {
0135         ss << "'" << names[i] << "' ";
0136       }
0137       ss << "]";
0138     }
0139 
0140     throw std::out_of_range("Object '" + name + "' does not exists" + ss.str());
0141   }
0142 
0143   const IHolder* holder = it->second.get();
0144 
0145   const auto* castedHolder = dynamic_cast<const HolderT<T>*>(holder);
0146   if (castedHolder == nullptr) {
0147     std::string msg =
0148         typeMismatchMessage(name, typeid(T).name(), holder->type().name());
0149     throw std::out_of_range(msg.c_str());
0150   }
0151 
0152   ACTS_VERBOSE("Retrieved object '" << name << "'");
0153   return castedHolder->value;
0154 }
0155 
0156 inline bool ActsExamples::WhiteBoard::exists(const std::string& name) const {
0157   return m_store.find(name) != m_store.end();
0158 }