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 
28 namespace itk
29 {
50 template <typename TObjectType>
52 {
53 public:
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
64  : m_Pointer(p.m_Pointer)
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 
96  SmartPointer(ObjectType * p) noexcept
97  : m_Pointer(p)
98  {
99  this->Register();
100  }
101 
103  ~SmartPointer() { this->UnRegister(); }
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
165  SmartPointer &
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  }
176  SmartPointer &
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 
217 private:
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 
245 template <class T, class TU>
246 bool
247 operator==(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
248 {
249  return (l.GetPointer() == r.GetPointer());
250 }
251 template <class T>
252 bool
253 operator==(const SmartPointer<T> & l, std::nullptr_t) noexcept
254 {
255  return (l.GetPointer() == nullptr);
256 }
257 template <class T>
258 bool
259 operator==(std::nullptr_t, const SmartPointer<T> & r) noexcept
260 {
261  return (nullptr == r.GetPointer());
262 }
266 template <class T, class TU>
267 bool
268 operator!=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
269 {
270  return (l.GetPointer() != r.GetPointer());
271 }
272 template <class T>
273 bool
274 operator!=(const SmartPointer<T> & l, std::nullptr_t) noexcept
275 {
276  return (l.GetPointer() != nullptr);
277 }
278 template <class T>
279 bool
280 operator!=(std::nullptr_t, const SmartPointer<T> & r) noexcept
281 {
282  return (nullptr != r.GetPointer());
283 }
288 template <class T, class TU>
289 bool
290 operator<(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
291 {
292  return (l.GetPointer() < r.GetPointer());
293 }
294 
296 template <class T, class TU>
297 bool
298 operator>(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
299 {
300  return (l.GetPointer() > r.GetPointer());
301 }
302 
304 template <class T, class TU>
305 bool
306 operator<=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
307 {
308  return (l.GetPointer() <= r.GetPointer());
309 }
310 
312 template <class T, class TU>
313 bool
314 operator>=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
315 {
316  return (l.GetPointer() >= r.GetPointer());
317 }
318 
319 template <typename T>
320 std::ostream &
321 operator<<(std::ostream & os, const SmartPointer<T> p)
322 {
323  p.Print(os);
324  return os;
325 }
326 
327 template <typename T>
328 inline void
330 {
331  a.Swap(b);
332 }
333 
334 } // end namespace itk
335 
336 #endif
itk::SmartPointer::Swap
void Swap(SmartPointer &other) noexcept
Definition: itkSmartPointer.h:210
itk::SmartPointer::m_Pointer
ObjectType * m_Pointer
Definition: itkSmartPointer.h:219
itk::SmartPointer::SmartPointer
SmartPointer(const SmartPointer< T > &p) noexcept
Definition: itkSmartPointer.h:74
itk::operator<
bool operator<(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:566
itk::operator<=
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:580
itk::SmartPointer::SmartPointer
SmartPointer(ObjectType *p) noexcept
Definition: itkSmartPointer.h:96
itk::SmartPointer::Register
void Register() noexcept
Definition: itkSmartPointer.h:225
itk::SmartPointer::SmartPointer
SmartPointer(SmartPointer< ObjectType > &&p) noexcept
Definition: itkSmartPointer.h:81
itk::SmartPointer::operator=
SmartPointer & operator=(SmartPointer r) noexcept
Definition: itkSmartPointer.h:166
itk::operator<<
ITKCommon_EXPORT std::ostream & operator<<(std::ostream &out, typename AnatomicalOrientation::CoordinateEnum value)
itk::SmartPointer
Implements transparent reference counting.
Definition: itkSmartPointer.h:51
itk::SmartPointer::Print
ObjectType * Print(std::ostream &os) const
Definition: itkSmartPointer.h:186
itk::SmartPointer::~SmartPointer
~SmartPointer()
Definition: itkSmartPointer.h:103
itk::SmartPointer::SmartPointer
constexpr SmartPointer() noexcept=default
itk::SmartPointer< const Self >::EnableIfConvertible
typename std::enable_if< std::is_convertible_v< T *, const Self * > > EnableIfConvertible
Definition: itkSmartPointer.h:57
itk::SmartPointer::GetPointer
ObjectType * GetPointer() const noexcept
Definition: itkSmartPointer.h:144
itk::SmartPointer::UnRegister
void UnRegister() noexcept
Definition: itkSmartPointer.h:234
itk::SmartPointer::operator*
ObjectType & operator*() const noexcept
Definition: itkSmartPointer.h:113
itk::operator>=
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:587
itk::SmartPointer::operator->
ObjectType * operator->() const noexcept
Definition: itkSmartPointer.h:107
itk::operator>
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:573
itk::operator==
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:552
itk::SmartPointer::IsNull
bool IsNull() const noexcept
Definition: itkSmartPointer.h:136
itk::SmartPointer::SmartPointer
SmartPointer(SmartPointer< T > &&p) noexcept
Definition: itkSmartPointer.h:89
itk::operator!=
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:559
itk::SmartPointer::operator=
SmartPointer & operator=(std::nullptr_t) noexcept
Definition: itkSmartPointer.h:177
itk::swap
void swap(Array< T > &a, Array< T > &b) noexcept
Definition: itkArray.h:242
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkAnatomicalOrientation.h:29
itk::SmartPointer::IsNotNull
bool IsNotNull() const noexcept
Definition: itkSmartPointer.h:129
itk::SmartPointer::ObjectType
TObjectType ObjectType
Definition: itkSmartPointer.h:54
itk::SmartPointer::SmartPointer
constexpr SmartPointer(std::nullptr_t) noexcept
Definition: itkSmartPointer.h:70
itk::SmartPointer::get
ObjectType * get() const noexcept
Definition: itkSmartPointer.h:152