3DiVi Face SDK  3.24.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Groups
heavy_shared_ptr.h
1 // Actually this is a smart pointer from OpenCV library assembled in a single file.
2 
3 
4 /*M///////////////////////////////////////////////////////////////////////////////////////
5 //
6 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
7 //
8 // By downloading, copying, installing or using the software you agree to this license.
9 // If you do not agree to this license, do not download, install,
10 // copy or use the software.
11 //
12 //
13 // License Agreement
14 // For Open Source Computer Vision Library
15 //
16 // Copyright (C) 2013, NVIDIA Corporation, all rights reserved.
17 // Third party copyrights are property of their respective owners.
18 //
19 // Redistribution and use in source and binary forms, with or without modification,
20 // are permitted provided that the following conditions are met:
21 //
22 // * Redistribution's of source code must retain the above copyright notice,
23 // this list of conditions and the following disclaimer.
24 //
25 // * Redistribution's in binary form must reproduce the above copyright notice,
26 // this list of conditions and the following disclaimer in the documentation
27 // and/or other materials provided with the distribution.
28 //
29 // * The name of the copyright holders may not be used to endorse or promote products
30 // derived from this software without specific prior written permission.
31 //
32 // This software is provided by the copyright holders and contributors "as is" and
33 // any express or implied warranties, including, but not limited to, the implied
34 // warranties of merchantability and fitness for a particular purpose are disclaimed.
35 // In no event shall the copyright holders or contributors be liable for any direct,
36 // indirect, incidental, special, exemplary, or consequential damages
37 // (including, but not limited to, procurement of substitute goods or services;
38 // loss of use, data, or profits; or business interruption) however caused
39 // and on any theory of liability, whether in contract, strict liability,
40 // or tort (including negligence or otherwise) arising in any way out of
41 // the use of this software, even if advised of the possibility of such damage.
42 //
43 //M*/
44 
45 #ifndef __PBIO__SMART_PTR__OPENCV_CORE_PTR_INL_HPP__dbae1c6458e54ffbb5f63f308a482027
46 #define __PBIO__SMART_PTR__OPENCV_CORE_PTR_INL_HPP__dbae1c6458e54ffbb5f63f308a482027
47 
48 #include <algorithm>
49 
50 #include "../Error.h"
51 #include "atomic_exchange_add.h"
52 
54 
55 
56 namespace pbio {
57 namespace cv_smart_ptr {
58 namespace cv {
59 
60 
61 namespace detail
62 {
63 
64 // Metafunction to avoid taking a reference to void.
65 template<typename T>
66 struct RefOrVoid { typedef T& type; };
67 
68 template<>
69 struct RefOrVoid<void>{ typedef void type; };
70 
71 template<>
72 struct RefOrVoid<const void>{ typedef const void type; };
73 
74 template<>
75 struct RefOrVoid<volatile void>{ typedef volatile void type; };
76 
77 template<>
78 struct RefOrVoid<const volatile void>{ typedef const volatile void type; };
79 
80 // This class would be private to Ptr, if it didn't have to be a non-template.
81 struct PtrOwner;
82 
83 }
84 
85 template<typename Y>
86 struct DefaultDeleter
87 {
88  void operator () (Y* p) const;
89 };
90 
91 template<typename T>
92 struct Ptr
93 {
94  typedef T element_type;
95 
96  Ptr();
97 
98  template<typename Y>
99  explicit
100  Ptr(Y* p);
101 
102  template<typename Y, typename D>
103  Ptr(Y* p, D d);
104 
105  Ptr(const Ptr& o);
106 
107  template<typename Y>
108  Ptr(const Ptr<Y>& o);
109 
110  template<typename Y>
111  Ptr(const Ptr<Y>& o, T* p);
112 
113  ~Ptr();
114 
115  Ptr& operator = (const Ptr& o);
116 
117  template<typename Y>
118  Ptr& operator = (const Ptr<Y>& o);
119 
120  void release();
121 
122  template<typename Y>
123  void reset(Y* p);
124 
125  template<typename Y, typename D>
126  void reset(Y* p, D d);
127 
128  void swap(Ptr& o);
129 
130  T* get() const;
131 
132  typename detail::RefOrVoid<T>::type operator * () const;
133 
134  T* operator -> () const;
135 
136  operator T* () const;
137 
138  bool empty() const;
139 
140  template<typename Y>
141  Ptr<Y> staticCast() const;
142 
143  template<typename Y>
144  Ptr<Y> constCast() const;
145 
146  template<typename Y>
147  Ptr<Y> dynamicCast() const;
148 
149 private:
150  detail::PtrOwner* owner;
151  T* stored;
152 
153  template<typename Y>
154  friend struct Ptr;
155 };
156 
157 template<typename T>
158 void swap(Ptr<T>& ptr1, Ptr<T>& ptr2);
159 
160 template<typename T>
161 bool operator == (const Ptr<T>& ptr1, const Ptr<T>& ptr2);
162 template<typename T>
163 bool operator != (const Ptr<T>& ptr1, const Ptr<T>& ptr2);
164 
165 
166 
167 
168 
169 
170 template<typename Y>
171 void DefaultDeleter<Y>::operator () (Y* p) const
172 {
173  delete p;
174 }
175 
176 namespace detail
177 {
178 
179 struct PtrOwner
180 {
181  PtrOwner() : refCount(1)
182  {}
183 
184  void incRef()
185  {
186  atomic_exchange_add(refCount, 1);
187  }
188 
189  void decRef()
190  {
191  if (atomic_exchange_add(refCount, -1) == 1) deleteSelf();
192  }
193 
194 protected:
195  virtual ~PtrOwner()
196  {}
197 
198  virtual void deleteSelf() = 0;
199 
200 private:
201  int refCount;
202 
203  // noncopyable
204  PtrOwner(const PtrOwner&);
205  PtrOwner& operator = (const PtrOwner&);
206 };
207 
208 template<typename Y, typename D>
209 struct PtrOwnerImpl : PtrOwner
210 {
211  PtrOwnerImpl(Y* p, D d) : owned(p), deleter(d)
212  {}
213 
214  void deleteSelf()
215  {
216  deleter(owned);
217  delete this;
218  }
219 
220 private:
221  Y* owned;
222  D deleter;
223 };
224 
225 
226 }
227 
228 template<typename T>
229 Ptr<T>::Ptr() : owner(NULL), stored(NULL)
230 {}
231 
232 template<typename T>
233 template<typename Y>
234 Ptr<T>::Ptr(Y* p)
235  : owner(p
236  ? new detail::PtrOwnerImpl<Y, DefaultDeleter<Y> >(p, DefaultDeleter<Y>())
237  : NULL),
238  stored(p)
239 {}
240 
241 template<typename T>
242 template<typename Y, typename D>
243 Ptr<T>::Ptr(Y* p, D d)
244  : owner(p
245  ? new detail::PtrOwnerImpl<Y, D>(p, d)
246  : NULL),
247  stored(p)
248 {}
249 
250 template<typename T>
251 Ptr<T>::Ptr(const Ptr& o) : owner(o.owner), stored(o.stored)
252 {
253  if (owner) owner->incRef();
254 }
255 
256 template<typename T>
257 template<typename Y>
258 Ptr<T>::Ptr(const Ptr<Y>& o) : owner(o.owner), stored(o.stored)
259 {
260  if (owner) owner->incRef();
261 }
262 
263 template<typename T>
264 template<typename Y>
265 Ptr<T>::Ptr(const Ptr<Y>& o, T* p) : owner(o.owner), stored(p)
266 {
267  if (owner) owner->incRef();
268 }
269 
270 template<typename T>
271 Ptr<T>::~Ptr()
272 {
273  release();
274 }
275 
276 template<typename T>
277 Ptr<T>& Ptr<T>::operator = (const Ptr<T>& o)
278 {
279  Ptr(o).swap(*this);
280  return *this;
281 }
282 
283 template<typename T>
284 template<typename Y>
285 Ptr<T>& Ptr<T>::operator = (const Ptr<Y>& o)
286 {
287  Ptr(o).swap(*this);
288  return *this;
289 }
290 
291 template<typename T>
292 void Ptr<T>::release()
293 {
294  if (owner) owner->decRef();
295  owner = NULL;
296  stored = NULL;
297 }
298 
299 template<typename T>
300 template<typename Y>
301 void Ptr<T>::reset(Y* p)
302 {
303  Ptr(p).swap(*this);
304 }
305 
306 template<typename T>
307 template<typename Y, typename D>
308 void Ptr<T>::reset(Y* p, D d)
309 {
310  Ptr(p, d).swap(*this);
311 }
312 
313 template<typename T>
314 void Ptr<T>::swap(Ptr<T>& o)
315 {
316  std::swap(owner, o.owner);
317  std::swap(stored, o.stored);
318 }
319 
320 template<typename T>
321 T* Ptr<T>::get() const
322 {
323  return stored;
324 }
325 
326 template<typename T>
327 typename detail::RefOrVoid<T>::type Ptr<T>::operator * () const
328 {
329  if(!stored)
330  {
331  throw pbio::Error(0x1afccd1c, "Error: Ptr::operator* called with NULL pointer stored, error code: 0x1afccd1c.");
332  }
333  return *stored;
334 }
335 
336 template<typename T>
337 T* Ptr<T>::operator -> () const
338 {
339  if(!stored)
340  {
341  throw pbio::Error(0x42a96bad, "Error: Ptr::operator-> called with NULL pointer stored, error code: 0x42a96bad.");
342  }
343  return stored;
344 }
345 
346 template<typename T>
347 Ptr<T>::operator T* () const
348 {
349  return stored;
350 }
351 
352 
353 template<typename T>
354 bool Ptr<T>::empty() const
355 {
356  return !stored;
357 }
358 
359 template<typename T>
360 template<typename Y>
361 Ptr<Y> Ptr<T>::staticCast() const
362 {
363  return Ptr<Y>(*this, static_cast<Y*>(stored));
364 }
365 
366 template<typename T>
367 template<typename Y>
368 Ptr<Y> Ptr<T>::constCast() const
369 {
370  return Ptr<Y>(*this, const_cast<Y*>(stored));
371 }
372 
373 template<typename T>
374 template<typename Y>
375 Ptr<Y> Ptr<T>::dynamicCast() const
376 {
377  return Ptr<Y>(*this, dynamic_cast<Y*>(stored));
378 }
379 
380 template<typename T>
381 void swap(Ptr<T>& ptr1, Ptr<T>& ptr2){
382  ptr1.swap(ptr2);
383 }
384 
385 template<typename T>
386 bool operator == (const Ptr<T>& ptr1, const Ptr<T>& ptr2)
387 {
388  return ptr1.get() == ptr2.get();
389 }
390 
391 template<typename T>
392 bool operator != (const Ptr<T>& ptr1, const Ptr<T>& ptr2)
393 {
394  return ptr1.get() != ptr2.get();
395 }
396 
397 } // namespace cv
398 } // namespace cv_smart_ptr
399 } // namespace pbio
400 
401 
403 
404 #endif // __PBIO__SMART_PTR__OPENCV_CORE_PTR_INL_HPP__dbae1c6458e54ffbb5f63f308a482027
The class of exceptions thrown when errors occur.
Definition: Error.h:26