File indexing completed on 2025-01-18 09:10:52
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 template <typename... Factories>
0025 class NavigationPolicyFactoryImpl;
0026 }
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 class NavigationPolicyFactory {
0039 public:
0040 virtual ~NavigationPolicyFactory() = default;
0041
0042
0043
0044 static auto make();
0045
0046
0047
0048
0049 virtual std::unique_ptr<INavigationPolicy> build(
0050 const GeometryContext& gctx, const TrackingVolume& volume,
0051 const Logger& logger) const = 0;
0052 };
0053
0054 namespace detail {
0055
0056 template <typename F, typename... Args>
0057 concept NavigationPolicyIsolatedFactoryConcept = requires(
0058 F f, const GeometryContext& gctx, const TrackingVolume& volume,
0059 const Logger& logger, Args&&... args) {
0060 { f(gctx, volume, logger, args...) } -> std::derived_from<INavigationPolicy>;
0061
0062 requires NavigationPolicyConcept<decltype(f(gctx, volume, logger, args...))>;
0063
0064 requires(std::is_copy_constructible_v<Args> && ...);
0065 };
0066
0067 template <>
0068 class NavigationPolicyFactoryImpl<> {
0069 public:
0070 template <typename...>
0071 friend class NavigationPolicyFactoryImpl;
0072 NavigationPolicyFactoryImpl() = default;
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 auto add(Args&&... args) && {
0086 auto factory = [=](const GeometryContext& gctx,
0087 const TrackingVolume& volume, const Logger& logger) {
0088 return P{gctx, volume, logger, args...};
0089 };
0090
0091 return NavigationPolicyFactoryImpl<decltype(factory)>{
0092 std::make_tuple(std::move(factory))};
0093 }
0094
0095
0096
0097
0098
0099
0100
0101 template <typename Fn, typename... Args>
0102 requires(NavigationPolicyIsolatedFactoryConcept<Fn, Args...>)
0103 constexpr auto add(Fn&& fn, Args&&... args) {
0104 auto factory = [=](const GeometryContext& gctx,
0105 const TrackingVolume& volume, const Logger& logger) {
0106 return fn(gctx, volume, logger, args...);
0107 };
0108
0109 return NavigationPolicyFactoryImpl<decltype(factory)>{
0110 std::make_tuple(std::move(factory))};
0111 }
0112 };
0113
0114 template <typename F, typename... Fs>
0115 class NavigationPolicyFactoryImpl<F, Fs...> : public NavigationPolicyFactory {
0116 public:
0117
0118
0119
0120
0121
0122
0123 template <NavigationPolicyConcept P, typename... Args>
0124 requires(std::is_constructible_v<P, const GeometryContext&,
0125 const TrackingVolume&, const Logger&,
0126 Args...> &&
0127 (std::is_copy_constructible_v<Args> && ...))
0128 constexpr auto add(Args&&... args) && {
0129 auto factory = [=](const GeometryContext& gctx,
0130 const TrackingVolume& volume, const Logger& logger) {
0131 return P{gctx, volume, logger, args...};
0132 };
0133
0134 return NavigationPolicyFactoryImpl<F, Fs..., decltype(factory)>{
0135 std::tuple_cat(std::move(m_factories),
0136 std::make_tuple(std::move(factory)))};
0137 }
0138
0139
0140
0141
0142
0143
0144
0145 template <typename Fn, typename... Args>
0146 requires(NavigationPolicyIsolatedFactoryConcept<Fn, Args...>)
0147 constexpr auto add(Fn&& fn, Args&&... args) && {
0148 auto factory = [=](const GeometryContext& gctx,
0149 const TrackingVolume& volume, const Logger& logger) {
0150 return fn(gctx, volume, logger, args...);
0151 };
0152
0153 return NavigationPolicyFactoryImpl<F, Fs..., decltype(factory)>{
0154 std::tuple_cat(std::move(m_factories),
0155 std::make_tuple(std::move(factory)))};
0156 }
0157
0158
0159
0160
0161 constexpr std::unique_ptr<NavigationPolicyFactoryImpl<F, Fs...>>
0162 asUniquePtr() && {
0163 return std::make_unique<NavigationPolicyFactoryImpl<F, Fs...>>(
0164 std::move(*this));
0165 }
0166
0167
0168
0169
0170
0171 auto operator()(const GeometryContext& gctx, const TrackingVolume& volume,
0172 const Logger& logger) const {
0173 return std::apply(
0174 [&](auto&&... factories) {
0175
0176 using policy_type = decltype(MultiNavigationPolicy{
0177 std::invoke(factories, std::declval<const GeometryContext&>(),
0178 std::declval<const TrackingVolume&>(),
0179 std::declval<const Logger&>())...});
0180
0181
0182
0183 return std::make_unique<policy_type>(
0184 std::invoke(factories, gctx, volume, logger)...);
0185 },
0186 m_factories);
0187 }
0188
0189
0190
0191
0192
0193 std::unique_ptr<INavigationPolicy> build(
0194 const GeometryContext& gctx, const TrackingVolume& volume,
0195 const Logger& logger) const override {
0196 return operator()(gctx, volume, logger);
0197 }
0198
0199 private:
0200 template <typename...>
0201 friend class NavigationPolicyFactoryImpl;
0202
0203 explicit NavigationPolicyFactoryImpl(std::tuple<F, Fs...>&& factories)
0204 : m_factories(std::move(factories)) {}
0205
0206 std::tuple<F, Fs...> m_factories;
0207 };
0208
0209 }
0210
0211 inline auto NavigationPolicyFactory::make() {
0212 return detail::NavigationPolicyFactoryImpl<>{};
0213 }
0214
0215 }