00001 /* 00002 * Copyright (C) 2005 Maarten Keijzer 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of version 2 of the GNU General Public License as 00006 * published by the Free Software Foundation. 00007 * 00008 * This program is distributed in the hope that it will be useful, 00009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 * GNU General Public License for more details. 00012 * 00013 * You should have received a copy of the GNU General Public License 00014 * along with this program; if not, write to the Free Software 00015 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00016 */ 00017 00018 #ifndef _SHARED_PTR_H 00019 #define _SHARED_PTR_H 00020 00021 00022 template <class T> class weak_ptr; 00023 00024 template <class T> 00025 class shared_ptr { 00026 private: 00027 T* ptr; 00028 unsigned* count; // 00029 00030 /* special case, null pointer (nil-code) */ 00031 static unsigned* nil() { static unsigned nil_counter(1); return &nil_counter; } 00032 00033 void decref() { if (--(*count) == 0) { delete ptr; delete count; }} 00034 void incref() { ++(*count); } 00035 00036 friend class weak_ptr<T>; 00037 00038 public: 00039 00040 shared_ptr() : ptr(0), count(nil()) { incref(); } 00041 ~shared_ptr() { decref(); } 00042 00043 shared_ptr(const shared_ptr<T>& o) : ptr(o.ptr), count(o.count) { incref(); } 00044 shared_ptr(T* p) : ptr(p), count(new unsigned(1)) {} 00045 explicit shared_ptr(const weak_ptr<T>& w) : ptr(w.ptr), count(w.count) { incref(); } 00046 00047 shared_ptr<T>& operator=(const shared_ptr<T>& o) { 00048 if (ptr == o.ptr) return *this; 00049 decref(); 00050 ptr = o.ptr; 00051 count = o.count; 00052 incref(); 00053 return *this; 00054 } 00055 00056 T* get() { return ptr; } 00057 T* operator->() { return ptr; } 00058 T& operator*() { return *ptr; } 00059 00060 const T* get() const { return ptr; } 00061 const T* operator->() const { return ptr; } 00062 const T& operator*() const { return *ptr; } 00063 00064 bool operator==(const shared_ptr<T>& o) const { return ptr == o.ptr; } 00065 bool operator!=(const shared_ptr<T>& o) const { return ptr != o.ptr; } 00066 bool operator<(const shared_ptr<T>& o) const { return ptr < o.ptr; } 00067 00068 unsigned refcount() const { return *count; } 00069 }; 00070 00071 template <class T> 00072 class weak_ptr { 00073 T* ptr; 00074 unsigned* count; 00075 00076 friend class shared_ptr<T>; 00077 00078 public: 00079 00080 weak_ptr() : ptr(0), count(shared_ptr<T>::nil()) {} 00081 explicit weak_ptr( const shared_ptr<T>& s) : ptr(s.ptr), count(s.count) {} 00082 00083 shared_ptr<T> lock() const { return shared_ptr<T>(*this); } 00084 00085 00086 T* get() { return ptr; } 00087 T* operator->() { return ptr; } 00088 T& operator*() { return *ptr; } 00089 00090 const T* get() const { return ptr; } 00091 const T* operator->() const { return ptr; } 00092 const T& operator*() const { return *ptr; } 00093 00094 bool operator==(const shared_ptr<T>& o) const { return ptr == o.ptr; } 00095 bool operator!=(const shared_ptr<T>& o) const { return ptr != o.ptr; } 00096 bool operator<(const shared_ptr<T>& o) const { return ptr < o.ptr; } 00097 00098 unsigned refcount() const { return *count; } 00099 00100 }; 00101 00102 #endif
1.4.7