ATLAS Offline Software
Loading...
Searching...
No Matches
RefCountedPtr.icc
Go to the documentation of this file.
1/*
2 * Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration.
3 */
4/**
5 * @file CxxUtils/RefCountedPtr.icc
6 * @author scott snyder <snyder@bnl.gov>
7 * @date Oct, 2025
8 * @brief Simple smart pointer for Gaudi-style refcounted objects.
9 */
10
11
12namespace CxxUtils {
13
14
15/// Constructor from pointer. Adds to the refcount.
16template <CxxUtils::detail::RefCounted T>
17inline
18RefCountedPtr<T>::RefCountedPtr (T* p)
19 : m_ptr (p)
20{
21 if (m_ptr) m_ptr->addRef();
22}
23
24
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*>
29inline
30RefCountedPtr<T>::RefCountedPtr (std::unique_ptr<OTHER>&& other)
31 : RefCountedPtr (other.release())
32{
33}
34
35
36/// Copy constructor.
37template <CxxUtils::detail::RefCounted T>
38inline
39RefCountedPtr<T>::RefCountedPtr (const RefCountedPtr& other)
40 : RefCountedPtr (other.m_ptr)
41{
42}
43
44
45/// Move constructor.
46template <CxxUtils::detail::RefCounted T>
47inline
48RefCountedPtr<T>::RefCountedPtr (RefCountedPtr&& other)
49 : m_ptr (other.release())
50{
51}
52
53
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*>
58inline
59RefCountedPtr<T>::RefCountedPtr (const RefCountedPtr<OTHER>& other)
60 : RefCountedPtr (other.m_ptr)
61{
62}
63
64
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*>
69inline
70RefCountedPtr<T>::RefCountedPtr (RefCountedPtr<OTHER>&& other)
71 : m_ptr (other.release())
72{
73}
74
75
76/// Assignment.
77template <CxxUtils::detail::RefCounted T>
78inline
79RefCountedPtr<T>& RefCountedPtr<T>::operator= (const RefCountedPtr& other)
80{
81 reset (other.m_ptr);
82 return *this;
83}
84
85
86/// Move.
87template <CxxUtils::detail::RefCounted T>
88inline
89RefCountedPtr<T>& RefCountedPtr<T>::operator= (RefCountedPtr&& other)
90{
91 if (m_ptr) m_ptr->release();
92 m_ptr = other.release();
93 return *this;
94}
95
96
97/// Assignment from pointer.
98template <CxxUtils::detail::RefCounted T>
99inline
100RefCountedPtr<T>& RefCountedPtr<T>::operator= (T* p)
101{
102 reset (p);
103 return *this;
104}
105
106
107/// Assignment from different type.
108template <CxxUtils::detail::RefCounted T>
109template <CxxUtils::detail::RefCounted OTHER>
110requires std::convertible_to<OTHER*, T*>
111inline
112RefCountedPtr<T>& RefCountedPtr<T>::operator= (const RefCountedPtr<OTHER>& other)
113{
114 reset (other.m_ptr);
115 return *this;
116}
117
118
119/// Move from different type.
120template <CxxUtils::detail::RefCounted T>
121template <CxxUtils::detail::RefCounted OTHER>
122requires std::convertible_to<OTHER*, T*>
123inline
124RefCountedPtr<T>& RefCountedPtr<T>::operator= (RefCountedPtr<OTHER>&& other)
125{
126 if (m_ptr) m_ptr->release();
127 m_ptr = other.release();
128 return *this;
129}
130
131
132/// Destructor.
133template <CxxUtils::detail::RefCounted T>
134inline
135RefCountedPtr<T>::~RefCountedPtr()
136{
137 if (m_ptr) m_ptr->release();
138}
139
140
141/// Change the pointer.
142template <CxxUtils::detail::RefCounted T>
143inline
144void RefCountedPtr<T>::reset (T* p)
145{
146 if (p == m_ptr) return;
147 if (m_ptr) m_ptr->release();
148 m_ptr = p;
149 if (m_ptr) m_ptr->addRef();
150}
151
152
153/// Check if the pointer is valid.
154template <CxxUtils::detail::RefCounted T>
155inline
156bool RefCountedPtr<T>::isValid() const
157{
158 return m_ptr != nullptr;
159}
160
161
162/// Check if the pointer is valid.
163template <CxxUtils::detail::RefCounted T>
164inline
165RefCountedPtr<T>::operator bool() const
166{
167 return m_ptr != nullptr;
168}
169
170
171/// Check if the pointer is invalid.
172template <CxxUtils::detail::RefCounted T>
173inline
174bool RefCountedPtr<T>::operator!() const
175{
176 return m_ptr == nullptr;
177}
178
179
180/// Get the pointer.
181template <CxxUtils::detail::RefCounted T>
182inline
183T* RefCountedPtr<T>::get()
184{
185 return m_ptr;
186}
187template <CxxUtils::detail::RefCounted T>
188inline
189const T* RefCountedPtr<T>::get() const
190{
191 return m_ptr;
192}
193
194
195/// Convert to pointer.
196template <CxxUtils::detail::RefCounted T>
197inline
198RefCountedPtr<T>::operator T*()
199{
200 return m_ptr;
201}
202template <CxxUtils::detail::RefCounted T>
203inline
204RefCountedPtr<T>::operator const T*() const
205{
206 return m_ptr;
207}
208
209
210/// Dereference.
211template <CxxUtils::detail::RefCounted T>
212inline
213T* RefCountedPtr<T>::operator->()
214{
215 return m_ptr;
216}
217template <CxxUtils::detail::RefCounted T>
218inline
219const T* RefCountedPtr<T>::operator->() const
220{
221 return m_ptr;
222}
223
224
225/// Dereference.
226template <CxxUtils::detail::RefCounted T>
227inline
228T& RefCountedPtr<T>::operator*()
229{
230 return *m_ptr;
231}
232template <CxxUtils::detail::RefCounted T>
233inline
234const T& RefCountedPtr<T>::operator*() const
235{
236 return *m_ptr;
237}
238
239
240/// Return the pointer and give up ownership.
241template <CxxUtils::detail::RefCounted T>
242inline
243T* RefCountedPtr<T>::release()
244{
245 T* p = m_ptr;
246 m_ptr = nullptr;
247 return p;
248}
249
250
251} // namespace CxxUtils