ITK  5.1.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
61  : m_Pointer(nullptr)
62  {}
63 
65  SmartPointer(const SmartPointer & p) noexcept
66  : m_Pointer(p.m_Pointer)
67  {
68  this->Register();
69  }
70 
71  constexpr SmartPointer(std::nullptr_t p) noexcept
72  : m_Pointer(p)
73  {}
74 
76  template <typename T, typename = typename EnableIfConvertible<T>::type>
77  SmartPointer(const SmartPointer<T> & p) noexcept
78  : m_Pointer(p.m_Pointer)
79  {
80  this->Register();
81  }
82 
85  : m_Pointer(p.m_Pointer)
86  {
87  p.m_Pointer = nullptr;
88  }
89 
91  template <typename T, typename = typename EnableIfConvertible<T>::type>
93  : m_Pointer(p.m_Pointer)
94  {
95  p.m_Pointer = nullptr;
96  }
97 
99  SmartPointer(ObjectType * p) noexcept
100  : m_Pointer(p)
101  {
102  this->Register();
103  }
104 
107  {
108  this->UnRegister();
109  m_Pointer = nullptr;
110  }
112 
114  ObjectType * operator->() const noexcept { return m_Pointer; }
115 
116  ObjectType & operator*() const noexcept { return *m_Pointer; }
117 
118  explicit operator bool() const noexcept { return m_Pointer != nullptr; }
119 
121  operator ObjectType *() const noexcept { return m_Pointer; }
122 
124  bool
125  IsNotNull() const noexcept
126  {
127  return m_Pointer != nullptr;
128  }
129 
131  bool
132  IsNull() const noexcept
133  {
134  return m_Pointer == nullptr;
135  }
136 
137 
139  ObjectType *
140  GetPointer() const noexcept
141  {
142  return m_Pointer;
143  }
144 
151  // cppcheck-suppress operatorEqVarError
152  SmartPointer &
154  {
155  // The Copy-Swap idiom is used, with the implicit copy from the
156  // value-based argument r (intentionally not reference). If a move
157  // is requested it will be moved into r with the move constructor.
158  this->Swap(r);
159  return *this;
160  }
162 
163  SmartPointer & operator=(std::nullptr_t) noexcept
164  {
165  this->UnRegister();
166  this->m_Pointer = nullptr;
167  return *this;
168  }
169 
171  ObjectType *
172  Print(std::ostream & os) const
173  {
174  if (this->IsNull())
175  {
176  os << "(null)";
177  }
178  else
179  {
180  // This prints the object pointed to by the pointer
181  (*m_Pointer).Print(os);
182  }
183  return m_Pointer;
184  }
186 
187 #if !defined(ITK_LEGACY_REMOVE)
188  void
189  swap(SmartPointer & other) noexcept
190  {
191  this->Swap(other);
192  }
193 #endif
194 
195  void
196  Swap(SmartPointer & other) noexcept
197  {
198  ObjectType * tmp = this->m_Pointer;
199  this->m_Pointer = other.m_Pointer;
200  other.m_Pointer = tmp;
201  }
202 
203 private:
206 
207  template <typename T>
208  friend class SmartPointer;
209 
210  void
211  Register() noexcept
212  {
213  if (m_Pointer)
214  {
215  m_Pointer->Register();
216  }
217  }
218 
219  void
220  UnRegister() noexcept
221  {
222  if (m_Pointer)
223  {
224  m_Pointer->UnRegister();
225  }
226  }
227 };
228 
229 
231 template <class T, class TU>
232 bool
233 operator==(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
234 {
235  return (l.GetPointer() == r.GetPointer());
236 }
237 template <class T>
238 bool
239 operator==(const SmartPointer<T> & l, std::nullptr_t) noexcept
240 {
241  return (l.GetPointer() == nullptr);
242 }
243 template <class T>
244 bool
245 operator==(std::nullptr_t, const SmartPointer<T> & r) noexcept
246 {
247  return (nullptr == r.GetPointer());
248 }
250 
252 template <class T, class TU>
253 bool
254 operator!=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
255 {
256  return (l.GetPointer() != r.GetPointer());
257 }
258 template <class T>
259 bool
260 operator!=(const SmartPointer<T> & l, std::nullptr_t) noexcept
261 {
262  return (l.GetPointer() != nullptr);
263 }
264 template <class T>
265 bool
266 operator!=(std::nullptr_t, const SmartPointer<T> & r) noexcept
267 {
268  return (nullptr != r.GetPointer());
269 }
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 
298 template <class T, class TU>
299 bool
300 operator>=(const SmartPointer<T> & l, const SmartPointer<TU> & r) noexcept
301 {
302  return (l.GetPointer() >= r.GetPointer());
303 }
304 
305 template <typename T>
306 std::ostream &
307 operator<<(std::ostream & os, const SmartPointer<T> p)
308 {
309  p.Print(os);
310  return os;
311 }
312 
313 template <typename T>
314 inline void
316 {
317  a.Swap(b);
318 }
319 
320 } // end namespace itk
321 
322 #endif
itk::SmartPointer::Swap
void Swap(SmartPointer &other) noexcept
Definition: itkSmartPointer.h:196
itk::SmartPointer::m_Pointer
ObjectType * m_Pointer
Definition: itkSmartPointer.h:205
itk::SmartPointer::SmartPointer
SmartPointer(const SmartPointer< T > &p) noexcept
Definition: itkSmartPointer.h:77
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:99
itk::operator<<
std::ostream & operator<<(std::ostream &os, const Array< TValue > &arr)
Definition: itkArray.h:213
itk::swap
void swap(Array< T > &a, Array< T > &b)
Definition: itkArray.h:239
itk::SmartPointer::Register
void Register() noexcept
Definition: itkSmartPointer.h:211
itk::SmartPointer::SmartPointer
SmartPointer(SmartPointer< ObjectType > &&p) noexcept
Definition: itkSmartPointer.h:84
itk::SmartPointer::operator=
SmartPointer & operator=(SmartPointer r) noexcept
Definition: itkSmartPointer.h:153
itk::SmartPointer
Implements transparent reference counting.
Definition: itkSmartPointer.h:51
itk::SmartPointer::SmartPointer
SmartPointer(const SmartPointer &p) noexcept
Definition: itkSmartPointer.h:65
itk::SmartPointer::Print
ObjectType * Print(std::ostream &os) const
Definition: itkSmartPointer.h:172
itk::SmartPointer::~SmartPointer
~SmartPointer()
Definition: itkSmartPointer.h:106
itk::SmartPointer::SmartPointer
constexpr SmartPointer(std::nullptr_t p) noexcept
Definition: itkSmartPointer.h:71
itk::SmartPointer::GetPointer
ObjectType * GetPointer() const noexcept
Definition: itkSmartPointer.h:140
itk::SmartPointer::UnRegister
void UnRegister() noexcept
Definition: itkSmartPointer.h:220
itk::SmartPointer::operator*
ObjectType & operator*() const noexcept
Definition: itkSmartPointer.h:116
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:114
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:132
itk::SmartPointer::SmartPointer
SmartPointer(SmartPointer< T > &&p) noexcept
Definition: itkSmartPointer.h:92
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:163
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkArray.h:26
itk::SmartPointer::IsNotNull
bool IsNotNull() const noexcept
Definition: itkSmartPointer.h:125
itk::SmartPointer::SmartPointer
constexpr SmartPointer() noexcept
Definition: itkSmartPointer.h:60
itk::SmartPointer::ObjectType
TObjectType ObjectType
Definition: itkSmartPointer.h:54