00001 /* 00002 * 00003 * 00004 * Distributed under the OpenDDS License. 00005 * See: http://www.opendds.org/license.html 00006 */ 00007 00008 #ifndef OPENDDS_RCHANDLE_T_H 00009 #define OPENDDS_RCHANDLE_T_H 00010 00011 namespace OpenDDS { 00012 namespace DCPS { 00013 00014 /// Templated Reference counted handle to a pointer. 00015 /// A non-DDS specific helper class. 00016 template <typename T> 00017 class RcHandle { 00018 public: 00019 00020 RcHandle() 00021 : ptr_(0) 00022 {} 00023 00024 RcHandle(T* p, bool take_ownership = true) 00025 : ptr_(p) 00026 { 00027 if (!take_ownership) { 00028 this->bump_up(); 00029 } 00030 } 00031 00032 RcHandle(const RcHandle& b) 00033 : ptr_(b.ptr_) 00034 { 00035 this->bump_up(); 00036 } 00037 00038 ~RcHandle() 00039 { 00040 this->bump_down(); 00041 } 00042 00043 RcHandle& operator=(T* p) 00044 { 00045 RcHandle tmp(p); 00046 swap(tmp); 00047 return *this; 00048 } 00049 00050 RcHandle& operator=(const RcHandle& b) 00051 { 00052 RcHandle tmp(b); 00053 swap(tmp); 00054 return *this; 00055 } 00056 00057 void swap(RcHandle& rhs) 00058 { 00059 T* t = this->ptr_; 00060 this->ptr_ = rhs.ptr_; 00061 rhs.ptr_ = t; 00062 } 00063 00064 T* operator->() const 00065 { 00066 return this->ptr_; 00067 } 00068 00069 T& operator*() const 00070 { 00071 return *this->ptr_; 00072 } 00073 00074 bool is_nil() const 00075 { 00076 return this->ptr_ == 0; 00077 } 00078 00079 T* in() const 00080 { 00081 return this->ptr_; 00082 } 00083 00084 T*& inout() 00085 { 00086 return this->ptr_; 00087 } 00088 00089 T*& out() 00090 { 00091 this->bump_down(); 00092 return this->ptr_; 00093 } 00094 00095 T* _retn() 00096 { 00097 T* retval = this->ptr_; 00098 this->ptr_ = 0; 00099 return retval; 00100 } 00101 00102 bool operator==(const RcHandle& rhs) 00103 { 00104 return in() == rhs.in(); 00105 } 00106 00107 bool operator!=(const RcHandle& rhs) 00108 { 00109 return in() != rhs.in(); 00110 } 00111 00112 private: 00113 00114 void bump_up() 00115 { 00116 if (this->ptr_ != 0) { 00117 this->ptr_->_add_ref(); 00118 } 00119 } 00120 00121 void bump_down() 00122 { 00123 if (this->ptr_ != 0) { 00124 this->ptr_->_remove_ref(); 00125 this->ptr_ = 0; 00126 } 00127 } 00128 00129 /// The actual "unsmart" pointer to the T object. 00130 T* ptr_; 00131 }; 00132 00133 00134 template <typename T> 00135 void swap(RcHandle<T>& lhs, RcHandle<T>& rhs) 00136 { 00137 lhs.swap(rhs); 00138 } 00139 00140 template <typename T, typename U> 00141 RcHandle<T> static_rchandle_cast(const RcHandle<U>& h) 00142 { 00143 return RcHandle<T>(static_cast<T*>(h.in()), false); 00144 } 00145 00146 template <typename T, typename U> 00147 RcHandle<T> const_rchandle_cast(const RcHandle<U>& h) 00148 { 00149 return RcHandle<T>(const_cast<T*>(h.in()), false); 00150 } 00151 00152 template <typename T, typename U> 00153 RcHandle<T> dynamic_rchandle_cast(const RcHandle<U>& h) 00154 { 00155 return RcHandle<T>(dynamic_cast<T*>(h.in()), false); 00156 } 00157 00158 } // namespace DCPS 00159 } // namespace OpenDDS 00160 00161 #endif /* OPENDDS_RCHANDLE_T_H */