PolyBoRi
CExtrusivePtr.h
Go to the documentation of this file.
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