Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:47

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 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 https://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 <typeinfo>
0022 #include <unordered_map>
0023 #include <utility>
0024 #include <vector>
0025 
0026 namespace ActsExamples {
0027 
0028 /// A container to store arbitrary objects with ownership transfer.
0029 ///
0030 /// This is an append-only container that takes ownership of the objects
0031 /// added to it. Once an object has been added, it can only be read but not
0032 /// be modified. Trying to replace an existing object is considered an error.
0033 /// Its lifetime is bound to the lifetime of the white board.
0034 class WhiteBoard {
0035  public:
0036   WhiteBoard(std::unique_ptr<const Acts::Logger> logger =
0037                  Acts::getDefaultLogger("WhiteBoard", Acts::Logging::INFO),
0038              std::unordered_map<std::string, std::string> objectAliases = {});
0039 
0040   WhiteBoard(const WhiteBoard& other) = delete;
0041   WhiteBoard& operator=(const WhiteBoard&) = delete;
0042 
0043   WhiteBoard(WhiteBoard&& other) = default;
0044   WhiteBoard& operator=(WhiteBoard&& other) = default;
0045 
0046   bool exists(const std::string& name) const;
0047 
0048   /// Copies key from another whiteboard to this whiteboard.
0049   /// This is a low overhead operation, since the data holders are
0050   /// shared pointers.
0051   /// Throws an exception if this whiteboard already contains one of
0052   /// the keys in the other whiteboard.
0053   void copyFrom(const WhiteBoard& other);
0054 
0055  private:
0056   /// Find similar names for suggestions with levenshtein-distance
0057   std::vector<std::string_view> similarNames(const std::string_view& name,
0058                                              int distThreshold,
0059                                              std::size_t maxNumber) const;
0060 
0061   // type-erased value holder for move-constructible types
0062   struct IHolder {
0063     virtual ~IHolder() = default;
0064     virtual const std::type_info& type() const = 0;
0065   };
0066   template <Acts::Concepts::nothrow_move_constructible T>
0067   struct HolderT : public IHolder {
0068     T value;
0069 
0070     explicit HolderT(T&& v) : value(std::move(v)) {}
0071     const std::type_info& type() const override { return typeid(T); }
0072   };
0073 
0074   /// Store a holder on the white board.
0075   ///
0076   /// @param name Non-empty identifier to store it under
0077   /// @param holder The holder to store
0078   /// @throws std::invalid_argument on empty or duplicate name
0079   void addHolder(const std::string& name, std::shared_ptr<IHolder> holder);
0080 
0081   /// Store an object on the white board and transfer ownership.
0082   ///
0083   /// @param name Non-empty identifier to store it under
0084   /// @param object Movable reference to the transferable object
0085   template <typename T>
0086   void add(const std::string& name, T&& object) {
0087     addHolder(name, std::make_shared<HolderT<T>>(std::forward<T>(object)));
0088   }
0089 
0090   /// Get access to a stored object.
0091   ///
0092   /// @param[in] name Identifier for the object
0093   /// @return reference to the stored object
0094   /// @throws std::out_of_range if no object is stored under the requested name
0095   template <typename T>
0096   const T& get(const std::string& name) const;
0097 
0098   std::unique_ptr<const Acts::Logger> m_logger;
0099   std::unordered_map<std::string, std::shared_ptr<IHolder>> m_store;
0100   std::unordered_map<std::string, std::string> m_objectAliases;
0101 
0102   const Acts::Logger& logger() const { return *m_logger; }
0103 
0104   static std::string typeMismatchMessage(const std::string& name,
0105                                          const char* req, const char* act);
0106 
0107   template <typename T>
0108   friend class WriteDataHandle;
0109 
0110   template <typename T>
0111   friend class ReadDataHandle;
0112 };
0113 
0114 }  // namespace ActsExamples
0115 
0116 inline ActsExamples::WhiteBoard::WhiteBoard(
0117     std::unique_ptr<const Acts::Logger> logger,
0118     std::unordered_map<std::string, std::string> objectAliases)
0119     : m_logger(std::move(logger)), m_objectAliases(std::move(objectAliases)) {}
0120 
0121 template <typename T>
0122 inline const T& ActsExamples::WhiteBoard::get(const std::string& name) const {
0123   ACTS_VERBOSE("Attempt to get object '" << name << "' of type "
0124                                          << typeid(T).name());
0125   auto it = m_store.find(name);
0126   if (it == m_store.end()) {
0127     const auto names = similarNames(name, 10, 3);
0128 
0129     std::stringstream ss;
0130     if (!names.empty()) {
0131       ss << ", similar ones are: [ ";
0132       for (std::size_t i = 0; i < std::min(3ul, names.size()); ++i) {
0133         ss << "'" << names[i] << "' ";
0134       }
0135       ss << "]";
0136     }
0137 
0138     throw std::out_of_range("Object '" + name + "' does not exists" + ss.str());
0139   }
0140 
0141   const IHolder* holder = it->second.get();
0142 
0143   const auto* castedHolder = dynamic_cast<const HolderT<T>*>(holder);
0144   if (castedHolder == nullptr) {
0145     std::string msg =
0146         typeMismatchMessage(name, typeid(T).name(), holder->type().name());
0147     throw std::out_of_range(msg.c_str());
0148   }
0149 
0150   ACTS_VERBOSE("Retrieved object '" << name << "'");
0151   return castedHolder->value;
0152 }
0153 
0154 inline bool ActsExamples::WhiteBoard::exists(const std::string& name) const {
0155   // TODO remove this function?
0156   return m_store.contains(name);
0157 }