File indexing completed on 2026-09-10 08:20:19
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Utilities/Any.hpp"
0012 #include "Acts/Utilities/HashedString.hpp"
0013 #include "Acts/Utilities/Logger.hpp"
0014
0015 #include <algorithm>
0016 #include <cstddef>
0017 #include <memory>
0018 #include <sstream>
0019 #include <stdexcept>
0020 #include <string>
0021 #include <string_view>
0022 #include <typeinfo>
0023 #include <unordered_map>
0024 #include <utility>
0025 #include <vector>
0026
0027 namespace ActsExamples {
0028
0029
0030
0031
0032
0033
0034
0035 class WhiteBoard {
0036 public:
0037 struct StringHash {
0038 using is_transparent = void;
0039
0040 std::size_t operator()(std::string_view sv) const {
0041 std::hash<std::string_view> hasher;
0042 return hasher(sv);
0043 }
0044 };
0045
0046 using StoreValue =
0047 std::pair<std::shared_ptr<Acts::AnyMoveOnly>, std::uint64_t>;
0048 using StoreMapType =
0049 std::unordered_map<std::string, StoreValue, StringHash, std::equal_to<>>;
0050 using AliasMapType = std::unordered_multimap<std::string, std::string,
0051 StringHash, std::equal_to<>>;
0052
0053 explicit WhiteBoard(std::unique_ptr<const Acts::Logger> logger =
0054 Acts::getDefaultLogger("WhiteBoard",
0055 Acts::Logging::INFO),
0056 AliasMapType objectAliases = {});
0057
0058 WhiteBoard(const WhiteBoard& other) = delete;
0059 WhiteBoard& operator=(const WhiteBoard&) = delete;
0060
0061 WhiteBoard(WhiteBoard&& other) = default;
0062 WhiteBoard& operator=(WhiteBoard&& other) = default;
0063
0064 bool exists(const std::string& name) const;
0065
0066
0067
0068
0069
0070
0071 void copyFrom(const WhiteBoard& other);
0072
0073 std::vector<std::string> getKeys() const;
0074
0075 private:
0076
0077 std::vector<std::string_view> similarNames(const std::string_view& name,
0078 int distThreshold,
0079 std::size_t maxNumber) const;
0080
0081
0082
0083
0084
0085
0086
0087 void addHolder(const std::string& name,
0088 const std::shared_ptr<Acts::AnyMoveOnly>& holder,
0089 std::uint64_t typeHash);
0090
0091
0092 void addHolder(const std::string& name,
0093 std::unique_ptr<Acts::AnyMoveOnly> holder,
0094 std::uint64_t typeHash);
0095
0096
0097
0098
0099
0100 template <typename T>
0101 const T& add(const std::string& name, T&& object) {
0102 addHolder(name,
0103 std::make_shared<Acts::AnyMoveOnly>(std::forward<T>(object)),
0104 Acts::typeHash<T>());
0105 return get<T>(name);
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 Acts::AnyMoveOnly* getHolder(const std::string& name) const;
0118
0119
0120 std::pair<Acts::AnyMoveOnly*, std::uint64_t> getHolder(
0121 const std::string& name) const;
0122
0123 template <typename T>
0124 T pop(const std::string& name);
0125
0126 std::unique_ptr<const Acts::Logger> m_logger;
0127
0128 StoreMapType m_store;
0129
0130 AliasMapType m_objectAliases;
0131
0132 const Acts::Logger& logger() const { return *m_logger; }
0133
0134 static std::string typeMismatchMessage(const std::string& name,
0135 const char* req, const char* act);
0136
0137 friend class DataHandleBase;
0138 };
0139
0140 inline WhiteBoard::WhiteBoard(std::unique_ptr<const Acts::Logger> logger,
0141 AliasMapType objectAliases)
0142 : m_logger(std::move(logger)), m_objectAliases(std::move(objectAliases)) {}
0143
0144 template <typename T>
0145 Acts::AnyMoveOnly* WhiteBoard::getHolder(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 auto& [holder, storedTypeHash] = it->second;
0163 if (storedTypeHash != Acts::typeHash<T>()) {
0164 const char* holderTypeName =
0165 holder->typeInfo() ? holder->typeInfo()->name() : "unknown";
0166 std::string msg =
0167 typeMismatchMessage(name, typeid(T).name(), holderTypeName);
0168 throw std::out_of_range(msg.c_str());
0169 }
0170
0171 return holder.get();
0172 }
0173
0174 template <typename T>
0175 inline const T& 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->template as<T>();
0181 }
0182
0183 template <typename T>
0184 T WhiteBoard::pop(const std::string& name) {
0185 ACTS_VERBOSE("Pop object '" << name << "'");
0186 (void)getHolder<T>(name);
0187 auto node = m_store.extract(name);
0188 return node.mapped().first->template take<T>();
0189 }
0190
0191 inline bool WhiteBoard::exists(const std::string& name) const {
0192
0193 return m_store.contains(name);
0194 }
0195
0196 }