00001
00002
00016
00017
00018 #ifndef polybori_common_CExtrusivePtr_h_
00019 #define polybori_common_CExtrusivePtr_h_
00020
00021
00022 #include <polybori/pbori_defs.h>
00023 #include <algorithm>
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