File indexing completed on 2025-12-11 09:40:23
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Utilities/Logger.hpp"
0012
0013 #include <concepts>
0014
0015 #include <boost/preprocessor/seq/for_each.hpp>
0016 #include <boost/preprocessor/variadic/to_seq.hpp>
0017 #include <pybind11/pybind11.h>
0018
0019 namespace ActsExamples {
0020 struct AlgorithmContext;
0021 enum class ProcessCode;
0022 }
0023
0024 namespace ActsPython::Concepts {
0025 template <typename T>
0026 concept has_write_method =
0027 requires(T& t, const ActsExamples::AlgorithmContext& ctx) {
0028 { t.write(ctx) } -> std::same_as<ActsExamples::ProcessCode>;
0029 };
0030 }
0031
0032 #define ACTS_PYTHON_MEMBER(name) \
0033 _binding_instance.def_readwrite(#name, &_struct_type::name)
0034
0035 #define ACTS_PYTHON_STRUCT_BEGIN(object) \
0036 { \
0037 [[maybe_unused]] auto& _binding_instance = object; \
0038 using _struct_type = decltype(object)::type; \
0039 do { \
0040 } while (0)
0041
0042 #define ACTS_PYTHON_STRUCT_END() \
0043 } \
0044 do { \
0045 } while (0)
0046
0047
0048 #define ACTS_PYTHON_MEMBER_LOOP(r, data, elem) ACTS_PYTHON_MEMBER(elem);
0049
0050
0051
0052 #define ACTS_PYTHON_STRUCT(object, ...) \
0053 do { \
0054 ACTS_PYTHON_STRUCT_BEGIN(object); \
0055 BOOST_PP_SEQ_FOR_EACH(ACTS_PYTHON_MEMBER_LOOP, _, \
0056 BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
0057 ACTS_PYTHON_STRUCT_END(); \
0058 } while (0)
0059
0060 template <typename A, typename B>
0061 auto declareAlgorithm(pybind11::module_& m, const char* name) {
0062 using Config = typename A::Config;
0063 auto alg = pybind11::class_<A, B, std::shared_ptr<A>>(m, name)
0064 .def(pybind11::init<const Config&, Acts::Logging::Level>(),
0065 pybind11::arg("config"), pybind11::arg("level"))
0066 .def_property_readonly("config", &A::config);
0067 auto c = pybind11::class_<Config>(alg, "Config").def(pybind11::init<>());
0068 return std::tuple{alg, c};
0069 }
0070
0071
0072
0073 #define ACTS_PYTHON_DECLARE_ALGORITHM(algorithm, mod, name, ...) \
0074 do { \
0075 auto [alg, c] = \
0076 declareAlgorithm<algorithm, ActsExamples::IAlgorithm>(mod, name); \
0077 ACTS_PYTHON_STRUCT(c, __VA_ARGS__); \
0078 } while (0)
0079
0080
0081 #define ACTS_PYTHON_DECLARE_WRITER(writer, mod, name, ...) \
0082 do { \
0083 using Writer = writer; \
0084 using Config = Writer::Config; \
0085 auto w = \
0086 py::class_<Writer, ActsExamples::IWriter, std::shared_ptr<Writer>>( \
0087 mod, name) \
0088 .def(py::init<const Config&, Acts::Logging::Level>(), \
0089 py::arg("config"), py::arg("level")) \
0090 .def_property_readonly("config", &Writer::config); \
0091 \
0092 constexpr bool has_write_method = \
0093 ActsPython::Concepts::has_write_method<Writer>; \
0094 \
0095 if constexpr (has_write_method) { \
0096 w.def("write", &Writer::write); \
0097 } \
0098 auto c = py::class_<Config>(w, "Config").def(py::init<>()); \
0099 ACTS_PYTHON_STRUCT(c, __VA_ARGS__); \
0100 } while (0)
0101
0102
0103 #define ACTS_PYTHON_DECLARE_READER(reader, mod, name, ...) \
0104 do { \
0105 using Reader = reader; \
0106 using Config = Reader::Config; \
0107 auto r = \
0108 py::class_<Reader, ActsExamples::IReader, std::shared_ptr<Reader>>( \
0109 mod, name) \
0110 .def(py::init<const Config&, Acts::Logging::Level>(), \
0111 py::arg("config"), py::arg("level")) \
0112 .def_property_readonly("config", &Reader::config); \
0113 \
0114 auto c = py::class_<Config>(r, "Config").def(py::init<>()); \
0115 ACTS_PYTHON_STRUCT(c, __VA_ARGS__); \
0116 } while (0)