Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-26 08:22:00

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 // Project include(s).
0011 #include "traccc/geometry/detector.hpp"
0012 #include "traccc/geometry/detector_type_list.hpp"
0013 #include "traccc/geometry/move_only_any.hpp"
0014 
0015 // Detray include(s).
0016 #include <any>
0017 
0018 namespace traccc {
0019 
0020 /// Typeless, owning, host detector object
0021 class host_detector {
0022  public:
0023   template <typename detector_traits_t>
0024   void set(typename detector_traits_t::host&& obj)
0025     requires(is_detector_traits<detector_traits_t>)
0026   {
0027     m_obj.set<typename detector_traits_t::host>(std::move(obj));
0028   }
0029 
0030   template <typename detector_traits_t>
0031   bool is() const
0032     requires(is_detector_traits<detector_traits_t>)
0033   {
0034     return (type() == typeid(typename detector_traits_t::host));
0035   }
0036 
0037   const std::type_info& type() const { return m_obj.type(); }
0038 
0039   template <typename detector_traits_t>
0040   const typename detector_traits_t::host& as() const
0041     requires(is_detector_traits<detector_traits_t>)
0042   {
0043     return m_obj.as<typename detector_traits_t::host>();
0044   }
0045 
0046  private:
0047   move_only_any m_obj;
0048 };
0049 
0050 /// @brief Helper function for `host_detector_visitor`
0051 template <typename callable_t, typename detector_t, typename... detector_ts>
0052 auto host_detector_visitor_helper(const host_detector& host_detector,
0053                                   callable_t&& callable,
0054                                   std::tuple<detector_t, detector_ts...>*) {
0055   if (host_detector.is<detector_t>()) {
0056     return callable.template operator()<detector_t>(
0057         host_detector.as<detector_t>());
0058   } else {
0059     if constexpr (sizeof...(detector_ts) > 0) {
0060       return host_detector_visitor_helper(
0061           host_detector, std::forward<callable_t>(callable),
0062           static_cast<std::tuple<detector_ts...>*>(nullptr));
0063     } else {
0064       std::stringstream exception_message;
0065 
0066       exception_message << "Invalid detector type ("
0067                         << host_detector.type().name()
0068                         << ") received, but this type is not supported"
0069                         << std::endl;
0070 
0071       throw std::invalid_argument(exception_message.str());
0072     }
0073   }
0074 }
0075 
0076 /// @brief Visitor for polymorphic host detector types
0077 ///
0078 /// This function takes a list of supported detector trait types and checks
0079 /// if the provided field is one of them. If it is, it will call the provided
0080 /// callable on a view of it and otherwise it will throw an exception.
0081 template <typename detector_list_t, typename callable_t>
0082 auto host_detector_visitor(const host_detector& host_detector,
0083                            callable_t&& callable) {
0084   return host_detector_visitor_helper(host_detector,
0085                                       std::forward<callable_t>(callable),
0086                                       static_cast<detector_list_t*>(nullptr));
0087 }
0088 }  // namespace traccc