1010
1111#include " Acts/Utilities/Any.hpp"
1212#include " Acts/Utilities/HashedString.hpp"
13- #include " Acts/Utilities/Visibility.hpp"
1413
1514#include < concepts>
15+ #include < cstdint>
1616#include < functional>
17- #include < unordered_map>
17+ #include < memory>
18+ #include < typeinfo>
1819
1920#include < pybind11/pybind11.h>
2021
@@ -54,6 +55,21 @@ class WhiteBoardRegistry {
5455 using FromPythonFunction = std::function<std::unique_ptr<Acts::AnyMoveOnly>(
5556 const pybind11::object& obj)>;
5657
58+ public:
59+ // / Opaque handle to an internal registry entry.
60+ struct EntryHandle {
61+ protected:
62+ EntryHandle () = default ;
63+ ~EntryHandle () = default ;
64+ };
65+
66+ private:
67+ static void registerTypeImpl (PyObject* pyType, ToPythonFunction toPython,
68+ FromPythonFunction fromPython,
69+ const std::type_info* typeinfo,
70+ std::uint64_t typeHash);
71+
72+ public:
5773 // / Register a C++ type T with its pybind11 Python type for WhiteBoard
5874 // / access. Use when the `py::class_<T>` type cannot be deduced (e.g. for
5975 // / template types).
@@ -75,26 +91,22 @@ class WhiteBoardRegistry {
7591
7692 using type = T;
7793
78- instance ()[pyType. ptr ()] = {
79- . toPython = []( const Acts::AnyMoveOnly& any ,
80- const py::object& wbPy) -> py::object {
94+ registerTypeImpl (
95+ pyType. ptr () ,
96+ []( const Acts::AnyMoveOnly& any, const py::object& wbPy) -> py::object {
8197 // wb needed to ensure correct lifetime
8298 return py::cast (any.as <type>(),
8399 py::return_value_policy::reference_internal, wbPy);
84100 },
85- .fromPython =
86- [](const py::object& obj) {
87- // This communicates to pybind11's smart_holder that the object is
88- // consumed in C++
89- auto up = py::cast<std::unique_ptr<T>>(obj);
90- return std::make_unique<Acts::AnyMoveOnly>(std::move (*up));
91- },
92- .typeinfo = &typeid (type),
93- .typeHash = Acts::typeHash<type>(),
94- };
101+ [](const py::object& obj) {
102+ // This communicates to pybind11's smart_holder that the object is
103+ // consumed in C++
104+ auto up = py::cast<std::unique_ptr<T>>(obj);
105+ return std::make_unique<Acts::AnyMoveOnly>(std::move (*up));
106+ },
107+ &typeid (type), Acts::typeHash<type>());
95108 }
96109
97- public:
98110 // / Register a pybind11-bound type T for WhiteBoard read access.
99111 // / Call this after the `py::class_<T>` definition.
100112 // / @tparam Ts The types to register.
@@ -103,35 +115,32 @@ class WhiteBoardRegistry {
103115 static void registerClass (const pybind11::class_<Ts...>& pyClass)
104116 requires PyClassWithSmartHolder<Ts...>
105117 {
106- namespace py = pybind11;
107118 using type = pybind11::class_<Ts...>::type;
108119 registerType<type>(pyClass);
109120 }
110121
111- // / Per-type registry entry: downcast function and type metadata for lookups .
112- struct ACTS_SYMBOL_LOCAL RegistryEntry {
113- ToPythonFunction toPython{
114- nullptr }; // /< Converts `void*` + `WhiteBoard` -> `py::object`
122+ // / Look up a registered type by Python type object .
123+ // / @param pyType The Python type object to look up.
124+ // / @return Opaque handle to the internal entry, or nullptr if not registered.
125+ static const EntryHandle* find (PyObject* pyType) noexcept ;
115126
116- FromPythonFunction fromPython{nullptr };
117- const std::type_info* typeinfo{nullptr }; // /< C++ type for type checking
118- std::uint64_t typeHash{0 }; // /< Hash for runtime type verification
119- };
127+ // / Access the registered C++ type metadata.
128+ static const std::type_info* typeInfo (const EntryHandle* entry) noexcept ;
120129
121- // / Look up a registered type by its pybind11 Python type object.
122- // / @param pyType The pybind11 Python type object to look up.
123- // / @return Pointer to the `RegistryEntry`, or `nullptr` if not registered
124- static RegistryEntry* find (const pybind11::object& pyType) {
125- if (auto it = instance ().find (pyType.ptr ()); it != instance ().end ()) {
126- return &it->second ;
127- }
128- return nullptr ;
129- }
130+ // / Access the registered hash for runtime type verification.
131+ static std::uint64_t typeHash (const EntryHandle* entry) noexcept ;
132+
133+ // / Convert a WhiteBoard object into a Python object.
134+ // / @return New reference (`PyObject*`) owned by the caller.
135+ static PyObject* toPython (const EntryHandle* entry,
136+ const Acts::AnyMoveOnly& any, PyObject* wbPy);
137+
138+ // / Convert a Python object into a WhiteBoard-storable holder.
139+ static std::unique_ptr<Acts::AnyMoveOnly> fromPython (const EntryHandle* entry,
140+ PyObject* obj);
130141
131142 private:
132143 WhiteBoardRegistry () = default;
133-
134- static std::unordered_map<PyObject*, RegistryEntry>& instance ();
135144};
136145
137146} // namespace ActsPython
0 commit comments