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