File indexing completed on 2026-03-30 07:45:38
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Navigation/INavigationPolicy.hpp"
0012 #include "Acts/Navigation/MultiNavigationPolicy.hpp"
0013
0014 #include <concepts>
0015 #include <memory>
0016
0017 namespace Acts {
0018
0019 class TrackingVolume;
0020 class GeometryContext;
0021 class Logger;
0022 class INavigationPolicy;
0023
0024 namespace detail {
0025
0026
0027
0028
0029 template <typename F, typename... Args>
0030 concept NavigationPolicyIsolatedFactoryConcept = requires(
0031 F f, const GeometryContext& gctx, const TrackingVolume& volume,
0032 const Logger& logger, Args&&... args) {
0033 { f(gctx, volume, logger, args...) } -> std::derived_from<INavigationPolicy>;
0034
0035 requires NavigationPolicyConcept<decltype(f(gctx, volume, logger, args...))>;
0036
0037 requires(std::is_copy_constructible_v<Args> && ...);
0038 };
0039 }
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 class NavigationPolicyFactory {
0052 private:
0053
0054 using factory_type = std::function<std::unique_ptr<INavigationPolicy>(
0055 const GeometryContext&, const TrackingVolume&, const Logger&)>;
0056
0057
0058
0059 explicit NavigationPolicyFactory(std::vector<factory_type>&& factories)
0060 : m_factories(std::move(factories)) {}
0061
0062 public:
0063
0064 NavigationPolicyFactory() = default;
0065
0066
0067
0068
0069
0070
0071
0072
0073 template <NavigationPolicyConcept P, typename... Args>
0074 requires(std::is_constructible_v<P, const GeometryContext&,
0075 const TrackingVolume&, const Logger&,
0076 Args...> &&
0077 (std::is_copy_constructible_v<Args> && ...))
0078 constexpr NavigationPolicyFactory add(Args&&... args) && {
0079 auto factory = [=](const GeometryContext& gctx,
0080 const TrackingVolume& volume, const Logger& logger) {
0081 return std::make_unique<P>(gctx, volume, logger, args...);
0082 };
0083
0084 m_factories.push_back(std::move(factory));
0085 return std::move(*this);
0086 }
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 template <typename Fn, typename... Args>
0097 requires(detail::NavigationPolicyIsolatedFactoryConcept<Fn, Args...>)
0098 constexpr NavigationPolicyFactory add(Fn&& fn, Args&&... args) && {
0099 auto factory = [=](const GeometryContext& gctx,
0100 const TrackingVolume& volume, const Logger& logger) {
0101 using policy_type = decltype(fn(gctx, volume, logger, args...));
0102 return std::make_unique<policy_type>(fn(gctx, volume, logger, args...));
0103 };
0104
0105 m_factories.push_back(std::move(factory));
0106 return std::move(*this);
0107 }
0108
0109
0110
0111 std::unique_ptr<NavigationPolicyFactory> asUniquePtr() && {
0112 return std::make_unique<NavigationPolicyFactory>(std::move(*this));
0113 }
0114
0115
0116
0117
0118
0119
0120
0121 std::unique_ptr<MultiNavigationPolicy> operator()(
0122 const GeometryContext& gctx, const TrackingVolume& volume,
0123 const Logger& logger) const {
0124 if (m_factories.empty()) {
0125 throw std::runtime_error(
0126 "No factories registered in the navigation policy factory");
0127 }
0128
0129 std::vector<std::unique_ptr<INavigationPolicy>> policies;
0130 policies.reserve(m_factories.size());
0131 for (auto& factory : m_factories) {
0132 policies.push_back(factory(gctx, volume, logger));
0133 }
0134
0135 return std::make_unique<MultiNavigationPolicy>(std::move(policies));
0136 }
0137
0138
0139
0140
0141
0142
0143 std::unique_ptr<INavigationPolicy> build(const GeometryContext& gctx,
0144 const TrackingVolume& volume,
0145 const Logger& logger) const {
0146 return operator()(gctx, volume, logger);
0147 }
0148
0149 private:
0150
0151 std::vector<factory_type> m_factories;
0152 };
0153
0154 }