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