Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-03-30 07:45:38

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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 /// Concept for factory functions that create navigation policies
0027 /// @tparam F The factory function type
0028 /// @tparam Args The argument types for the factory function
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 }  // namespace detail
0040 
0041 /// Base class for navigation policy factories. The factory can be assembled
0042 /// iteratively by using `make` followed by a number of calls to the `add`
0043 /// function of the helper type. Example:
0044 ///
0045 /// ```cpp
0046 /// auto factory = NavigationPolicyFactory{}
0047 ///  .add<NavigationPolicy1>(arg1, arg2)
0048 ///  .add<NavigationPolicy2>(/*no args*/)
0049 ///  .asUniquePtr();
0050 /// ```
0051 class NavigationPolicyFactory {
0052  private:
0053   /// Type alias for factory functions that create navigation policies
0054   using factory_type = std::function<std::unique_ptr<INavigationPolicy>(
0055       const GeometryContext&, const TrackingVolume&, const Logger&)>;
0056 
0057   /// Private constructor for internal use
0058   /// @param factories Vector of factory functions
0059   explicit NavigationPolicyFactory(std::vector<factory_type>&& factories)
0060       : m_factories(std::move(factories)) {}
0061 
0062  public:
0063   /// Default constructor
0064   NavigationPolicyFactory() = default;
0065 
0066   /// Add a navigation policy to the factory
0067   /// @tparam P The policy type to add
0068   /// @param args The arguments to pass to the policy constructor
0069   /// @note Arguments need to be copy constructible because the factory must be
0070   ///       able to execute multiple times.
0071   /// @return New instance of this object with the added factory for method
0072   ///         chaining
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   /// Add a policy created by a factory function
0089   /// @tparam Fn The type of the function to construct the policy
0090   /// @param fn The factory function
0091   /// @param args The arguments to pass to the policy factory
0092   /// @note Arguments need to be copy constructible because the factory must be
0093   ///       able to execute multiple times.
0094   /// @return New instance of this object with the added factory for method
0095   ///         chaining
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   /// Move the factory into a unique pointer
0110   /// @return A unique pointer to the factory
0111   std::unique_ptr<NavigationPolicyFactory> asUniquePtr() && {
0112     return std::make_unique<NavigationPolicyFactory>(std::move(*this));
0113   }
0114 
0115   /// Construct a multi-navigation policy using the registered factories
0116   /// @param gctx The geometry context
0117   /// @param volume The tracking volume
0118   /// @param logger The logger
0119   /// @return A unique pointer to the constructed MultiNavigationPolicy
0120   /// @throws std::runtime_error if no factories are registered
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   /// Construct a navigation policy using the factories (alias for operator())
0139   /// @param gctx The geometry context
0140   /// @param volume The tracking volume
0141   /// @param logger The logger
0142   /// @return A unique pointer to the constructed navigation policy
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   /// Vector of factory functions to create navigation policies
0151   std::vector<factory_type> m_factories;
0152 };
0153 
0154 }  // namespace Acts