pingus-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pingus-CVS] r2710 - branches/pingus_sdl/src


From: jsalmon3
Subject: [Pingus-CVS] r2710 - branches/pingus_sdl/src
Date: Thu, 12 Jul 2007 09:18:26 +0200

Author: jsalmon3
Date: 2007-07-12 09:18:22 +0200 (Thu, 12 Jul 2007)
New Revision: 2710

Modified:
   branches/pingus_sdl/src/shared_ptr.hpp
Log:
Added a more complete SharedPtr class, fixes many large memory leaks

Modified: branches/pingus_sdl/src/shared_ptr.hpp
===================================================================
--- branches/pingus_sdl/src/shared_ptr.hpp      2007-07-11 04:28:40 UTC (rev 
2709)
+++ branches/pingus_sdl/src/shared_ptr.hpp      2007-07-12 07:18:22 UTC (rev 
2710)
@@ -22,32 +22,147 @@
 
 #include <assert.h>
 
+// This code is a modified version of CL_SharedPtr from ClanLib
+
+class UnknownSharedPtrImpl
+{
+public:
+  UnknownSharedPtrImpl() : count(1) {}
+  virtual ~UnknownSharedPtrImpl() {}
+
+  unsigned count;
+};
+
+template<typename U>
+class SharedPtrImpl : public UnknownSharedPtrImpl
+{
+public:
+  SharedPtrImpl() : ptr(0) {}
+
+  U* ptr;
+};
+
+template<typename T, typename U>
+class SharedPtrDelete : public SharedPtrImpl<T>
+{
+public:
+  SharedPtrDelete(U* ptr) { this->ptr = ptr; }
+  ~SharedPtrDelete() { delete this->ptr; }
+};
+
+class UnknownSharedPtr;
+
 /** */
-template<typename T>
+template<typename T, typename U = T>
 class SharedPtr
 {
-private:
-  T* ptr;
 public:
-  template<typename Parent> friend class SharedPtr;
-
-  SharedPtr() : ptr(0) {}
-  SharedPtr(T* p) : ptr(p) {}
+  SharedPtr() : impl(0) {}
+  SharedPtr(const SharedPtr<T, U>& ptr) : impl(ptr.impl) { increment(); }
+  SharedPtr(const UnknownSharedPtr& ptr) : impl(0) {
+    if (ptr.impl) {
+      impl = dynamic_cast<SharedPtrImpl<T>*>(ptr.impl);
+      increment();
+    }
+  }
   
-  template <typename Parent>
-  SharedPtr(const SharedPtr<Parent>& p) : ptr(p.ptr) {}
+  template<typename D>
+  explicit SharedPtr(D* ptr) : impl(0) {
+    if (ptr)
+      impl = new SharedPtrDelete<T, D>(ptr);
+  }
+  explicit SharedPtr(SharedPtrImpl<T>* impl) : impl(impl) { increment(); }
+  
+  ~SharedPtr() { decrement(); }
 
-  T& operator*() { assert(ptr); return *ptr; }
-  T const& operator*() const { assert(ptr); return *ptr; }
+  bool operator==(const T* ptr) const { return ptr == (impl ? impl.ptr : 0); }
+  bool operator==(const SharedPtr<T, U>& ptr) const { return ptr.impl == impl; 
}
 
-  T* operator->() { assert(ptr); return ptr; }
-  T const* operator->() const { assert(ptr); return ptr; }
+  SharedPtr<T>& operator=(const SharedPtr<T>& ptr) {
+    if (ptr.impl != impl) {
+      decrement();
+      impl = ptr.impl;
+      increment();
+    }
+    return *this;
+  }
+  SharedPtr<T>& operator=(const UnknownSharedPtr& ptr) {
+    if (ptr.impl != impl) {
+      decrement();
+      if (ptr.impl) {
+       impl = dynamic_cast<SharedPtrImpl<T>*>(ptr.impl);
+       increment();
+      }
+    }
+    return *this;
+  }
 
-  T* get() const { return ptr; }
+  U& operator*() { assert(impl); return *((U*)impl->ptr); }
+  U const& operator*() const { assert(impl); return *((const U*)impl->ptr); }
 
-  operator bool() const { return ptr; }
+  U* operator->() { assert(impl); return (U*)(impl->ptr); }
+  U const* operator->() const { assert(impl); return (const U*)(impl->ptr); }
+
+  const U* get() const { return (U*)(impl ? impl->ptr : 0); }
+
+  operator bool() const { return impl ? impl->ptr : 0; }
+
+private:
+  SharedPtrImpl<T>* impl;
+
+  void increment() {
+    if (impl)
+      impl->count++;
+  }
+  void decrement() {
+    if (impl && --impl->count == 0) {
+      delete impl;
+      impl = 0;
+    }
+  }
+
+  friend class UnknownSharedPtr;
 };
 
+class UnknownSharedPtr
+{
+public:
+  UnknownSharedPtr() : impl(0) {}
+  template<typename T>
+  explicit UnknownSharedPtr(const SharedPtr<T>& ptr) : impl(ptr.impl) {
+    increment();
+  }
+  ~UnknownSharedPtr() { decrement(); }
+
+  bool operator==(const UnknownSharedPtr& ptr) const { return ptr.impl == 
impl; }
+  template <typename T, typename U>
+  bool operator==(const SharedPtr<T, U>& ptr) const { return ptr.impl == impl; 
}
+
+  template<typename T, typename U>
+  UnknownSharedPtr& operator=(const SharedPtr<T, U>& ptr) {
+    if (ptr.impl != impl) {
+      decrement();
+      impl = ptr.impl;
+      increment();
+    }
+    return *this;
+  }
+
+private:
+  UnknownSharedPtrImpl* impl;
+
+  void increment() {
+    if (impl)
+      impl->count++;
+  }
+  void decrement() {
+    if (impl && --impl->count == 0) {
+      delete impl;
+      impl = 0;
+    }
+  }
+};
+
 #endif
 
 /* EOF */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]