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.
16template <CxxUtils::detail::RefCounted T>
18RefCountedPtr<T>::RefCountedPtr (T* p)
21 if (m_ptr) m_ptr->addRef();
25/// Constructor from unique_ptr. Adds to the refcount.
26template <CxxUtils::detail::RefCounted T>
27template <CxxUtils::detail::RefCounted OTHER>
28requires std::convertible_to<OTHER*, T*>
30RefCountedPtr<T>::RefCountedPtr (std::unique_ptr<OTHER>&& other)
31 : RefCountedPtr (other.release())
37template <CxxUtils::detail::RefCounted T>
39RefCountedPtr<T>::RefCountedPtr (const RefCountedPtr& other)
40 : RefCountedPtr (other.m_ptr)
46template <CxxUtils::detail::RefCounted T>
48RefCountedPtr<T>::RefCountedPtr (RefCountedPtr&& other)
49 : m_ptr (other.release())
54/// Constructor from another RefCountedPtr, with a different type.
55template <CxxUtils::detail::RefCounted T>
56template <CxxUtils::detail::RefCounted OTHER>
57requires std::convertible_to<OTHER*, T*>
59RefCountedPtr<T>::RefCountedPtr (const RefCountedPtr<OTHER>& other)
60 : RefCountedPtr (other.m_ptr)
65/// Move from another RefCountedPtr, with a different type.
66template <CxxUtils::detail::RefCounted T>
67template <CxxUtils::detail::RefCounted OTHER>
68requires std::convertible_to<OTHER*, T*>
70RefCountedPtr<T>::RefCountedPtr (RefCountedPtr<OTHER>&& other)
71 : m_ptr (other.release())
77template <CxxUtils::detail::RefCounted T>
79RefCountedPtr<T>& RefCountedPtr<T>::operator= (const RefCountedPtr& other)
87template <CxxUtils::detail::RefCounted T>
89RefCountedPtr<T>& RefCountedPtr<T>::operator= (RefCountedPtr&& other)
91 if (m_ptr) m_ptr->release();
92 m_ptr = other.release();
97/// Assignment from pointer.
98template <CxxUtils::detail::RefCounted T>
100RefCountedPtr<T>& RefCountedPtr<T>::operator= (T* p)
107/// Assignment from different type.
108template <CxxUtils::detail::RefCounted T>
109template <CxxUtils::detail::RefCounted OTHER>
110requires std::convertible_to<OTHER*, T*>
112RefCountedPtr<T>& RefCountedPtr<T>::operator= (const RefCountedPtr<OTHER>& other)
119/// Move from different type.
120template <CxxUtils::detail::RefCounted T>
121template <CxxUtils::detail::RefCounted OTHER>
122requires std::convertible_to<OTHER*, T*>
124RefCountedPtr<T>& RefCountedPtr<T>::operator= (RefCountedPtr<OTHER>&& other)
126 if (m_ptr) m_ptr->release();
127 m_ptr = other.release();
133template <CxxUtils::detail::RefCounted T>
135RefCountedPtr<T>::~RefCountedPtr()
137 if (m_ptr) m_ptr->release();
141/// Change the pointer.
142template <CxxUtils::detail::RefCounted T>
144void 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.
154template <CxxUtils::detail::RefCounted T>
156bool RefCountedPtr<T>::isValid() const
158 return m_ptr != nullptr;
162/// Check if the pointer is valid.
163template <CxxUtils::detail::RefCounted T>
165RefCountedPtr<T>::operator bool() const
167 return m_ptr != nullptr;
171/// Check if the pointer is invalid.
172template <CxxUtils::detail::RefCounted T>
174bool RefCountedPtr<T>::operator!() const
176 return m_ptr == nullptr;
181template <CxxUtils::detail::RefCounted T>
183T* RefCountedPtr<T>::get()
187template <CxxUtils::detail::RefCounted T>
189const T* RefCountedPtr<T>::get() const
195/// Convert to pointer.
196template <CxxUtils::detail::RefCounted T>
198RefCountedPtr<T>::operator T*()
202template <CxxUtils::detail::RefCounted T>
204RefCountedPtr<T>::operator const T*() const
211template <CxxUtils::detail::RefCounted T>
213T* RefCountedPtr<T>::operator->()
217template <CxxUtils::detail::RefCounted T>
219const T* RefCountedPtr<T>::operator->() const
226template <CxxUtils::detail::RefCounted T>
228T& RefCountedPtr<T>::operator*()
232template <CxxUtils::detail::RefCounted T>
234const T& RefCountedPtr<T>::operator*() const
240/// Return the pointer and give up ownership.
241template <CxxUtils::detail::RefCounted T>
243T* RefCountedPtr<T>::release()
251} // namespace CxxUtils