![]() |
|
|||
File indexing completed on 2025-06-21 08:08:47
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/Geometry/VolumeBounds.hpp" 0012 #include "Acts/Surfaces/SurfaceBounds.hpp" 0013 0014 #include <cassert> 0015 #include <cmath> 0016 #include <limits> 0017 #include <memory> 0018 #include <set> 0019 #include <type_traits> 0020 #include <vector> 0021 0022 namespace Acts { 0023 namespace detail { 0024 0025 /// @brief Concept to define the minimal requirements on the bounds to apply the deduplication mechanism 0026 /// using the BoundFactory. 0027 template <typename BoundsType_t> 0028 concept ComparableBoundConcept = requires(const BoundsType_t& bounds) { 0029 /// @brief Getter function to distinguish the various bound types (e.g box vs. cylinder) 0030 { bounds.type() }; 0031 /// @brief Getter function returning all defining parameters of the bounds as an std::vector 0032 { bounds.values() } -> std::same_as<std::vector<double>>; 0033 }; 0034 } // namespace detail 0035 0036 /// @brief Factory helper class to construct volume or surface bounds where the constructed bounds 0037 /// are cached inside the factory and if the same bound parameters are 0038 /// requested at a later stage the factory automatically returns the 0039 /// cached bounds. This provides a simple sharing mechanism of the same 0040 /// bounds across multiple surfaces / volumes 0041 template <detail::ComparableBoundConcept BoundsType_t> 0042 class BoundFactory { 0043 public: 0044 /// @brief Empty default constructor 0045 BoundFactory() = default; 0046 /// @brief Delete the copy constructor 0047 BoundFactory(const BoundFactory& other) = delete; 0048 /// @brief Delete copy assignment 0049 BoundFactory& operator=(const BoundFactory& other) = delete; 0050 /// @brief Pass externally constructed bounds to the factory and run the deduplication 0051 /// mechanism on them 0052 /// @tparam BoundsImpl_t: Template specification of the bounds to deduplicate 0053 /// @param bounds: Pointer to the bounds to deduplicated 0054 /// @return Pointer to an equivalent bound object 0055 template <typename BoundsImpl_t> 0056 std::shared_ptr<BoundsImpl_t> insert( 0057 const std::shared_ptr<BoundsImpl_t>& bounds) 0058 requires(std::is_base_of_v<BoundsType_t, BoundsImpl_t>) 0059 { 0060 assert(bounds); 0061 return std::dynamic_pointer_cast<BoundsImpl_t>( 0062 *m_boundSet.insert(bounds).first); 0063 } 0064 /// @brief Factory method to construct new bounds from the passed arguments 0065 /// @tparam BoundsImpl_t: Explicit template specification of the bounds to construct 0066 /// @param args: List of defining bound parameters 0067 /// @return A pointer to the newly constructed bounds or to an already existing 0068 /// equivalent bound object 0069 template <typename BoundsImpl_t, class... argList> 0070 std::shared_ptr<BoundsImpl_t> makeBounds(argList... args) 0071 requires(std::is_base_of_v<BoundsType_t, BoundsImpl_t>) 0072 { 0073 return insert(std::make_shared<BoundsImpl_t>(args...)); 0074 } 0075 /// @brief Returns the number of cached objects inside the bound factory 0076 std::size_t size() const { return m_boundSet.size(); } 0077 0078 private: 0079 /// @brief Helper struct to actually perform the deduplication of the passed bound objects. 0080 /// For a pair of two bound pointers, the struct defines the < 0081 /// operator which is then exploited by a std::set to deduplicate 0082 /// equivalent bounds. 0083 struct BoundComparator { 0084 public: 0085 /// @brief Implementation of the comparison operator between two bound pointers 0086 /// @param a: First bound pointer in the comparison 0087 /// @param b: Second bound pointer in the comparison 0088 bool operator()(const std::shared_ptr<BoundsType_t>& a, 0089 const std::shared_ptr<BoundsType_t>& b) const { 0090 /// If we deal with two fundamental different bound sets, then just 0091 /// cast the type to int and return the comparison 0092 if (a->type() != b->type()) { 0093 return static_cast<int>(a->type()) < static_cast<int>(b->type()); 0094 } 0095 const std::vector<double> avalues{a->values()}; 0096 const std::vector<double> bvalues{b->values()}; 0097 /// In case of polygon shaped bounds, the vectors may differ 0098 if (avalues.size() != bvalues.size()) { 0099 return avalues.size() < bvalues.size(); 0100 } 0101 /// Loop over the defining parameters of the two bounds and compare them 0102 /// pairwise. If a difference is spotted, then use it to assign the < 0103 /// ordering 0104 return std::ranges::lexicographical_compare( 0105 avalues, bvalues, 0106 [](double parA, double parB) { return parA < parB; }); 0107 } 0108 }; 0109 std::set<std::shared_ptr<BoundsType_t>, BoundComparator> m_boundSet{}; 0110 }; 0111 0112 /// @brief Abrivation for a factory to construct surface bounds 0113 using SurfaceBoundFactory = BoundFactory<SurfaceBounds>; 0114 /// @brief Abrivation for a factory to construct volume bounds 0115 using VolumeBoundFactory = BoundFactory<VolumeBounds>; 0116 0117 } // namespace Acts
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |