00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef FIFE_SHARED_PTR_H_
00022 #define FIFE_SHARED_PTR_H_
00023
00024
00025 #include <cassert>
00026 #include <functional>
00027
00028
00029
00030
00031
00032
00033
00034 #include "fife_stdint.h"
00035
00036 namespace FIFE {
00041 template <typename T>
00042 class SharedPtr {
00043 public:
00044
00049 SharedPtr()
00050 : m_ptr(0), m_refCount(0) {
00051
00052 }
00053
00059 template <typename U>
00060 explicit SharedPtr(U *ptr)
00061 : m_ptr(ptr), m_refCount(ptr ? new uint32_t(1) : 0) {
00062
00063 }
00064
00068 SharedPtr(const SharedPtr& rhs)
00069 : m_ptr(rhs.m_ptr), m_refCount(rhs.m_refCount) {
00070
00071 incRefCount();
00072 }
00073
00079 template <typename U>
00080 SharedPtr(const SharedPtr<U>& rhs) {
00081 m_ptr = rhs.get();
00082 m_refCount = rhs.useCountPtr();
00083 incRefCount();
00084 }
00085
00090 ~SharedPtr() {
00091
00092 decRefCount();
00093
00094
00095 if (m_refCount && *m_refCount == 0) {
00096
00097 delete m_ptr;
00098 delete m_refCount;
00099 m_ptr = 0;
00100 m_refCount = 0;
00101 }
00102 }
00103
00106 SharedPtr& operator=(const SharedPtr& rhs) {
00107
00108 if (rhs.get() == m_ptr) {
00109 return *this;
00110 }
00111
00112
00113
00114 SharedPtr<T> temp(rhs);
00115 swap(temp);
00116 return *this;
00117 }
00118
00123 template <typename U>
00124 SharedPtr& operator=(const SharedPtr<U>& rhs) {
00125
00126 if (rhs.get() == m_ptr) {
00127 return *this;
00128 }
00129
00130
00131
00132 SharedPtr<T> temp(rhs);
00133 swap(temp);
00134 return *this;
00135 }
00136
00140 inline T& operator*() const {
00141 assert(m_ptr);
00142 return *m_ptr;
00143 }
00144
00148 inline T* operator->() const {
00149 assert(m_ptr);
00150 return m_ptr;
00151 }
00152
00155 inline T* get() const {
00156 return m_ptr;
00157 }
00158
00164 inline void reset(T* ptr = 0) {
00165 assert(ptr == 0 || ptr != m_ptr);
00166 SharedPtr<T>(ptr).swap(*this);
00167 }
00168
00173 inline uint32_t useCount() const {
00174 assert(m_refCount);
00175
00176 if (!m_refCount) {
00177 return 0;
00178 }
00179
00180 return *m_refCount;
00181 }
00182
00187 inline uint32_t* useCountPtr() const {
00188 return m_refCount;
00189 }
00190
00197 inline bool unique() const {
00198 assert(m_refCount);
00199 return (*m_refCount == 1);
00200 }
00201
00207 operator bool() const {
00208 return (m_ptr != 0);
00209 }
00210
00213 bool operator!() const {
00214 return (m_ptr == 0);
00215 }
00216
00217 private:
00218
00222 inline void swap(SharedPtr<T>& rhs) {
00223 std::swap(m_ptr, rhs.m_ptr);
00224 std::swap(m_refCount, rhs.m_refCount);
00225 }
00226
00230 inline void incRefCount() {
00231 if (m_refCount) {
00232 ++(*m_refCount);
00233 }
00234 }
00235
00239 inline void decRefCount() {
00240 if (m_refCount) {
00241 --(*m_refCount);
00242 }
00243 }
00244
00245 private:
00246 T* m_ptr;
00247 uint32_t* m_refCount;
00248 };
00249
00252 template <typename T, typename U>
00253 inline bool operator==(const SharedPtr<T>& lhs, const SharedPtr<U>& rhs) {
00254 return (lhs.get() == rhs.get());
00255 }
00256
00259 template <typename T, typename U>
00260 inline bool operator!=(const SharedPtr<T>& lhs, const SharedPtr<U>& rhs) {
00261 return (lhs.get() != rhs.get());
00262 }
00263
00266 template<class T, class U>
00267 inline bool operator<(SharedPtr<T> const& lhs, SharedPtr<U> const& rhs) {
00268 return std::less<const void*>()(lhs.get(), rhs.get());
00269 }
00270
00274 template <typename T>
00275 SharedPtr<T> make_shared(T* ptr) {
00276 return SharedPtr<T>(ptr);
00277 }
00278 }
00279
00280 #endif //FIFE_SHARED_PTR_H_