Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-26 08:21:57

0001 /** TRACCC library, part of the ACTS project (R&D line)
0002  *
0003  * (c) 2025 CERN for the benefit of the ACTS project
0004  *
0005  * Mozilla Public License Version 2.0
0006  */
0007 
0008 #pragma once
0009 
0010 // Covfie include(s).
0011 #include <covfie/core/concepts.hpp>
0012 #include <covfie/core/field.hpp>
0013 
0014 // System include(s).
0015 #include <any>
0016 #include <sstream>
0017 
0018 namespace traccc {
0019 
0020 /// Typeless, owning, host-only magnetic field object
0021 class magnetic_field {
0022  public:
0023   /// Default constructor
0024   magnetic_field() = default;
0025 
0026   /// Constructor from a specific b-field object
0027   ///
0028   /// @tparam bfield_backend_t The backend type of the b-field object
0029   /// @param obj The b-field object to construct from
0030   ///
0031   template <covfie::concepts::field_backend bfield_backend_t>
0032   explicit magnetic_field(covfie::field<bfield_backend_t>&& obj);
0033 
0034   /// Set a specific b-field object
0035   ///
0036   /// @tparam bfield_backend_t The backend type of the b-field object
0037   /// @param obj The b-field object to set
0038   ///
0039   template <covfie::concepts::field_backend bfield_backend_t>
0040   void set(covfie::field<bfield_backend_t>&& obj);
0041 
0042   /// Check if the b-field is of a certain type
0043   ///
0044   /// @tparam bfield_backend_t The covfie backend type to check
0045   /// @return @c true if the b-field is of the specified type,
0046   ///         @c false otherwise
0047   ///
0048   template <covfie::concepts::field_backend bfield_backend_t>
0049   bool is() const;
0050 
0051   /// Get a b-field view object as a specific type
0052   ///
0053   /// @tparam bfield_backend_t The covfie backend type to use
0054   /// @return The b-field view object of the specified type
0055   ///
0056   template <covfie::concepts::field_backend bfield_backend_t>
0057   typename covfie::field<bfield_backend_t>::view_t as_view() const;
0058 
0059   /// Get the b-field object as a specific type
0060   ///
0061   /// @tparam bfield_backend_t The covfie backend type to use
0062   /// @return The b-field object cast to the specified type
0063   ///
0064   template <covfie::concepts::field_backend bfield_backend_t>
0065   const covfie::field<bfield_backend_t>& as_field() const;
0066 
0067   /// @brief Return type information about the contained magnetic field.
0068   const std::type_info& type() const { return m_field.type(); }
0069 
0070  private:
0071   /// The actualy covfie b-field object
0072   std::any m_field;
0073 
0074 };  // class magnetic_field
0075 
0076 /// @brief Helper function for `bfield_visitor`
0077 template <typename callable_t, typename bfield_t, typename... bfield_ts>
0078 auto magnetic_field_visitor_helper(const magnetic_field& bfield,
0079                                    callable_t&& callable,
0080                                    std::tuple<bfield_t, bfield_ts...>*)
0081   requires(covfie::concepts::field_backend<bfield_t> &&
0082            (covfie::concepts::field_backend<bfield_ts> && ...))
0083 {
0084   if (bfield.is<bfield_t>()) {
0085     return callable(bfield.as_view<bfield_t>());
0086   } else {
0087     if constexpr (sizeof...(bfield_ts) > 0) {
0088       return magnetic_field_visitor_helper(
0089           bfield, std::forward<callable_t>(callable),
0090           static_cast<std::tuple<bfield_ts...>*>(nullptr));
0091     } else {
0092       std::stringstream exception_message;
0093 
0094       exception_message << "Invalid B-field type (" << bfield.type().name()
0095                         << ") received, but this type is not supported"
0096                         << std::endl;
0097 
0098       throw std::invalid_argument(exception_message.str());
0099     }
0100   }
0101 }
0102 
0103 /// @brief Visitor for polymorphic magnetic field types
0104 ///
0105 /// This function takes a list of supported magnetic field types and checks
0106 /// if the provided field is one of them. If it is, it will call the provided
0107 /// callable on a view of it and otherwise it will throw an exception.
0108 template <typename bfield_list_t, typename callable_t>
0109 auto magnetic_field_visitor(const magnetic_field& bfield,
0110                             callable_t&& callable) {
0111   return magnetic_field_visitor_helper(bfield,
0112                                        std::forward<callable_t>(callable),
0113                                        static_cast<bfield_list_t*>(nullptr));
0114 }
0115 
0116 }  // namespace traccc
0117 
0118 // Include the implementation.
0119 #include "traccc/bfield/impl/magnetic_field.ipp"