Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-13 08:19:00

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/Utilities/PointerTraits.hpp"
0012 
0013 #include <concepts>
0014 #include <type_traits>
0015 #include <utility>
0016 
0017 namespace Acts {
0018 
0019 /// @brief Non-owning holder for referencing a backend.
0020 /// @tparam T Backend type.
0021 ///
0022 /// The referenced backend must outlive the holder.
0023 template <typename T>
0024 struct RefHolder {
0025   /// Element type
0026   using element_type = T;
0027 
0028   /// Pointer to the referenced object
0029   T* ptr;
0030 
0031   /// Constructor from pointer
0032   /// @param _ptr Pointer to the object
0033   explicit RefHolder(T* _ptr) : ptr{_ptr} {}
0034   /// Constructor from reference
0035   /// @param ref Reference to the object
0036   explicit RefHolder(T& ref) : ptr{&ref} {}
0037 
0038   /// Dereference operator
0039   /// @return Const reference to the object
0040   const T& operator*() const { return *ptr; }
0041   /// Dereference operator
0042   /// @return Reference to the object
0043   T& operator*() { return *ptr; }
0044 
0045   /// Arrow operator
0046   /// @return Const pointer to the object
0047   const T* operator->() const { return ptr; }
0048   /// Arrow operator
0049   /// @return Pointer to the object
0050   T* operator->() { return ptr; }
0051 
0052   /// Bool conversion operator
0053   explicit operator bool() const { return ptr != nullptr; }
0054 };
0055 
0056 /// @brief Non-owning holder for referencing a backend with const access.
0057 /// @tparam T Backend type.
0058 ///
0059 /// The referenced backend must outlive the holder.
0060 template <typename T>
0061 struct ConstRefHolder {
0062   /// Element type
0063   using element_type = std::add_const_t<T>;
0064 
0065   /// Pointer to the referenced object
0066   const T* ptr;
0067 
0068   /// Constructor from pointer
0069   /// @param _ptr Pointer to the object
0070   explicit ConstRefHolder(const T* _ptr) : ptr{_ptr} {}
0071   /// Constructor from reference
0072   /// @param ref Reference to the object
0073   explicit ConstRefHolder(const T& ref) : ptr{&ref} {}
0074 
0075   /// Dereference operator
0076   /// @return Reference to the object
0077   const T& operator*() const { return *ptr; }
0078 
0079   /// Arrow operator
0080   /// @return Pointer to the object
0081   const T* operator->() const { return ptr; }
0082 
0083   /// Bool conversion operator
0084   explicit operator bool() const { return ptr != nullptr; }
0085 };
0086 
0087 /// @brief Owning holder that stores a backend by value.
0088 /// @tparam T Backend type.
0089 ///
0090 /// The backend is moved into the holder and owned for its lifetime.
0091 template <typename T>
0092 struct ValueHolder {
0093   /// Element type
0094   using element_type = T;
0095 
0096   /// Stored value
0097   T val;
0098 
0099   // Let's be clear with the user that we take the ownership
0100   // Only require rvalues and avoid hidden copies
0101   ValueHolder(T& _val) = delete;
0102   /// Constructor from rvalue
0103   /// @param _val Value to move into the holder
0104   // @FIXME: Ideally we want this to be explicit, but cannot be explicit,
0105   // because using an explicit constructor and a deduction guide leads to
0106   // a SEGFAULT in GCC11 (an up?). Re-evaluate down the line
0107   /* explicit */ ValueHolder(T&& _val) : val{std::move(_val)} {}  // NOLINT
0108 
0109   // Does it make sense to allow copy operations?
0110 
0111   /// Dereference operator
0112   /// @return Const reference to the value
0113   const T& operator*() const { return val; }
0114   /// Dereference operator
0115   /// @return Reference to the value
0116   T& operator*() { return val; }
0117 
0118   /// Arrow operator
0119   /// @return Const pointer to the value
0120   const T* operator->() const { return &val; }
0121   /// Arrow operator
0122   /// @return Pointer to the value
0123   T* operator->() { return &val; }
0124 
0125   /// Bool conversion operator
0126   explicit operator bool() const { return true; }
0127 };
0128 
0129 /// @brief Concept for holder templates that provide pointer-like access.
0130 /// @tparam Holder Holder template to instantiate.
0131 /// @tparam T Backend type.
0132 ///
0133 /// This concept is satisfied by RefHolder, ConstRefHolder, ValueHolder, and
0134 /// smart pointers such as std::shared_ptr and std::unique_ptr.
0135 template <template <typename...> class Holder, typename T>
0136 concept HolderFor =
0137     std::move_constructible<Holder<T>> && PointerConcept<Holder<T>>;
0138 
0139 }  // namespace Acts
0140 
0141 namespace Acts::detail {
0142 template <typename T>
0143 using RefHolder = Acts::RefHolder<T>;
0144 
0145 template <typename T>
0146 using ConstRefHolder = Acts::ConstRefHolder<T>;
0147 
0148 template <typename T>
0149 using ValueHolder = Acts::ValueHolder<T>;
0150 }  // namespace Acts::detail