ITK  5.2.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  * http://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<T *, TObjectType *>::value>;
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 
143  // cppcheck-suppress operatorEqVarError
144  SmartPointer &
146  {
147  // The Copy-Swap idiom is used, with the implicit copy from the
148  // value-based argument r (intentionally not reference). If a move
149  // is requested it will be moved into r with the move constructor.
150  this->Swap(r);
151  return *this;
152  }
154 
155  SmartPointer & operator=(std::nullptr_t) noexcept
156  {
157  this->UnRegister();
158  this->m_Pointer = nullptr;
159  return *this;
160  }
161 
163  ObjectType *
164  Print(std::ostream & os) const
165  {
166  if (this->IsNull())
167  {
168  os << "(null)";
169  }
170  else
171  {
172  // This prints the object pointed to by the pointer
173  (*m_Pointer).Print(os);
174  }
175  return m_Pointer;
176  }
178 
179 #if !defined(ITK_LEGACY_REMOVE)
180  void
181  swap(SmartPointer & other) noexcept
182  {
183  this->Swap(other);
184  }
185 #endif
186 
187  void
188  Swap(SmartPointer & other) noexcept
189  {
190  ObjectType * tmp = this->m_Pointer;
191  this->m_Pointer = other.m_Pointer;
192  other.m_Pointer = tmp;
193  }
194 
195 private:
197  ObjectType * m_Pointer{ nullptr };
198 
199  template <typename T>
200  friend class SmartPointer;
201 
202  void
203  Register() noexcept
204  {
205  if (m_Pointer)
206  {
207  m_Pointer->Register();
208  }
209  }
210 
211  void
212  UnRegister() noexcept
213  {
214  if (m_Pointer)
215  {
216  m_Pointer->UnRegister();
217  }
218  }
219 };
220 
221 
223 template <class T, class TU>
224 bool
225 operator==(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
226 {
227  return (l.GetPointer() == r.GetPointer());
228 }
229 template <class T>
230 bool
231 operator==(const SmartPointer<T> & l, std::nullptr_t) noexcept
232 {
233  return (l.GetPointer() == nullptr);
234 }
235 template <class T>
236 bool
237 operator==(std::nullptr_t, const SmartPointer<T> & r) noexcept
238 {
239  return (nullptr == r.GetPointer());
240 }
242 
244 template <class T, class TU>
245 bool
246 operator!=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
247 {
248  return (l.GetPointer() != r.GetPointer());
249 }
250 template <class T>
251 bool
252 operator!=(const SmartPointer<T> & l, std::nullptr_t) noexcept
253 {
254  return (l.GetPointer() != nullptr);
255 }
256 template <class T>
257 bool
258 operator!=(std::nullptr_t, const SmartPointer<T> & r) noexcept
259 {
260  return (nullptr != r.GetPointer());
261 }
263 
264 
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 
274 template <class T, class TU>
275 bool
276 operator>(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
277 {
278  return (l.GetPointer() > r.GetPointer());
279 }
280 
282 template <class T, class TU>
283 bool
284 operator<=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
285 {
286  return (l.GetPointer() <= r.GetPointer());
287 }
288 
290 template <class T, class TU>
291 bool
292 operator>=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
293 {
294  return (l.GetPointer() >= r.GetPointer());
295 }
296 
297 template <typename T>
298 std::ostream &
299 operator<<(std::ostream & os, const SmartPointer<T> p)
300 {
301  p.Print(os);
302  return os;
303 }
304 
305 template <typename T>
306 inline void
308 {
309  a.Swap(b);
310 }
311 
312 } // end namespace itk
313 
314 #endif
itk::SmartPointer::Swap
void Swap(SmartPointer &other) noexcept
Definition: itkSmartPointer.h:188
itk::SmartPointer::m_Pointer
ObjectType * m_Pointer
Definition: itkSmartPointer.h:197
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:546
itk::SmartPointer< const Self >::EnableIfConvertible
typename std::enable_if< std::is_convertible< T *, const Self * >::value > EnableIfConvertible
Definition: itkSmartPointer.h:57
itk::operator<=
bool operator<=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:560
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:218
itk::swap
void swap(Array< T > &a, Array< T > &b)
Definition: itkArray.h:244
itk::SmartPointer::Register
void Register() noexcept
Definition: itkSmartPointer.h:203
itk::SmartPointer::SmartPointer
SmartPointer(SmartPointer< ObjectType > &&p) noexcept
Definition: itkSmartPointer.h:81
itk::SmartPointer::operator=
SmartPointer & operator=(SmartPointer r) noexcept
Definition: itkSmartPointer.h:145
itk::SmartPointer
Implements transparent reference counting.
Definition: itkSmartPointer.h:51
itk::SmartPointer::Print
ObjectType * Print(std::ostream &os) const
Definition: itkSmartPointer.h:164
itk::SmartPointer::~SmartPointer
~SmartPointer()
Definition: itkSmartPointer.h:103
itk::SmartPointer::SmartPointer
constexpr SmartPointer() noexcept=default
itk::SmartPointer::GetPointer
ObjectType * GetPointer() const noexcept
Definition: itkSmartPointer.h:132
itk::SmartPointer::UnRegister
void UnRegister() noexcept
Definition: itkSmartPointer.h:212
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:567
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:553
itk::operator==
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:532
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:539
itk::SmartPointer::operator=
SmartPointer & operator=(std::nullptr_t) noexcept
Definition: itkSmartPointer.h:155
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