ITK  6.0.0
Insight Toolkit
itkSmartPointer.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18
19#ifndef itkSmartPointer_h
20#define itkSmartPointer_h
21
22#include <iostream>
23#include <utility>
24#include <type_traits>
25#include "itkConfigure.h"
26
27
28namespace itk
29{
50template <typename TObjectType>
52{
53public:
54 using ObjectType = TObjectType;
55
56 template <typename T>
57 using EnableIfConvertible = typename std::enable_if<std::is_convertible_v<T *, TObjectType *>>;
58
60 constexpr SmartPointer() noexcept = default;
61
63 SmartPointer(const SmartPointer & p) noexcept
65 {
66 this->Register();
67 }
68
70 constexpr SmartPointer(std::nullptr_t) noexcept {}
71
73 template <typename T, typename = typename EnableIfConvertible<T>::type>
74 SmartPointer(const SmartPointer<T> & p) noexcept
75 : m_Pointer(p.m_Pointer)
76 {
77 this->Register();
78 }
79
82 : m_Pointer(p.m_Pointer)
83 {
84 p.m_Pointer = nullptr;
85 }
86
88 template <typename T, typename = typename EnableIfConvertible<T>::type>
90 : m_Pointer(p.m_Pointer)
91 {
92 p.m_Pointer = nullptr;
93 }
94
97 : m_Pointer(p)
98 {
99 this->Register();
100 }
101
104
106 ObjectType *
107 operator->() const noexcept
108 {
109 return m_Pointer;
110 }
111
112 ObjectType &
113 operator*() const noexcept
114 {
115 return *m_Pointer;
116 }
117
118 explicit
119 operator bool() const noexcept
120 {
121 return m_Pointer != nullptr;
122 }
123
125 operator ObjectType *() const noexcept { return m_Pointer; }
126
128 bool
129 IsNotNull() const noexcept
130 {
131 return m_Pointer != nullptr;
132 }
133
135 bool
136 IsNull() const noexcept
137 {
138 return m_Pointer == nullptr;
139 }
140
141
143 ObjectType *
144 GetPointer() const noexcept
145 {
146 return m_Pointer;
147 }
148
151 ObjectType *
152 get() const noexcept
153 {
154 return m_Pointer;
155 }
156
157
164 // cppcheck-suppress operatorEqVarError
167 {
168 // The Copy-Swap idiom is used, with the implicit copy from the
169 // value-based argument r (intentionally not reference). If a move
170 // is requested it will be moved into r with the move constructor.
171 this->Swap(r);
172 return *this;
173 }
177 operator=(std::nullptr_t) noexcept
178 {
179 this->UnRegister();
180 this->m_Pointer = nullptr;
181 return *this;
182 }
183
185 ObjectType *
186 Print(std::ostream & os) const
187 {
188 if (this->IsNull())
189 {
190 os << "(null)";
191 }
192 else
193 {
194 // This prints the object pointed to by the pointer
195 m_Pointer->Print(os);
196 }
197 return m_Pointer;
198 }
201#if !defined(ITK_LEGACY_REMOVE)
202 void
203 swap(SmartPointer & other) noexcept
204 {
205 this->Swap(other);
206 }
207#endif
208
209 void
210 Swap(SmartPointer & other) noexcept
211 {
212 ObjectType * tmp = this->m_Pointer;
213 this->m_Pointer = other.m_Pointer;
214 other.m_Pointer = tmp;
215 }
216
217private:
219 ObjectType * m_Pointer{ nullptr };
220
221 template <typename T>
222 friend class SmartPointer;
223
224 void
225 Register() noexcept
226 {
227 if (m_Pointer)
228 {
229 m_Pointer->Register();
230 }
231 }
232
233 void
234 UnRegister() noexcept
235 {
236 if (m_Pointer)
237 {
238 m_Pointer->UnRegister();
239 }
240 }
241};
242
243
245template <class T, class TU>
246bool
247operator==(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
248{
249 return (l.GetPointer() == r.GetPointer());
250}
251template <class T>
252bool
253operator==(const SmartPointer<T> & l, std::nullptr_t) noexcept
254{
255 return (l.GetPointer() == nullptr);
256}
257template <class T>
258bool
259operator==(std::nullptr_t, const SmartPointer<T> & r) noexcept
260{
261 return (nullptr == r.GetPointer());
262}
266template <class T, class TU>
267bool
268operator!=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
269{
270 return (l.GetPointer() != r.GetPointer());
271}
272template <class T>
273bool
274operator!=(const SmartPointer<T> & l, std::nullptr_t) noexcept
275{
276 return (l.GetPointer() != nullptr);
277}
278template <class T>
279bool
280operator!=(std::nullptr_t, const SmartPointer<T> & r) noexcept
281{
282 return (nullptr != r.GetPointer());
283}
288template <class T, class TU>
289bool
290operator<(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
291{
292 return (l.GetPointer() < r.GetPointer());
293}
294
296template <class T, class TU>
297bool
298operator>(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
299{
300 return (l.GetPointer() > r.GetPointer());
301}
302
304template <class T, class TU>
305bool
306operator<=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
307{
308 return (l.GetPointer() <= r.GetPointer());
309}
310
312template <class T, class TU>
313bool
314operator>=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
315{
316 return (l.GetPointer() >= r.GetPointer());
317}
318
319template <typename T>
320std::ostream &
321operator<<(std::ostream & os, const SmartPointer<T> p)
322{
323 p.Print(os);
324 return os;
325}
326
327template <typename T>
328inline void
330{
331 a.Swap(b);
332}
333
334} // end namespace itk
335
336#endif
Implements transparent reference counting.
ObjectType & operator*() const noexcept
SmartPointer & operator=(SmartPointer r) noexcept
constexpr SmartPointer(std::nullptr_t) noexcept
ObjectType * GetPointer() const noexcept
SmartPointer(const SmartPointer< T > &p) noexcept
SmartPointer(ObjectType *p) noexcept
void UnRegister() noexcept
ObjectType * m_Pointer
bool IsNull() const noexcept
ObjectType * get() const noexcept
SmartPointer(SmartPointer< ObjectType > &&p) noexcept
ObjectType * operator->() const noexcept
void Swap(SmartPointer &other) noexcept
bool IsNotNull() const noexcept
typename std::enable_if< std::is_convertible_v< T *, TObjectType * > > EnableIfConvertible
ObjectType * Print(std::ostream &os) const
void Register() noexcept
SmartPointer(SmartPointer< T > &&p) noexcept
constexpr SmartPointer() noexcept=default
SmartPointer & operator=(std::nullptr_t) noexcept
TObjectType ObjectType
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
void swap(Array< T > &a, Array< T > &b) noexcept
Definition: itkArray.h:242
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:573
ITKCommon_EXPORT std::ostream & operator<<(std::ostream &out, typename AnatomicalOrientation::CoordinateEnum value)
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:580
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:552
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:559
bool operator<(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:566
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:587