File indexing completed on 2025-07-02 07:51:28
0001
0002
0003
0004
0005
0006
0007
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
0029
0030
0031
0032
0033
0034 class WhiteBoard {
0035 private:
0036
0037 struct IHolder {
0038 virtual ~IHolder() = default;
0039 virtual const std::type_info& type() const = 0;
0040 };
0041 template <Acts::Concepts::nothrow_move_constructible T>
0042 struct HolderT : public IHolder {
0043 T value;
0044
0045 explicit HolderT(T&& v) : value(std::move(v)) {}
0046 const std::type_info& type() const override { return typeid(T); }
0047 };
0048
0049 struct StringHash {
0050 using is_transparent = void;
0051
0052 std::size_t operator()(std::string_view sv) const {
0053 std::hash<std::string_view> hasher;
0054 return hasher(sv);
0055 }
0056 };
0057
0058 public:
0059 using StoreMapType = std::unordered_map<std::string, std::shared_ptr<IHolder>,
0060 StringHash, std::equal_to<>>;
0061 using AliasMapType = std::unordered_multimap<std::string, std::string,
0062 StringHash, std::equal_to<>>;
0063
0064 explicit WhiteBoard(std::unique_ptr<const Acts::Logger> logger =
0065 Acts::getDefaultLogger("WhiteBoard",
0066 Acts::Logging::INFO),
0067 AliasMapType objectAliases = {});
0068
0069 WhiteBoard(const WhiteBoard& other) = delete;
0070 WhiteBoard& operator=(const WhiteBoard&) = delete;
0071
0072 WhiteBoard(WhiteBoard&& other) = default;
0073 WhiteBoard& operator=(WhiteBoard&& other) = default;
0074
0075 bool exists(const std::string& name) const;
0076
0077
0078
0079
0080
0081
0082 void copyFrom(const WhiteBoard& other);
0083
0084 std::vector<std::string> getKeys() const;
0085
0086 private:
0087
0088 std::vector<std::string_view> similarNames(const std::string_view& name,
0089 int distThreshold,
0090 std::size_t maxNumber) const;
0091
0092
0093
0094
0095
0096
0097 void addHolder(const std::string& name,
0098 const std::shared_ptr<IHolder>& holder);
0099
0100
0101
0102
0103
0104 template <typename T>
0105 void add(const std::string& name, T&& object) {
0106 addHolder(name, std::make_shared<HolderT<T>>(std::forward<T>(object)));
0107 }
0108
0109
0110
0111
0112
0113
0114 template <typename T>
0115 const T& get(const std::string& name) const;
0116
0117 template <typename T>
0118 HolderT<T>* getHolder(const std::string& name) const;
0119
0120 template <typename T>
0121 T pop(const std::string& name);
0122
0123 std::unique_ptr<const Acts::Logger> m_logger;
0124
0125 StoreMapType m_store;
0126
0127 AliasMapType m_objectAliases;
0128
0129 const Acts::Logger& logger() const { return *m_logger; }
0130
0131 static std::string typeMismatchMessage(const std::string& name,
0132 const char* req, const char* act);
0133
0134 friend class DataHandleBase;
0135 };
0136
0137 }
0138
0139 inline ActsExamples::WhiteBoard::WhiteBoard(
0140 std::unique_ptr<const Acts::Logger> logger, AliasMapType objectAliases)
0141 : m_logger(std::move(logger)), m_objectAliases(std::move(objectAliases)) {}
0142
0143 template <typename T>
0144 ActsExamples::WhiteBoard::HolderT<T>* ActsExamples::WhiteBoard::getHolder(
0145 const std::string& name) const {
0146 auto it = m_store.find(name);
0147 if (it == m_store.end()) {
0148 const auto names = similarNames(name, 10, 3);
0149
0150 std::stringstream ss;
0151 if (!names.empty()) {
0152 ss << ", similar ones are: [ ";
0153 for (std::size_t i = 0; i < std::min(3ul, names.size()); ++i) {
0154 ss << "'" << names[i] << "' ";
0155 }
0156 ss << "]";
0157 }
0158
0159 throw std::out_of_range("Object '" + name + "' does not exists" + ss.str());
0160 }
0161
0162 IHolder* holder = it->second.get();
0163
0164 auto* castedHolder = dynamic_cast<HolderT<T>*>(holder);
0165 if (castedHolder == nullptr) {
0166 std::string msg =
0167 typeMismatchMessage(name, typeid(T).name(), holder->type().name());
0168 throw std::out_of_range(msg.c_str());
0169 }
0170
0171 return castedHolder;
0172 }
0173
0174 template <typename T>
0175 inline const T& ActsExamples::WhiteBoard::get(const std::string& name) const {
0176 ACTS_VERBOSE("Attempt to get object '" << name << "' of type "
0177 << typeid(T).name());
0178 ACTS_VERBOSE("Retrieved object '" << name << "'");
0179 auto* holder = getHolder<T>(name);
0180 return holder->value;
0181 }
0182
0183 template <typename T>
0184 T ActsExamples::WhiteBoard::pop(const std::string& name) {
0185 ACTS_VERBOSE("Pop object '" << name << "'");
0186
0187
0188 auto* holder = getHolder<T>(name);
0189
0190 auto owned = m_store.extract(name);
0191
0192 return std::move(holder->value);
0193 }
0194
0195 inline bool ActsExamples::WhiteBoard::exists(const std::string& name) const {
0196
0197 return m_store.contains(name);
0198 }