ITK  5.4.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 * operator->() const noexcept { return m_Pointer; }
107
108 ObjectType & operator*() const noexcept { return *m_Pointer; }
109
110 explicit operator bool() const noexcept { return m_Pointer != nullptr; }
111
113 operator ObjectType *() const noexcept { return m_Pointer; }
114
116 bool
117 IsNotNull() const noexcept
118 {
119 return m_Pointer != nullptr;
120 }
121
123 bool
124 IsNull() const noexcept
125 {
126 return m_Pointer == nullptr;
127 }
128
129
131 ObjectType *
132 GetPointer() const noexcept
133 {
134 return m_Pointer;
135 }
136
139 ObjectType *
140 get() const noexcept
141 {
142 return m_Pointer;
143 }
144
145
152 // cppcheck-suppress operatorEqVarError
155 {
156 // The Copy-Swap idiom is used, with the implicit copy from the
157 // value-based argument r (intentionally not reference). If a move
158 // is requested it will be moved into r with the move constructor.
159 this->Swap(r);
160 return *this;
161 }
164 SmartPointer & operator=(std::nullptr_t) noexcept
165 {
166 this->UnRegister();
167 this->m_Pointer = nullptr;
168 return *this;
169 }
170
172 ObjectType *
173 Print(std::ostream & os) const
174 {
175 if (this->IsNull())
176 {
177 os << "(null)";
178 }
179 else
180 {
181 // This prints the object pointed to by the pointer
182 m_Pointer->Print(os);
183 }
184 return m_Pointer;
185 }
188#if !defined(ITK_LEGACY_REMOVE)
189 void
190 swap(SmartPointer & other) noexcept
191 {
192 this->Swap(other);
193 }
194#endif
195
196 void
197 Swap(SmartPointer & other) noexcept
198 {
199 ObjectType * tmp = this->m_Pointer;
200 this->m_Pointer = other.m_Pointer;
201 other.m_Pointer = tmp;
202 }
203
204private:
206 ObjectType * m_Pointer{ nullptr };
207
208 template <typename T>
209 friend class SmartPointer;
210
211 void
212 Register() noexcept
213 {
214 if (m_Pointer)
215 {
216 m_Pointer->Register();
217 }
218 }
219
220 void
221 UnRegister() noexcept
222 {
223 if (m_Pointer)
224 {
225 m_Pointer->UnRegister();
226 }
227 }
228};
229
230
232template <class T, class TU>
233bool
234operator==(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
235{
236 return (l.GetPointer() == r.GetPointer());
237}
238template <class T>
239bool
240operator==(const SmartPointer<T> & l, std::nullptr_t) noexcept
241{
242 return (l.GetPointer() == nullptr);
243}
244template <class T>
245bool
246operator==(std::nullptr_t, const SmartPointer<T> & r) noexcept
247{
248 return (nullptr == r.GetPointer());
249}
253template <class T, class TU>
254bool
255operator!=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
256{
257 return (l.GetPointer() != r.GetPointer());
258}
259template <class T>
260bool
261operator!=(const SmartPointer<T> & l, std::nullptr_t) noexcept
262{
263 return (l.GetPointer() != nullptr);
264}
265template <class T>
266bool
267operator!=(std::nullptr_t, const SmartPointer<T> & r) noexcept
268{
269 return (nullptr != r.GetPointer());
270}
275template <class T, class TU>
276bool
277operator<(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
278{
279 return (l.GetPointer() < r.GetPointer());
280}
281
283template <class T, class TU>
284bool
285operator>(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
286{
287 return (l.GetPointer() > r.GetPointer());
288}
289
291template <class T, class TU>
292bool
293operator<=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
294{
295 return (l.GetPointer() <= r.GetPointer());
296}
297
299template <class T, class TU>
300bool
301operator>=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
302{
303 return (l.GetPointer() >= r.GetPointer());
304}
305
306template <typename T>
307std::ostream &
308operator<<(std::ostream & os, const SmartPointer<T> p)
309{
310 p.Print(os);
311 return os;
312}
313
314template <typename T>
315inline void
317{
318 a.Swap(b);
319}
320
321} // end namespace itk
322
323#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....
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:566
void swap(Array< T > &a, Array< T > &b)
Definition: itkArray.h:242
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:573
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:545
std::ostream & operator<<(std::ostream &os, const Array< TValue > &arr)
Definition: itkArray.h:216
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:580