ViennaCL - The Vienna Computing Library
1.5.0
|
00001 #ifndef VIENNACL_TOOLS_SHARED_PTR_HPP 00002 #define VIENNACL_TOOLS_SHARED_PTR_HPP 00003 00004 /* ========================================================================= 00005 Copyright (c) 2010-2012, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 Portions of this software are copyright by UChicago Argonne, LLC. 00009 00010 ----------------- 00011 ViennaCL - The Vienna Computing Library 00012 ----------------- 00013 00014 Project Head: Karl Rupp rupp@iue.tuwien.ac.at 00015 00016 (A list of authors and contributors can be found in the PDF manual) 00017 00018 License: MIT (X11), see file LICENSE in the base directory 00019 ============================================================================= */ 00020 00027 #include <cstdlib> 00028 #include <algorithm> 00029 00030 namespace viennacl 00031 { 00032 namespace tools 00033 { 00034 00035 namespace detail 00036 { 00037 00039 class count 00040 { 00041 public: 00042 count(unsigned int val) : val_(val){ } 00043 void dec(){ --val_; } 00044 void inc(){ ++val_; } 00045 bool is_null(){ return val_ == 0; } 00046 unsigned int val(){ return val_; } 00047 private: 00048 unsigned int val_; 00049 }; 00050 00052 struct aux 00053 { 00054 detail::count count; 00055 00056 aux() :count(1) {} 00057 virtual void destroy()=0; 00058 virtual ~aux() {} 00059 }; 00060 00062 template<class U, class Deleter> 00063 struct auximpl: public detail::aux 00064 { 00065 U* p; 00066 Deleter d; 00067 00068 auximpl(U* pu, Deleter x) :p(pu), d(x) {} 00069 virtual void destroy() { d(p); } 00070 }; 00071 00073 template<class U> 00074 struct default_deleter 00075 { 00076 void operator()(U* p) const { delete p; } 00077 }; 00078 00079 } 00080 00082 template<class T> 00083 class shared_ptr 00084 { 00085 template<class U> 00086 friend class shared_ptr; 00087 00088 detail::aux* pa; 00089 T* pt; 00090 00091 public: 00092 00093 shared_ptr() :pa(NULL), pt(NULL) {} 00094 00095 template<class U, class Deleter> 00096 shared_ptr(U* pu, Deleter d) : pa(new detail::auximpl<U, Deleter>(pu, d)), pt(pu) {} 00097 00098 template<class U> 00099 explicit shared_ptr(U* pu) : pa(new detail::auximpl<U, detail::default_deleter<U> >(pu, detail::default_deleter<U>())), pt(pu) {} 00100 00101 shared_ptr(const shared_ptr& s) :pa(s.pa), pt(s.pt) { inc(); } 00102 00103 template<class U> 00104 shared_ptr(const shared_ptr<U>& s) :pa(s.pa), pt(s.pt) { inc(); } 00105 00106 ~shared_ptr() { dec(); } 00107 00108 void reset(){ 00109 shared_ptr<T>().swap(*this); 00110 } 00111 00112 void reset(T * ptr){ 00113 shared_ptr<T>(ptr).swap(*this); 00114 } 00115 00116 void swap(shared_ptr<T> & other){ 00117 std::swap(pt,other.pt); 00118 std::swap(pa, other.pa); 00119 } 00120 00121 00122 shared_ptr& operator=(const shared_ptr& s) 00123 { 00124 if(this!=&s) 00125 { 00126 dec(); 00127 pa = s.pa; 00128 pt = s.pt; 00129 inc(); 00130 } 00131 return *this; 00132 } 00133 00134 T* get() const { return pt; } 00135 00136 T* operator->() const { return pt; } 00137 00138 T& operator*() const { return *pt; } 00139 00140 void inc() { if(pa) pa->count.inc(); } 00141 00142 void dec() 00143 { 00144 if(pa) 00145 { 00146 pa->count.dec(); 00147 00148 if(pa->count.is_null()) 00149 { 00150 pa->destroy(); 00151 delete pa; 00152 pa = NULL; 00153 } 00154 } 00155 } 00156 00157 }; 00158 00159 } 00160 00161 } 00162 00163 #endif // VIENNACL_UTILS_SHARED_PTR_HPP