File indexing completed on 2026-07-17 07:49:34
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 template <typename F, typename... Args>
0041 concept NavigationPolicyValueFactoryConcept = requires(
0042 F f, const GeometryContext& gctx, const TrackingVolume& volume,
0043 const Logger& logger, Args&&... args) {
0044 { f(gctx, volume, logger, args...) } -> std::derived_from<INavigationPolicy>;
0045
0046 requires NavigationPolicyConcept<decltype(f(gctx, volume, logger, args...))>;
0047 };
0048
0049
0050
0051
0052
0053
0054
0055 template <typename F, typename... Args>
0056 concept NavigationPolicyPointerFactoryConcept = requires(
0057 F f, const GeometryContext& gctx, const TrackingVolume& volume,
0058 const Logger& logger, Args&&... args) {
0059 requires IsNavigationPolicyPtr<
0060 std::remove_cvref_t<decltype(f(gctx, volume, logger, args...))>>::value;
0061 };
0062 }
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 class NavigationPolicyFactory {
0075 private:
0076
0077 using factory_type = std::function<std::unique_ptr<INavigationPolicy>(
0078 const GeometryContext&, const TrackingVolume&, const Logger&)>;
0079
0080
0081
0082 explicit NavigationPolicyFactory(std::vector<factory_type>&& factories)
0083 : m_factories(std::move(factories)) {}
0084
0085 public:
0086
0087 NavigationPolicyFactory() = default;
0088
0089
0090
0091
0092
0093
0094
0095
0096 template <NavigationPolicyConcept P, typename... Args>
0097 requires(std::is_constructible_v<P, const GeometryContext&,
0098 const TrackingVolume&, const Logger&,
0099 Args...> &&
0100 (std::is_copy_constructible_v<Args> && ...))
0101 constexpr NavigationPolicyFactory add(Args&&... args) && {
0102 auto factory = [=](const GeometryContext& gctx,
0103 const TrackingVolume& volume, const Logger& logger) {
0104 return std::make_unique<P>(gctx, volume, logger, args...);
0105 };
0106
0107 m_factories.push_back(std::move(factory));
0108 return std::move(*this);
0109 }
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122 template <typename Fn, typename... Args>
0123 requires(detail::NavigationPolicyPointerFactoryConcept<Fn, Args...> &&
0124 (std::is_copy_constructible_v<Args> && ...))
0125 constexpr NavigationPolicyFactory add(Fn&& fn, Args&&... args) && {
0126 auto factory = [=](const GeometryContext& gctx,
0127 const TrackingVolume& volume,
0128 const Logger& logger) -> factory_type::result_type {
0129 return fn(gctx, volume, logger, args...);
0130 };
0131
0132 m_factories.push_back(std::move(factory));
0133 return std::move(*this);
0134 }
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148 template <typename Fn, typename... Args>
0149 requires(detail::NavigationPolicyValueFactoryConcept<Fn, Args...> &&
0150 !detail::NavigationPolicyPointerFactoryConcept<Fn, Args...> &&
0151 (std::is_copy_constructible_v<Args> && ...))
0152 [[deprecated(
0153 "Return a std::unique_ptr<INavigationPolicy> from the factory function "
0154 "instead of a policy by value.")]]
0155 constexpr NavigationPolicyFactory add(Fn&& fn, Args&&... args) && {
0156 auto factory = [=](const GeometryContext& gctx,
0157 const TrackingVolume& volume,
0158 const Logger& logger) -> factory_type::result_type {
0159 using policy_type = decltype(fn(gctx, volume, logger, args...));
0160 return std::make_unique<policy_type>(fn(gctx, volume, logger, args...));
0161 };
0162
0163 m_factories.push_back(std::move(factory));
0164 return std::move(*this);
0165 }
0166
0167
0168
0169 std::unique_ptr<NavigationPolicyFactory> asUniquePtr() && {
0170 return std::make_unique<NavigationPolicyFactory>(std::move(*this));
0171 }
0172
0173
0174
0175
0176
0177
0178
0179 std::unique_ptr<MultiNavigationPolicy> operator()(
0180 const GeometryContext& gctx, const TrackingVolume& volume,
0181 const Logger& logger) const {
0182 if (m_factories.empty()) {
0183 throw std::runtime_error(
0184 "No factories registered in the navigation policy factory");
0185 }
0186
0187 std::vector<std::unique_ptr<INavigationPolicy>> policies;
0188 policies.reserve(m_factories.size());
0189 for (auto& factory : m_factories) {
0190 policies.push_back(factory(gctx, volume, logger));
0191 }
0192
0193 return std::make_unique<MultiNavigationPolicy>(std::move(policies));
0194 }
0195
0196
0197
0198
0199
0200
0201 std::unique_ptr<INavigationPolicy> build(const GeometryContext& gctx,
0202 const TrackingVolume& volume,
0203 const Logger& logger) const {
0204 return operator()(gctx, volume, logger);
0205 }
0206
0207 private:
0208
0209 std::vector<factory_type> m_factories;
0210 };
0211
0212 }