File indexing completed on 2026-11-14 09:30:32
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 T>
0030 struct IsNavigationPolicyPtr : std::false_type {};
0031
0032 template <typename T>
0033 requires(std::derived_from<T, INavigationPolicy>)
0034 struct IsNavigationPolicyPtr<std::unique_ptr<T>> : std::true_type {};
0035
0036
0037
0038
0039
0040
0041
0042 template <typename F, typename... Args>
0043 concept NavigationPolicyPointerFactoryConcept = requires(
0044 F f, const GeometryContext& gctx, const TrackingVolume& volume,
0045 const Logger& logger, Args&&... args) {
0046 requires IsNavigationPolicyPtr<
0047 std::remove_cvref_t<decltype(f(gctx, volume, logger, args...))>>::value;
0048 };
0049 }
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 class NavigationPolicyFactory {
0062 private:
0063
0064 using factory_type = std::function<std::unique_ptr<INavigationPolicy>(
0065 const GeometryContext&, const TrackingVolume&, const Logger&)>;
0066
0067
0068
0069 explicit NavigationPolicyFactory(std::vector<factory_type>&& factories)
0070 : m_factories(std::move(factories)) {}
0071
0072 public:
0073
0074 NavigationPolicyFactory() = default;
0075
0076
0077
0078
0079
0080
0081
0082
0083 template <NavigationPolicyConcept P, typename... Args>
0084 requires(std::is_constructible_v<P, const GeometryContext&,
0085 const TrackingVolume&, const Logger&,
0086 Args...> &&
0087 (std::is_copy_constructible_v<Args> && ...))
0088 constexpr NavigationPolicyFactory add(Args&&... args) && {
0089 auto factory = [=](const GeometryContext& gctx,
0090 const TrackingVolume& volume, const Logger& logger) {
0091 return std::make_unique<P>(gctx, volume, logger, args...);
0092 };
0093
0094 m_factories.push_back(std::move(factory));
0095 return std::move(*this);
0096 }
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 template <typename Fn, typename... Args>
0110 requires(detail::NavigationPolicyPointerFactoryConcept<Fn, Args...> &&
0111 (std::is_copy_constructible_v<Args> && ...))
0112 constexpr NavigationPolicyFactory add(Fn&& fn, Args&&... args) && {
0113 auto factory = [=](const GeometryContext& gctx,
0114 const TrackingVolume& volume,
0115 const Logger& logger) -> factory_type::result_type {
0116 return fn(gctx, volume, logger, args...);
0117 };
0118
0119 m_factories.push_back(std::move(factory));
0120 return std::move(*this);
0121 }
0122
0123
0124
0125 std::unique_ptr<NavigationPolicyFactory> asUniquePtr() && {
0126 return std::make_unique<NavigationPolicyFactory>(std::move(*this));
0127 }
0128
0129
0130
0131
0132
0133
0134
0135 std::unique_ptr<MultiNavigationPolicy> operator()(
0136 const GeometryContext& gctx, const TrackingVolume& volume,
0137 const Logger& logger) const {
0138 if (m_factories.empty()) {
0139 throw std::runtime_error(
0140 "No factories registered in the navigation policy factory");
0141 }
0142
0143 std::vector<std::unique_ptr<INavigationPolicy>> policies;
0144 policies.reserve(m_factories.size());
0145 for (auto& factory : m_factories) {
0146 policies.push_back(factory(gctx, volume, logger));
0147 }
0148
0149 return std::make_unique<MultiNavigationPolicy>(std::move(policies));
0150 }
0151
0152
0153
0154
0155
0156
0157 std::unique_ptr<INavigationPolicy> build(const GeometryContext& gctx,
0158 const TrackingVolume& volume,
0159 const Logger& logger) const {
0160 return operator()(gctx, volume, logger);
0161 }
0162
0163 private:
0164
0165 std::vector<factory_type> m_factories;
0166 };
0167
0168 }