00001 #ifndef QUICKSP_H_ 00002 #define QUICKSP_H_ 00003 00004 #include "mythmetaexp.h" 00005 00006 struct NoLock 00007 { 00008 void lock() {} 00009 void unlock() {} 00010 }; 00011 00012 // TODO: implement for threads 00013 // If implemented for threads move the instance pointer to simple_ref_ptr 00014 // so simple access isn't synchronized. 00015 struct ThreadLock 00016 { 00017 void lock() {} 00018 00019 void unlock() {} 00020 }; 00021 00022 // TODO: Get a real reference counted smart pointer in libmyth 00023 template <typename T, class Locker = NoLock> 00024 class simple_ref_ptr 00025 { 00026 public: 00027 simple_ref_ptr() : m_ref(0) 00028 { 00029 } 00030 00031 simple_ref_ptr(T *ptr) 00032 { 00033 m_ref = new ref(ptr); 00034 } 00035 00036 simple_ref_ptr(const simple_ref_ptr &rhs) : m_ref(0) 00037 { 00038 *this = rhs; 00039 } 00040 00041 ~simple_ref_ptr() 00042 { 00043 unref(); 00044 } 00045 00046 simple_ref_ptr &operator=(const simple_ref_ptr &rhs) 00047 { 00048 rhs.m_ref->inc(); 00049 unref(); 00050 m_ref = rhs.m_ref; 00051 00052 return *this; 00053 } 00054 00055 T *operator->() const 00056 { 00057 return get(); 00058 } 00059 00060 T &operator*() const 00061 { 00062 return *get(); 00063 } 00064 00065 T *get() const 00066 { 00067 if (m_ref) return m_ref->get(); 00068 00069 return 0; 00070 } 00071 00072 void reset(T *ptr) 00073 { 00074 unref(); 00075 m_ref = new ref(ptr); 00076 } 00077 00078 typedef T *(simple_ref_ptr<T>::*fake_bool)() const; 00079 00080 operator fake_bool() const 00081 { 00082 return m_ref == 0 ? 0 : &simple_ref_ptr<T>::get; 00083 } 00084 00085 bool operator!() const 00086 { 00087 return m_ref == 0; 00088 } 00089 00090 private: 00091 class ref : public Locker 00092 { 00093 public: 00094 ref(T *ptr) : m_count(1), m_type(ptr) {} 00095 00096 ~ref() 00097 { 00098 delete m_type; 00099 } 00100 00101 unsigned int inc() 00102 { 00103 this->lock(); 00104 ++m_count; 00105 this->unlock(); 00106 return m_count; 00107 } 00108 00109 unsigned int dec() 00110 { 00111 this->lock(); 00112 --m_count; 00113 this->unlock(); 00114 return m_count; 00115 } 00116 00117 T *get() 00118 { 00119 return m_type; 00120 } 00121 00122 T *get() const 00123 { 00124 return m_type; 00125 } 00126 00127 private: 00128 unsigned int m_count; 00129 T *m_type; 00130 }; 00131 00132 void unref() 00133 { 00134 if (m_ref && m_ref->dec() <= 0) 00135 { 00136 delete m_ref; 00137 m_ref = 0; 00138 } 00139 } 00140 00141 private: 00142 ref *m_ref; 00143 }; 00144 00145 template <typename T> 00146 bool operator==(const simple_ref_ptr<T> &lhs, const simple_ref_ptr<T> &rhs) 00147 { 00148 return lhs.get() == rhs.get(); 00149 } 00150 00151 template <typename T> 00152 bool operator!=(const simple_ref_ptr<T> &lhs, const simple_ref_ptr<T> &rhs) 00153 { 00154 return lhs.get() != rhs.get(); 00155 } 00156 00157 #endif // QUICKSP_H_
1.6.3