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 
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 * 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
153  SmartPointer &
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 
204 private:
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 
232 template <class T, class TU>
233 bool
234 operator==(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
235 {
236  return (l.GetPointer() == r.GetPointer());
237 }
238 template <class T>
239 bool
240 operator==(const SmartPointer<T> & l, std::nullptr_t) noexcept
241 {
242  return (l.GetPointer() == nullptr);
243 }
244 template <class T>
245 bool
246 operator==(std::nullptr_t, const SmartPointer<T> & r) noexcept
247 {
248  return (nullptr == r.GetPointer());
249 }
253 template <class T, class TU>
254 bool
255 operator!=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
256 {
257  return (l.GetPointer() != r.GetPointer());
258 }
259 template <class T>
260 bool
261 operator!=(const SmartPointer<T> & l, std::nullptr_t) noexcept
262 {
263  return (l.GetPointer() != nullptr);
264 }
265 template <class T>
266 bool
267 operator!=(std::nullptr_t, const SmartPointer<T> & r) noexcept
268 {
269  return (nullptr != r.GetPointer());
270 }
275 template <class T, class TU>
276 bool
277 operator<(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
278 {
279  return (l.GetPointer() < r.GetPointer());
280 }
281 
283 template <class T, class TU>
284 bool
285 operator>(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
286 {
287  return (l.GetPointer() > r.GetPointer());
288 }
289 
291 template <class T, class TU>
292 bool
293 operator<=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
294 {
295  return (l.GetPointer() <= r.GetPointer());
296 }
297 
299 template <class T, class TU>
300 bool
301 operator>=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
302 {
303  return (l.GetPointer() >= r.GetPointer());
304 }
305 
306 template <typename T>
307 std::ostream &
308 operator<<(std::ostream & os, const SmartPointer<T> p)
309 {
310  p.Print(os);
311  return os;
312 }
313 
314 template <typename T>
315 inline void
317 {
318  a.Swap(b);
319 }
320 
321 } // end namespace itk
322 
323 #endif
itk::SmartPointer::Swap
void Swap(SmartPointer &other) noexcept
Definition: itkSmartPointer.h:197
itk::SmartPointer::m_Pointer
ObjectType * m_Pointer
Definition: itkSmartPointer.h:206
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:559
itk::operator<=
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:573
itk::SmartPointer::SmartPointer
SmartPointer(ObjectType *p) noexcept
Definition: itkSmartPointer.h:96
itk::operator<<
std::ostream & operator<<(std::ostream &os, const Array< TValue > &arr)
Definition: itkArray.h:216
itk::swap
void swap(Array< T > &a, Array< T > &b)
Definition: itkArray.h:242
itk::SmartPointer::Register
void Register() noexcept
Definition: itkSmartPointer.h:212
itk::SmartPointer::SmartPointer
SmartPointer(SmartPointer< ObjectType > &&p) noexcept
Definition: itkSmartPointer.h:81
itk::SmartPointer::operator=
SmartPointer & operator=(SmartPointer r) noexcept
Definition: itkSmartPointer.h:154
itk::SmartPointer
Implements transparent reference counting.
Definition: itkSmartPointer.h:51
itk::SmartPointer::Print
ObjectType * Print(std::ostream &os) const
Definition: itkSmartPointer.h:173
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:132
itk::SmartPointer::UnRegister
void UnRegister() noexcept
Definition: itkSmartPointer.h:221
itk::SmartPointer::operator*
ObjectType & operator*() const noexcept
Definition: itkSmartPointer.h:108
itk::operator>=
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:580
itk::SmartPointer::operator->
ObjectType * operator->() const noexcept
Definition: itkSmartPointer.h:106
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:545
itk::SmartPointer::IsNull
bool IsNull() const noexcept
Definition: itkSmartPointer.h:124
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:552
itk::SmartPointer::operator=
SmartPointer & operator=(std::nullptr_t) noexcept
Definition: itkSmartPointer.h:164
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkAnnulusOperator.h:24
itk::SmartPointer::IsNotNull
bool IsNotNull() const noexcept
Definition: itkSmartPointer.h:117
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:140