2 * Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration.
5 * @file CxxUtils/RefCountedPtr.icc
6 * @author scott snyder <snyder@bnl.gov>
8 * @brief Simple smart pointer for Gaudi-style refcounted objects.
15 /// Constructor from pointer. Adds to the refcount.
16 template <CxxUtils::detail::RefCounted T>
18 RefCountedPtr<T>::RefCountedPtr (T* p)
21 if (m_ptr) m_ptr->addRef();
25 /// Constructor from unique_ptr. Adds to the refcount.
26 template <CxxUtils::detail::RefCounted T>
27 template <CxxUtils::detail::RefCounted OTHER>
28 requires std::convertible_to<OTHER*, T*>
30 RefCountedPtr<T>::RefCountedPtr (std::unique_ptr<OTHER>&& other)
31 : RefCountedPtr (other.release())
37 template <CxxUtils::detail::RefCounted T>
39 RefCountedPtr<T>::RefCountedPtr (const RefCountedPtr& other)
40 : RefCountedPtr (other.m_ptr)
46 template <CxxUtils::detail::RefCounted T>
48 RefCountedPtr<T>::RefCountedPtr (RefCountedPtr&& other)
49 : m_ptr (other.release())
54 /// Constructor from another RefCountedPtr, with a different type.
55 template <CxxUtils::detail::RefCounted T>
56 template <CxxUtils::detail::RefCounted OTHER>
57 requires std::convertible_to<OTHER*, T*>
59 RefCountedPtr<T>::RefCountedPtr (const RefCountedPtr<OTHER>& other)
60 : RefCountedPtr (other.m_ptr)
65 /// Move from another RefCountedPtr, with a different type.
66 template <CxxUtils::detail::RefCounted T>
67 template <CxxUtils::detail::RefCounted OTHER>
68 requires std::convertible_to<OTHER*, T*>
70 RefCountedPtr<T>::RefCountedPtr (RefCountedPtr<OTHER>&& other)
71 : m_ptr (other.release())
77 template <CxxUtils::detail::RefCounted T>
79 RefCountedPtr<T>& RefCountedPtr<T>::operator= (const RefCountedPtr& other)
87 template <CxxUtils::detail::RefCounted T>
89 RefCountedPtr<T>& RefCountedPtr<T>::operator= (RefCountedPtr&& other)
91 if (m_ptr) m_ptr->release();
92 m_ptr = other.release();
97 /// Assignment from pointer.
98 template <CxxUtils::detail::RefCounted T>
100 RefCountedPtr<T>& RefCountedPtr<T>::operator= (T* p)
107 /// Assignment from different type.
108 template <CxxUtils::detail::RefCounted T>
109 template <CxxUtils::detail::RefCounted OTHER>
110 requires std::convertible_to<OTHER*, T*>
112 RefCountedPtr<T>& RefCountedPtr<T>::operator= (const RefCountedPtr<OTHER>& other)
119 /// Move from different type.
120 template <CxxUtils::detail::RefCounted T>
121 template <CxxUtils::detail::RefCounted OTHER>
122 requires std::convertible_to<OTHER*, T*>
124 RefCountedPtr<T>& RefCountedPtr<T>::operator= (RefCountedPtr<OTHER>&& other)
126 if (m_ptr) m_ptr->release();
127 m_ptr = other.release();
133 template <CxxUtils::detail::RefCounted T>
135 RefCountedPtr<T>::~RefCountedPtr()
137 if (m_ptr) m_ptr->release();
141 /// Change the pointer.
142 template <CxxUtils::detail::RefCounted T>
144 void RefCountedPtr<T>::reset (T* p)
146 if (p == m_ptr) return;
147 if (m_ptr) m_ptr->release();
149 if (m_ptr) m_ptr->addRef();
153 /// Check if the pointer is valid.
154 template <CxxUtils::detail::RefCounted T>
156 bool RefCountedPtr<T>::isValid() const
158 return m_ptr != nullptr;
162 /// Check if the pointer is valid.
163 template <CxxUtils::detail::RefCounted T>
165 RefCountedPtr<T>::operator bool() const
167 return m_ptr != nullptr;
171 /// Check if the pointer is invalid.
172 template <CxxUtils::detail::RefCounted T>
174 bool RefCountedPtr<T>::operator!() const
176 return m_ptr == nullptr;
181 template <CxxUtils::detail::RefCounted T>
183 T* RefCountedPtr<T>::get()
187 template <CxxUtils::detail::RefCounted T>
189 const T* RefCountedPtr<T>::get() const
195 /// Convert to pointer.
196 template <CxxUtils::detail::RefCounted T>
198 RefCountedPtr<T>::operator T*()
202 template <CxxUtils::detail::RefCounted T>
204 RefCountedPtr<T>::operator const T*() const
211 template <CxxUtils::detail::RefCounted T>
213 T* RefCountedPtr<T>::operator->()
217 template <CxxUtils::detail::RefCounted T>
219 const T* RefCountedPtr<T>::operator->() const
226 template <CxxUtils::detail::RefCounted T>
228 T& RefCountedPtr<T>::operator*()
232 template <CxxUtils::detail::RefCounted T>
234 const T& RefCountedPtr<T>::operator*() const
240 /// Return the pointer and give up ownership.
241 template <CxxUtils::detail::RefCounted T>
243 T* RefCountedPtr<T>::release()
251 } // namespace CxxUtils