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