PolyBoRi
|
00001 // -*- c++ -*- 00002 //***************************************************************************** 00016 //***************************************************************************** 00017 00018 #ifndef polybori_common_CExtrusivePtr_h_ 00019 #define polybori_common_CExtrusivePtr_h_ 00020 00021 // include basic definitions 00022 #include <polybori/pbori_defs.h> 00023 #include <algorithm> // std::swap 00024 00025 BEGIN_NAMESPACE_PBORI 00026 00043 template <class DataType, class ValueType> 00044 class CExtrusivePtr { 00045 00047 typedef CExtrusivePtr self; 00048 00049 public: 00050 00052 typedef DataType data_type; 00053 00055 typedef ValueType value_type; 00056 00058 CExtrusivePtr(const data_type& data, value_type* ptr): 00059 m_data(data), p_ptr(ptr) { lock(); } 00060 00062 CExtrusivePtr(const self& rhs): 00063 m_data(rhs.m_data), p_ptr(rhs.p_ptr) { lock(); } 00064 00065 CExtrusivePtr(): 00066 m_data(), p_ptr(NULL) { } 00067 00069 ~CExtrusivePtr() { release(); } 00070 00072 self& operator=(const self& rhs) { 00073 self(rhs).swap(*this); 00074 return *this; 00075 } 00076 00078 const data_type& data() const { return m_data; } 00079 00081 value_type* get() const { 00082 return p_ptr; 00083 } 00084 00086 const value_type & operator*() const { 00087 PBORI_ASSERT(p_ptr != NULL); 00088 return *p_ptr; 00089 } 00090 00092 value_type & operator*() { 00093 PBORI_ASSERT(p_ptr != NULL); 00094 return *p_ptr; 00095 } 00096 00098 value_type* operator->() const { 00099 PBORI_ASSERT(p_ptr != NULL); 00100 return p_ptr; 00101 } 00102 00104 void swap(self & rhs) { 00105 std::swap(m_data, rhs.m_data); 00106 std::swap(p_ptr, rhs.p_ptr); 00107 } 00108 00109 protected: 00110 void lock() { 00111 extrusive_ptr_add_ref(data(), get()); 00112 } 00113 void release() { 00114 extrusive_ptr_release(data(), get()); 00115 } 00116 00118 data_type m_data; 00119 00121 value_type* p_ptr; 00122 }; 00123 00125 template <class Data1, class Type1, class Data2, class Type2> 00126 inline bool 00127 operator==(const CExtrusivePtr<Data1, Type1> & lhs, 00128 const CExtrusivePtr<Data2, Type2> & rhs) { 00129 return lhs.get() == rhs.get(); 00130 } 00131 00133 template <class Data1, class Type1, class Data2, class Type2> 00134 inline bool 00135 operator!=(const CExtrusivePtr<Data1, Type1> & lhs, 00136 const CExtrusivePtr<Data2, Type2> & rhs) { 00137 return lhs.get() != rhs.get(); 00138 } 00139 00141 template <class Data1, class Type1, class Type2> 00142 inline bool 00143 operator==(const CExtrusivePtr<Data1, Type1> & lhs, Type2 * rhs) { 00144 return lhs.get() == rhs; 00145 } 00146 00148 template <class Data1, class Type1, class Type2> 00149 inline bool 00150 operator!=(const CExtrusivePtr<Data1, Type1> & lhs, Type2* rhs) { 00151 return lhs.get() != rhs; 00152 } 00153 00155 template <class Type1, class Data2, class Type2> 00156 inline bool 00157 operator==(Type1* lhs, const CExtrusivePtr<Data2, Type2> & rhs) { 00158 return lhs == rhs.get(); 00159 } 00160 00162 template <class Type1, class Data2, class Type2> 00163 inline bool 00164 operator!=(Type1* lhs, const CExtrusivePtr<Data2, Type2> & rhs) { 00165 return lhs != rhs.get(); 00166 } 00167 00168 END_NAMESPACE_PBORI 00169 00170 #endif