ITK  5.0.0
Insight Segmentation and Registration Toolkit
itkSmartPointer.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
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> using EnableIfConvertible =
57  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  { this->Register(); }
68 
69  constexpr SmartPointer (std::nullptr_t p) noexcept:
70  m_Pointer(p)
71  {}
72 
74  template<typename T,
75  typename = typename EnableIfConvertible<T>::type>
76  SmartPointer(const SmartPointer<T> &p) noexcept:
77  m_Pointer(p.m_Pointer)
78  {
79  this->Register();
80  }
81 
85  { p.m_Pointer = nullptr; }
86 
88  template<typename T,
89  typename = typename EnableIfConvertible<T>::type >
90  SmartPointer( SmartPointer<T> &&p) noexcept:
92  { p.m_Pointer = nullptr; }
93 
95  SmartPointer (ObjectType *p) noexcept:
96  m_Pointer(p)
97  { this->Register(); }
98 
101  {
102  this->UnRegister();
103  m_Pointer = nullptr;
104  }
106 
108  ObjectType * operator->() const noexcept
109  { return m_Pointer; }
110 
111  ObjectType &operator*() const noexcept
112  {return *m_Pointer;}
113 
114  explicit operator bool() const noexcept
115  { return m_Pointer != nullptr; }
116 
118  operator ObjectType *() const noexcept
119  { return m_Pointer; }
120 
122  bool IsNotNull() const noexcept
123  { return m_Pointer != nullptr; }
124 
126  bool IsNull() const noexcept
127  { return m_Pointer == nullptr; }
128 
129 
131  ObjectType * GetPointer() const noexcept
132  { return m_Pointer; }
133 
140  // cppcheck-suppress operatorEqVarError
142  {
143  // The Copy-Swap idiom is used, with the implicit copy from the
144  // value-based argument r (intentionally not reference). If a move
145  // is requested it will be moved into r with the move constructor.
146  this->Swap(r);
147  return *this;
148  }
150 
151  SmartPointer &operator=(std::nullptr_t) noexcept
152  {
153  this->UnRegister();
154  this->m_Pointer = nullptr;
155  return *this;
156  }
157 
159  ObjectType * Print(std::ostream & os) const
160  {
161  if( this->IsNull() )
162  {
163  os << "(null)";
164  }
165  else
166  {
167  // This prints the object pointed to by the pointer
168  ( *m_Pointer ).Print(os);
169  }
170  return m_Pointer;
171  }
173 
174 #if ! defined ( ITK_LEGACY_REMOVE )
175  void swap(SmartPointer &other) noexcept
176  {
177  this->Swap(other);
178  }
179 #endif
180 
181  void Swap(SmartPointer &other) noexcept
182  {
183  ObjectType *tmp = this->m_Pointer;
184  this->m_Pointer = other.m_Pointer;
185  other.m_Pointer = tmp;
186  }
187 
188 private:
191 
192  template<typename T>
193  friend class SmartPointer;
194 
195  void Register() noexcept
196  {
197  if ( m_Pointer ) { m_Pointer->Register(); }
198  }
199 
200  void UnRegister() noexcept
201  {
202  if ( m_Pointer ) { m_Pointer->UnRegister(); }
203  }
204 };
205 
206 
208 template < class T, class TU >
209 bool operator==( const SmartPointer<T>& l, const SmartPointer<TU>& r ) noexcept
210 { return ( l.GetPointer() == r.GetPointer() ); }
211 template < class T >
212 bool operator==( const SmartPointer<T>& l, std::nullptr_t ) noexcept
213 { return ( l.GetPointer() == nullptr ); }
214 template < class T >
215 bool operator==( std::nullptr_t, const SmartPointer<T>& r ) noexcept
216 { return ( nullptr == r.GetPointer() ); }
218 
220 template < class T, class TU >
221 bool operator!=( const SmartPointer<T>& l, const SmartPointer<TU>& r ) noexcept
222 { return ( l.GetPointer() != r.GetPointer() ); }
223 template < class T >
224 bool operator!=( const SmartPointer<T>& l, std::nullptr_t ) noexcept
225 { return ( l.GetPointer() != nullptr ); }
226 template < class T >
227 bool operator!=( std::nullptr_t, const SmartPointer<T>& r ) noexcept
228 { return ( nullptr != r.GetPointer() ); }
230 
231 
233 template < class T, class TU >
234 bool operator<( const SmartPointer<T>& l, const SmartPointer<TU>& r ) noexcept
235 { return ( l.GetPointer() < r.GetPointer() ); }
236 
238 template < class T, class TU >
239 bool operator>( const SmartPointer<T>& l, const SmartPointer<TU>& r ) noexcept
240 { return ( l.GetPointer() > r.GetPointer() ); }
241 
243 template < class T, class TU >
244 bool operator<=( const SmartPointer<T>& l, const SmartPointer<TU>& r ) noexcept
245 { return ( l.GetPointer() <= r.GetPointer() ); }
246 
248 template < class T, class TU >
249 bool operator>=( const SmartPointer<T>& l, const SmartPointer<TU>& r ) noexcept
250 { return ( l.GetPointer() >= r.GetPointer() ); }
251 
252 template< typename T >
253 std::ostream & operator<<(std::ostream & os, SmartPointer< T > p)
254 {
255  p.Print(os);
256  return os;
257 }
258 
259 template<typename T>
260 inline void swap( SmartPointer<T> &a, SmartPointer<T> &b ) noexcept
261 {
262  a.Swap(b);
263 }
264 
265 } // end namespace itk
266 
267 #endif
constexpr SmartPointer() noexcept
bool operator==(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:485
void UnRegister() noexcept
SmartPointer(SmartPointer< ObjectType > &&p) noexcept
ObjectType * GetPointer() const noexcept
bool operator>(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:507
SmartPointer(const SmartPointer< T > &p) noexcept
SmartPointer & operator=(SmartPointer r) noexcept
void Register() noexcept
bool IsNotNull() const noexcept
TObjectType ObjectType
SmartPointer(const SmartPointer &p) noexcept
void swap(Array< T > &a, Array< T > &b)
Definition: itkArray.h:211
ObjectType * operator->() const noexcept
bool operator!=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:492
SmartPointer & operator=(std::nullptr_t) noexcept
bool IsNull() const noexcept
typename std::enable_if< std::is_convertible< T *, const Self * >::value > EnableIfConvertible
SmartPointer(ObjectType *p) noexcept
ObjectType & operator*() const noexcept
Implements transparent reference counting.
SmartPointer(SmartPointer< T > &&p) noexcept
ObjectType * Print(std::ostream &os) const
constexpr SmartPointer(std::nullptr_t p) noexcept
bool operator>=(const Index< VDimension > &one, const Index< VDimension > &two)
Definition: itkIndex.h:521
ObjectType * m_Pointer
void Swap(SmartPointer &other) noexcept