]> git.mxchange.org Git - simgear.git/blobdiff - simgear/structure/SGSharedPtr.hxx
Merge branch 'master' of git://gitorious.org/fg/simgear into fredb/winbuild
[simgear.git] / simgear / structure / SGSharedPtr.hxx
index d0f899bd6682945396e8e1b01cc038c05e8b5607..f321b12dc4a3e4578b14276d2e5f74dfded32b2c 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c++-*-
  *
- * Copyright (C) 2005-2006 Mathias Froehlich 
+ * Copyright (C) 2005-2009 Mathias Froehlich 
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
 /// to zero and consequently the objects will never be destroyed.
 /// Always try to use directed graphs where the references away from the
 /// top node are made with SGSharedPtr's and the back references are done with
-/// ordinary pointers.
+/// ordinary pointers or SGWeakPtr's.
 /// There is a very good description of OpenSceneGraphs ref_ptr which is
 /// pretty much the same than this one at
 /// http://dburns.dhs.org/OSG/Articles/RefPointers/RefPointers.html
 
+template<typename T>
+class SGWeakPtr;
+
 template<typename T>
 class SGSharedPtr {
 public:
@@ -49,19 +52,19 @@ public:
   {}
   SGSharedPtr(T* ptr) : _ptr(ptr)
   { get(_ptr); }
-  SGSharedPtr(const SGSharedPtr& p) : _ptr(p.ptr())
+  SGSharedPtr(const SGSharedPtr& p) : _ptr(p.get())
   { get(_ptr); }
   template<typename U>
-  SGSharedPtr(const SGSharedPtr<U>& p) : _ptr(p.ptr())
+  SGSharedPtr(const SGSharedPtr<U>& p) : _ptr(p.get())
   { get(_ptr); }
   ~SGSharedPtr(void)
   { put(); }
   
   SGSharedPtr& operator=(const SGSharedPtr& p)
-  { assign(p.ptr()); return *this; }
+  { assign(p.get()); return *this; }
   template<typename U>
   SGSharedPtr& operator=(const SGSharedPtr<U>& p)
-  { assign(p.ptr()); return *this; }
+  { assign(p.get()); return *this; }
   template<typename U>
   SGSharedPtr& operator=(U* p)
   { assign(p); return *this; }
@@ -74,26 +77,48 @@ public:
   { return _ptr; }
   T* ptr(void) const
   { return _ptr; }
+  T* get(void) const
+  { return _ptr; }
+  T* release()
+  { T* tmp = _ptr; _ptr = 0; T::put(tmp); return tmp; }
 
   bool isShared(void) const
-  { return SGReferenced::shared(_ptr); }
+  { return T::shared(_ptr); }
   unsigned getNumRefs(void) const
-  { return SGReferenced::count(_ptr); }
+  { return T::count(_ptr); }
 
   bool valid(void) const
   { return _ptr; }
 
+  void clear()
+  { put(); }
+  void swap(SGSharedPtr& sharedPtr)
+  { T* tmp = _ptr; _ptr = sharedPtr._ptr; sharedPtr._ptr = tmp; }
+
 private:
   void assign(T* p)
   { get(p); put(); _ptr = p; }
+  void assignNonRef(T* p)
+  { put(); _ptr = p; }
 
   void get(const T* p) const
-  { SGReferenced::get(p); }
+  { T::get(p); }
   void put(void)
-  { if (!SGReferenced::put(_ptr)) { delete _ptr; _ptr = 0; } }
+  { if (!T::put(_ptr)) { delete _ptr; _ptr = 0; } }
   
   // The reference itself.
   T* _ptr;
+
+  template<typename U>
+  friend class SGWeakPtr;
 };
 
+/**
+ * Support for boost::mem_fn
+ */
+template<typename T>
+T* get_pointer(SGSharedPtr<T> const & p)
+{
+  return p.ptr();
+}
 #endif