PolyBoRi
CExtrusivePtr.h
Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //*****************************************************************************
00016 //*****************************************************************************
00017 
00018 // include basic definitions
00019 #include "pbori_defs.h"
00020 
00021 #include <algorithm>            // std::swap
00022 
00023 BEGIN_NAMESPACE_PBORI
00024 
00041 template <class DataType, class ValueType>
00042 class CExtrusivePtr {
00043 
00045   typedef CExtrusivePtr self;
00046 
00047 public:
00048 
00050   typedef DataType data_type;
00051 
00053   typedef ValueType value_type;
00054 
00056   CExtrusivePtr(const data_type& data, value_type* ptr): 
00057     m_data(data), p_ptr(ptr) { lock(); }
00058 
00060   CExtrusivePtr(const self& rhs): 
00061     m_data(rhs.m_data), p_ptr(rhs.p_ptr) { lock(); } 
00062 
00063   CExtrusivePtr(): 
00064     m_data(), p_ptr(NULL) { } 
00065 
00067   ~CExtrusivePtr() { release(); }
00068 
00070   self& operator=(const self& rhs) {
00071     self(rhs).swap(*this);
00072     return *this;
00073   }
00074 
00076   const data_type& data() const { return m_data; }
00077 
00079   value_type* get() const {
00080     return p_ptr;
00081   }
00082 
00084   const value_type & operator*() const {
00085     assert(p_ptr != NULL);
00086     return *p_ptr;
00087   }
00088 
00090   value_type & operator*() {
00091     assert(p_ptr != NULL);
00092     return *p_ptr;
00093   }
00094   
00096   value_type* operator->() const {
00097     assert(p_ptr != NULL);
00098     return p_ptr;
00099   }
00100 
00102   void swap(self & rhs) {
00103     std::swap(m_data, rhs.m_data);
00104     std::swap(p_ptr, rhs.p_ptr);
00105   }
00106 
00107 protected:
00108   void lock() {
00109     extrusive_ptr_add_ref(data(), get());
00110   }
00111   void release() {
00112     extrusive_ptr_release(data(), get());
00113   }
00114 
00116   data_type m_data;
00117 
00119   value_type* p_ptr;
00120 };
00121 
00123 template <class Data1, class Type1, class Data2, class Type2> 
00124 inline bool
00125 operator==(const CExtrusivePtr<Data1, Type1> & lhs, 
00126            const CExtrusivePtr<Data2, Type2> & rhs) {
00127   return lhs.get() == rhs.get();
00128 }
00129 
00131 template <class Data1, class Type1, class Data2, class Type2>
00132 inline bool
00133 operator!=(const CExtrusivePtr<Data1, Type1> & lhs,
00134            const CExtrusivePtr<Data2, Type2> & rhs) {
00135   return lhs.get() != rhs.get();
00136 }
00137 
00139 template <class Data1, class Type1, class Type2>
00140 inline bool
00141 operator==(const CExtrusivePtr<Data1, Type1> & lhs, Type2 * rhs) {
00142   return lhs.get() == rhs;
00143 }
00144 
00146 template <class Data1, class Type1, class Type2>
00147 inline bool 
00148 operator!=(const CExtrusivePtr<Data1, Type1> & lhs, Type2* rhs) {
00149   return lhs.get() != rhs;
00150 }
00151 
00153 template <class Type1, class Data2, class Type2>
00154 inline bool
00155 operator==(Type1* lhs, const CExtrusivePtr<Data2, Type2> & rhs) {
00156   return lhs == rhs.get();
00157 }
00158 
00160 template <class Type1, class Data2, class Type2>
00161 inline bool
00162 operator!=(Type1* lhs, const CExtrusivePtr<Data2, Type2> & rhs) {
00163   return lhs != rhs.get();
00164 }
00165 
00166 END_NAMESPACE_PBORI